[PATCH] sigaltstack bug

From: Bruno Haible (haible@ilog.fr)
Date: Mon May 22 2000 - 05:16:55 EST


sigaltstack settings are currently inherited to child processes through
fork(), exec() and clone(). For fork() it's ok. For exec() it doesn't
make sense. SUSV2 even states it explicitly:

    After a successful call to one of the exec functions, there are no
    alternate signal stacks in the new process image.

A simple test case is appended below: Program "caller" sets up a signal
stack and calls program "callee". The latter attempts to set up a signal
stack smaller than "caller"'s one and fails because the current stack
address is within the bounds of the [inherited] alternate stack region.

The fix is to forget the signal stack during exec.

Bruno

Fix:

*** fs/exec.c.bak Sat Mar 25 11:37:41 2000
--- fs/exec.c Sun May 21 01:03:25 2000
***************
*** 476,481 ****
--- 476,483 ----
          /* This is the point of no return */
          release_old_signals(oldsig);
  
+ current->sas_ss_sp = current->sas_ss_size = 0;
+
          if (current->euid == current->uid && current->egid == current->gid)
                  current->dumpable = 1;
          name = bprm->filename;

Test case:

========================== caller.c ===========================
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

int main ()
{
  struct sigaltstack x;
  int buf[16384];
  int pid;

  x.ss_sp = buf;
  x.ss_size = sizeof buf;
  x.ss_flags = 0;
  if (sigaltstack(&x,NULL) < 0) {
    perror("caller sigaltstack");
    return 1;
  } else {
    printf("caller sigaltstack ok\n");
  }
  pid = fork();
  if (pid < 0) {
    perror("caller fork");
    return 1;
  } else if (pid == 0) {
    execlp("callee","callee",NULL);
    perror("exec");
    return -1;
  } else {
    sleep(1);
    return 0;
  }
}
============================ callee.c ================================
#include <signal.h>
#include <stdio.h>

int main ()
{
  struct sigaltstack x;
  int buf[1024];
  x.ss_sp = buf;
  x.ss_size = sizeof buf;
  x.ss_flags = 0;
  if (sigaltstack(&x,NULL) < 0) {
    perror("callee sigaltstack");
    return 1;
  } else {
    printf("callee sigaltstack ok\n");
    return 0;
  }
}
======================================================================
$ callee
callee sigaltstack ok
$ caller
caller sigaltstack ok
callee sigaltstack: Operation not permitted

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue May 23 2000 - 21:00:21 EST