This is a working notebook, not a magazine. Posts here are research notes: things that broke, things that shouldn’t have worked, and the occasional teardown that turned out to be worth writing down.
How posts work
Every post is a Markdown file in src/content/posts/. The filename becomes the
URL slug, and the frontmatter is schema-validated at build time — a missing
description or a malformed pubDate fails the build rather than shipping a
broken page.
---
title: 'Escaping a hardened container'
description: 'One sentence that shows up on the index and in RSS.'
pubDate: 2026-08-04
tags: ['containers', 'linux']
draft: true
---
Setting draft: true keeps a post visible in astro dev but excluded from
production builds, RSS, and the sitemap.
Code gets the good treatment
Syntax highlighting runs at build time via Shiki, so there’s no client-side JavaScript involved:
import ctypes
libc = ctypes.CDLL("libc.so.6")
# CLONE_NEWUSER | CLONE_NEWNS
if libc.unshare(0x10000000 | 0x00020000) != 0:
raise OSError("unshare failed — no unprivileged user namespaces?")
print("in a fresh namespace")
Inline code like CLONE_NEWUSER renders in amber against the ink background,
and long lines in blocks scroll horizontally rather than wrapping — which
matters when you’re pasting real terminal output:
$ ./probe --target 10.0.0.14 --timeout 2
[*] 10.0.0.14:22 open SSH-2.0-OpenSSH_9.6p1 Debian-4
[*] 10.0.0.14:443 open TLSv1.3 CN=*.internal
[!] 10.0.0.14:8080 open HTTP/1.1 200 Server: Werkzeug/3.0.1 Python/3.11.2
Tables, quotes, the rest
| Primitive | Reliability | Notes |
|---|---|---|
| UAF → tcache | high | needs a heap groom |
| Off-by-one | medium | depends on allocator version |
Race on /proc | low | wildly timing-dependent |
Everything here is written for authorized testing and research. If you need that sentence explained, this blog is not for you.
More soon.