cybersecurity · intermediate · ~15 min · safe pentest lab
Bounds-safe TLV walking with overflow checks at every step.
Implement:
#include <stdint.h>
#include <stddef.h>
int extract_local_name(const uint8_t *adv, size_t n, char *out, size_t cap);
Walk the TLV-encoded advertisement. Each record is:
[len] [type] [value bytes... (len-1 of them)]
Note: len covers type + value together, so the next record starts
at offset + len + 1.
When you encounter a record with type 0x09 (Complete Local Name) OR
0x08 (Shortened Local Name), copy its value bytes into out (bounded
by cap - 1, NUL-terminating), and return the number of value bytes
copied.
Return -1 if:
cap == 0nlen == 0 record is encountered (malformed)cap (need room for NUL)offset starts at 0; each loop iteration reads len
at adv[offset], then type at adv[offset + 1], then advances
by len + 1.len == 0 spins the loop forever.len - 1 (because type
takes one of those bytes).TLV walking is a foundational pattern that shows up in BLE, DHCP, ICMPv6 options, X.509 extensions — get it right once and the rest fall out.
A const byte buffer, its length, a bounded output buffer, and its capacity.
Number of name bytes copied (>= 0) on success, -1 otherwise.
Every byte read must be bounds-checked. NUL-terminate the output. Fail on len==0.
#include <stdint.h>
#include <stddef.h>
int extract_local_name(const uint8_t *adv, size_t n, char *out, size_t cap) {
/* TODO */
(void)adv; (void)n; (void)out; (void)cap;
return -1;
}
Forgetting that len covers type+value (so the value is len - 1 bytes). Allowing len == 0. Reading the value before bounds-checking.
Empty buffer (n == 0). Single record with no name. Name field at the very end of the buffer.
O(n) — visits each byte at most once.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.