Build1 distinct publisher2 min readUpdated
A dev.to walkthrough compiles the same vulnerable socket server with -z execstack and -z noexecstack. The code does not change, the linked image does, and the script reads the wrong file.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
The frame arithmetic is worth doing by hand, because it prices the bug. `handle_client` subtracts 0x160 from rsp, which is 352 bytes [10][14]. The 256-byte `request` array is addressed at rbp-0x150 [12][2], 336 bytes below the frame pointer, so it ends at rbp-0x51 [15]. The socket argument is spilled to rbp-0x154 [11]. That leaves one contiguous region big enough for the 64-byte `buffer`: the 80 bytes between rbp-0x50 and rbp. So the destination starts no more than 80 bytes under the saved frame pointer and no more than 88 under the saved return address, meaning 89 written bytes are enough to reach it [16]. `recv` is capped at 0xff [13], and `strcpy` appends a terminator, so up to 256 bytes can land in those 64: 192 past the end [17]. Eighty-nine needed, 256 available.
None of that arithmetic moves when the flag changes. `-z` is a pass-through to the linker [5], so there is no codegen difference to find in the first place, and `execstack` works by removing a default the linker would otherwise apply [6]. That is why each build step in the script is paired with `readelf -l` rather than a second `objdump` [7][22].
It is also worth being clear about what the protected build does not buy. The source itself explains the exploit as overwriting the saved return address to redirect execution [24]. Refusing to execute bytes on the stack removes one place to put a payload; it does not stop the write, and the 89-byte reach above is unchanged either way.
The material supplied stops mid-disassembly, at the `call` to `recv@plt` [21], so the header dump the whole exercise points at is still owed. Which is fine, because this is the rare mitigation you can verify yourself in two commands: build any object twice, once per `-z` spelling, and compare the program header output. If your toolchain behaves as the author describes, the safe build needs no flag at all [6], and the interesting question is which of your makefiles, spec files, or vendored build scripts names the unsafe one.
One more detail from the same file, for anyone tempted to enable the extra test functions: `test2` calls `strcpy(buffer2[0], buffer1)` where `buffer2` is declared `char *buffer2[10]` and never initialised [19]. That writes through an uninitialised pointer, a different failure entirely, and `_NOTEST` is what keeps it out of the binary [20]. The demo is deliberately vulnerable in exactly one place [4]; the guard is load-bearing.
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
The walkthrough compiles the same server.c twice: once as gcc -g -fno-stack-protector -z execstack -no-pie -o server, once as gcc -g -fno-stack-protector -z noexecstack -no-pie -o server_sNX.
handle_client declares char buffer[BUFFER_SIZE] with BUFFER_SIZE defined as 64, and char request[256].
The code calls recv(client_socket, request, sizeof(request) - 1, 0) and then sets request[bytes_received] = '\0'.
The article describes strcpy(buffer, request) as a deliberate stack-based buffer overflow for educational purposes, noting strcpy performs no bounds checking.
Each build block in the script runs readelf -l on a binary and redirects the output to a .readelf file.
Each binary is disassembled with objdump -M intel --show-raw-insn -d and post-processed by clean_objdump.py.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Strong primary artefacts, missing the decisive one
The source quotes the complete C program, the exact two-build shell script, and a raw Intel-syntax disassembly of handle_client, which makes the code-level and frame-level claims independently checkable from the text itself. Evidence is capped because the artefact that would show where the non-executable-stack setting is recorded — the readelf program headers — is never printed, and the script's own collection of it targets the wrong binary. There is also only one publisher, so nothing is corroborated externally.
No adoption signal in supplied material
The cluster contains one tutorial article. Nothing in it reports a release, deployment, benchmark, usage disclosure, pricing or licence change, or any third-party uptake, so adoption cannot be measured without inventing facts.
Modestly overstated demonstration
The article's technical assertions are sober and mostly self-verifying from the quoted code and disassembly, so there is little rhetorical inflation. The positive tilt comes from the framing: it promises to explain how to make the stack non-executable and its script claims to capture headers for both builds, yet the noexecstack header dump reads the execstack binary and no header output is shown, so the central demonstration is implied rather than delivered.
Low, mainly series continuity
The only incentive visible in the supplied material is authorial series momentum: the piece opens by referring back to the author's preceding article on -fstack-protector and continues a personal 'What Does GCC Actually Do?' sequence on a developer-blogging platform. Nothing in the source ties the walkthrough to a product, vendor, sponsorship, or funding claim, and the technical content is presented as reproducible commands rather than persuasion.
Checkable primaries, single unchallenged source
Confidence is above middling because the load-bearing claims rest on quoted code and a quoted instruction stream whose arithmetic can be recomputed, and the script defect is visible on the page. It is held down by single-publisher sourcing, the absence of the readelf output needed to close the argument, and the fact that the frame-layout conclusions are derived rather than directly stated by the author.
build
The failure modes of AI agents in low-level code have names, and names can be gated in CI1 distinct publisher
build
Shared memory in Java: the mmap is the easy half, the descriptor handoff is the work1 distinct publisher
build
The kernel's unlikely() macro buys you fall-through, and bills you when you guess wrong1 distinct publisher
build
Three manual interventions in a month, and every guard was working as designed1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 23, 2026