Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 15 Jun 2002 05:02:44 -0700 (PDT)
From:      Peter Edwards <pmedwards@eircom.net>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   misc/39326: execve() for ELF exe drops VTEXT when re-execing the current executable
Message-ID:  <200206151202.g5FC2ijv048554@www.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         39326
>Category:       misc
>Synopsis:       execve() for ELF exe drops VTEXT when re-execing the current executable
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Jun 15 05:10:01 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Peter Edwards
>Release:        -STABLE at 4.6 -prerelease
>Organization:
>Environment:
FreeBSD rocklobster 4.6-RC FreeBSD 4.6-RC #17: Sat Jun 15 12:13:08 IST 2002     petere@rocklobster:/a/archie/host/pub/FreeBSD/stable/src/sys/compile/ROCKLOBSTER  i386

>Description:
exec_elf_imgact() sets the VTEXT flag on the vnode that is being 
loaded to stop it being changed while the kernel is setting up the 
process with it. This is done before the call to
exec_new_vmspace(). If a running process execs the same executable
that it is currently running, the exec_new_vmspace() can eventually
end up deallocating the underlying pager for the vnode, via
vm_object_vndeallocate, which is where the VTEXT flag is stored.

The fix seems trivial. The intent of VTEXT is to stop the image
changing once the kernel starts to peer into it, but that only
happens _after_ the exec_new_vmspace(), anyway, so the setting of
VTEXT is just a little premature.

>        simple_lock(&imgp->vp->v_interlock);
>        imgp->vp->v_flag |= VTEXT;
>        simple_unlock(&imgp->vp->v_interlock);



>How-To-Repeat:
petere@rocklobster$ cat > exectest.c << +++ 
> #include <sys/types.h>
> #include <err.h>
> #include <signal.h>
> #include <stdio.h>
> #include <unistd.h>
> 
> 
> void interrupt(int sig) { }
> 
> int main(int argc, char *argv[])
> {
>     struct sigaction sa;
> 
>     sigemptyset(&sa.sa_mask);
>     sa.sa_handler = interrupt;
>     sa.sa_flags = 0;
>     sigaction(SIGINT, &sa, 0);
> 
>     if (argc != 2)
>         errx(-1, "usage: %s <executable>", argv[0]);
> 
>     pause();
>     fprintf(stderr, "exec...\n");
>     if (execve(argv[1], argv, 0) == -1)
>         err(-1, "...failed \n");
>     return 0;
> }
> +++
petere@rocklobster$ make exectest
cc -O -pipe   exectest.c  -o exectest
petere@rocklobster$ ./exectest ./exectest&
[1] 1045
petere@rocklobster$ true > ./exectest
bash: ./exectest: Text file busy
petere@rocklobster$ kill -INT 1045
exec...
petere@rocklobster$ true > ./exectest
petere@rocklobster$

>Fix:
diff -u -r1.73.2.9 imgact_elf.c
--- imgact_elf.c        16 Dec 2001 18:26:16 -0000      1.73.2.9
+++ imgact_elf.c        15 Jun 2002 11:12:12 -0000
@@ -492,6 +492,11 @@
         * From this point on, we may have resources that need to be freed.
         */
 
+       if ((error = exec_extract_strings(imgp)) != 0)
+               goto fail;
+
+       exec_new_vmspace(imgp);
+
        /*
         * Yeah, I'm paranoid.  There is every reason in the world to get
         * VTEXT now since from here on out, there are places we can have
@@ -501,11 +506,6 @@
        simple_lock(&imgp->vp->v_interlock);
        imgp->vp->v_flag |= VTEXT;
        simple_unlock(&imgp->vp->v_interlock);
-
-       if ((error = exec_extract_strings(imgp)) != 0)
-               goto fail;
-
-       exec_new_vmspace(imgp);
 
        vmspace = imgp->proc->p_vmspace;
 

>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200206151202.g5FC2ijv048554>