All of lore.kernel.org
 help / color / mirror / Atom feed
* Odd fork/vfork failure / hang running selinux kerenel in slackware - current
@ 2002-12-03 19:55 forrest whitcher
  0 siblings, 0 replies; only message in thread
From: forrest whitcher @ 2002-12-03 19:55 UTC (permalink / raw)
  To: selinux

[-- Attachment #1: Type: text/plain, Size: 3151 bytes --]


I'm attempting to setup a full working configuration for SELinux on slackware,
which is mostly working well (openssh, apache, mod-ssl, standard net utils are all
working in enforcing mode, with just a few lines of edits to the policy
config files).


However on building MIT kerberos I ran across a 'hang' in the ./configure
process which turned out to be a problem in vfork (&fork). The test code 
extracted from ./configure and modified to dig out the issue is posted
below. Originally it was a vfork() test. The vfork configuration test
never returns.



The system under test is using gcc 3.2 and glibc 2.3.1.

This problem replicated only on slackware with the selinux kernel 
(enforcing or permissive mode), I've tested on 2 identical machines
which were running the selinux kernel with essentally identical
kernel .config's 

fork(), vfork() works normally:

redhat 7.1            gcc 2.96 / glibc 2.2.5 selinux kernel
'lunar' (source-dist) gcc 3.2 /  glibc 2.3.1 selinux kernel
slackware -current    gcc 3.2 /  glibc 2.3.1 stock kernel

fork problem:

slackware -current    gcc 3.2 /  glibc 2.3.1 selinux kernel


Finaly, this issue does not present itself in the following circomstances:

If the current shell is not /bin/bash. running csh and then testing, or 
running csh, then invoking bash gives expected behavior ??! I have also
found that I get 'normal' behavior if I am in role user_r, fork failures
after 'newrole -r sysadm_r'.

Any ideas what the heck is going on with this?

forrest


Attached file slowfork2.c --- I very much doubt this problem is going to
replicate anyplace but on the slackware-current + selinux config, however
it's attached so you can see the 

compile and run:      

Bash 2.05b$ ./slowfork2 nloops

Code snippet:

The inserted while loop below to is used kill some time and determine 
how much of a delay is needed in order for the fork to work properly
giving wait() something to actually do, values for ii ca 1-2 *10^6 
(on a pIII/900) are in the range of what's needed to allow 'correct' 
operation --- probably a 1-10 ms delay.


  child = fork ();
  if (child == 0) {
    printf ("Main :4(postforkchld=0)\n");

    pid_t p = getpid();

/* allow fork() to complete??? */

    while (i <= ii){
      i++;
    }

    printf ("Getpid = %d %d\n", p, ii);
    pid_t  p1 = getpid(), p2 = getpid(), p3 = getpid() ;

    /* Convince the compiler that p..p7 are live; otherwise, it might
       use the same hardware register for all 8 local variables.  */

    if (p != p1 || p != p2 || p != p3 )
      _exit(1);

  } else {
    printf ("Main :5postforkchld !=0\n");
    int status;
    struct stat st;

    while (wait(&status) != child){
      printf ("Main :6 status = %d\n", status);
      sleep(1);
      }
      printf ("Main :7 got to exit\n");
    exit(
         /* Was there some problem with vforking?  */
         child < 0

         /* Did the child fail?  (This shouldn't happen.)  */
         || status

         /* Did the vfork/compiler bug occur?  */
         || parent != getpid()

         /* Did the file descriptor bug occur?  */
         || fstat(fileno(stdout), &st) != 0
         );
  }

[-- Attachment #2: slowfork2.c --]
[-- Type: application/octet-stream, Size: 2683 bytes --]

#line 2334 "configure"
/* Thanks to Paul Eggert for this test.  */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_VFORK_H
#include <vfork.h>
#endif
/* On some sparc systems, changes by the child to local and incoming
   argument registers are propagated back to the parent.
   The compiler is told about this with #include <vfork.h>,
   but some compilers (e.g. gcc -O) don't grok <vfork.h>.
   Test for this by using a static variable whose address
   is put into a register that is clobbered by the vfork.  */
main(int argc, char *argv[]) {
  printf ("Main :0\n");
  pid_t parent = getpid ();
  printf ("Main :1\n");
  pid_t child;
  printf ("Main :2\n");
  long i=0, ii=atoi(argv[1]);

  printf ("Main :3(spt)\n");
  child = fork ();
  if (child == 0) {
    printf ("Main :4(postforkchld=0)\n");

    /* Here is another test for sparc vfork register problems.
       This test uses lots of local variables, at least
       as many local variables as main has allocated so far
       including compiler temporaries.  4 locals are enough for
       gcc 1.40.3 on a Solaris 4.1.3 sparc, but we use 8 to be safe.
       A buggy compiler should reuse the register of parent
       for one of the local variables, since it will think that
       parent can't possibly be used any more in this routine.
       Assigning to the local variable will thus munge parent
       in the parent process.  */
    pid_t p = getpid();
    while (i <= ii){
      i++;
    }
    printf ("Getpid = %d %d\n", p, ii);
    pid_t  p1 = getpid(), p2 = getpid(), p3 = getpid() ;
    /* Convince the compiler that p..p7 are live; otherwise, it might
       use the same hardware register for all 8 local variables.  */
    if (p != p1 || p != p2 || p != p3 )
      _exit(1);

    /* On some systems (e.g. IRIX 3.3),
       vfork doesn't separate parent from child file descriptors.
       If the child closes a descriptor before it execs or exits,
       this munges the parent's descriptor as well.
       Test for this by closing stdout in the child.  */
    _exit(close(fileno(stdout)) != 0);
  } else {
    printf ("Main :5postforkchld !=0\n");
    int status;
    struct stat st;

    while (wait(&status) != child){
      printf ("Main :6 status = %d\n", status);
      sleep(1);
      }
      printf ("Main :7 got to exit\n");
    exit(
	 /* Was there some problem with vforking?  */
	 child < 0

	 /* Did the child fail?  (This shouldn't happen.)  */
	 || status

	 /* Did the vfork/compiler bug occur?  */
	 || parent != getpid()

	 /* Did the file descriptor bug occur?  */
	 || fstat(fileno(stdout), &st) != 0
	 );
  }
}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2002-12-03 19:55 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-12-03 19:55 Odd fork/vfork failure / hang running selinux kerenel in slackware - current forrest whitcher

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.