pointers-memory · intermediate · ~25 min
The mechanism behind GCC's -fstack-protector.
Implement a stack-canary check by hand: a buffer is bracketed by two "canary" words holding a known magic value. If either word changes, something has overrun the buffer.
The struct and API:
typedef struct { uint32_t canary_lo; char buf[16]; uint32_t canary_hi; } guarded_t;
void guarded_init(guarded_t *g);
int guarded_check(const guarded_t *g); /* 1 if both canaries intact, 0 otherwise */
Implement two functions (no main — the grader calls them):
guarded_init sets both canary_lo and canary_hi to the magic value 0xDEADBEEFu (and zeroes buf).guarded_check returns 1 if both canaries still equal 0xDEADBEEFu, otherwise 0.A pointer to a guarded_t. (The grader simulates corruption by writing to a canary field directly — no real buffer overflow occurs, so this is safe under -fstack-protector.)
guarded_check returns 1 (both canaries intact) or 0 (either has changed). guarded_init returns nothing.
guarded_t g; guarded_init(&g);
guarded_check(&g) -> 1
g.canary_hi = 0xCAFEBABE;
guarded_check(&g) -> 0
u suffix so the literal matches the uint32_t field.Stack canaries are the cheap, ubiquitous defense against buffer overflows — every modern compiler emits them. Implementing the concept yourself in pure C makes the mechanism obvious.
A pointer to a guarded_t.
guarded_check returns 1 (intact) or 0 (corrupted); guarded_init returns nothing.
No allocations; just set / compare fields. Check both canaries against 0xDEADBEEFu.
#include <stdint.h>
#ifndef GUARDED_T_DEFINED
#define GUARDED_T_DEFINED
typedef struct { uint32_t canary_lo; char buf[16]; uint32_t canary_hi; } guarded_t;
#endif
void guarded_init(guarded_t *g);
int guarded_check(const guarded_t *g);
Setting the canary to 0 (any uninitialized memory looks like a corrupted canary); checking only one canary (real overflows can come from either side via under/over-runs); using == against the wrong magic word.
Both canaries intact — return 1. Either canary changed — return 0.
O(1).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.