0x0 漏洞信息
影响所有Nexus手机和部分Android手机的漏洞,Google于2016/03/18发布了公告修复,具体请看链接.
http://www.cvedetails.com/cve-details.php?t=1&cve_id=cve-2015-1805X
http://source.android.com/security/advisory/2016-03-18.html
0x1 漏洞描述
在linux 内核3.16版本之前的fs/pipe.c当中,由于pipe_read和pipe_write没有考虑到拷贝过程中数据没有同步的一些临界情况,造成了拷贝越界的问题,因此有可能导致系统crash以及系统权限提升.这种漏洞又称之为” I/O vector array overrun”
0x2 代码分析
//摘自fs/pipe.c:
static ssize_t
pipe_read(struct kiocb *iocb, const struct iovec *_iov,
unsigned long nr_segs, loff_t pos)
{
struct file *filp = iocb->ki_filp;
struct pipe_inode_info *pipe = filp->private_data;
int do_wakeup;
ssize_t ret;
struct iovec *iov = (struct iovec *)_iov;
size_t total_len;
total_len = iov_length(iov, nr_segs);
/* Null read succeeds. */
if (unlikely(total_len == 0))
return 0;
do_wakeup = 0;
ret = 0;
__pipe_lock(pipe);
for (;;) {
int bufs = pipe->nrbufs;
if (bufs) {
int curbuf = pipe->curbuf;
struct pipe_buffer *buf = pipe->bufs + curbuf;
const struct pipe_buf_operations *ops = buf->ops;
void *addr;
size_t chars = buf->len;
int error, atomic;
if (chars > total_len)
chars = total_len;
error = ops->confirm(pipe, buf);
if (error) {
if (!ret)
ret = error;
break;
}
//(1)
atomic = !iov_fault_in_pages_write(iov, chars);
redo:
addr = ops->map(pipe, buf, atomic);
//(2)
error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars, atomic);
op