summaryrefslogtreecommitdiffstats
path: root/sys/i386/ibcs2/imgact_coff.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2012-11-02 13:56:36 +0000
committerkib <kib@FreeBSD.org>2012-11-02 13:56:36 +0000
commitf16ea990070abd8c9cb42bfc7001ada604b4df01 (patch)
tree77eb9f8e9de108d0ae7792cfceedcd340198177e /sys/i386/ibcs2/imgact_coff.c
parent37f3bd87e4ec81bcec505485b1cf96c74db846f0 (diff)
downloadFreeBSD-src-f16ea990070abd8c9cb42bfc7001ada604b4df01.zip
FreeBSD-src-f16ea990070abd8c9cb42bfc7001ada604b4df01.tar.gz
The r241025 fixed the case when a binary, executed from nullfs mount,
was still possible to open for write from the lower filesystem. There is a symmetric situation where the binary could already has file descriptors opened for write, but it can be executed from the nullfs overlay. Handle the issue by passing one v_writecount reference to the lower vnode if nullfs vnode has non-zero v_writecount. Note that only one write reference can be donated, since nullfs only keeps one use reference on the lower vnode. Always use the lower vnode v_writecount for the checks. Introduce the VOP_GET_WRITECOUNT to read v_writecount, which is currently always bypassed to the lower vnode, and VOP_ADD_WRITECOUNT to manipulate the v_writecount value, which manages a single bypass reference to the lower vnode. Caling the VOPs instead of directly accessing v_writecount provide the fix described in the previous paragraph. Tested by: pho MFC after: 3 weeks
Diffstat (limited to 'sys/i386/ibcs2/imgact_coff.c')
-rw-r--r--sys/i386/ibcs2/imgact_coff.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/sys/i386/ibcs2/imgact_coff.c b/sys/i386/ibcs2/imgact_coff.c
index a28ba52..b155ef9 100644
--- a/sys/i386/ibcs2/imgact_coff.c
+++ b/sys/i386/ibcs2/imgact_coff.c
@@ -168,7 +168,7 @@ coff_load_file(struct thread *td, char *name)
unsigned long text_offset = 0, text_address = 0, text_size = 0;
unsigned long data_offset = 0, data_address = 0, data_size = 0;
unsigned long bss_size = 0;
- int i;
+ int i, writecount;
NDINIT(&nd, LOOKUP, ISOPEN | LOCKLEAF | FOLLOW | SAVENAME,
UIO_SYSSPACE, name, td);
@@ -181,7 +181,10 @@ coff_load_file(struct thread *td, char *name)
if (vp == NULL)
return ENOEXEC;
- if (vp->v_writecount) {
+ error = VOP_GET_WRITECOUNT(vp, &writecount);
+ if (error != 0)
+ goto fail;
+ if (writecount != 0) {
error = ETXTBSY;
goto fail;
}
OpenPOWER on IntegriCloud