Overflow when copying into a heap buffer

Overflow when copying into a dynamically allocated heap buffer

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 size and the actual copy length. If img.data is a pointer, sizeof(img.data) is the pointer size, not the full data length.
  • After: The example assumes width, height, and data_len are size_t. It checks addition and byte-count multiplication against SIZE_MAX separately, verifies that the actual source length data_len fits the calculated capacity and that allocation succeeds, then copies only the validated number of bytes. It does not use sizeof on img.data, which may be a pointer.

References