Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

pmem: fix buddy free memory corruption bug

Enforce explicit upper limit for buddy index during memory free
operations. This index is generated during memory free operations of
the buddy bestfit allocator. The index points to each free buddy that
should be coalesced into a greater free memory area. The upper limit
now enforced is the number of entries in the current PMEM region.

Without this fix, pmem_buddy_bestfit_free would continue to corrupt
bytes in ever higher addresses, by power of 2, of memory until
stopped by the high bit being set in the currently examined byte.
Unless the high bit was set immediately at the first invalid byte,
this could have caused memory corruption past the current pmem region
metadata in kernel memory space.

One manifestation of this problem was a corner case where
non-existent buddies were incorrectly coalesced.

In a 12MB region, the buddy free for 8MB tried to coalesce the freed
buddy metadata with a non-existent 8MB buddy which actually belonged
to the following region. This caused the order number in the metadata
belonging to the following region to be incorrectly incremented past
the region boundary. Soon after, there was a subsequent invalid
allocation in that following region past the region boundary.

Signed-off-by: Stephen Biggs <sbiggs@quicinc.com>
  • Loading branch information...
commit 37f48579e75efa785ab8eb98bad3f3d840584447 1 parent 96f2c42
@kangtastic authored
Showing with 2 additions and 1 deletion.
  1. +2 −1  src/kernel/drivers/misc/pmem.c
View
3  src/kernel/drivers/misc/pmem.c
@@ -250,7 +250,8 @@ static int pmem_free(int id, int index)
*/
do {
buddy = PMEM_BUDDY_INDEX(id, curr);
- if (PMEM_IS_FREE(id, buddy) &&
+ if (buddy < pmem[id].num_entries &&
+ PMEM_IS_FREE(id, buddy) &&
PMEM_ORDER(id, buddy) == PMEM_ORDER(id, curr)) {
PMEM_ORDER(id, buddy)++;
PMEM_ORDER(id, curr)++;
Please sign in to comment.
Something went wrong with that request. Please try again.