CVE-2012-2119 macvtap: zerocopy: vector length is not validated before pinning user pages (rhbz 814278 814289)

This commit is contained in:
Justin M. Forbes 2012-04-19 16:27:40 -05:00
parent 0f5390a921
commit c54adc8eef
2 changed files with 37 additions and 2 deletions

View File

@ -713,9 +713,12 @@ Patch21710: disable-hid-battery.patch
Patch22000: weird-root-dentry-name-debug.patch
#rhbz 814149 814155
#rhbz 814149 814155 CVE-2012-2121
Patch22006: KVM-unmap-pages-from-the-iommu-when-slots-are-removed.patch
#rhbz 814278 814289 CVE-2012-2119
Patch22007: macvtap-zerocopy-validate-vector-length.patch
# END OF PATCH DEFINITIONS
%endif
@ -1322,9 +1325,12 @@ ApplyPatch x86-microcode-Ensure-that-module-is-only-loaded-for-supported-AMD-CPU
#rhbz 806295
ApplyPatch disable-hid-battery.patch
#rhbz 814149 814155
#rhbz 814149 814155 CVE-2012-2121
ApplyPatch KVM-unmap-pages-from-the-iommu-when-slots-are-removed.patch
#rhbz 814278 814289 CVE-2012-2119
ApplyPatch macvtap-zerocopy-validate-vector-length.patch
# END OF PATCH APPLICATIONS
%endif
@ -1977,6 +1983,10 @@ fi
# and build.
%changelog
* Thu Apr 19 2012 Justin M. Forbes <jforbes@redhat.com> 2.6.43.2-4
- CVE-2012-2119 macvtap: zerocopy: vector length is not validated before
pinning user pages (rhbz 814278 814289)
* Thu Apr 19 2012 Justin M. Forbes <jforbes@redhat.com>
- Fix KVM device assignment page leak (rhbz 814149 814155)

View File

@ -0,0 +1,25 @@
Currently we do not validate the vector length before calling
get_user_pages_fast(), host stack would be easily overflowed by
malicious guest driver who give us a descriptor with length greater
than MAX_SKB_FRAGS. Solve this problem by checking the free entries
before trying to pin user pages.
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
drivers/net/macvtap.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 7cb2684..d197a78 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -527,6 +527,8 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from,
}
base = (unsigned long)from->iov_base + offset1;
size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT;
+ if (i + size >= MAX_SKB_FRAGS)
+ return -EFAULT;
num_pages = get_user_pages_fast(base, size, 0, &page[i]);
if ((num_pages != size) ||
(num_pages > MAX_SKB_FRAGS - skb_shinfo(skb)->nr_frags))