Project 1: Safe String Library

A complete safe string library implementing strlcpy(), strlcat(), safe snprintf() wrappers, and bounded string operations that prevent buffer overflows.

Quick Reference

Attribute Value
Primary Language C
Alternative Languages Rust, Go
Difficulty Level 2: Intermediate
Time Estimate 1 week
Knowledge Area Secure Coding / String Handling
Tooling GCC, Valgrind, AddressSanitizer
Prerequisites Understanding of C pointers, arrays, and memory layout

What You Will Build

A complete safe string library implementing strlcpy(), strlcat(), safe snprintf() wrappers, and bounded string operations that prevent buffer overflows.

Why It Matters

This project builds core skills that appear repeatedly in real-world systems and tooling.

Core Challenges

  • Handling edge cases → maps to empty strings, NULL pointers, zero-length buffers
  • Ensuring NUL termination → maps to strncpy doesn’t guarantee it
  • Calculating remaining space → maps to preventing off-by-one errors
  • Return value design → maps to detecting truncation

Key Concepts

  • String Representation in C: “C Programming: A Modern Approach” Ch. 13 - K.N. King
  • Buffer Overflow Prevention: “Effective C, 2nd Edition” Ch. 5 - Seacord
  • Safe String Functions: OpenBSD strlcpy(3) man page

Real-World Outcome

$ ./test_safestring
Testing safe_strlcpy...
  ✓ Normal copy: "Hello" -> "Hello"
  ✓ Truncation: "Very long string" -> "Very lon" (truncated, returns 16)
  ✓ Zero-length buffer: Returns strlen(src), no write
  ✓ NULL source: Returns 0, dest unchanged

Testing safe_strlcat...
  ✓ Normal concat: "Hello" + " World" -> "Hello World"
  ✓ Truncation: Properly truncated, returns total needed
  ✓ Full buffer: No overflow, returns needed length

Testing safe_snprintf wrapper...
  ✓ Format string attacks blocked
  ✓ Truncation detected: snprintf_safe returned -1
  ✓ Always NUL-terminated

All 15 tests passed!

Implementation Guide

  1. Reproduce the simplest happy-path scenario.
  2. Build the smallest working version of the core feature.
  3. Add input validation and error handling.
  4. Add instrumentation/logging to confirm behavior.
  5. Refactor into clean modules with tests.

Milestones

  • Milestone 1: Minimal working program that runs end-to-end.
  • Milestone 2: Correct outputs for typical inputs.
  • Milestone 3: Robust handling of edge cases.
  • Milestone 4: Clean structure and documented usage.

Validation Checklist

  • Output matches the real-world outcome example
  • Handles invalid inputs safely
  • Provides clear errors and exit codes
  • Repeatable results across runs

References

  • Main guide: LEARN_SECURE_C_AND_EXPLOIT_AWARENESS.md
  • “Effective C, 2nd Edition” by Robert C. Seacord