mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
nfscl: Do not use nfso_own for delayed nfsrpc_doclose()
When an initial attempt to close an NFSv4 lock returns NFSERR_DELAY, the open structure is put on a list for delayed closing. When this is done, the nfso_own field is set to NULL, so it cannot be used by nfsrpc_doclose(). Without this patch, the NFSv4 client can crash when a NFSv4 server replies NFSERR_DELAY to a Close operation. Fortunately, most extant NFSv4 servers do not do this. This patch avoids the crash for any that do return NFSERR_DELAY for Close. Found during a IETF bakeathon testing event this week. (cherry picked from commit 6251027c4252edb3b8f8fc359a40e610349e9af3)
This commit is contained in:
parent
8774c92e32
commit
c91861cc21
1 changed files with 14 additions and 6 deletions
|
|
@ -826,6 +826,7 @@ nfsrpc_doclose(struct nfsmount *nmp, struct nfsclopen *op, NFSPROC_T *p,
|
|||
u_int64_t off = 0, len = 0;
|
||||
u_int32_t type = NFSV4LOCKT_READ;
|
||||
int error, do_unlock, trycnt;
|
||||
bool own_not_null;
|
||||
|
||||
tcred = newnfs_getcred();
|
||||
newnfs_copycred(&op->nfso_cred, tcred);
|
||||
|
|
@ -892,22 +893,29 @@ nfsrpc_doclose(struct nfsmount *nmp, struct nfsclopen *op, NFSPROC_T *p,
|
|||
* There could be other Opens for different files on the same
|
||||
* OpenOwner, so locking is required.
|
||||
*/
|
||||
NFSLOCKCLSTATE();
|
||||
nfscl_lockexcl(&op->nfso_own->nfsow_rwlock, NFSCLSTATEMUTEXPTR);
|
||||
NFSUNLOCKCLSTATE();
|
||||
own_not_null = false;
|
||||
if (op->nfso_own != NULL) {
|
||||
own_not_null = true;
|
||||
NFSLOCKCLSTATE();
|
||||
nfscl_lockexcl(&op->nfso_own->nfsow_rwlock, NFSCLSTATEMUTEXPTR);
|
||||
NFSUNLOCKCLSTATE();
|
||||
}
|
||||
do {
|
||||
error = nfscl_tryclose(op, tcred, nmp, p, loop_on_delayed);
|
||||
if (error == NFSERR_GRACE)
|
||||
(void) nfs_catnap(PZERO, error, "nfs_close");
|
||||
} while (error == NFSERR_GRACE);
|
||||
NFSLOCKCLSTATE();
|
||||
nfscl_lockunlock(&op->nfso_own->nfsow_rwlock);
|
||||
if (own_not_null) {
|
||||
NFSLOCKCLSTATE();
|
||||
nfscl_lockunlock(&op->nfso_own->nfsow_rwlock);
|
||||
}
|
||||
|
||||
LIST_FOREACH_SAFE(lp, &op->nfso_lock, nfsl_list, nlp)
|
||||
nfscl_freelockowner(lp, 0);
|
||||
if (freeop && error != NFSERR_DELAY)
|
||||
nfscl_freeopen(op, 0, true);
|
||||
NFSUNLOCKCLSTATE();
|
||||
if (own_not_null)
|
||||
NFSUNLOCKCLSTATE();
|
||||
NFSFREECRED(tcred);
|
||||
return (error);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue