COMMAND
BSD I/O signals
SYSTEMS AFFECTED
BSDI, NetBSD, OpenBSD, and FreeBSD, IRIX
PROBLEM
Following info is based on OpenBSD Security Advisory from
September 15, 1997 and it covers vulnerability in I/O Signal
handling.
A vulnerability discovered in the 4.4BSD kernel allows
unprivileged users to send certain signals to arbitrary processes
on the system. Depending on the operating system and targeted
program, this may allow users to kill off processes or disrupt
the operation of certain programs.
Certain programs implemented in Unix operating systems make use
of a facility called "asynchronous I/O" to handle multiple tasks
simultaneously. Asynchronous I/O allows a process to be notified
whenever it has data that needs to be read from an input source;
the kernel notifies the process using a signal.
Asynchronous I/O is enabled on a descriptor using the fcntl()
system call; a descriptor with the O_ASYNC flag set will cause a
signal to be sent whenever there is data available to be read
from it. Additionally, using the FIOASYNC ioctl(), asynchronous
notification can be enabled on a descriptor.
In cases where multiple processes are used in an application, it
becomes useful to allow a descriptor to notify other processes as
well. This is accomplished by use of another fcntl() operation,
F_SETOWN, as well as an ioctl, FIOSETOWN (certain devices also
provide an interface to this facility with the TIOCSPGRP ioctl).
These operations allow a program to set the process or process
group that will receive signal notification of pending I/O.
A lack of checking in the code that handles these operations
allows a program to specify an arbitrary process ID when using a
socket or device file descriptor. By setting the recipient of
signal notification to a process that is not owned by the
program, the kernel can be tricked into signalling arbitrary
programs.
Additionally, vulnerable kernels do not keep track of the
credentials associated with a process when determining whether to
send I/O signals; because of this, it is possible to specify the
PID of a process that is owned by an attacker, and then destroy
that process and wait for it's PID to be re-used. The new process
occupying that PID can then be signalled by the attacker,
regardless of it's owner.
It's important to note that operating systems that check
credentials when a program attempts to set the PID for I/O
notification (thus evading part of this vulnerability) may still
be vulnerable to the latter problem (process ID re-use), if
credentials aren't checked at signal delivery time.
This vulnerability exists due to a lack of credential checking in
the kernel when setting the recipient of I/O notification.
BSD-based kernels maintain this information in descriptor-specific
data structures unrelated to the process table; the vulnerability
discussed here involves sockets, which maintain the signal
recipient in the per-descriptor "socket" structure, although
certain devices provide similar facilities and vulnerabilities.
On 4.4BSD systems, the signal normally sent to inform a process
of pending I/O is SIGIO. The default disposition of the SIGIO
signal is "ignore" - thus, most processes are unaffected by this
vulnerability. However, certain programs explicitly catch SIGIO
in order to use asynchronous I/O; these programs can be disrupted
by sending stray SIGIO's.
The process notification information is also used to determine
the process that receives notification of out-of-band data on a
socket. The same vulnerability applies, this time by setting the
process to notify and then sending a message with the MSG_OOB
flag set; the targetted process will receive a SIGURG signal.
Certain network daemons (ftpd, for instance) can be disrupted by
being sent a stray SIGURG signal when no data is available for
reading.
The problem is more serious on vulnerable System V operating
systems; in many cases, SIGIO is the equivalent of SIGPOLL, and
the default disposition of that signal is "terminate process". On
SGI's IRIX operating system, exploitation of this vulnerability
can kill any process on the system.
In addition to being an extremely potent denial of service attack,
surgical application of this vulnerability can be used to
compromise the system - for example, a process holding a bound
address (NFS port 2049, for instance) can be killed off and it's
port stolen; this can be used to steal NFS file handles.
In addition to sockets, some devices also provide facilities for
notification of pending I/O; examples include the "log", "tun",
and "bpf". The BPF and tunnel devices are of minimal concern, as
they are not typically accessible by arbitrary users (although
BPF is interesting in that it will allow the owner of a
bpf-associated descriptor to choose an arbitrary signal to send,
including SIGSTOP).
Unfortunately, the log device is normally accessible by users,
and can be used to perform the same attack as sockets allow. It's
also worth noting that the interface that allows programs to set
the process to receive notification of I/O on the log device
renders the legitimate purpose of this facility totally
unreliable; unrelated programs can seize control of the
asynchronous I/O notification on the log device, causing programs
that rely on it to fail. The provided patches that are available
from address do not attempt to resolve this problem.
This vulnerability is believed to have been discovered originally
by Alan Peakall.
SOLUTION
This is a kernel problem that can only be fixed by patching the
problematic system code. Patches for the OpenBSD operating system
are provided advisory mentioned above; FreeBSD is known to be
working on a similar solution.
OpenBSD patch causes the kernel to keep track of the credentials
of the process associated with an I/O object; the credentials are
checked whenever I/O notification will occur, and therefore
resolve both the F_SETOWN and PID-reuse problems. Device drivers
that present an interface to I/O notification must be modified to
check credentials when the TIOCSPGRP (or equivalent) ioctl() is
used to set notificatio PID; the OpenBSD patch resolves all
currently known occurances of this in that operating system.