Share
## https://sploitus.com/exploit?id=11837B16-AF24-5BE3-98EE-BE6251A2B965
# PACKET_EDIT_MEME - CVE-2026-46331
net/sched `act_pedit` partial-COW page-cache corruption (culprit 899ee91156e5,
present v5.18 .. fixed v7.1-rc7). `packet_edit_meme.c` turns it into
unprivileged local root: a userns CAP_NET_ADMIN child overwrites the cached
ELF metadata of a setuid-root binary with `setgid(0)+setuid(0)+execve("/bin/sh")`
shellcode.
```
make
./packet_edit_meme
./packet_edit_meme --ubuntu # AppArmor-gated Ubuntu: aa-exec bypass first
```
## Targets
| Distro | Kernel | Flag | Result |
|---------------------|-------------------|------------|--------|
| RHEL 10.0 | 6.12.0 | (none) | ROOT |
| Debian 13 trixie | 6.12.90+deb13.1 | (none) | ROOT |
| Ubuntu 24.04.4 | 6.17.0-22 | `--ubuntu` | ROOT |
| Alpine edge | 7.0.10-0-stable | (none) | ROOT |
## Alpine PIE fix
Alpine Linux (musl) compiles PIE executables where the executable PT_LOAD
segment starts at file offset โฅ `0x1000` โ beyond the pedit TCP header offset
limit of 511 bytes. The ELF header and program headers occupy the first
read-only PT_LOAD (file offset 0). This adapted exploit:
1. **Makes page 0 executable** by adding `PF_X` to the first PT_LOAD's
`p_flags` field at file offset `0xB4` (phdr[2] + 4).
2. **Splits the shellcode** to avoid corrupting critical LOAD program headers:
- `e_entry` โ `0x28` (an `e_shoff` field the kernel does not check at exec
time).
- **Trampoline** at file offset `0x28`: a 5-byte `jmp 0x1C8`.
- **Shellcode** at file offset `0x1C8`, overwriting PT_NOTE program headers
that the kernel ignores during exec.
3. **Targets `/bin/mount`** (or any world-readable setuid-root binary on a
non-`nosuid` filesystem) โ Alpine's `/bin/su` (-> `/bin/bbsuid`) has
permissions `---s--x--x` and cannot be opened by an unprivileged user.
## Ubuntu AppArmor gate
Ubuntu denies unconfined unprivileged userns via two sysctls:
```
kernel.apparmor_restrict_unprivileged_userns # denies unconfined userns creation
kernel.apparmor_restrict_unprivileged_unconfined # forces unconfined change_profile to STACK,
# so an aa-exec permissive profile cannot
# shed the userns restriction
```
`--ubuntu` re-execs via `aa-exec -p {trinity,chrome,flatpak}` (profiles that
carry a `userns,` rule).
| Ubuntu | userns | unconfined | aa-exec bypass |
|------------------|--------|------------|----------------|
| 24.04.4 | 1 | 0 | WORKS |
| 26.04 | 1 | 1 | CLOSED |
## Build dependencies
A static `x86_64-linux-gnu` cross-compiler:
```
# Debian / Ubuntu
apt install gcc-x86-64-linux-gnu
# Alpine
apk add gcc musl-dev
```