From 73b1879c2d5c87161c291ce27448f8e707e0673e Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Mon, 11 Jun 2018 19:00:07 +0000 Subject: [PATCH] Add a couple of safety belt checks to the NFSv4.1 client related to sessions. There were a couple of cases in newnfs_request() that it assumed that it was an NFSv4.1 mount with a session. This should always be the case when a Sequence operation is in the reply or the server replies NFSERR_BADSESSION. However, if a server was broken and sent an erroneous reply, these safety belt checks should avoid trouble. The one check required a small tweak to nfsmnt_mdssession() so that it returns NULL when there is no session instead of the offset of the field in the structure (0x8 for i386). This patch should have no effect on normal operation of the client. Found by inspection during pNFS server development. MFC after: 2 weeks --- sys/fs/nfs/nfs_commonkrpc.c | 9 +++++---- sys/fs/nfsclient/nfsmount.h | 4 +++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 9dfd9b6f8911..48e92426f7a0 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -852,9 +852,9 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, if ((nmp != NULL && i == NFSV4OP_SEQUENCE && j != 0) || (clp != NULL && i == NFSV4OP_CBSEQUENCE && j != 0)) NFSCL_DEBUG(1, "failed seq=%d\n", j); - if ((nmp != NULL && i == NFSV4OP_SEQUENCE && j == 0) || - (clp != NULL && i == NFSV4OP_CBSEQUENCE && j == 0) - ) { + if (((nmp != NULL && i == NFSV4OP_SEQUENCE && j == 0) || + (clp != NULL && i == NFSV4OP_CBSEQUENCE && + j == 0)) && sep != NULL) { if (i == NFSV4OP_SEQUENCE) NFSM_DISSECT(tl, uint32_t *, NFSX_V4SESSIONID + @@ -896,7 +896,8 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, } if (nd->nd_repstat != 0) { if (nd->nd_repstat == NFSERR_BADSESSION && - nmp != NULL && dssep == NULL) { + nmp != NULL && dssep == NULL && + (nd->nd_flag & ND_NFSV41) != 0) { /* * If this is a client side MDS RPC, mark * the MDS session defunct and initiate diff --git a/sys/fs/nfsclient/nfsmount.h b/sys/fs/nfsclient/nfsmount.h index e04d0cf7c185..ab3147bdb511 100644 --- a/sys/fs/nfsclient/nfsmount.h +++ b/sys/fs/nfsclient/nfsmount.h @@ -129,8 +129,10 @@ nfsmnt_mdssession(struct nfsmount *nmp) { struct nfsclsession *tsep; + tsep = NULL; mtx_lock(&nmp->nm_mtx); - tsep = NFSMNT_MDSSESSION(nmp); + if (TAILQ_FIRST(&nmp->nm_sess) != NULL) + tsep = NFSMNT_MDSSESSION(nmp); mtx_unlock(&nmp->nm_mtx); return (tsep); }