Full Disclosure mailing list archives

glibc 2.1.3 linuxthreads sigaction


From: silvio () big net au (silvio () big net au)
Date: Thu, 12 Sep 2002 01:36:12 -0700

Here is a THREATCON -0.1 advisory (making current threatcon around 1.9).

This "bug" has been fixed for quite a while now.. so it seems appropriate to
post on this.

JFYI, I have seen the effects of this bug appear in closed source software -->

However, due to the nature of opensource, I was able to look at the glibc
sources we were using (2.1.3), knowing the fact that linuxthreads commandears
3 of the RT signals for the kernel version we were using (2.2.x).

Knowing that non opensource code was using those RT signals.. I immediately
suspected that sigaction was failing internally in linuxthreads.

About 2 minutes later, I was kicking back drinking coffee and happy that
I was able to fix our own code, because of the open nature of Linux
and GNU software.

PS.  Because we couldn't just roll out new distributions on our platforms
for mass consuption, and people are always wary of doing binary
patches.  The "working solution" involved knowing exactly what this bug
and the obvious "fix" in our "code" was

        if (sigaction() !=  0)

instead of (previous)

        if (sigaction() == -1)

The only way I could feel comfortable knowing this workaround would
actually work, was by knowing the explicit details of this particular
issue with glibc.

2 minutes of opensource, versus 22 months of slogans, patches, slogans,
campaigns, and eventual denial.

PS -->

This entire email is obviously very silly and I suspect threatcon
will continue to decline.

--
Silvio

Linux man page for sigaction -->

RETURN VALUES

       sigaction, sigprocmask, sigpending and sigsuspend return 0
       on success and -1 on error.

--

From glibc 2.1.3 -->

/* The wrapper around sigaction.  Install our own signal handler
   around the signal. */
int sigaction(int sig, const struct sigaction * act,
              struct sigaction * oact)
{
  struct sigaction newact;
  struct sigaction *newactp;

  if (sig == __pthread_sig_restart ||
      sig == __pthread_sig_cancel ||
      (sig == __pthread_sig_debug && __pthread_sig_debug > 0))
    return EINVAL;

notice that it returns EINVAL.. not -1 (or even setting errno)

--

From glibc 2.2.x -->

* The wrapper around sigaction.  Install our own signal handler
   around the signal. */
int __sigaction(int sig, const struct sigaction * act,
              struct sigaction * oact)
{
  struct sigaction newact;
  struct sigaction *newactp;

  if (sig == __pthread_sig_restart ||
      sig == __pthread_sig_cancel ||
      (sig == __pthread_sig_debug && __pthread_sig_debug > 0))
    {
      __set_errno (EINVAL);
      return -1;
    }

OK.. Fixed here.

--
Silvio


Current thread: