Mark Ruvald Pedersen has uploaded this change for review. ( https://review.gerrithub.io/c/ffilz/nfs-ganesha/+/1246962?usp=email ) Change subject: XDR: stop consuming the entry3/entryplus3 discriminator twice ...................................................................... XDR: stop consuming the entry3/entryplus3 discriminator twice xdr_dirlist3() and xdr_dirlistplus3() wrapped the entry3/entryplus3 list walkers in xdr_pointer(). Both layers read a "value follows" boolean, but RFC 1813 puts only one in front of each element: [bool=TRUE][entry][bool=TRUE][entry] ... [bool=FALSE] xdr_pointer() consumed the real boolean, so the walker then read the high 32 bits of the first entry's fileid3 as its own discriminator. Both outcomes are broken, and which one you get depends on the server: - High word zero: the walker stops immediately, leaving the zeroed node xdr_pointer() had already allocated as an entry whose name is NULL, and eof is then read from the fileid's low word. FSAL_PROXY_V3 walks that entry and calls strcmp() on the NULL name. - High word non-zero: the stream desyncs, so the following filename3 length is read from the wrong offset. Both were observed against NetApp ONTAP volumes. One puts the significant bits in the upper half -- a fileid of 9242200323076915308 is 0x8042e43a0000006c, so XDR puts 0x8042e43a on the wire first -- and READDIRPLUS against it fails with xdr_string_decode ERROR size 785966203 > max 8192 proxyv3_call: Failed to do xdr_replymsg Another volume hands out fileids below 2^32 and crashed instead. This is very likely the bug behind issue #1142. Only FSAL_PROXY_V3 decodes these. The server encodes non-empty replies through the uio path in xdr_dirlist3_encode() and xdr_dirlistplus3_encode(), and so never exercised the defect; empty continuations do reach the fallback encoder, but both the old and the new code emit [FALSE][eof] correctly there. Encode and decode were wrong symmetrically, so a round trip through this code agreed with itself even though neither direction matched the wire format. Give the walkers the whole chain: they now take the address of the caller's head pointer and own the per-element boolean, and the dirlist functions call them directly instead of through xdr_pointer(). They are renamed to xdr_entry3_list() and xdr_entryplus3_list() and made static, rather than keeping the established rpcgen-style xdr_entry3()/xdr_entryplus3() names with a changed signature. Both call sites are in this file, so nothing else needs them, and an out-of-tree caller now fails to link instead of silently reinterpreting a fileid3 as a pointer. A FALSE discriminator also has to clear the caller's head pointer the way xdr_pointer() did, otherwise decoding an empty or shorter list into a reused destination leaves the previous entries in place. While here, fix a use-after-free on the XDR_FREE path. It saved &(*ent)->nextentry and dereferenced it after freeing the object that field lives in; save the successor by value instead. Note that this fixes directory listing only. Reading file contents through FSAL_PROXY_V3 additionally requires the xdrmem_fillbufs() fix in ntirpc, submitted as nfs-ganesha/ntirpc#408; without it a proxied READ returns the front of the RPC reply rather than the payload. This patch deliberately does not bump the src/libntirpc submodule, so it applies cleanly on top of the current pin. Signed-off-by: Mark Ruvald Pedersen <wabsie@gmail.com> Change-Id: Ib547cd2223cc07be8c02f7d7a3703ed018b1889d --- M src/Protocols/XDR/xdr_nfs23.c M src/include/nfs23.h 2 files changed, 102 insertions(+), 48 deletions(-) git pull ssh://review.gerrithub.io:29418/ffilz/nfs-ganesha refs/changes/62/1246962/1 -- To view, visit https://review.gerrithub.io/c/ffilz/nfs-ganesha/+/1246962?usp=email To unsubscribe, or for help writing mail filters, visit https://review.gerrithub.io/settings?usp=email Gerrit-MessageType: newchange Gerrit-Project: ffilz/nfs-ganesha Gerrit-Branch: next Gerrit-Change-Id: Ib547cd2223cc07be8c02f7d7a3703ed018b1889d Gerrit-Change-Number: 1246962 Gerrit-PatchSet: 1 Gerrit-Owner: Mark Ruvald Pedersen <wabsie@gmail.com>