Re: Question about execve.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 27 Mar 2010, Carlos O'Donell wrote:

> Helge,
> 
> On PARISC I'm seeing the following reproducible behvaiour:
> 
> * Parent calls vfork()
> * Child of vfork() calls execve()
> * Child returns from execve() and starts corrupting parent state
> eventually leading to a segmentation fault.
> * New process (as a result of execve) runs to completion.
> 
> What code in the Linux kernel prevents the child, which calls
> execve(), from returning?

All the execute a file commands can return if an error occurs.  Thus,
I question the fact that the execve wrapper doesn't save registers.

The vfork child runs using the parent's stack.  Thus, even the call
to execve potentially corrupts the parent's stack, and depending on
scheduling, this might cause a segmentation fault in either parent or
child.

Here's a couple of excerpts from the vfork man page for HP-UX:

Series 800

Process times for the parent and child processes within the [vfork,exec]
window may be inaccurate.

    * Parent and child processes share the same stack space within the
    [vfork,exec] window. If the size of the stack has been changed within
    this window by the child process (return from or call to a function,
    for example), it is likely that the parent and child processes will
    be killed with signal SIGSEGV or SIGBUS.

The [vfork,exec] window begins at the vfork() call and ends when the child
completes its exec() call.

The Open Group man page says:

The use of vfork() for any purpose except as a prelude to an immediate call
to a function from the exec  family, or to _exit(), is not advised.  On HP-UX,
it's not supported.

I see that this is not a new issue for linux:
http://lkml.indiana.edu/hypermail/linux/kernel/9902.0/0256.html

It is ok to treat vfork() identically to fork(), and the HP-UX
manpage indicates that this may be the case for certain HP-UX
implementations (maybe Series 700).

> Test case attached.

I was not able to save your pt-fork.S file.   mutt didn't understand
the encoding.

I tried the vfork.c test case on my c3750 with 32-bit kernel.  It
didn't segv in a limited number of runs.  However, I did notice that
getpid() is broken after vfork().

The printf call in the child path probably isn't legit.  It's also not
legit to simply return if execve fails.  _exit must be called.

My guess would be that the parent is not blocked leading to corruption.

> #include <stdio.h>
> #include <stdlib.h>
> #include <errno.h>
> #include <unistd.h>
> 
> #define CALL_EXIT 0
> 
> int main (void)
> {
>   pid_t child;
>   char *cmd[] = { "bash", "-c", "echo In child $$;", (char *)0 };
>   char *env[] = { "HOME=/tmp", (char *)0 };
>   int ret;
> 
>   child = vfork();
> 
>   if (child == 0)
>     {
>       ret = execve("/bin/bash", cmd, env);
>       printf ("ret = %d\n", ret);
> #if CALL_EXIT == 1
>       _exit(1);
> #endif
>     }
>   else
>     {
>       printf("child != 0\n");
>     }
> 
>   printf("parent is %d\n", (unsigned int)getpid());
>   printf("child is %d\n", (unsigned int)child);
> 
>   return 0;
> }

Dave
-- 
J. David Anglin                                  dave.anglin@xxxxxxxxxxxxxx
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)
--
To unsubscribe from this list: send the line "unsubscribe linux-parisc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux SoC]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux