diff options
author | kib <kib@FreeBSD.org> | 2012-09-28 11:25:02 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2012-09-28 11:25:02 +0000 |
commit | 8f845e475e69e9777c5f940109bf0c45b87aadda (patch) | |
tree | 2c2a67940ecbf715c5dc909f32de63a9eed6f793 /sys/kern/kern_exec.c | |
parent | 025fb75eb6e2720e82276647d1f8fad9515c281c (diff) | |
download | FreeBSD-src-8f845e475e69e9777c5f940109bf0c45b87aadda.zip FreeBSD-src-8f845e475e69e9777c5f940109bf0c45b87aadda.tar.gz |
Fix the mis-handling of the VV_TEXT on the nullfs vnodes.
If you have a binary on a filesystem which is also mounted over by
nullfs, you could execute the binary from the lower filesystem, or
from the nullfs mount. When executed from lower filesystem, the lower
vnode gets VV_TEXT flag set, and the file cannot be modified while the
binary is active. But, if executed as the nullfs alias, only the
nullfs vnode gets VV_TEXT set, and you still can open the lower vnode
for write.
Add a set of VOPs for the VV_TEXT query, set and clear operations,
which are correctly bypassed to lower vnode.
Tested by: pho (previous version)
MFC after: 2 weeks
Diffstat (limited to 'sys/kern/kern_exec.c')
-rw-r--r-- | sys/kern/kern_exec.c | 13 |
1 files changed, 5 insertions, 8 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 90f7311b..eff0f83 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -473,9 +473,8 @@ interpret: * Remember if this was set before and unset it in case this is not * actually an executable image. */ - textset = imgp->vp->v_vflag & VV_TEXT; - ASSERT_VOP_ELOCKED(imgp->vp, "vv_text"); - imgp->vp->v_vflag |= VV_TEXT; + textset = VOP_IS_TEXT(imgp->vp); + VOP_SET_TEXT(imgp->vp); error = exec_map_first_page(imgp); if (error) @@ -506,10 +505,8 @@ interpret: if (error) { if (error == -1) { - if (textset == 0) { - ASSERT_VOP_ELOCKED(imgp->vp, "vv_text"); - imgp->vp->v_vflag &= ~VV_TEXT; - } + if (textset == 0) + VOP_UNSET_TEXT(imgp->vp); error = ENOEXEC; } goto exec_fail_dealloc; @@ -527,7 +524,7 @@ interpret: * VV_TEXT will be set. The vnode lock is held over this * entire period so nothing should illegitimately be blocked. */ - imgp->vp->v_vflag &= ~VV_TEXT; + VOP_UNSET_TEXT(imgp->vp); /* free name buffer and old vnode */ if (args->fname != NULL) NDFREE(&nd, NDF_ONLY_PNBUF); |