# False Positive Analysis Report: LIBC Pointer Misidentification ## Executive Summary The `free(): invalid pointer` error is caused by **SS guessing logic** (lines 58-61 in `core/box/hak_free_api.inc.h`) which incorrectly identifies LIBC pointers as HAKMEM SuperSlab pointers, leading to wrong free path execution. ## Root Cause: SS Guessing Logic ### The Problematic Code ```c // Lines 58-61 in core/box/hak_free_api.inc.h for (int lg=21; lg>=20; lg--) { uintptr_t mask=((uintptr_t)1<magic==SUPERSLAB_MAGIC) { int sidx=slab_index_for(guess,ptr); int cap=ss_slabs_capacity(guess); if (sidx>=0&&sidx CRASH ## Test Results Our test program demonstrates: ``` LIBC pointer: 0x65329b0e42b0 2MB-aligned base: 0x65329b000000 (reading from here is UNSAFE!) ``` The SS guessing reads from `0x65329b000000` which is: - 2,093,072 bytes away from the actual pointer - Arbitrary memory that might contain anything - Not validated as belonging to HAKMEM ## Other Lookup Functions ### ✅ `hak_super_lookup()` - SAFE - Uses proper registry with O(1) lookup - Validates magic BEFORE returning pointer - Thread-safe with acquire/release semantics - Returns NULL for LIBC pointers ### ✅ `hak_pool_mid_lookup()` - SAFE - Uses page descriptor hash table - Only returns true for registered Mid pages - Returns 0 for LIBC pointers ### ✅ `hak_l25_lookup()` - SAFE - Uses page descriptor lookup - Only returns true for registered L2.5 pages - Returns 0 for LIBC pointers ### ❌ SS Guessing (lines 58-61) - UNSAFE - Reads from arbitrary aligned addresses - No proper validation - High false positive risk ## Recommended Fix ### Option 1: Remove SS Guessing (RECOMMENDED) ```c // DELETE lines 58-61 entirely // The registered lookup already handles valid SuperSlabs ``` ### Option 2: Add Proper Validation ```c // Only use registered SuperSlabs, no guessing SuperSlab* ss = hak_super_lookup(ptr); if (ss && ss->magic == SUPERSLAB_MAGIC) { int sidx = slab_index_for(ss, ptr); int cap = ss_slabs_capacity(ss); if (sidx >= 0 && sidx < cap) { hak_tiny_free(ptr); goto done; } } // No guessing loop! ``` ### Option 3: Check Header First ```c // Check header magic BEFORE any SS operations AllocHeader* hdr = (AllocHeader*)((char*)ptr - HEADER_SIZE); if (hdr->magic == HAKMEM_MAGIC) { // Only then try SS operations } else { // Definitely LIBC, use __libc_free() __libc_free(ptr); goto done; } ``` ## Recommended Routing Order The safest routing order for `hak_free_at()`: 1. **NULL check** - Return immediately if ptr is NULL 2. **Header check** - Check HAKMEM_MAGIC first (most reliable) 3. **Registered lookups only** - Use hak_super_lookup(), never guess 4. **Mid/L25 lookups** - These are safe with proper registry 5. **Fallback to LIBC** - If no match, assume LIBC and use __libc_free() ## Impact - **Current**: LIBC pointers can be misidentified → crash - **After fix**: Clean separation between HAKMEM and LIBC pointers - **Performance**: Removing guessing loop actually improves performance ## Action Items 1. **IMMEDIATE**: Remove lines 58-61 (SS guessing loop) 2. **TEST**: Verify LIBC allocations work correctly 3. **AUDIT**: Check for similar guessing logic elsewhere 4. **DOCUMENT**: Add warnings about reading arbitrary aligned memory