mirror of
https://github.com/opnsense/src.git
synced 2026-06-11 09:41:03 -04:00
nfsd: Fix accumulating nfslockfile structures
If a NFSv4 client does an exclusive open where the file already exists, the server returns EEXIST. However, without this patch, a partially filled in nfslockfile structure is allocated, but is not referenced by any open and, as such, never gets freed. This patch fixes the bug by checking for EEXIST before calling nfsvno_open(). Reported by: Christoper Iler <ciler@volexity.com> Tested by: Christoper Iler <ciler@volexity.com> MFC after: 2 weeks
This commit is contained in:
parent
6b6542ec84
commit
1749465947
1 changed files with 16 additions and 12 deletions
|
|
@ -2857,7 +2857,7 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram,
|
|||
int how = NFSCREATE_UNCHECKED;
|
||||
int32_t cverf[2], tverf[2] = { 0, 0 };
|
||||
vnode_t vp = NULL, dirp = NULL;
|
||||
struct nfsvattr nva, dirfor, diraft;
|
||||
struct nfsvattr nva, dirfor, diraft, nva2;
|
||||
struct nameidata named;
|
||||
nfsv4stateid_t stateid, delegstateid;
|
||||
nfsattrbit_t attrbits;
|
||||
|
|
@ -3107,11 +3107,23 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram,
|
|||
}
|
||||
break;
|
||||
case NFSCREATE_EXCLUSIVE:
|
||||
exclusive_flag = 1;
|
||||
if (nd->nd_repstat == 0 && named.ni_vp == NULL)
|
||||
nva.na_mode = 0;
|
||||
break;
|
||||
/* FALLTHROUGH */
|
||||
case NFSCREATE_EXCLUSIVE41:
|
||||
if (nd->nd_repstat == 0 && named.ni_vp != NULL) {
|
||||
nd->nd_repstat = nfsvno_getattr(named.ni_vp,
|
||||
&nva2, nd, p, 1, NULL);
|
||||
if (nd->nd_repstat == 0) {
|
||||
tverf[0] = nva2.na_atime.tv_sec;
|
||||
tverf[1] = nva2.na_atime.tv_nsec;
|
||||
if (cverf[0] != tverf[0] ||
|
||||
cverf[1] != tverf[1]))
|
||||
nd->nd_repstat = EEXIST;
|
||||
}
|
||||
if (nd->nd_repstat != 0)
|
||||
done_namei = true;
|
||||
}
|
||||
exclusive_flag = 1;
|
||||
break;
|
||||
}
|
||||
|
|
@ -3201,16 +3213,8 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram,
|
|||
NFSACCCHK_VPISLOCKED, NULL);
|
||||
}
|
||||
|
||||
if (!nd->nd_repstat) {
|
||||
if (!nd->nd_repstat)
|
||||
nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1, NULL);
|
||||
if (!nd->nd_repstat) {
|
||||
tverf[0] = nva.na_atime.tv_sec;
|
||||
tverf[1] = nva.na_atime.tv_nsec;
|
||||
}
|
||||
}
|
||||
if (!nd->nd_repstat && exclusive_flag && (cverf[0] != tverf[0] ||
|
||||
cverf[1] != tverf[1]))
|
||||
nd->nd_repstat = EEXIST;
|
||||
/*
|
||||
* Do the open locking/delegation stuff.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue