<<< Date Index >>>     <<< Thread Index >>>

Re: COSEINC Linux Advisory #1: Linux Kernel Parent Process Death Signal Vulnerability



On Fri, 17 Aug 2007, Glynn Clements wrote:

> > Really? An what if we fork right after startup and perform operations as a 
> > child?
> 
> That would work, but might have undesirable consequences of its own. 
> 
> In particular, it prevents a non-malicious caller from using PDEATHSIG
> to send e.g. SIGINT, which the setuid program may reasonably handle.
> 
So I don't understand you, whether is the bug in question a DoS issue or not in 
your opinion? IOW, do we need to reset pdeath_signal on exec()ing the 
setuid/setgid binary or not?

> > > SIGKILL and SIGSTOP cannot be blocked, handled or ignored.
> > 
> > As for SIGKILL, I again repeat that the program must operate in a fail safe 
> > way 
> > when that makes sense.
> 
> It's really a question of whether it's possible rather than "making
> sense". Eliminating critical sections is desirable, but it isn't
> always possible.
> 
Of course, critical sections are unavoidable, but there can be measures 
undertaken to minimize their impact. That is what I talk about.

> > BTW, SIGKILL and SIGSTOP can be issued by an O_ASYNC file I/O also (look in 
> > fcntl(2) at F_SETSIG section). If you use F_SETSIG for sending SIGKILL or 
> > SIGSTOP, there's nothing to be done with that - that behaviour is well 
> > documented and setuid root program must know which file descriptor should 
> > be 
> > closed to prevent that, which is of course not possible. The only cure here 
> > is 
> > closing every file descriptor above 2, but that is still insufficient, 
> > since 
> > fcntl() might be issued on file descriptors from 0 to 2.
> 
> The fcntl(2) manpage says:
> 
>     Sending  a  signal  to  the  owner  process (group) specified by
>     F_SETOWN is subject  to  the  same  permissions  checks  as  are
>     described for kill(2), where the sending process is the one that
>     employs F_SETOWN (but see BUGS below).
> 
> Also, note the use of the term "permissions checks"; this is
> considered a security mechanism.
> 
Yes, I just learned that from the kernel source, so my apologies for the false 
alarm :-)

> > And this IS generally impossible. Once spawned setuid root binary that will
> > send a signal while dying, you have no control over the moment the signal 
> > is 
> > being sent at. The exploitation scenario for this bug is a bit artificial.
> 
> IMO, privilege elevation is a security issue regardless of whether or
> not one can provide a "useful" scenario immediately upon the issue
> becoming known.
> 
I talked about the severity of this bug here. I see it's much simpler to post 
the patch fixing it rather than endlessly discussing it here. Anyway, I'm not 
inclined to consider signals a reliable and secure information source. They are 
rather a subsidiary facility. Attached a patch that is meant to fix a bug in 
question.
-- 

    Sincerely Your, Dan.
--- linux-2.6.22/fs/exec.c.pdeathsig    2007-07-09 03:32:17.000000000 +0400
+++ linux-2.6.22/fs/exec.c      2007-08-17 18:01:27.000000000 +0400
@@ -896,6 +896,16 @@
                suid_keys(current);
                current->mm->dumpable = suid_dumpable;
        }
+       /*
+        * Clear out pdeath_signal for setuid executables.
+        * This fixes a bug where general kill() permission checks
+        * can be effectively bypassed by abusing setuid executables.
+        * Note, we don't do that for setgid executables, since kill()
+        * permission checking routine checks only EUID/UID to UID/SUID
+        * matching, so setgid processes can be killed in a usual way.
+         */
+       if (bprm->e_uid != current->euid)
+               current->pdeath_signal = 0;
 
        /* An exec changes our domain. We are no longer part of the thread
           group */