Lukas' Notes

security c

Definition

Secure C Coding

Secure C coding is the discipline of writing C string and I/O code so that the bugs the memory-corruption attack cluster exploits never arise — null-terminating strings, bounding every copy against the destination’s size, using the safer library variants, and checking I/O return values. The canonical reference is the SEI CERT C Coding Standard; the goal is to remove the bugs at the source rather than to mitigate them afterward.

Safe String Operations

Practices that close the buffer-overflow class

  • null-terminate — every string ends in a null byte, and every operation must preserve that invariant;
  • size for the terminator — declare and read desired size + 1 so the destination has room for both data and the trailing \0;
  • use the l/n versionsstrlcpy, strlcat, strncmp, and similar take a size argument and check the byte count they move, so the copy cannot overshoot the destination;
  • ensure the chosen function writes the terminatorstrlcpy does, strncpy does not always; pick the function that upholds the invariant, not merely the one that bounds the length.
void copy(size_t n, char src[n], char dest[n]) {
    size_t i;
    for (i = 0; src[i] && (i < n - 1); ++i) { dest[i] = src[i]; }
    dest[i] = '\0';
}

The loop stops at n - 1 rather than n precisely to leave the last slot for the terminator, then re-establishes it explicitly. Match every bounded-string routine to this shape.

Safe I/O

Practices that close the input-handling class

  • declare maximum sizes once, as macros, and use them both at array declaration and as the size argument to every I/O call — MAX_LEN is one source of truth;
  • use fgets instead of getsfgets(buf, n, stream) is bounded; gets never was;
  • check the I/O return valuefgets, read, scanf all signal errors via their return value; ignoring it lets a failed or truncated read silently flow downstream.
#define MAX_LEN 0x20
int main(void) {
    char buffer[MAX_LEN];
    if (fgets(buffer, MAX_LEN, stdin)) {
        char *p = strchr(buffer, '\n');
        if (p) { *p = '\0'; }
        else   { /* handle error: line too long */ }
    }
    printf("%s\n", buffer);
    return 0;
}

The bounds macro, the bounded reader, and the return-value check are three instances of the same idea — size is a first-class concern, not a post-condition.

CERT C Coding Standard

Obs

The discipline above is not a checklist the slides invented; it is codified in the SEI CERT C Coding Standard, which collects rules and recommendations for secure C — covering integers, strings, memory management, I/O, and the format-string and concurrency classes on top. Following a security-focused coding standard is the structural fix the lecture points at: each rule closes one of the bug subclasses the format-string / buffer-overflow attacks exploit, before any runtime mitigation has to catch the residual.