安全研究
安全漏洞
FreeBSD semconfig()系统调用本地拒绝服务漏洞
发布日期:2000-05-29
更新日期:2000-05-29
受影响系统:
所有版本FreeBSD系统不受影响系统:
OpenBSD 2.7以及更高版本描述:
NetBSD
FreeBSD 中的一个系统调用semconfig()可被用来执行本地的拒绝服务攻击。
System V IPC 是进程间通信的一系列接口,包括共享内存,消息队列和信号量等。
在用户空间内,这些内容由ipcs(1)及其相关的工具管理。存在一个未见诸任何文
档的系统调用semconfig() ,它没有进行正确的访问控制检查。这个系统调用正常
只是被ipcs(1)用来对系统中当前System V IPC资源情况进行自动采样,例如确保采
样进程自身的资源不被释放或者分配。 由于没有进行正常的访问控制检查,普通用
户也可以执行这个系统调用,这将导致系统中所有进程在执行exit()函数退出时挂起
,直到另一个相应的系统调用来取消挂起状态或者系统重新启动。这将导致严重的本
地拒绝服务攻击。
<* 来源:Peter Wemm <peter@FreeBSD.org>
FreeBSD-SA-00:19
*>
建议:
1. 更新到2000-5-1号以后到的FreeBSD 2.1.7.1-STABLE, 2.2.8-STABLE, 3.4-STABLE,
4.0-STABLE 或者 5.0-CURRENT 版本。
2. 打下列补丁,并重建内核和src/usr.bin/ipcs工具
下列补丁可以在3.4-RELEASE,3.4-STABLE, 4.0-RELEASE 和4.0-STABLE 系统使用。
1) 保存下面的内容到一个advisory文件,以root身份执行下列命令:
# cd /usr/src
# patch -p < /path/to/advisory
# cd usr.bin/ipcs
# make all install
2) 按照FreeBSD手册中的方法重建并重新安装内核和内核模块
3) 重新启动系统
下面是相应的补丁程序:
(也可以在这里下载:ftp://ftp.freebsd.org/pub/FreeBSD/CERT/patches/SA-00:19/semconfig.patch)
--- 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");
}
浏览次数:6392
严重程度:0(网友投票)
绿盟科技给您安全的保障