__________________________________________________________ The U.S. Department of Energy Computer Incident Advisory Capability ___ __ __ _ ___ / | /_\ / \___ __|__ / \ \___ __________________________________________________________ INFORMATION BULLETIN 386-BSD Based Operating Systems - IPCS Vulnerability May 31, 2000 20:00 GMT Number K-046 ______________________________________________________________________________ PROBLEM: A System V, IPC kernel parameter has a vulnerability. Due to an undocumented system call, it is possible for a local user to disable a system process from exiting. PLATFORM: 386BSD-derived OSes, including all versions of FreeBSD, NetBSD and OpenBSD DAMAGE: The use of this vulnerability against a system would result in a Denial Of Service against the system. No process could run until the "unblock" call is issued to the system, or the system is rebooted. SOLUTION: There are two solutions to rectify this problem; Apply the patch included in the advisory, or upgrade to FreeBSD 2.1.7.1-STABLE, 2.2.8-STABLE, 3.4-STABLE,4.0-STABLE or 5.0-CURRENT after the correction date. ______________________________________________________________________________ VULNERABILITY The risk is LOW. There have been no reported instances of this ASSESSMENT: being used against any systems. ______________________________________________________________________________ [****** Begin FreeBSD Security Advisory ******] ============================================================================= FreeBSD-SA-00:19 Security Advisory FreeBSD, Inc. Topic: local users can prevent all processes from exiting Category: core Module: kernel Announced: 2000-05-26 Credits: Peter Wemm Affects: 386BSD-derived OSes, including all versions of FreeBSD, NetBSD and OpenBSD. Corrected: 2000-05-01 FreeBSD only: NO Patch: ftp://ftp.freebsd.org/pub/FreeBSD/CERT/patches/SA- 00:19/semconfig.patch I. Background System V IPC is a set of interfaces for providing inter-process communication, in the form of shared memory segments, message queues and semaphores. These are managed in user-space by ipcs(1) and related utilities. II. Problem Description An undocumented system call is incorrectly exported from the kernel without access-control checks. This operation causes the acquisition in the kernel of a global semaphore which causes all processes on the system to block during exit() handling, thereby preventing any process from exiting until the corresponding "unblock" system call is issued. This operation was intended for use only by ipcs(1) to atomically sample the state of System V IPC resources on the system (i.e., to ensure that resources are not allocated or deallocated during the process of sampling itself). In the future, this functionality may be reimplemented as a sysctl() node. III. Impact An unprivileged local user can cause every process on the system to hang during exiting. In other words, after the system call is issued, no process on the system will be able to exit completely until another user issues the "unblock" call or the system is rebooted. This is a denial-of-service attack. IV. Workaround None available. V. Solution Upgrade to FreeBSD 2.1.7.1-STABLE, 2.2.8-STABLE, 3.4-STABLE, 4.0-STABLE or 5.0-CURRENT after the correction date. Alternatively, apply the following patch and rebuild the kernel and the src/usr.bin/ipcs utility. This patch removes the semconfig() syscall. It has been tested to apply cleanly against 3.4-RELEASE, 3.4-STABLE, 4.0-RELEASE and 4.0-STABLE systems. 1) Save this advisory as a file, and run the following commands as root: # cd /usr/src # patch -p < /path/to/advisory # cd usr.bin/ipcs # make all install 2) Rebuild and reinstall the kernel and kernel modules as described in the FreeBSD handbook (see: http://www.freebsd.org/handbook/kernelconfig.html for more information) 3) Reboot the system Patches for FreeBSD systems before the resolution date: --- sys/kern/syscalls.master 2000/01/19 06:01:07 1.72 +++ sys/kern/syscalls.master 2000/05/01 11:15:10 1.72.2.1 @@ -342,7 +342,7 @@ 221 STD BSD { int semget(key_t key, int nsems, int semflg); } 222 STD BSD { int semop(int semid, struct sembuf *sops, \ u_int nsops); } -223 STD BSD { int semconfig(int flag); } +223 UNIMPL NOHIDE semconfig 224 STD BSD { int msgctl(int msqid, int cmd, \ struct msqid_ds *buf); } 225 STD BSD { int msgget(key_t key, int msgflg); } --- sys/kern/init_sysent.c 2000/01/19 06:02:29 1.79 +++ sys/kern/init_sysent.c 2000/05/01 11:15:56 1.79.2.1 @@ -243,7 +243,7 @@ { 4, (sy_call_t *)__semctl }, /* 220 = __semctl */ { 3, (sy_call_t *)semget }, /* 221 = semget */ { 3, (sy_call_t *)semop }, /* 222 = semop */ - { 1, (sy_call_t *)semconfig }, /* 223 = semconfig */ + { 0, (sy_call_t *)nosys }, /* 223 = semconfig */ { 3, (sy_call_t *)msgctl }, /* 224 = msgctl */ { 2, (sy_call_t *)msgget }, /* 225 = msgget */ { 4, (sy_call_t *)msgsnd }, /* 226 = msgsnd */ --- sys/kern/syscalls.c 2000/01/19 06:02:29 1.71 +++ sys/kern/syscalls.c 2000/05/01 11:15:56 1.71.2.1 @@ -230,7 +230,7 @@ "__semctl", /* 220 = __semctl */ "semget", /* 221 = semget */ "semop", /* 222 = semop */ - "semconfig", /* 223 = semconfig */ + "#223", /* 223 = semconfig */ "msgctl", /* 224 = msgctl */ "msgget", /* 225 = msgget */ "msgsnd", /* 226 = msgsnd */ --- sys/kern/sysv_ipc.c 2000/02/29 22:58:59 1.13 +++ sys/kern/sysv_ipc.c 2000/05/01 11:15:56 1.13.2.1 @@ -107,15 +107,6 @@ semsys(p, uap) struct proc *p; struct semsys_args *uap; -{ - sysv_nosys(p, "SYSVSEM"); - return nosys(p, (struct nosys_args *)uap); -}; - -int -semconfig(p, uap) - struct proc *p; - struct semconfig_args *uap; { sysv_nosys(p, "SYSVSEM"); return nosys(p, (struct nosys_args *)uap); --- sys/kern/sysv_sem.c 2000/04/02 08:47:08 1.24.2.1 +++ sys/kern/sysv_sem.c 2000/05/01 11:15:56 1.24.2.2 @@ -26,8 +26,6 @@ int semget __P((struct proc *p, struct semget_args *uap)); struct semop_args; int semop __P((struct proc *p, struct semop_args *uap)); -struct semconfig_args; -int semconfig __P((struct proc *p, struct semconfig_args *uap)); #endif static struct sem_undo *semu_alloc __P((struct proc *p)); @@ -38,7 +36,7 @@ /* XXX casting to (sy_call_t *) is bogus, as usual. */ static sy_call_t *semcalls[] = { (sy_call_t *)__semctl, (sy_call_t *)semget, - (sy_call_t *)semop, (sy_call_t *)semconfig + (sy_call_t *)semop }; static int semtot = 0; @@ -47,8 +45,6 @@ static struct sem_undo *semu_list; /* list of active undo structures */ int *semu; /* undo structure pool */ -static struct proc *semlock_holder = NULL; - void seminit(dummy) void *dummy; @@ -87,64 +83,12 @@ } */ *uap; { - while (semlock_holder != NULL && semlock_holder != p) - (void) tsleep((caddr_t)&semlock_holder, (PZERO - 4), "semsys", 0); - if (uap->which >= sizeof(semcalls)/sizeof(semcalls[0])) return (EINVAL); return ((*semcalls[uap->which])(p, &uap->a2)); } /* - * Lock or unlock the entire semaphore facility. - * - * This will probably eventually evolve into a general purpose semaphore - * facility status enquiry mechanism (I don't like the "read /dev/kmem" - * approach currently taken by ipcs and the amount of info that we want - * to be able to extract for ipcs is probably beyond what the capability - * of the getkerninfo facility. - * - * At the time that the current version of semconfig was written, ipcs is - * the only user of the semconfig facility. It uses it to ensure that the - * semaphore facility data structures remain static while it fishes around - * in /dev/kmem. - */ - -#ifndef _SYS_SYSPROTO_H_ -struct semconfig_args { - semconfig_ctl_t flag; -}; -#endif - -int -semconfig(p, uap) - struct proc *p; - struct semconfig_args *uap; -{ - int eval = 0; - - switch (uap->flag) { - case SEM_CONFIG_FREEZE: - semlock_holder = p; - break; - - case SEM_CONFIG_THAW: - semlock_holder = NULL; - wakeup((caddr_t)&semlock_holder); - break; - - default: - printf("semconfig: unknown flag parameter value (%d) - ignored\n", - uap->flag); - eval = EINVAL; - break; - } - - p->p_retval[0] = 0; - return(eval); -} - -/* * Allocate a new sem_undo structure for a process * (returns ptr to structure or NULL if no more room) */ @@ -873,17 +817,6 @@ register struct sem_undo **supptr; int did_something; - /* - * If somebody else is holding the global semaphore facility lock - * then sleep until it is released. - */ - while (semlock_holder != NULL && semlock_holder != p) { -#ifdef SEM_DEBUG - printf("semaphore facility locked - sleeping ...\n"); -#endif - (void) tsleep((caddr_t)&semlock_holder, (PZERO - 4), "semext", 0); - } - did_something = 0; /* @@ -898,7 +831,7 @@ } if (suptr == NULL) - goto unlock; + return; #ifdef SEM_DEBUG printf("proc @%08x has undo structure with %d entries\n", p, @@ -955,14 +888,4 @@ #endif suptr->un_proc = NULL; *supptr = suptr->un_next; - -unlock: - /* - * If the exiting process is holding the global semaphore facility - * lock then release it. - */ - if (semlock_holder == p) { - semlock_holder = NULL; - wakeup((caddr_t)&semlock_holder); - } } --- sys/sys/sem.h 1999/12/29 04:24:46 1.20 +++ sys/sys/sem.h 2000/05/01 11:15:58 1.20.2.1 @@ -163,13 +163,5 @@ * Process sem_undo vectors at proc exit. */ void semexit __P((struct proc *p)); - -/* - * Parameters to the semconfig system call - */ -typedef enum { - SEM_CONFIG_FREEZE, /* Freeze the semaphore facility. */ - SEM_CONFIG_THAW /* Thaw the semaphore facility. */ -} semconfig_ctl_t; #endif /* _KERNEL */ --- sys/sys/syscall-hide.h 2000/01/19 06:02:31 1.65 +++ sys/sys/syscall-hide.h 2000/05/01 11:15:58 1.65.2.1 @@ -191,7 +191,6 @@ HIDE_BSD(__semctl) HIDE_BSD(semget) HIDE_BSD(semop) -HIDE_BSD(semconfig) HIDE_BSD(msgctl) HIDE_BSD(msgget) HIDE_BSD(msgsnd) --- sys/sys/syscall.h 2000/01/19 06:02:31 1.69 +++ sys/sys/syscall.h 2000/05/01 11:15:59 1.69.2.1 @@ -196,7 +196,6 @@ #define SYS___semctl 220 #define SYS_semget 221 #define SYS_semop 222 -#define SYS_semconfig 223 #define SYS_msgctl 224 #define SYS_msgget 225 #define SYS_msgsnd 226 --- sys/sys/syscall.mk 2000/01/19 06:07:34 1.23 +++ sys/sys/syscall.mk 2000/05/01 11:15:59 1.23.2.1 @@ -148,7 +148,6 @@ __semctl.o \ semget.o \ semop.o \ - semconfig.o \ msgctl.o \ msgget.o \ msgsnd.o \ --- sys/sys/sysproto.h 2000/01/19 06:02:31 1.59 +++ sys/sys/sysproto.h 2000/05/01 11:16:00 1.59.2.1 @@ -662,9 +662,6 @@ struct sembuf * sops; char sops_[PAD_(struct sembuf *)]; u_int nsops; char nsops_[PAD_(u_int)]; }; -struct semconfig_args { - int flag; char flag_[PAD_(int)]; -}; struct msgctl_args { int msqid; char msqid_[PAD_(int)]; int cmd; char cmd_[PAD_(int)]; @@ -1158,7 +1155,6 @@ int __semctl __P((struct proc *, struct __semctl_args *)); int semget __P((struct proc *, struct semget_args *)); int semop __P((struct proc *, struct semop_args *)); -int semconfig __P((struct proc *, struct semconfig_args *)); int msgctl __P((struct proc *, struct msgctl_args *)); int msgget __P((struct proc *, struct msgget_args *)); int msgsnd __P((struct proc *, struct msgsnd_args *)); --- usr.bin/ipcs/ipcs.c 1999/12/29 05:05:32 1.12 +++ usr.bin/ipcs/ipcs.c 2000/05/01 10:51:37 1.12.2.1 @@ -56,7 +56,6 @@ struct shminfo shminfo; struct shmid_ds *shmsegs; -int semconfig __P((int,...)); void usage __P((void)); static struct nlist symbols[] = { @@ -420,11 +419,6 @@ seminfo.semaem); } if (display & SEMINFO) { - if (semconfig(SEM_CONFIG_FREEZE) != 0) { - perror("semconfig"); - fprintf(stderr, - "Can't lock semaphore facility - winging it...\n"); - } kvm_read(kd, symbols[X_SEMA].n_value, &sema, sizeof(sema)); xsema = malloc(sizeof(struct semid_ds) * seminfo.semmni); kvm_read(kd, (u_long) sema, xsema, sizeof(struct semid_ds) * seminfo.semmni); @@ -470,8 +464,6 @@ printf("\n"); } } - - (void) semconfig(SEM_CONFIG_THAW); printf("\n"); } [****** End FreeBSD Security Advisory ******] ____________________________________________________________________________ CIAC wishes to acknowledge the contributions of FreeBSD, Inc. for the information contained in this bulletin. ____________________________________________________________________________ CIAC, the Computer Incident Advisory Capability, is the computer security incident response team for the U.S. Department of Energy (DOE) and the emergency backup response team for the National Institutes of Health (NIH). CIAC is located at the Lawrence Livermore National Laboratory in Livermore, California. CIAC is also a founding member of FIRST, the Forum of Incident Response and Security Teams, a global organization established to foster cooperation and coordination among computer security teams worldwide. CIAC services are available to DOE, DOE contractors, and the NIH. CIAC can be contacted at: Voice: +1 925-422-8193 FAX: +1 925-423-8002 STU-III: +1 925-423-2604 E-mail: ciac@llnl.gov For emergencies and off-hour assistance, DOE, DOE contractor sites, and the NIH may contact CIAC 24-hours a day. During off hours (5PM - 8AM PST), use one of the following methods to contact CIAC: 1. Call the CIAC voice number 925-422-8193 and leave a message, or 2. Call 888-449-8369 to send a Sky Page to the CIAC duty person or 3. Send e-mail to 4498369@skytel.com, or 4. Call 800-201-9288 for the CIAC Project Leader. Previous CIAC notices, anti-virus software, and other information are available from the CIAC Computer Security Archive. World Wide Web: http://www.ciac.org/ (or http://ciac.llnl.gov -- they're the same machine) Anonymous FTP: ftp.ciac.org (or ciac.llnl.gov -- they're the same machine) Modem access: +1 (925) 423-4753 (28.8K baud) +1 (925) 423-3331 (28.8K baud) PLEASE NOTE: Many users outside of the DOE, ESnet, and NIH computing communities receive CIAC bulletins. If you are not part of these communities, please contact your agency's response team to report incidents. Your agency's team will coordinate with CIAC. The Forum of Incident Response and Security Teams (FIRST) is a world-wide organization. A list of FIRST member organizations and their constituencies can be obtained via WWW at http://www.first.org/. This document was prepared as an account of work sponsored by an agency of the United States Government. Neither the United States Government nor the University of California nor any of their employees, makes any warranty, express or implied, or assumes any legal liability or responsibility for the accuracy, completeness, or usefulness of any information, apparatus, product, or process disclosed, or represents that its use would not infringe privately owned rights. Reference herein to any specific commercial products, process, or service by trade name, trademark, manufacturer, or otherwise, does not necessarily constitute or imply its endorsement, recommendation or favoring by the United States Government or the University of California. The views and opinions of authors expressed herein do not necessarily state or reflect those of the United States Government or the University of California, and shall not be used for advertising or product endorsement purposes. LAST 10 CIAC BULLETINS ISSUED (Previous bulletins available from CIAC) K-036: Continuing Compromises of DNS Servers K-037: "mstream" Distributed Denial of Service Tool K-038: Security Holes in FileMaker 5 Web Companion K-039: LoveLetter.A Worm K-040: Netscape Navigator Improperly Validates SSL Sessions K-041: Denial of Service and File reading Vulnerabilities K-042: Microsoft "Office 2000 UA Control" Vulnerability K-043: Buffer Overrun Vulnerabilities in Kerberos K-044: Microsoft Vulnerabilities in Internet Explorer K-045: SGI Vulnerability in infosrch.cgi