Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nfs/nfsd/sunrpc: enforce transport requirements for NFSv4

NFSv4 requires a transport "that is specified to avoid network
congestion" (RFC 7530, section 3.1, paragraph 2). In practical terms,
that means that you should not run NFSv4 over UDP. The server has never
enforced that requirement, however.

This patchset fixes this by adding a new flag to the svc_version that
states that it has these transport requirements. With that, we can check
that the transport has XPT_CONG_CTRL set before processing an RPC. If it
doesn't we reject it with RPC_PROG_MISMATCH.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>

authored by

Jeff Layton and committed by
J. Bruce Fields
5283b03e 362142b2

+27 -6
+2
fs/nfs/callback_xdr.c
··· 1084 1084 .vs_xdrsize = NFS4_CALLBACK_XDRSIZE, 1085 1085 .vs_dispatch = NULL, 1086 1086 .vs_hidden = true, 1087 + .vs_need_cong_ctrl = true, 1087 1088 }; 1088 1089 1089 1090 struct svc_version nfs4_callback_version4 = { ··· 1094 1093 .vs_xdrsize = NFS4_CALLBACK_XDRSIZE, 1095 1094 .vs_dispatch = NULL, 1096 1095 .vs_hidden = true, 1096 + .vs_need_cong_ctrl = true, 1097 1097 };
+7 -6
fs/nfsd/nfs4proc.c
··· 2537 2537 }; 2538 2538 2539 2539 struct svc_version nfsd_version4 = { 2540 - .vs_vers = 4, 2541 - .vs_nproc = 2, 2542 - .vs_proc = nfsd_procedures4, 2543 - .vs_dispatch = nfsd_dispatch, 2544 - .vs_xdrsize = NFS4_SVC_XDRSIZE, 2545 - .vs_rpcb_optnl = true, 2540 + .vs_vers = 4, 2541 + .vs_nproc = 2, 2542 + .vs_proc = nfsd_procedures4, 2543 + .vs_dispatch = nfsd_dispatch, 2544 + .vs_xdrsize = NFS4_SVC_XDRSIZE, 2545 + .vs_rpcb_optnl = true, 2546 + .vs_need_cong_ctrl = true, 2546 2547 }; 2547 2548 2548 2549 /*
+3
include/linux/sunrpc/svc.h
··· 406 406 /* Don't care if the rpcbind registration fails */ 407 407 bool vs_rpcb_optnl; 408 408 409 + /* Need xprt with congestion control */ 410 + bool vs_need_cong_ctrl; 411 + 409 412 /* Override dispatch function (e.g. when caching replies). 410 413 * A return value of 0 means drop the request. 411 414 * vs_dispatch == NULL means use default dispatcher.
+15
net/sunrpc/svc.c
··· 1169 1169 !(versp = progp->pg_vers[vers])) 1170 1170 goto err_bad_vers; 1171 1171 1172 + /* 1173 + * Some protocol versions (namely NFSv4) require some form of 1174 + * congestion control. (See RFC 7530 section 3.1 paragraph 2) 1175 + * In other words, UDP is not allowed. We mark those when setting 1176 + * up the svc_xprt, and verify that here. 1177 + * 1178 + * The spec is not very clear about what error should be returned 1179 + * when someone tries to access a server that is listening on UDP 1180 + * for lower versions. RPC_PROG_MISMATCH seems to be the closest 1181 + * fit. 1182 + */ 1183 + if (versp->vs_need_cong_ctrl && 1184 + !test_bit(XPT_CONG_CTRL, &rqstp->rq_xprt->xpt_flags)) 1185 + goto err_bad_vers; 1186 + 1172 1187 procp = versp->vs_proc + proc; 1173 1188 if (proc >= versp->vs_nproc || !procp->pc_func) 1174 1189 goto err_bad_proc;