12th Aug 2002 [SBWID-5622]
COMMAND
OpenBSD local priviledge escalation via select call
SYSTEMS AFFECTED
All versions of OpenBSD
PROBLEM
In OpenBSD security advisory by Niels Provos [provos@citi.umich.edu] :
Insufficient boundary checks in the select call allow an attacker to
overwrite kernel memory and execute arbitrary code in kernel context.
Traditionally, the size parameter for the select system call is a
signed integer. As a result, the kernel evaluates the upper boundary
checks in a signed context, so that an attacker can circumvent when
using certain negative values.
When the kernel copies the data for the select system call from
userland the size is used as an unsigned integer which causes kernel
memory to be overwritten with arbitrary data.
Local users can obtain complete system privileges and circumvent the
extra security measures provided by the securelevel system.
SOLUTION
Apply one of the supplied kernel patches or update to 3.0-stable or
3.1-stable from 2002-08-11 17:00 EDT or later.
Apply by doing:
cd /usr/src
patch -p0 < 014_scarg.patch
And then rebuild your kernel.
Index: sys/kern/sys_generic.c
===================================================================
RCS file: /cvs/src/sys/kern/sys_generic.c,v
retrieving revision 1.39
retrieving revision 1.39.2.1
diff -u -r1.39 -r1.39.2.1
--- sys/kern/sys_generic.c 14 Mar 2002 01:27:04 -0000 1.39
+++ sys/kern/sys_generic.c 11 Aug 2002 17:14:55 -0000 1.39.2.1
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_generic.c,v 1.39 2002/03/14 01:27:04 millert Exp $ */
+/* $OpenBSD: sys_generic.c,v 1.39.2.1 2002/08/11 17:14:55 jason Exp $ */
/* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */
/*
@@ -644,12 +644,9 @@
* Select system call.
*/
int
-sys_select(p, v, retval)
- register struct proc *p;
- void *v;
- register_t *retval;
+sys_select(struct proc *p, void *v, register_t *retval)
{
- register struct sys_select_args /* {
+ struct sys_select_args /* {
syscallarg(int) nd;
syscallarg(fd_set *) in;
syscallarg(fd_set *) ou;
@@ -659,14 +656,15 @@
fd_set bits[6], *pibits[3], *pobits[3];
struct timeval atv;
int s, ncoll, error = 0, timo;
- u_int ni;
+ u_int nd, ni;
- if (SCARG(uap, nd) > p->p_fd->fd_nfiles) {
+ nd = SCARG(uap, nd);
+ if (nd > p->p_fd->fd_nfiles) {
/* forgiving; slightly wrong */
- SCARG(uap, nd) = p->p_fd->fd_nfiles;
+ nd = p->p_fd->fd_nfiles;
}
- ni = howmany(SCARG(uap, nd), NFDBITS) * sizeof(fd_mask);
- if (SCARG(uap, nd) > FD_SETSIZE) {
+ ni = howmany(nd, NFDBITS) * sizeof(fd_mask);
+ if (nd > FD_SETSIZE) {
caddr_t mbits;
mbits = malloc(ni * 6, M_TEMP, M_WAITOK);
@@ -713,7 +711,7 @@
retry:
ncoll = nselcoll;
p->p_flag |= P_SELECT;
- error = selscan(p, pibits[0], pobits[0], SCARG(uap, nd), retval);
+ error = selscan(p, pibits[0], pobits[0], nd, retval);
if (error || *retval)
goto done;
if (SCARG(uap, tv)) {
@@ -919,10 +917,7 @@
* differently.
*/
int
-sys_poll(p, v, retval)
- register struct proc *p;
- void *v;
- register_t *retval;
+sys_poll(struct proc *p, void *v, register_t *retval)
{
struct sys_poll_args *uap = v;
size_t sz;
@@ -931,13 +926,13 @@
struct timeval atv;
int timo, ncoll, i, s, error, error2;
extern int nselcoll, selwait;
+ u_int nfds = SCARG(uap, nfds);
/* Standards say no more than MAX_OPEN; this is possibly better. */
- if (SCARG(uap, nfds) > min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur,
- maxfiles))
+ if (nfds > min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles))
return (EINVAL);
- sz = sizeof(struct pollfd) * SCARG(uap, nfds);
+ sz = sizeof(struct pollfd) * nfds;
/* optimize for the default case, of a small nfds value */
if (sz > sizeof(pfds))
@@ -946,7 +941,7 @@
if ((error = copyin(SCARG(uap, fds), pl, sz)) != 0)
goto bad;
- for (i = 0; i < SCARG(uap, nfds); i++)
+ for (i = 0; i < nfds; i++)
pl[i].revents = 0;
if (msec != -1) {
@@ -966,7 +961,7 @@
retry:
ncoll = nselcoll;
p->p_flag |= P_SELECT;
- pollscan(p, pl, SCARG(uap, nfds), retval);
+ pollscan(p, pl, nfds, retval);
if (*retval)
goto done;
if (msec != -1) {
TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2025 AOH