Pointers & Memory · intermediate · ~12 min

Memory safety — the whole bug class

Combine capacity, lifetime, initialization, and arithmetic checks before accessing memory.

Overview

Memory safety combines several obligations: access a live object, stay within its bounds, initialize values before reading, and calculate sizes without overflow. Use a small checked copy to connect these obligations before trying larger security exercises.

Core concepts

A valid pointer alone says nothing about how many elements can be written. Carry capacity with the destination and a count with the source. Compute a safe copy count before the loop and preserve storage beyond the intended range.

Check integer arithmetic before using its result for an allocation or a bound. Signed overflow is undefined behavior; comparing a wrapped result afterward is too late.

Capacity checks cannot validate object lifetime or ownership automatically. State those preconditions explicitly. Tests should target one failed obligation at a time so their feedback explains what went wrong.

Lesson

Memory safety combines several obligations: access a live object, stay within its bounds, initialize values before reading, and calculate sizes without overflow. Use a small checked copy to connect these obligations before trying larger security exercises.

Code examples

#include <stdio.h>
int copy_prefix(int *dst, int cap, const int *src, int n) {
    int count = n < cap ? n : cap;
    for (int i = 0; i < count; ++i) dst[i] = src[i];
    return count;
}
int main(void) {
    int src[] = {1, 2, 3};
    int dst[2] = {0};
    int count = copy_prefix(dst, 2, src, 3);
    printf("%d: %d %d\n", count, dst[0], dst[1]);
    return 0;
}

Expected output on a successful allocation, where applicable:

2: 1 2

Line by line

For this example, counts are nonnegative, the buffers are live and disjoint, and their stated extents are valid. The minimum count limits writes to the two-element destination.

Practice tasks

  1. Name the preconditions of copy_prefix before running it.
  2. Solve Capacity-checked copy.
  3. Solve Overflow-checked addition.
  4. Optional later transfer: Safe overlapping copy. Explain why the earlier disjoint-copy contract does not cover overlap.

Summary

Validate arithmetic before calculating sizes, cap accesses by real extents, and keep objects alive. Document what a helper checks and what it requires from its caller.

Practice with these exercises