Description
Copying a fixed or calculated amount of data without ensuring that a heap buffer can hold it may write beyond the allocation.
Potential impact
- Heap metadata corruption, crashes, or arbitrary code execution may result.
Remediation
Derive the allocation size and copy length from the same validated values, and check the destination capacity before copying.
Examples
Before
c
/* width, height and data_len are size_t; data points to data_len bytes. */
struct Image img = load_image();
int size = img.width + img.height;
char *buf = malloc(size);
memcpy(buf, img.data, sizeof(img.data));
After
c
struct Image img = load_image();
const size_t bytes_per_element = 4;
size_t elements;
if (img.width > SIZE_MAX - img.height) { return; }
elements = img.width + img.height;
if (elements > SIZE_MAX / bytes_per_element) { return; }
size_t capacity = elements * bytes_per_element;
if (img.data_len > capacity) { return; }
unsigned char *buf = malloc(capacity);
if (buf == NULL) { return; }
memcpy(buf, img.data, img.data_len);
Explanation:
- Before: The code does not check the relationship between the calculated allocation size
sizeand the actual copy length. Ifimg.datais a pointer,sizeof(img.data)is the pointer size, not the full data length. - After: The example assumes
width,height, anddata_lenaresize_t. It checks addition and byte-count multiplication againstSIZE_MAXseparately, verifies that the actual source lengthdata_lenfits the calculated capacity and that allocation succeeds, then copies only the validated number of bytes. It does not usesizeofonimg.data, which may be a pointer.