Skip to content

Commit

Permalink
Reset sx_fbtbc to 0 once we are sure it's a haproxy v2 header fragment
Browse files Browse the repository at this point in the history
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
  • Loading branch information
taodd committed Sep 28, 2024
1 parent d351293 commit 7cb5246
Showing 1 changed file with 4 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/svc_vc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 7cb5246

Please sign in to comment.