lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  PHC 
Open Source and information security mailing list archives
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Thu, 16 Aug 2007 17:17:29 +0400 (MSD)
From: Dan Yefimov <>
To: Glynn Clements <>
Subject: Re: COSEINC Linux Advisory #1: Linux Kernel Parent Process Death
 Signal Vulnerability

On Thu, 16 Aug 2007, Glynn Clements wrote:

> > The signal in question in the given situation is issued by PRIVILEGED process, 
> > no matter how.
> And that's the bug,

The case we consider is of course a bug. But generally privileged process 
sending a signal to another privileged process is of course not a bug.
Yes, the user toggles a signal that privileged process sends to another one,
but how many ways to trigger sending a signal to a process spawned by that user 
are there? User can always press Ctrl-C, Ctrl-Q, Ctrl-R at the terminal, he can 
hang up the terminal, he can open some socket/pipe/FIFO for non-blocking I/O
and issue fcntl() call to activate sending either a SIGIO or some other signal 
when some new data become available in it, he can issue alarm(), and probably 
many, many, many other ways. Yes, all they can be turned off, but that would 
require a large artificial intelligence and excessive knowledge about
everything occurred in the system before startup from the program being
started. It's much simpler for that program to just block, ignore or install 
proper signal handler for every possible signal in the system whose default
action is terminating a process.

> because it's an unprivileged process which
> *causes* the signal to be issued. If the process tried to send the
> signal directly with kill(), it would fail. This vulnerability is a
> form of privilege escalation; it can cause the sending of signal which
> would normally be prohibited on security grounds.
The matter here is that you cannot abuse this bug to send arbitrary signal to 
arbitrary process in the system. You can only send it to your children. And
this is in general not exploitable. For example, what scary things can happen 
when you send SIGKILL, SIGQUIT, SIGBUS, SIGSTOP or SIGSEGV to /bin/su in 
condition that the latter doesn't allow arbitrary code execution on receiving a 

> > Well written program must not depend on anything that is out of 
> > it's control.
> That's neither possible

Really? Let's consider the following scenario. You write an analogue of 
/bin/passwd. Here you make a temporary copy of /etc/shadow, hard link 
/etc/shadow to /etc/shadow- pre-removing existing /etc/shadow- if that exists,
perform operations on the temporary copy of /etc/shadow, close it and issue 
rename() on it to rename it to /etc/shadow. According to specs (see rename(2)) 
rename() atomically removes /etc/shadow (at this point it is an old link to an 
old /etc/shadow content) and renames temporary copy of /etc/shadow to 
/etc/shadow. At any point in this algorithm the content of /etc/shadow is 

> nor sensible.

If it is not sensible, it is the more not a problem.

> Programs have to rely upon the
> OS to guarantee certain behaviours. The problem here is that there is
> a mechanism which causes a guarantee to be violated.
Yes, and I said this is a bug, but it is in general not exploitable.

> Just in case it hasn't sunk in yet, the inability to trust signals is
> a consequence of this bug. Ordinarily, it should be possible to rely
> upon the fact that an asynchronous signal cannot be sent to a suid
> process by an unprivileged user.
I disagree with you in that. Any hard guarantee can be given only by God.
I repeat, signals are in general not a reliable information source since they 
can be generated in a couple of ways, even by an unkind superuser :-) .

> > In fact, PDEATHSIG should be reset for every binary, not just suid/sgid, since 
> > it emits signal that exec()ed program may not expect.
> Are you talking about the parent exec()ing or the child?
No matter.

> If you're talking about the child, that would almost entirely defeat
> the purpose of having PDEATHSIG.
The only useful exploitation of PDEATHSIG I can imagine is signalling to a 
server subprocess that it's superprocess died for some reason and the
subprocess should exit as far as possible in order to avoid some harm. That 
model doesn't include execing.

> > But in any case, every program shouldn't trust any signal in the
> > system. That is a good tone rule.
> In which case, what's the point of having signals in the first place?
> Processes are supposed to respond to signals. Security is achieved
> placing controls on who can signal who, and this bug circumvents that
> mechanism.
But the process in general is in no way obliged to respond to every signal 
unless explicitly wanted.

> > I still don't see why this bug should be considered as a security issue but not 
> > as an ordinary bug.
> Because it's a form of privilege escalation. Non-root processes can't
> normally send signals to processes which are owned by another UID (and
> most modern operating systems prevent non-root processes from sending
> signals to any process where suid/sgid is involved regardless of the
> current UID or EUID).
I repeat, this bug cannot be abused to send arbitrary signal to arbitrary 
process in the system. Only direct successors (children) are affected, and this 
is in general not exploitable.

> > > Moreover, I would suggest that exec()ing a suid/sgid binary should
> > > reset *everything* which is not explicitly specified as being
> > > preserved.
> > 
> > Specified with what?
I got you. I just thought you want to reset everything successively including 
sigmasks and open files :-) .

    Sincerely Your, Dan.

Powered by blists - more mailing lists