# Source code auditing - Malloc --- Functions useful: --- * alloc_perturb: * If the perturb_byte parameter for malloc is non-zero, the alloc_perturb function sets the n bytes starting from the address pointed to by p to be equal to perturb_byte ^ 0xff. --- # _int_malloc: * argument: size bytes and the main arena. * Convert the given size into a aligned size. * If the main arena pointer is NULL, call sysmalloc to get a mmapped area. fastbins: -- REMOVE_FB: * this derictive removes the respective fastbin from the list. * Checks if the chunk is misaligned or null. * remove the head from the fastbin list in that fastbin chosen (multithreaded process). --- * If the size fits under the fastbin range, then it will allocate the chunk in one of the fastbin. * Does REMOVE_FB for multithreaded or if single thread update the head alone in the only fb poitner. * alloc_perturb is called with the bytes. then returns the pointer to the fastbin chunk. * Check if the index is not corrupted. (by checking if the chunksize is actually corresponding to the fastbin indx size). * Here there is no care for in_use bits. Smallbins: -- * check if the size is suitable in the small bins range in that particular arena pointed by the av. * Check if the doubly linked list pointers are corrupted. (P->bk->fd = P). * Set the prev_in_use bit to true for the next chunk in memory. * if the av doesnt point to the main arena, set non_main_arena bit maybe. * unlink the smallbin chosen from the chain. * after alloc_perturb it returns the allocated small bin chunk. > IF the request is very big then consolidate the fastbins and then continue. ## malloc_consolidate: * It will remove all the fastbins and consolidate them (merge them with the adjacent free chunks) which are the unsorted bins. * Check: if the size of the chunk is equal to prevsize of next chunk. * If previous chunk is free call unlink on it. * If the next chunk is top chunk just merge into it. * If the nexr chunk is also free and its not the top chunk then unlink is called on the chunk. Unsorted bins: -- * Now that it is here, it will go through the unsorted bins and has different checks on it. * check if the size is < sys_mem and size is a valid size. * Also checks if the next chunk after this chunk is having a correct size(< sys_mem). * Checks if the size is correct from the prev_size of the next chunk in the offset. * prev_in_use is also checked for the next chunk in memory. - * If the size asked is small bin range, victim = lastchunkremainder then spilt the chunk into the correct size and leftover is made the last remainder chunk. * call alloc_perturb nd then return the chunk allcoated after a check(check_malloced_chunk). Again Unsorted bins: * check if the backward chunks fd is the current selected chunk, else raise error. * If it is the exact fit then just alloc_perturb and return the chunk. * If the remainder chunk fits into the smallbin range then bin it in the arena (update the HEAD). * Else put it in the large bins and also keep the large bins in sorted manner. * make around 10k iterations to move the unsorted chunks into small and large bins. Post iterations: * If not in smallbin range: choose appropriate bin, (avoids removing the first entry). * So if not last, size is correct; unlink it from the doubly linked list. * make the remainder split and be a seperate chunk. make size fwd, bck null. Set headers and alloc_perturb and return the chunk. * Using bestfit find a chunk and then bitmaps helps to avoid the empty chunks. * Do the same as above when you find the appropriate chunk to be used. (slpitting and stuff) -> If there is still no pointer for the victim the top_chunk will be used to provide the heap chunk. # _int_free: * Check if the size is wrapping around and misaligned chunk. Also check if its a multiple of the alignment. * if eligible place it in the fastbin chunks list. * Locking and stuff happens here for making sure each process has its own thingy. * do free_perturb which will just fill the entire space with a set byte. * double free check if you are freeing the thing that was freed before this. * single thread no need lock, else lock and do stuff. * if no prev_used consolidate backward, if next is not used consolidate forward. * chunks are not placed in the bins until they are used atleast once. * do more stuff... # __libc_malloc: * some initialisation, arena_get is called. locks (thread related stuff is done). just returns the pointer given by the _int_malloc. * Wrapper for _int_malloc. # Safe linking: * fastbins and tcache forward links are protected by randomness from ASLR. * PROTECT_PTR: will do some XORing. the least nibble needs to be 0 after all the de-mangling. * hence REVEAL_PTR to get the actual address, PROTECT_PTR to mangle it. # Unlink_chunk: * chunk size checked to be equal to prev size of next chunk. * fd->bk == p and bk->fd == p should be true always. * normal unlinking happens here.