Skip to content

os/mm: Added a quarantine mechanism to delay reuse of freed chunks for improved use after free detection . - #7478

Open
prathamrajbhatt-456 wants to merge 3 commits into
Samsung:masterfrom
prathamrajbhatt-456:mmu_pr
Open

os/mm: Added a quarantine mechanism to delay reuse of freed chunks for improved use after free detection .#7478
prathamrajbhatt-456 wants to merge 3 commits into
Samsung:masterfrom
prathamrajbhatt-456:mmu_pr

Conversation

@prathamrajbhatt-456

@prathamrajbhatt-456 prathamrajbhatt-456 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

This PR is based on #7475 .
In this we have improved the UAF report by limiting the size of heap dump and fixing poison patterns.

Added a quarantine mechanism to delay reuse of freed chunks for improved use after free detection.
We have used a quarantine list of 32 nodes before making free nodes available for allocation.
This is able to detect test cases for use after free among multiple threads.
like for example -- Thread A frees the memory, Thread B allocates it for use, and Thread A uses it again.

New Configs:
CONFIG_DEBUG_MM_QUARANTINE
CONFIG_DEBUG_MM_QUARANTINE_CHUNKS
CONFIG_DEBUG_MM_QUARANTINE_BYTES
CONFIG_DEBUG_MM_QUARANTINE_MAX_SIZE

[Example Log]
------------------------------------------------------------
 write through a stale pointer after somebody else allocated
------------------------------------------------------------
  [CONFIG] Quarantine: ENABLED
  [STEP 1] Owner allocated 0x63a94bb0
  [STEP 2] Owner freed 0x63a94bb0 - chunk held in quarantine
  [STEP 3] Another allocation landed at 0x63a94c00
  [INFO] Different address - quarantine is holding the freed chunk
  [STEP 4] Writing 0xdeadbeef through stale pointer at offset 0 of 0x63a94bb0
  [STEP 5] Churning heap to age out the held chunk...
#########################################################################################
mm_uaf_verify_range: ERROR: Use after free detected.
mm_dump_node: FREE NODE: addr = 0x63a94ba0, type = F, size = 80, preceding size = 144
mm_dump_node: FREE NODE owner pid = 29 (quartest), allocated by code at addr = 0x0e26e8b1
#########################################################################################
Dump heap: 0x63a94ba0 - 0x63a94bf0
#########################################################################################
63a94ba0: 00000090 0e26e8b1 0000001d 00000050 deadbeef a5a5a5a5 a5a5a5a5 a5a5a5a5
63a94bc0: a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5
63a94be0: a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 80000050 0e26e8e1 0000001d 00000050
#########################################################################################
============================================================
Result: UAF DETECTION TEST
Status: [PASS] - Quarantine caught the UAF!
        (The error report above confirms detection)
============================================================

Fill the data area of a chunk with the 0xA5A5A5A5 poison pattern when it enters the free list, and verify the pattern before the chunk is consumed again.
A mismatch means the chunk was written while it was free, which is a use-after-free by whoever owned it previously.

The pattern is written from mm_addfreechunk(), which every chunk passes through on its way into the free list.

Verification happens wherever a free chunk is consumed:
- mm_malloc() and mm_memalign(), before the chunk is split
- mm_free(), mm_realloc() and mm_shrinkchunk(), before a neighbouring free
  chunk is merged or absorbed. Checking here reports the corruption much
  earlier than waiting for the chunk to be handed out again.

On detection the report prints the ERROR line, the node information via mm_dump_node(), and a hex dump of the whole chunk so that the corrupted words stand out against the 0xA5A5A5A5 background.
Only the data area following the free node bookkeeping is covered.
The allocator reuses the first SIZEOF_MM_FREENODE bytes for flink/blink and the free debug info while a chunk is free, so a write there corrupts the free list and is caught by DEBUGASSERT_MM_FREE_NODE instead.
The covered size is capped by CONFIG_DEBUG_MM_UAF_POISON_SIZE to bound the cost added to every free and every allocation.

New configuration options:
- CONFIG_DEBUG_MM_UAF: enable the detector
- CONFIG_DEBUG_MM_UAF_POISON_SIZE: bytes to poison per chunk, default 64
- CONFIG_DEBUG_MM_UAF_PANIC: assert on detection instead of only reporting

[Example Log]
```bash
mm_uaf_verify: ERROR: Use after free detected.
mm_dump_node: FREE NODE: addr = 0x63a94030, type = F, size = 112, preceding size = 112
mm_dump_node: FREE NODE owner pid = 29 (hello), allocated by code at addr = 0x0e26d4fb
Dump heap: 0x63a94030 - 0x63a940a0
63a94030: 00000070 0e26d4fb 0000001d 00000070 00000000 63a81088 0e26d785 0707001d
63a94050: deadbeef cafebabe 12345678 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5
63a94070: a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5
63a94090: 07070707 07070707 07070707 07070707 80000070 0e26d503 0000001d 00000070
```

Co-Authored-By: Claude

Signed-off-by: seokhun-eom <seokhun.eom@samsung.com>
@prathamrajbhatt-456 prathamrajbhatt-456 changed the title Added a quarantine mechanism to improve UAF detection (Do Not Merge) os/mm: Added a quarantine mechanism to delay reuse of freed chunks for improved use after free detection .(Do Not Merge) Aug 8, 2026
@prathamrajbhatt-456 prathamrajbhatt-456 changed the title os/mm: Added a quarantine mechanism to delay reuse of freed chunks for improved use after free detection .(Do Not Merge) os/mm: Added a quarantine mechanism to delay reuse of freed chunks for improved use after free detection . Aug 21, 2026

/* Check if this is a request to reduce the size of the allocation. */

oldsize = oldnode->size;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A chunk in quarantine still looks allocated, so realloc() on a freed pointer is accepted and grows it in place. The ring keeps the old size, so on release mm_qbytes underflows and memory that is in use again goes on the free list.
could you add the checking which mm_free() already has before this line at line no. 187?
#ifdef CONFIG_DEBUG_MM_QUARANTINE
if (mm_quarantine_contains(heap, oldnode)) {
mdbg("WARNING!! Realloc of a pointer still in quarantine\n");
mm_givesemaphore(heap);
return NULL;
}
#endif
This change is used in mm_free.c file.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated the code and verified on board also.

…nd range-based API

-It makes UAF reports safer by limiting hex dumps and fixing poison patterns.
…r improved UAF detection.

Hold freed chunks in a separate list temporarily instead of free list and verify the poison pattern when chunk is released.
This catches the multi-thread UAF bugs which the basic detector cannot see.

New Configs:
CONFIG_DEBUG_MM_QUARANTINE
CONFIG_DEBUG_MM_QUARANTINE_CHUNKS
CONFIG_DEBUG_MM_QUARANTINE_BYTES
CONFIG_DEBUG_MM_QUARANTINE_MAX_SIZE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants