Re: Signal handling different for root and others

From: Andi Kleen (ak@suse.de)
Date: Tue Sep 12 2000 - 11:05:36 EST


On Tue, Sep 12, 2000 at 03:09:40PM +0200, jury gerold wrote:
> Andi Kleen wrote:
> >
> > On Tue, Sep 12, 2000 at 11:33:31AM +0100, Alan Cox wrote:
> > > > > Normal users are only able to create a SIGIO signal when connecting.
> > > >
> > > > That's very unlikely. TCP does not propagate gid/uid information over sockets,
> > > > not even over localhost.
> > >
> > > However if something is looking at current-> and the test is on localhost
> > > then it starts to become quite believable
> >
> > The SIGIO is on the receiving side, not on the sending. current is always
> > the same.
> >
> > -Andi
>
> I know, the description was not very clear.
> But the attached program is very easy to compile and start.
> I tried to extract only what's necessary from the involved code.
> There are no hidden trojans inside, i promise.

Never mind I found it. send_siginfo indeed checks current and it is called
via sock_wake_async from net_bh. Sorry for dismissing your report at first,
I have no other excuse as that it was very late yesterday night.

The reason for the problem is that asm/siginfo.h messes up between
user signals and kernel queued signals. SI_SIGINFO is defined as a
user signal, but it is really a kernel signal (should be >= 0).

Thus SI_FROMUSER returns true for SI_SIGINFO, which leads to the signal
function checking checking current for credentials, which leads to the
weird behaviour of the SIGIO dependent on the sending process (or a random
process that just happens to run while the packet is processed)
[Stephen, I think that will explain many random queued SIGIO failures in the
past]

Here is an cheap workaround. it'll break programs that pass SI_SIGINFO
to sigqueue(). I don't think this is a problem.
I only fixed i386, other architectures may have the same
problem.

The patch should fix the problem, could you try it ?

--- kernel/signal.c-o Tue Sep 12 17:43:28 2000
+++ kernel/signal.c Tue Sep 12 17:53:40 2000
@@ -820,7 +820,7 @@
 
         /* Not even root can pretend to send signals from the kernel.
            Nor can they impersonate a kill(), which adds source info. */
- if (info.si_code >= 0)
+ if (!SI_FROMUSER(&info))
                 return -EPERM;
         info.si_signo = sig;
 
--- include/asm-i386/siginfo.h-o Tue Sep 12 17:55:00 2000
+++ include/asm-i386/siginfo.h Tue Sep 12 17:56:37 2000
@@ -89,8 +89,8 @@
 #define SI_ASYNCIO -4 /* sent by AIO completion */
 #define SI_SIGIO -5 /* sent by queued SIGIO */
 
-#define SI_FROMUSER(siptr) ((siptr)->si_code <= 0)
-#define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0)
+#define SI_FROMUSER(siptr) ((siptr)->si_code <= 0 && (siptr)->si_code!=SI_SIGIO)
+#define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0 || (siptr)->si_code==SI_SIGIO)
 
 /*
  * SIGILL si_codes

-Andi

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



This archive was generated by hypermail 2b29 : Fri Sep 15 2000 - 21:00:18 EST