Commit 7b7e07a0 authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] nfsd4: fix race in xdr encoding of lock_denied response.

We take a reference on the stateowner, and copy the clientid, instead of just
hoping no one destroys the stateowner before we reference it in
nfsd4_encode_lock_denied.
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: default avatarNeil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent d1c3bc1b
...@@ -1949,8 +1949,11 @@ nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny) ...@@ -1949,8 +1949,11 @@ nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
unsigned int hval = lockownerid_hashval(sop->so_id); unsigned int hval = lockownerid_hashval(sop->so_id);
deny->ld_sop = NULL; deny->ld_sop = NULL;
if (nfs4_verify_lock_stateowner(sop, hval)) if (nfs4_verify_lock_stateowner(sop, hval)) {
kref_get(&sop->so_ref);
deny->ld_sop = sop; deny->ld_sop = sop;
deny->ld_clientid = sop->so_client->cl_clientid;
}
deny->ld_start = fl->fl_start; deny->ld_start = fl->fl_start;
deny->ld_length = ~(u64)0; deny->ld_length = ~(u64)0;
if (fl->fl_end != ~(u64)0) if (fl->fl_end != ~(u64)0)
......
...@@ -1994,9 +1994,10 @@ nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denie ...@@ -1994,9 +1994,10 @@ nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denie
WRITE64(ld->ld_length); WRITE64(ld->ld_length);
WRITE32(ld->ld_type); WRITE32(ld->ld_type);
if (ld->ld_sop) { if (ld->ld_sop) {
WRITEMEM(&ld->ld_sop->so_client->cl_clientid, 8); WRITEMEM(&ld->ld_clientid, 8);
WRITE32(ld->ld_sop->so_owner.len); WRITE32(ld->ld_sop->so_owner.len);
WRITEMEM(ld->ld_sop->so_owner.data, ld->ld_sop->so_owner.len); WRITEMEM(ld->ld_sop->so_owner.data, ld->ld_sop->so_owner.len);
kref_put(&ld->ld_sop->so_ref, nfs4_free_stateowner);
} else { /* non - nfsv4 lock in conflict, no clientid nor owner */ } else { /* non - nfsv4 lock in conflict, no clientid nor owner */
WRITE64((u64)0); /* clientid */ WRITE64((u64)0); /* clientid */
WRITE32(0); /* length of owner name */ WRITE32(0); /* length of owner name */
......
...@@ -116,6 +116,7 @@ struct nfsd4_link { ...@@ -116,6 +116,7 @@ struct nfsd4_link {
}; };
struct nfsd4_lock_denied { struct nfsd4_lock_denied {
clientid_t ld_clientid;
struct nfs4_stateowner *ld_sop; struct nfs4_stateowner *ld_sop;
u64 ld_start; u64 ld_start;
u64 ld_length; u64 ld_length;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment