From patchwork Mon Jan 30 10:42:40 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [maverick/ti-omap4,CVE,1/1] fuse: verify ioctl retries Date: Mon, 30 Jan 2012 00:42:40 -0000 From: Andy Whitcroft X-Patchwork-Id: 138547 Message-Id: <1327920160-30601-2-git-send-email-apw@canonical.com> To: kernel-team@lists.ubuntu.com Cc: Andy Whitcroft From: Miklos Szeredi Verify that the total length of the iovec returned in FUSE_IOCTL_RETRY doesn't overflow iov_length(). Signed-off-by: Miklos Szeredi CC: Tejun Heo CC: [2.6.31+] (backported from commit 7572777eef78ebdee1ecb7c258c0ef94d35bad16) CVE-2010-4650 BugLink: http://bugs.launchpad.net/bugs/917804 Signed-off-by: Andy Whitcroft Acked-by: Stefan Bader --- fs/fuse/file.c | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+), 0 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index ada0ade..0459219 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1617,6 +1617,20 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov, return 0; } +/* Make sure iov_length() won't overflow */ +static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count) +{ + size_t n; + u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT; + + for (n = 0; n < count; n++) { + if (iov->iov_len > (size_t) max) + return -ENOMEM; + max -= iov->iov_len; + } + return 0; +} + /* * For ioctls, there is no generic way to determine how much memory * needs to be read and/or written. Furthermore, ioctls are allowed @@ -1810,6 +1824,14 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, in_iov = page_address(iov_page); out_iov = in_iov + in_iovs; + err = fuse_verify_ioctl_iov(in_iov, in_iovs); + if (err) + goto out; + + err = fuse_verify_ioctl_iov(out_iov, out_iovs); + if (err) + goto out; + goto retry; }