size_t overflow protection

This commit is contained in:
Abhishek Sathiabalan 2022-04-14 11:03:22 -04:00
parent 91b0f7b037
commit 01c2c84566

View File

@ -161,6 +161,32 @@ int mm_init(void)
/* Extend the empty heap with a free block of CHUNKSIZE bytes */
if (extend_heap(CHUNKSIZE) == NULL)
return -1;
void *bug = mm_malloc(SIZE_MAX - 1);
if (bug != NULL) {
struct block *bug_blk = bug - offsetof(struct block, payload);
printf("Bug Size Request: %ld\n Your code might be vulnerable to an size_t overflow attack in mm_malloc.\n", blk_size(bug_blk));
}
void *bug2 = mm_realloc(mm_malloc(2), SIZE_MAX - 1);
if (bug2 != NULL) {
struct block *bug_blk = bug2 - offsetof(struct block, payload);
printf("Bug Size Request: %ld\n Your code might be vulnerable to an size_t overflow attack in mm_realloc.\n", blk_size(bug_blk));
}
void *bug3 = malloc(9223372036854775807 - 1);
if (bug3 != NULL) {
printf("Malloc is vulnerable to size_t overflow attack\n");
}
void *bug4 = realloc(malloc(2), 9223372036854775807 - 1);
void *bug5 = calloc(1, 9223372036854775807 - 1);
if (bug3 != NULL || bug4 != NULL || bug5 != NULL) {
printf("Possible security vulnerability in malloc, realloc, or calloc.\n");
}
return 0;
}
@ -175,11 +201,26 @@ void *mm_malloc(size_t size)
if (size == 0)
return NULL;
size_t original_size = size;
/* Adjust block size to include overhead and alignment reqs. */
size += 2 * sizeof(struct boundary_tag); /* account for tags */
/* Adjusted block size in words */
size_t awords = max(MIN_BLOCK_SIZE_WORDS, align(size)/WSIZE); /* respect minimum size */
/*Overflow check:
The only time that this can occur is when align(size + overhead) exceeds the maximum value
of a size_t of SIZE_MAX (limits.h).
To test this code run:
void *bug = mm_malloc(SIZE_MAX - 1);
if (bug != NULL) {
struct block *bug_blk = bug - offsetof(struct block, payload); //You might need to change this depending on your block struct
printf("Bug Size Request: %ld\n Your code might be vulnerable to an size_t overflow attack in mm_malloc.\n", blk_size(bug_blk));
}
*/
if (awords * WSIZE < original_size) {
return NULL;
}
/* Search the free list for a fit */
if ((bp = find_fit(awords)) != NULL) {
place(bp, awords);
@ -261,6 +302,18 @@ void *mm_realloc(void *ptr, size_t size)
return mm_malloc(size);
}
/*WARNING: This code currently uses the overflow protection in mm_malloc.
Manuallly optimizing your code without checking for an size_t overflow
would leave your code vulnerable to a buffer-overflow attack.
To test this run something like this:
void *bug2 = mm_realloc(mm_malloc(2), SIZE_MAX - 1);
if (bug2 != NULL) {
struct block *bug_blk = bug2 - offsetof(struct block, payload); //You might need to changeg this accordingly
printf("Bug Size Request: %ld\n Your code might be vulnerable to an size_t overflow attack in mm_realloc.\n", blk_size(bug_blk));
}
*/
void *newptr = mm_malloc(size);
/* If realloc() fails the original block is left untouched */