From 7cb5246c1be77fb5cff872c3e6e4546ababee8ae Mon Sep 17 00:00:00 2001 From: Dongdong Tao Date: Sat, 28 Sep 2024 11:38:13 +0000 Subject: [PATCH] Reset sx_fbtbc to 0 once we are sure it's a haproxy v2 header fragment When receiving a haproxy v2 message, after processing the first fragment which only contain the proxy header, the ::recv might return EGAIN if the next fragment is not ready to read yet, then the function svc_vc_recv would return, but left xd->sx_fbtbx == 0x0d0a0d0a (PP2_SIG_UINT32), which was set when parsing the haproxy v2 header. When the next fragment is ready, the epoll event for the same xprt will be trigged, then a non-zero xd->sx_fbtbc would deceit sv_vc_recv into derefrencing a NULL uv pointer. Stack trace: Thread 76 "ganesha.nfsd" received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x7fc9937ee640 (LWP 2931)] 0x00007fc9f3e30fa6 in svc_vc_recv (xprt=0x7fc9dc00e3b0) at /git/nfs-ganesha/src/libntirpc/src/svc_vc.c:1070 1070 flags = uv->u.uio_flags; (gdb) bt (gdb) p uv $1 = (struct xdr_ioq_uv *) 0x0 (gdb) p xd->sx_fbtbc $2 = 218762506 --- src/svc_vc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/svc_vc.c b/src/svc_vc.c index e84658dca..127aaca2b 100644 --- a/src/svc_vc.c +++ b/src/svc_vc.c @@ -775,6 +775,8 @@ static enum haproxy_ret_code handle_haproxy_header(SVCXPRT *xprt) struct proxy_header_part s; union proxy_addr pa; enum haproxy_ret_code ret; + struct rpc_dplx_rec *rec = REC_XPRT(xprt); + struct svc_vc_xprt *xd = VC_DR(rec); __warnx(TIRPC_DEBUG_FLAG_SVC_VC, "%s: %p fd %d potential haproxy packet", @@ -803,6 +805,8 @@ static enum haproxy_ret_code handle_haproxy_header(SVCXPRT *xprt) return HAPROXY_RET_CODE__NOT_HAPROXY; } + /* Reset the sx_fbtbc for HA Proxy v2*/ + xd->sx_fbtbc = 0; rlen = recv(xprt->xp_fd, rest, sizeof(rest), MSG_WAITALL); if (rlen != sizeof(rest)) { __warnx(TIRPC_DEBUG_FLAG_ERROR,