This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix nptl :: sighandler_setxid() to handle negated pids


Hi,

I was facing a hang with a multithreaded program (testcase to simulate a problem we were facing) which is as follows :

The program spawns three threads, 2 of which sleeps indefinitely. The next child thread does a fork. Now, the main thread does a setreuid(). This caused the application hang with glibc-2.3.3-98.61 (or later).
The main thread was waiting on futex() for the counter to become 0. The forked thread was not doing the syscall as well as the futex(), even though it recieved the signal.


The problem has the following root cause:

The setxid() calls are implemented by sending SIGSETXID signal to each threads in the group, with signal handler as sighandler_setxid(). Now in __libc_fork(), we set the pid in the THREAD_SELF(), to -pid before issuing the syscall.

So, with 2.6 kernels, if the thread recieves the SIGSETXID signal while doing a fork(),

static void
sighandler_setxid (int sig, siginfo_t *si, void *ctx)
{
  /* Safety check.  It would be possible to call this function for
     other signals and send a signal from another process.  This is not
     correct and might even be a security problem.  Try to catch as
     many incorrect invocations as possible.  */
  if (sig != SIGSETXID
#ifdef __ASSUME_CORRECT_SI_PID
      /* Kernels before 2.5.75 stored the thread ID and not the process
         ID in si_pid so we skip this test.  */
      || si->si_pid != THREAD_GETMEM (THREAD_SELF, pid)

The above condition would fail, which causes the thread to return without doing the syscall and futex().

#endif
      || si->si_code != SI_TKILL)
    return;



Attached here is a patch which I think could solve this issue.

Could you please comment on this ?

Thanks.

Suzuki K P <suzuki@in.ibm.com>
Linux Technology Centre,
IBM Software Labs,



* npt/init.c: Fix sighandler_setxid() to take care of negated pid in THREAD_SELF while we are doing a fork().


--- nptl/init.c 2006-04-07 20:22:39.000000000 +0530 +++ nptl/init.c.mod 2006-04-07 21:02:39.000000000 +0530 @@ -195,12 +195,19 @@ sighandler_setxid (int sig, siginfo_t *s /* Safety check. It would be possible to call this function for other signals and send a signal from another process. This is not correct and might even be a security problem. Try to catch as - many incorrect invocations as possible. */ + many incorrect invocations as possible. If we are in the middle + of a fork, the pid is stored negated. */ +#ifdef __ASSUME_CORRECT_SI_PID + pid_t pid = THREAD_GETMEM (THREAD_SELF, pid); + if (__builtin_expect (pid < 0, 0)) + pid = -pid; +#endif + if (sig != SIGSETXID #ifdef __ASSUME_CORRECT_SI_PID /* Kernels before 2.5.75 stored the thread ID and not the process ID in si_pid so we skip this test. */ - || si->si_pid != THREAD_GETMEM (THREAD_SELF, pid) + || si->si_pid != pid #endif || si->si_code != SI_TKILL) return;





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]