Heap out-of-bounds read in libnfs ZDR fixed-opaque decode
fixed
Details
libnfs sahlberg master before 91de6ece9bc7; fixed 2026-07-27 CWE-125 medium fixed Timeline
10 Jul 2026 10 Jul 2026 27 Jul 2026 References
Notes
libnfs is a client, so a hostile (or MITM’d) NFS server can trigger a heap out-of-bounds read while its ZDR reply decoders run.
The fixed-length opaque decoder does not bounds-check before copying. In
libnfs_zdr_opaque() (lib/libnfs-zdr.c, ZDR_DECODE case) the code does
memcpy(objp, &zdrs->buf[zdrs->pos], size) with no guard, whereas every sibling
primitive checks first (e.g. libnfs_zdr_u_int() does
if (zdrs->pos + 4 > zdrs->size) return FALSE). A truncated or malicious reply
that ends just before a fixed-opaque field reads up to size bytes past the
receive buffer. The same primitive decodes many fixed fields — cookie/write/create
verifiers, fixed file handles, NFSv4 verifiers.
Minimal trigger: zdr_READDIR3res → zdr_READDIR3resok → zdr_cookieverf3
(zdr_opaque size 8). An 8-byte READDIR3 reply (status NFS3_OK, then an absent
dir_attributes post_op_attr) leaves the decoder at the 8-byte cookieverf3 with
nothing left, so it reads 8 bytes past the buffer (ASan: OOB READ size 8 at
libnfs-zdr.c:301). Fix: add the same zdrs->pos + size > zdrs->size guard the
sibling primitives already use.