(Hakuna ukaguzi ulioelezwa katika muhtasari huu na baadhi ya kesi zimeachwa kwa kifupi)
Ikiwa anwani ni null, usifanye chochote
Ikiwa kipande kilikuwa kimemmaped, mummap na maliza
Piga _int_free:
Ikiwezekana, ongeza kipande kwenye tcache
Ikiwezekana, ongeza kipande kwenye bakuli la haraka
Piga _int_free_merge_chunk ili kuunganisha kipande ikiwa ni lazima na kuongeza kwenye orodha isiyopangwa
__libc_free
Free inaita __libc_free.
Ikiwa anwani iliyopitishwa ni Null (0) usifanye chochote.
Angalia lebo ya kidude
Ikiwa kipande ni kimemmaped, mummap na hiyo yote
Ikiwa sivyo, ongeza rangi na piga _int_free juu yake
Kificho cha __lib_free
```c void __libc_free (void *mem) { mstate ar_ptr; mchunkptr p; /* chunk corresponding to mem */
if (mem == 0) /* free(0) has no effect */ return;
/* Quickly check that the freed pointer matches the tag for the memory. This gives a useful double-free detection. */ if (__glibc_unlikely (mtag_enabled)) *(volatile char *)mem;
int err = errno;
p = mem2chunk (mem);
if (chunk_is_mmapped (p)) /* release mmapped memory. / { / See if the dynamic brk/mmap threshold needs adjusting. Dumped fake mmapped chunks do not affect the threshold. */ if (!mp_.no_dyn_threshold && chunksize_nomask (p) > mp_.mmap_threshold && chunksize_nomask (p) <= DEFAULT_MMAP_THRESHOLD_MAX) { mp_.mmap_threshold = chunksize (p); mp_.trim_threshold = 2 * mp_.mmap_threshold; LIBC_PROBE (memory_mallopt_free_dyn_thresholds, 2, mp_.mmap_threshold, mp_.trim_threshold); } munmap_chunk (p); } else { MAYBE_INIT_TCACHE ();
/* Mark the chunk as belonging to the library again. */ (void)tag_region (chunk2mem (p), memsize (p));
</details>
## _int_free <a href="#int_free" id="int_free"></a>
### _int_free kuanza <a href="#int_free" id="int_free"></a>
Inaanza na ukaguzi fulani kuhakikisha:
* **kipekee** kime **pangiliwa,** au kuzua kosa `free(): pointer batili`
* **ukubwa** si mdogo kuliko kiwango cha chini na kwamba **ukubwa** pia umepangiliwa au kuzua kosa: `free(): ukubwa batili`
```c
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4493C1-L4513C28
#define aligned_OK(m) (((unsigned long) (m) &MALLOC_ALIGN_MASK) == 0)
static void
_int_free (mstate av, mchunkptr p, int have_lock)
{
INTERNAL_SIZE_T size; /* its size */
mfastbinptr *fb; /* associated fastbin */
size = chunksize (p);
/* Little security check which won't hurt performance: the
allocator never wraps around at the end of the address space.
Therefore we can exclude some size values which might appear
here by accident or by "design" from some intruder. */
if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0)
|| __builtin_expect (misaligned_chunk (p), 0))
malloc_printerr ("free(): invalid pointer");
/* We know that each chunk is at least MINSIZE bytes in size or a
multiple of MALLOC_ALIGNMENT. */
if (__glibc_unlikely (size < MINSIZE || !aligned_OK (size)))
malloc_printerr ("free(): invalid size");
check_inuse_chunk(av, p);
_int_free tcache
Kwanza itajaribu kutenga kipande hiki katika tcache inayohusiana. Walakini, ukaguzi fulani hufanywa hapo awali. Itapita kupitia vikundi vyote vya tcache katika index sawa na kipande kilichofutwa na:
Ikiwa kuna viingilio zaidi ya mp_.tcache_count: free(): too many chunks detected in tcache
Ikiwa kuingilio sio sawa: free(): unaligned chunk detected in tcache 2
ikiwa kipande kilichofutwa tayari kimefutwa na kipo kama kipande katika tcache: free(): double free detected in tcache 2
Ikiwa mambo yote yanaenda vizuri, kipande kitawekwa kwenye tcache na kazi itarudi.
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4515C1-L4554C7#ifUSE_TCACHE{size_t tc_idx =csize2tidx (size);if (tcache !=NULL&& tc_idx <mp_.tcache_bins){/* Check to see if it's already in the tcache. */tcache_entry *e = (tcache_entry *) chunk2mem (p);/* This test succeeds on double free. However, we don't 100%trust it (it also matches random payload data at a 1 in2^<size_t> chance), so verify it's not an unlikelycoincidence before aborting. */if (__glibc_unlikely (e->key == tcache_key)){tcache_entry *tmp;size_t cnt =0;LIBC_PROBE (memory_tcache_double_free,2, e, tc_idx);for (tmp =tcache->entries[tc_idx];tmp;tmp =REVEAL_PTR (tmp->next),++cnt){if (cnt >=mp_.tcache_count)malloc_printerr ("free(): too many chunks detected in tcache");if (__glibc_unlikely (!aligned_OK (tmp)))malloc_printerr ("free(): unaligned chunk detected in tcache 2");if (tmp == e)malloc_printerr ("free(): double free detected in tcache 2");/* If we get here, it was a coincidence. We've wasted afew cycles, but don't abort. */}}if (tcache->counts[tc_idx] <mp_.tcache_count){tcache_put (p, tc_idx);return;}}}#endif
_int_free kikasha cha haraka
Anza kwa kuangalia kwamba ukubwa unafaa kwa kikasha cha haraka na angalia ikiwa inawezekana kuweka karibu na kipande cha juu.
Kisha, ongeza kipande kilichofutwa juu ya kikasha cha haraka wakati ukifanya ukaguzi fulani:
Ikiwa ukubwa wa kipande ni batili (kubwa sana au dogo sana) itasababisha: free(): ukubwa usiofaa (haraka)
Ikiwa kipande kilichoongezwa kilikuwa tayari kilele cha kikasha cha haraka: uhuru maradufu au uharibifu (kilele cha haraka)
Ikiwa ukubwa wa kipande juu una ukubwa tofauti na kipande tunachoongeza: ingizo batili la kikasha cha haraka (uhuru)
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4556C2-L4631C4/*If eligible, place chunk on a fastbin so it can be foundand used quickly in malloc.*/if ((unsignedlong)(size) <= (unsignedlong)(get_max_fast ())#ifTRIM_FASTBINS/*If TRIM_FASTBINS set, don't place chunksbordering top into fastbins*/&& (chunk_at_offset(p, size) != av->top)#endif) {if (__builtin_expect (chunksize_nomask (chunk_at_offset (p, size))<= CHUNK_HDR_SZ,0)||__builtin_expect (chunksize (chunk_at_offset (p, size))>=av->system_mem,0)){bool fail =true;/* We might not have a lock at this point and concurrent modificationsof system_mem might result in a false positive. Redo the test aftergetting the lock. */if (!have_lock){__libc_lock_lock (av->mutex);fail = (chunksize_nomask (chunk_at_offset (p, size))<= CHUNK_HDR_SZ||chunksize (chunk_at_offset (p, size))>=av->system_mem);__libc_lock_unlock (av->mutex);}if (fail)malloc_printerr ("free(): invalid next size (fast)");}free_perturb (chunk2mem(p), size - CHUNK_HDR_SZ);atomic_store_relaxed (&av->have_fastchunks,true);unsignedint idx =fastbin_index(size);fb =&fastbin (av, idx);/* Atomically link P to its fastbin: P->FD = *FB; *FB = P; */mchunkptr old =*fb, old2;if (SINGLE_THREAD_P){/* Check that the top of the bin is not the record we are going toadd (i.e., double free). */if (__builtin_expect (old == p,0))malloc_printerr ("double free or corruption (fasttop)");p->fd =PROTECT_PTR (&p->fd, old);*fb = p;}elsedo{/* Check that the top of the bin is not the record we are going toadd (i.e., double free). */if (__builtin_expect (old == p,0))malloc_printerr ("double free or corruption (fasttop)");old2 = old;p->fd =PROTECT_PTR (&p->fd, old);}while ((old =catomic_compare_and_exchange_val_rel (fb, p, old2))!= old2);/* Check that size of fastbin chunk at the top is the same assize of the chunk that we are adding. We can dereference OLDonly if we have the lock, otherwise it might have already beenallocated again. */if (have_lock && old !=NULL&&__builtin_expect (fastbin_index (chunksize (old)) != idx,0))malloc_printerr ("invalid fastbin entry (free)");}
_int_free mwisho
Ikiwa kipande hakijatawiwa bado kwenye bakuli lolote, piga simu _int_free_merge_chunk
/*Consolidate other non-mmapped chunks as they arrive.*/elseif (!chunk_is_mmapped(p)) {/* If we're single-threaded, don't lock the arena. */if (SINGLE_THREAD_P)have_lock =true;if (!have_lock)__libc_lock_lock (av->mutex);_int_free_merge_chunk (av, p, size);if (!have_lock)__libc_lock_unlock (av->mutex);}/*If the chunk was allocated via mmap, release via munmap().*/else {munmap_chunk (p);}}
_int_free_merge_chunk
Hii function itajaribu kuunganisha chunk P ya SIZE bytes na majirani zake. Weka chunk iliyopatikana kwenye orodha ya bin isiyo na mpangilio.
Baadhi ya ukaguzi unafanywa:
Ikiwa chunk ni top chunk: double free or corruption (top)
Ikiwa chunk inayofuata iko nje ya mipaka ya uwanja: double free or corruption (out)
Ikiwa chunk haijatambulishwa kama iliyotumika (katika prev_inuse kutoka kwa chunk inayofuata): double free or corruption (!prev)
Ikiwa chunk inayofuata ina ukubwa mdogo sana au mkubwa sana: free(): invalid next size (normal)
ikiwa chunk iliyotangulia haiko katika matumizi, itajaribu kuunganisha. Lakini, ikiwa prev_size inatofautiana na ukubwa ulioonyeshwa kwenye chunk iliyotangulia: corrupted size vs. prev_size while consolidating
_int_free_merge_chunk code
```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4660C1-L4702C2
/* Try to merge chunk P of SIZE bytes with its neighbors. Put the resulting chunk on the appropriate bin list. P must not be on a bin list yet, and it can be in use. */ static void _int_free_merge_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size) { mchunkptr nextchunk = chunk_at_offset(p, size);
/* Lightweight tests: check whether the block is already the top block. / if (__glibc_unlikely (p == av->top)) malloc_printerr ("double free or corruption (top)"); / Or whether the next chunk is beyond the boundaries of the arena. */ if (__builtin_expect (contiguous (av) && (char *) nextchunk
= ((char ) av->top + chunksize(av->top)), 0)) malloc_printerr ("double free or corruption (out)"); / Or whether the block is actually not marked used. */ if (__glibc_unlikely (!prev_inuse(nextchunk))) malloc_printerr ("double free or corruption (!prev)");
/* Consolidate backward. */ if (!prev_inuse(p)) { INTERNAL_SIZE_T prevsize = prev_size (p); size += prevsize; p = chunk_at_offset(p, -((long) prevsize)); if (__glibc_unlikely (chunksize(p) != prevsize)) malloc_printerr ("corrupted size vs. prev_size while consolidating"); unlink_chunk (av, p); }
/* Write the chunk header, maybe after merging with the following chunk. */ size = _int_free_create_chunk (av, p, size, nextchunk, nextsize); _int_free_maybe_consolidate (av, size); }
</details>
<div data-gb-custom-block data-tag="hint" data-style='success'>
Jifunze na zoea AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**Mafunzo ya HackTricks ya Mtaalam wa Timu Nyekundu ya AWS (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Jifunze na zoea GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**Mafunzo ya HackTricks ya Mtaalam wa Timu Nyekundu ya GCP (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Angalia [**mpango wa michango**](https://github.com/sponsors/carlospolop)!
* **Jiunge na** 💬 [**Kikundi cha Discord**](https://discord.gg/hRep4RUj7f) au kikundi cha [**telegram**](https://t.me/peass) au **tufuate** kwenye **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Shiriki mbinu za udukuzi kwa kuwasilisha PRs kwa** [**HackTricks**](https://github.com/carlospolop/hacktricks) na [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
</div>