Linux System Programming · intermediate · ~20 min
Write defensive tools against /proc fields.
When writing defender tooling, /proc parsing is the foundation. Robust parsing means: cap line length, validate the field shape, default to 'unknown' rather than 0 on parse failure.
osquery, falco, auditd, and every Linux DFIR tool reads /proc. Bugs in those parsers turn into missed detections.
Stable fields: VmRSS, VmPeak, Threads, Pid, PPid, Uid, Name. Less stable: Cgroup, NSpgid, SigQ. Volatile: anything with a timestamp.
Per-PID race. A PID may disappear between you reading /proc/PID/ and reading inside. Always handle ENOENT on subsequent reads.
Pentester mindset. A defender's tool that crashes on a fast-cycling PID is a denial-of-defense vulnerability. Robust = test against bash -c 'while true; do true; done'.
Defensive coding habit. Cap line length. Use sscanf with explicit width specifiers. Always check return.
man 5 proc is the canonical reference; it's huge but indexed.
Beyond the recipes lesson, this one is for engineers writing the forensic tools themselves: cap line lengths, handle short reads, parse fields robustly, and refuse anything that doesn't match the documented format.
FILE *fp = fopen("/proc/self/status", "r");
char line[512];
long vm_rss_kb = -1;
while (fgets(line, sizeof line, fp))
if (sscanf(line, "VmRSS: %ld kB", &vm_rss_kb) == 1) break;
fclose(fp);
Above.
Diff your tool's output against ps -o pid,rss,vsz,comm for the canonical baseline.
Lines bounded; cap explicitly anyway. Some /proc files refuse pread; always sequential fgets.
osquery, falco, auditd, htop, monitorix, every observability agent.
Deep procfs = robust parsing + race awareness + capped reads.