sahlberg / libnfs

NFS client library
Other
510 stars 200 forks source link

NFSv3 UDP connection segmentation fault. #450

Closed davidgaleano closed 5 months ago

davidgaleano commented 5 months ago

The pointer rpc->pdu is null when calling rpc_process_reply.

Seems to be related to the changes done for Zero Copy READ3 (https://github.com/sahlberg/libnfs/commit/5e8f7ce273308eb77f94248f4501e574a703c1a5). The previous code was finding the pdu before processing the reply, the new code is broken for UDP connections.

Program received signal SIGSEGV, Segmentation fault.
0x000000000044747f in rpc_process_reply (zdr=0x7fffffffdbd0, rpc=0x30d80350300) at ../sub/libnfs/lib/pdu.c:542
542             msg.body.rbody.reply.areply.verf = _null_auth;

(gdb) bt
#0  0x000000000044747f in rpc_process_reply (zdr=0x7fffffffdbd0, rpc=0x30d80350300) at ../sub/libnfs/lib/pdu.c:542
#1  rpc_process_pdu(struct rpc_context *, char *, int) (rpc=rpc@entry=0x30d80350300, buf=0x30d80050000 "\030\231\261\b", size=28)
    at ../sub/libnfs/lib/pdu.c:860
#2  0x0000000000448c11 in rpc_read_from_socket (rpc=0x30d80350300) at ../sub/libnfs/lib/socket.c:459
#3  rpc_service(struct rpc_context *, int) (rpc=0x30d80350300, revents=5) at ../sub/libnfs/lib/socket.c:808

(gdb) p pdu
$1 = (struct rpc_pdu *) 0x0
(gdb) p rpc->pdu
$2 = (struct rpc_pdu *) 0x0

Please note that GDB points the crash at msg.body.rbody.reply.areply.verf = _null_auth; but in reality the instruction that generates the seg fault is the next line if (pdu->zdr_decode_bufsize > 0) {

sahlberg commented 5 months ago

You are right. It was due to the zero copy refactor.

I have fixed it now in master and verified with examples/nfsclient-listservers (which uses broadcast rpc over udp to detect any local nfs servers)

I will add a test too so that I catch it if it regresses.

davidgaleano commented 5 months ago

Thanks for the quick fix.