[SECURITY] NFS symlink chain buffer overflow → remote code execution (net/nfs-common.c)
manizzle alexandria
manizzle.msf at gmail.com
Fri Apr 3 20:44:49 CEST 2026
Hi Tom,
I'm reporting a remotely exploitable buffer overflow in U-Boot's NFS
client that I've confirmed leads to arbitrary code execution.
SUMMARY
A rogue NFS server can chain two READLINK (symlink) responses to
overflow the global nfs_path_buff[2048] in net/nfs-common.c by ~141
bytes. This corrupts the nfs_path pointer and adjacent globals,
allowing the attacker to hijack the NFS state machine and deliver
shellcode to a known memory address. I have a working end-to-end
exploit with code execution confirmed on QEMU ARM (Cortex-A15).
No authentication is required. The overflow triggers during normal
NFS boot before any OS is loaded.
AFFECTED
- All U-Boot versions with CONFIG_CMD_NFS=y (NFS boot support)
- Tested on: 2026.04-rc5, commit c704af3c8b0
- File: net/nfs-common.c, function nfs_readlink_reply(), lines 667-686
ROOT CAUSE
nfs_readlink_reply() reads the symlink target length (rlen) from
the RPC reply and validates it against the packet size, but NOT
against the destination buffer (nfs_path_buff[2048]):
rlen = ntohl(rpc_pkt.u.reply.data[1 + nfsv3_data_offset]);
// Checks rlen fits in packet — CORRECT
if (((uchar *)&rpc_pkt.u.reply.data[0] - (uchar *)&rpc_pkt + rlen) >
len)
return -NFS_RPC_DROP;
// Copies rlen bytes into nfs_path — NO CHECK against buffer size
memcpy(nfs_path + pathlen, ..., rlen);
A single response can't overflow because rlen maxes at ~1128 (packet
size limit). But two chained relative symlinks accumulate path length:
1st READLINK: 1100-byte relative target → nfs_path grows to ~1060B
2nd READLINK: 1128-byte relative target → writes to offset 2189
→ overflows nfs_path_buff[2048] by ~141 bytes
EXPLOIT CHAIN
1. Portmap lookup → attacker returns fake mountd/nfsd ports
2. Mount → attacker returns fake file handle
3. Lookup → attacker returns file handle
4. Read → attacker returns NFSERR_ISDIR (triggers symlink)
5. Readlink #1 → 1100-byte relative symlink (grows path)
6. Readlink #2 → OVERFLOW — overwrites nfs_path pointer to
attacker-planted "/x" string, state machine
survives
7. Mount/Lookup → re-enters NFS flow with controlled path
8. Read → attacker serves ARM shellcode as file content
→ written to image_load_addr (0x42000000)
9. Code execution → shellcode runs, writes "PWNED!" to UART
PROOF
GDB output after exploit:
=== SHELLCODE AT 0x42000000 ===
0x42000000: mov r0, #9
0x42000004: lsl r0, r0, #24 @ r0 = 0x09000000 (UART)
0x42000008: mov r1, #0x50 @ 'P'
0x4200000c: str r1, [r0] @ write to UART
...
=== AFTER EXECUTION ===
pc = 0x42000040 (completed, infinite loop)
r0 = 0x09000000 (UART base)
r1 = 0x0a (newline)
=== QEMU UART ===
Loading: *T #PWNED!
SUGGESTED FIX
Add a bounds check before the memcpy in nfs_readlink_reply():
--- a/net/nfs-common.c
+++ b/net/nfs-common.c
@@ -670,6 +670,10 @@
if (((uchar *)&rpc_pkt.u.reply.data[0] - (uchar *)&rpc_pkt + rlen)
> len)
return -NFS_RPC_DROP;
+ int current_len = strlen(nfs_path) + 1;
+ if (current_len + rlen >= sizeof(nfs_path_buff))
+ return -NFS_RPC_ERR;
+
if (*((char *)&rpc_pkt.u.reply.data[2 + nfsv3_data_offset]) !=
'/') {
I have a full advisory document and working PoC (Python script, ~300
lines) attached. The PoC runs as a rogue NFS server and was tested
against QEMU ARM virt with qemu_arm_defconfig.
I'm requesting a CVE for this issue. I plan to follow standard 90-day
coordinated disclosure. Please let me know if you need anything else
or would like to discuss the fix.
Thanks,
Murtaza Munaim
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ADVISORY.md
Type: text/markdown
Size: 7899 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20260403/dd729a29/attachment.md>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: nfs_rce.py
Type: text/x-python-script
Size: 11713 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20260403/dd729a29/attachment.bin>
More information about the U-Boot
mailing list