cybersecurity · advanced · ~15 min · safe pentest lab

Stack canary guard against buffer overflow

Simulate and understand how compiler and runtime stack canaries detect and trap memory corruptions.

Challenge

Stack canaries are sentinel values placed immediately before stack control data to detect overflows before function return. Defensive architectures also implement manual canary verification in sensitive parser frames.

Your Task

Implement:

int guarded_buffer_copy(const char *src, size_t src_len, char *dst, size_t dst_cap, uint32_t canary);

Frame Layout

Set up a local stack frame containing canaries:

struct frame {
    uint32_t head_canary;
    char buffer[64];
    uint32_t tail_canary;
} f;

Rules

  1. Initialize f.head_canary = canary and f.tail_canary = canary.
  2. If src == NULL, dst == NULL, or dst_cap == 0, return -1.
  3. Pre-check: If src_len >= sizeof(f.buffer) (64 bytes), return -1 without copying (prevent overflow).
  4. Copy src_len bytes from src into f.buffer and NUL-terminate (f.buffer[src_len] = '\0').
  5. Verify canaries: If f.head_canary != canary or f.tail_canary != canary, return -2 (canary corruption detected).
  6. If src_len >= dst_cap, return -1 (dst would overflow).
  7. Copy f.buffer to dst and return 0.

Input format

src: input bytes; src_len: input length; dst: output buffer; dst_cap: destination capacity; canary: sentinel value.

Output format

Returns 0 on clean copy, -1 on bounds violation, -2 on canary corruption.

Constraints

Freestanding C11. Stack canary verification pattern.

Starter code

#include <stddef.h>
#include <stdint.h>

/* Safely copy src into an internal 64-byte canary-guarded frame, verify canaries,
   and copy out to dst. Return 0 on success, -1 on bounds violation, or -2 on canary corruption. */
int guarded_buffer_copy(const char *src, size_t src_len, char *dst, size_t dst_cap, uint32_t canary) {
    (void)src; (void)src_len; (void)dst; (void)dst_cap; (void)canary;
    return -1;
}

Common mistakes

Overwriting buffer without bounds check causing actual stack corruption; forgetting NUL byte.

Edge cases to handle

src_len == 63 fits; src_len == 64 is rejected; corrupted canary returns -2.

Background lessons

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.