Lucene search

K
seebugRootSSV:4661
HistoryJan 15, 2009 - 12:00 a.m.

Linux Kernel locks_remove_flock()本地竞争条件漏洞

2009-01-1500:00:00
Root
www.seebug.org
13

0.0004 Low

EPSS

Percentile

8.6%

BUGTRAQ ID: 33237
CVE(CAN) ID: CVE-2008-4307

Linux Kernel是开放源码操作系统Linux所使用的内核。

RHEL4/5内核处理POSIX锁定时fcntl调用可能与关闭相同文件描述符出现竞争,本地攻击者可以利用这个漏洞导致拒绝服务或获得权限提升。

fcntl以如下方式获得POSIX锁定:

sys_fcntl()
fget()
do_fcntl()
fcntl_setlk()
fput()
if(!count) __fput()
locks_remove_flock()

fcntl_setlk()调用可能阻塞很长时间,允许同一进程中的其他线程关闭文件描述符:

sys_close()
filp_close()
locks_remove_posix()
fput()
if(!count) __fput()
locks_remove_flock()

如果其中一个线程仍在fcntl_setlk中阻断期间但在许可锁定之前(在将file_lock结构放置到inode的i_lock列表之前)从另一个线程关闭了文件描述符,关闭路径中的locks_remove_posix调用就会错过POSIX锁定。此时还无法调用locks_remove_flock,因为fcntl_setlk中线程仍持有对文件的引用。

当__fput调用locks_remove_flock时,sys_fcntl返回路径的最终fput可以触发漏洞:

/*

  • This function is called on the last close of an open file.
    */
    void locks_remove_flock(struct file *filp)
    {
    […]
    while ((fl = before) != NULL) {
    if (fl->fl_file == filp) {
    if (IS_FLOCK(fl)) {
    locks_delete_lock(before);
    continue;
    }
    if (IS_LEASE(fl)) {
    lease_modify(before, F_UNLCK);
    continue;
    }
    if (IS_POSIX(fl))
    continue;
    /
    What? */
    BUG(); <----
    }
    before = &fl->fl_next;
    }
    unlock_kernel();
    }

Linux kernel 2.6.x
厂商补丁:

Linux

目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

<a href=“http://www.kernel.org/pub/linux/kernel/v2.6/snapshots/old/patch-2.6.25-git6.log” target=“_blank”>http://www.kernel.org/pub/linux/kernel/v2.6/snapshots/old/patch-2.6.25-git6.log</a>