summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2016-06-25 09:32:35 +0000
committerkib <kib@FreeBSD.org>2016-06-25 09:32:35 +0000
commit0c3043629ef64c112ed0b12479dba33d286795cf (patch)
treeaf508359bb5cbacd4c09b54a2aba5842312ef0f6
parent4ea0d8730695362178cc5e3e727e3a5a5be535bc (diff)
downloadFreeBSD-src-0c3043629ef64c112ed0b12479dba33d286795cf.zip
FreeBSD-src-0c3043629ef64c112ed0b12479dba33d286795cf.tar.gz
MFC r302013:
After the vnode unlock, mount point might be destroyed immediately, dropping the reference on mnt_cred. Prevent this by referencing the temporal credentials before unlock.
-rw-r--r--sys/nlm/nlm_advlock.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/sys/nlm/nlm_advlock.c b/sys/nlm/nlm_advlock.c
index 003a43d..456af87 100644
--- a/sys/nlm/nlm_advlock.c
+++ b/sys/nlm/nlm_advlock.c
@@ -210,7 +210,7 @@ nlm_advlock_internal(struct vnode *vp, void *id, int op, struct flock *fl,
struct rpc_callextra ext;
struct nlm_feedback_arg nf;
AUTH *auth;
- struct ucred *cred;
+ struct ucred *cred, *cred1;
struct nlm_file_svid *ns;
int svid;
int error;
@@ -240,15 +240,17 @@ nlm_advlock_internal(struct vnode *vp, void *id, int op, struct flock *fl,
else
retries = INT_MAX;
- if (unlock_vp)
- VOP_UNLOCK(vp, 0);
-
/*
* We need to switch to mount-point creds so that we can send
- * packets from a privileged port.
+ * packets from a privileged port. Reference mnt_cred and
+ * switch to them before unlocking the vnode, since mount
+ * point could be unmounted right after unlock.
*/
cred = td->td_ucred;
td->td_ucred = vp->v_mount->mnt_cred;
+ crhold(td->td_ucred);
+ if (unlock_vp)
+ VOP_UNLOCK(vp, 0);
host = nlm_find_host_by_name(servername, sa, vers);
auth = authunix_create(cred);
@@ -373,7 +375,9 @@ nlm_advlock_internal(struct vnode *vp, void *id, int op, struct flock *fl,
if (ns)
nlm_free_svid(ns);
+ cred1 = td->td_ucred;
td->td_ucred = cred;
+ crfree(cred1);
AUTH_DESTROY(auth);
nlm_host_release(host);
OpenPOWER on IntegriCloud