From: Greg Kroah-Hartman Date: Fri, 5 Mar 2010 01:19:23 +0000 (-0800) Subject: more .27 patches X-Git-Tag: v2.6.32.10~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=945f7f365229530979fd054f01a6beb802f714b9;p=thirdparty%2Fkernel%2Fstable-queue.git more .27 patches --- diff --git a/queue-2.6.27/drm-r128-add-test-for-initialisation-to-all-ioctls-that-require-it.patch b/queue-2.6.27/drm-r128-add-test-for-initialisation-to-all-ioctls-that-require-it.patch new file mode 100644 index 00000000000..99419221d07 --- /dev/null +++ b/queue-2.6.27/drm-r128-add-test-for-initialisation-to-all-ioctls-that-require-it.patch @@ -0,0 +1,228 @@ +From 7dc482dfeeeefcfd000d4271c4626937406756d7 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Sun, 23 Aug 2009 16:59:04 +0100 +Subject: drm/r128: Add test for initialisation to all ioctls that require it + +From: Ben Hutchings + +commit 7dc482dfeeeefcfd000d4271c4626937406756d7 upstream. + +Almost all r128's private ioctls require that the CCE state has +already been initialised. However, most do not test that this has +been done, and will proceed to dereference a null pointer. This may +result in a security vulnerability, since some ioctls are +unprivileged. + +This adds a macro for the common initialisation test and changes all +ioctl implementations that require prior initialisation to use that +macro. + +Also, r128_do_init_cce() does not test that the CCE state has not +been initialised already. Repeated initialisation may lead to a crash +or resource leak. This adds that test. + +Signed-off-by: Ben Hutchings +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/gpu/drm/r128/r128_cce.c | 18 ++++++++++++++---- + drivers/gpu/drm/r128/r128_drv.h | 8 ++++++++ + drivers/gpu/drm/r128/r128_state.c | 36 +++++++++++++++++++----------------- + 3 files changed, 41 insertions(+), 21 deletions(-) + +--- a/drivers/gpu/drm/r128/r128_cce.c ++++ b/drivers/gpu/drm/r128/r128_cce.c +@@ -353,6 +353,11 @@ static int r128_do_init_cce(struct drm_d + + DRM_DEBUG("\n"); + ++ if (dev->dev_private) { ++ DRM_DEBUG("called when already initialized\n"); ++ return -EINVAL; ++ } ++ + dev_priv = drm_alloc(sizeof(drm_r128_private_t), DRM_MEM_DRIVER); + if (dev_priv == NULL) + return -ENOMEM; +@@ -651,6 +656,8 @@ int r128_cce_start(struct drm_device *de + + LOCK_TEST_WITH_RETURN(dev, file_priv); + ++ DEV_INIT_TEST_WITH_RETURN(dev_priv); ++ + if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) { + DRM_DEBUG("while CCE running\n"); + return 0; +@@ -673,6 +680,8 @@ int r128_cce_stop(struct drm_device *dev + + LOCK_TEST_WITH_RETURN(dev, file_priv); + ++ DEV_INIT_TEST_WITH_RETURN(dev_priv); ++ + /* Flush any pending CCE commands. This ensures any outstanding + * commands are exectuted by the engine before we turn it off. + */ +@@ -710,10 +719,7 @@ int r128_cce_reset(struct drm_device *de + + LOCK_TEST_WITH_RETURN(dev, file_priv); + +- if (!dev_priv) { +- DRM_DEBUG("called before init done\n"); +- return -EINVAL; +- } ++ DEV_INIT_TEST_WITH_RETURN(dev_priv); + + r128_do_cce_reset(dev_priv); + +@@ -730,6 +736,8 @@ int r128_cce_idle(struct drm_device *dev + + LOCK_TEST_WITH_RETURN(dev, file_priv); + ++ DEV_INIT_TEST_WITH_RETURN(dev_priv); ++ + if (dev_priv->cce_running) { + r128_do_cce_flush(dev_priv); + } +@@ -743,6 +751,8 @@ int r128_engine_reset(struct drm_device + + LOCK_TEST_WITH_RETURN(dev, file_priv); + ++ DEV_INIT_TEST_WITH_RETURN(dev->dev_private); ++ + return r128_do_engine_reset(dev); + } + +--- a/drivers/gpu/drm/r128/r128_drv.h ++++ b/drivers/gpu/drm/r128/r128_drv.h +@@ -418,6 +418,14 @@ static __inline__ void r128_update_ring_ + * Misc helper macros + */ + ++#define DEV_INIT_TEST_WITH_RETURN(_dev_priv) \ ++do { \ ++ if (!_dev_priv) { \ ++ DRM_ERROR("called with no initialization\n"); \ ++ return -EINVAL; \ ++ } \ ++} while (0) ++ + #define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ + do { \ + drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \ +--- a/drivers/gpu/drm/r128/r128_state.c ++++ b/drivers/gpu/drm/r128/r128_state.c +@@ -1244,14 +1244,18 @@ static void r128_cce_dispatch_stipple(st + static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *file_priv) + { + drm_r128_private_t *dev_priv = dev->dev_private; +- drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; ++ drm_r128_sarea_t *sarea_priv; + drm_r128_clear_t *clear = data; + DRM_DEBUG("\n"); + + LOCK_TEST_WITH_RETURN(dev, file_priv); + ++ DEV_INIT_TEST_WITH_RETURN(dev_priv); ++ + RING_SPACE_TEST_WITH_RETURN(dev_priv); + ++ sarea_priv = dev_priv->sarea_priv; ++ + if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS) + sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; + +@@ -1312,6 +1316,8 @@ static int r128_cce_flip(struct drm_devi + + LOCK_TEST_WITH_RETURN(dev, file_priv); + ++ DEV_INIT_TEST_WITH_RETURN(dev_priv); ++ + RING_SPACE_TEST_WITH_RETURN(dev_priv); + + if (!dev_priv->page_flipping) +@@ -1331,6 +1337,8 @@ static int r128_cce_swap(struct drm_devi + + LOCK_TEST_WITH_RETURN(dev, file_priv); + ++ DEV_INIT_TEST_WITH_RETURN(dev_priv); ++ + RING_SPACE_TEST_WITH_RETURN(dev_priv); + + if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS) +@@ -1354,10 +1362,7 @@ static int r128_cce_vertex(struct drm_de + + LOCK_TEST_WITH_RETURN(dev, file_priv); + +- if (!dev_priv) { +- DRM_ERROR("called with no initialization\n"); +- return -EINVAL; +- } ++ DEV_INIT_TEST_WITH_RETURN(dev_priv); + + DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n", + DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard); +@@ -1410,10 +1415,7 @@ static int r128_cce_indices(struct drm_d + + LOCK_TEST_WITH_RETURN(dev, file_priv); + +- if (!dev_priv) { +- DRM_ERROR("called with no initialization\n"); +- return -EINVAL; +- } ++ DEV_INIT_TEST_WITH_RETURN(dev_priv); + + DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID, + elts->idx, elts->start, elts->end, elts->discard); +@@ -1476,6 +1478,8 @@ static int r128_cce_blit(struct drm_devi + + LOCK_TEST_WITH_RETURN(dev, file_priv); + ++ DEV_INIT_TEST_WITH_RETURN(dev_priv); ++ + DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit->idx); + + if (blit->idx < 0 || blit->idx >= dma->buf_count) { +@@ -1501,6 +1505,8 @@ static int r128_cce_depth(struct drm_dev + + LOCK_TEST_WITH_RETURN(dev, file_priv); + ++ DEV_INIT_TEST_WITH_RETURN(dev_priv); ++ + RING_SPACE_TEST_WITH_RETURN(dev_priv); + + ret = -EINVAL; +@@ -1531,6 +1537,8 @@ static int r128_cce_stipple(struct drm_d + + LOCK_TEST_WITH_RETURN(dev, file_priv); + ++ DEV_INIT_TEST_WITH_RETURN(dev_priv); ++ + if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32))) + return -EFAULT; + +@@ -1555,10 +1563,7 @@ static int r128_cce_indirect(struct drm_ + + LOCK_TEST_WITH_RETURN(dev, file_priv); + +- if (!dev_priv) { +- DRM_ERROR("called with no initialization\n"); +- return -EINVAL; +- } ++ DEV_INIT_TEST_WITH_RETURN(dev_priv); + + DRM_DEBUG("idx=%d s=%d e=%d d=%d\n", + indirect->idx, indirect->start, indirect->end, +@@ -1620,10 +1625,7 @@ static int r128_getparam(struct drm_devi + drm_r128_getparam_t *param = data; + int value; + +- if (!dev_priv) { +- DRM_ERROR("called with no initialization\n"); +- return -EINVAL; +- } ++ DEV_INIT_TEST_WITH_RETURN(dev_priv); + + DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); + diff --git a/queue-2.6.27/ext4-avoid-null-pointer-dereference-when-decoding-erofs-w-o-a-journal.patch b/queue-2.6.27/ext4-avoid-null-pointer-dereference-when-decoding-erofs-w-o-a-journal.patch new file mode 100644 index 00000000000..ad4d3c79ab1 --- /dev/null +++ b/queue-2.6.27/ext4-avoid-null-pointer-dereference-when-decoding-erofs-w-o-a-journal.patch @@ -0,0 +1,32 @@ +From 78f1ddbb498283c2445c11b0dfa666424c301803 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Mon, 27 Jul 2009 23:09:47 -0400 +Subject: ext4: Avoid null pointer dereference when decoding EROFS w/o a journal + +From: Theodore Ts'o + +commit 78f1ddbb498283c2445c11b0dfa666424c301803 upstream. + +We need to check to make sure a journal is present before checking the +journal flags in ext4_decode_error(). + +Signed-off-by: Eric Sesterhenn +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/super.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -254,7 +254,8 @@ static const char *ext4_decode_error(str + errstr = "Out of memory"; + break; + case -EROFS: +- if (!sb || EXT4_SB(sb)->s_journal->j_flags & JBD2_ABORT) ++ if (!sb || (EXT4_SB(sb)->s_journal && ++ EXT4_SB(sb)->s_journal->j_flags & JBD2_ABORT)) + errstr = "Journal has aborted"; + else + errstr = "Readonly filesystem"; diff --git a/queue-2.6.27/kvm-vmx-check-cpl-before-emulating-debug-register-access.patch b/queue-2.6.27/kvm-vmx-check-cpl-before-emulating-debug-register-access.patch new file mode 100644 index 00000000000..4a568ebc42c --- /dev/null +++ b/queue-2.6.27/kvm-vmx-check-cpl-before-emulating-debug-register-access.patch @@ -0,0 +1,68 @@ +From 0a79b009525b160081d75cef5dbf45817956acf2 Mon Sep 17 00:00:00 2001 +From: Avi Kivity +Date: Tue, 1 Sep 2009 12:03:25 +0300 +Subject: KVM: VMX: Check cpl before emulating debug register access + +From: Avi Kivity + +commit 0a79b009525b160081d75cef5dbf45817956acf2 upstream. + +Debug registers may only be accessed from cpl 0. Unfortunately, vmx will +code to emulate the instruction even though it was issued from guest +userspace, possibly leading to an unexpected trap later. + +Signed-off-by: Avi Kivity +Signed-off-by: Marcelo Tosatti +Signed-off-by: Greg Kroah-Hartman + + +--- + arch/x86/kvm/vmx.c | 3 +++ + arch/x86/kvm/x86.c | 13 +++++++++++++ + include/asm-x86/kvm_host.h | 1 + + 3 files changed, 17 insertions(+) + +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -2464,6 +2464,9 @@ static int handle_dr(struct kvm_vcpu *vc + unsigned long val; + int dr, reg; + ++ if (!kvm_require_cpl(vcpu, 0)) ++ return 1; ++ + /* + * FIXME: this code assumes the host is debugging the guest. + * need to deal with guest debugging itself too. +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -198,6 +198,19 @@ static void __queue_exception(struct kvm + } + + /* ++ * Checks if cpl <= required_cpl; if true, return true. Otherwise queue ++ * a #GP and return false. ++ */ ++bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl) ++{ ++ if (kvm_x86_ops->get_cpl(vcpu) <= required_cpl) ++ return true; ++ kvm_queue_exception_e(vcpu, GP_VECTOR, 0); ++ return false; ++} ++EXPORT_SYMBOL_GPL(kvm_require_cpl); ++ ++/* + * Load the pae pdptrs. Return true is they are all valid. + */ + int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3) +--- a/include/asm-x86/kvm_host.h ++++ b/include/asm-x86/kvm_host.h +@@ -537,6 +537,7 @@ void kvm_queue_exception(struct kvm_vcpu + void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); + void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2, + u32 error_code); ++bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl); + + void kvm_inject_nmi(struct kvm_vcpu *vcpu); + diff --git a/queue-2.6.27/kvm-x86-check-for-cr3-validity-in-ioctl_set_sregs.patch b/queue-2.6.27/kvm-x86-check-for-cr3-validity-in-ioctl_set_sregs.patch new file mode 100644 index 00000000000..374279ccbc7 --- /dev/null +++ b/queue-2.6.27/kvm-x86-check-for-cr3-validity-in-ioctl_set_sregs.patch @@ -0,0 +1,53 @@ +From 59839dfff5eabca01cc4e20b45797a60a80af8cb Mon Sep 17 00:00:00 2001 +From: Marcelo Tosatti +Date: Thu, 16 Apr 2009 08:30:44 -0300 +Subject: KVM: x86: check for cr3 validity in ioctl_set_sregs + +From: Marcelo Tosatti + +commit 59839dfff5eabca01cc4e20b45797a60a80af8cb upstream. + +Matt T. Yourst notes that kvm_arch_vcpu_ioctl_set_sregs lacks validity +checking for the new cr3 value: + +"Userspace callers of KVM_SET_SREGS can pass a bogus value of cr3 to +the kernel. This will trigger a NULL pointer access in gfn_to_rmap() +when userspace next tries to call KVM_RUN on the affected VCPU and kvm +attempts to activate the new non-existent page table root. + +This happens since kvm only validates that cr3 points to a valid guest +physical memory page when code *inside* the guest sets cr3. However, kvm +currently trusts the userspace caller (e.g. QEMU) on the host machine to +always supply a valid page table root, rather than properly validating +it along with the rest of the reloaded guest state." + +http://sourceforge.net/tracker/?func=detail&atid=893831&aid=2687641&group_id=180599 + +Check for a valid cr3 address in kvm_arch_vcpu_ioctl_set_sregs, triple +fault in case of failure. + +Signed-off-by: Marcelo Tosatti +Signed-off-by: Avi Kivity +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/x86.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -3658,7 +3658,13 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct + + vcpu->arch.cr2 = sregs->cr2; + mmu_reset_needed |= vcpu->arch.cr3 != sregs->cr3; +- vcpu->arch.cr3 = sregs->cr3; ++ ++ down_read(&vcpu->kvm->slots_lock); ++ if (gfn_to_memslot(vcpu->kvm, sregs->cr3 >> PAGE_SHIFT)) ++ vcpu->arch.cr3 = sregs->cr3; ++ else ++ set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests); ++ up_read(&vcpu->kvm->slots_lock); + + kvm_set_cr8(vcpu, sregs->cr8); + diff --git a/queue-2.6.27/parisc-isa-eeprom-fix-loff_t-usage.patch b/queue-2.6.27/parisc-isa-eeprom-fix-loff_t-usage.patch new file mode 100644 index 00000000000..2f964a2c4af --- /dev/null +++ b/queue-2.6.27/parisc-isa-eeprom-fix-loff_t-usage.patch @@ -0,0 +1,33 @@ +From 6b4dbcd86a9d464057fcc7abe4d0574093071fcc Mon Sep 17 00:00:00 2001 +From: Michael Buesch +Date: Mon, 20 Jul 2009 22:58:44 +0000 +Subject: parisc: isa-eeprom - Fix loff_t usage + +From: Michael Buesch + +commit 6b4dbcd86a9d464057fcc7abe4d0574093071fcc upstream. + +loff_t is a signed type. If userspace passes a negative ppos, the "count" +range check is weakened. "count"s bigger than HPEE_MAX_LENGTH will pass the check. +Also, if ppos is negative, the readb(eisa_eeprom_addr + *ppos) will poke in random +memory. + +Signed-off-by: Michael Buesch +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/parisc/eisa_eeprom.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/parisc/eisa_eeprom.c ++++ b/drivers/parisc/eisa_eeprom.c +@@ -55,7 +55,7 @@ static ssize_t eisa_eeprom_read(struct f + ssize_t ret; + int i; + +- if (*ppos >= HPEE_MAX_LENGTH) ++ if (*ppos < 0 || *ppos >= HPEE_MAX_LENGTH) + return 0; + + count = *ppos + count < HPEE_MAX_LENGTH ? count : HPEE_MAX_LENGTH - *ppos; diff --git a/queue-2.6.27/series b/queue-2.6.27/series index 6f84bf4c677..9da1a5d6bd8 100644 --- a/queue-2.6.27/series +++ b/queue-2.6.27/series @@ -24,3 +24,9 @@ usb-usbfs-only-copy-the-actual-data-received.patch usb-usbfs-properly-clean-up-the-as-structure-on-error-paths.patch usb-ehci-fix-counting-of-transaction-error-retries.patch kvm-x86-emulator-limit-insns-to-15-bytes.patch +ext4-avoid-null-pointer-dereference-when-decoding-erofs-w-o-a-journal.patch +kvm-vmx-check-cpl-before-emulating-debug-register-access.patch +drm-r128-add-test-for-initialisation-to-all-ioctls-that-require-it.patch +tc-fix-unitialized-kernel-memory-leak.patch +parisc-isa-eeprom-fix-loff_t-usage.patch +kvm-x86-check-for-cr3-validity-in-ioctl_set_sregs.patch diff --git a/queue-2.6.27/tc-fix-unitialized-kernel-memory-leak.patch b/queue-2.6.27/tc-fix-unitialized-kernel-memory-leak.patch new file mode 100644 index 00000000000..1434fbb593c --- /dev/null +++ b/queue-2.6.27/tc-fix-unitialized-kernel-memory-leak.patch @@ -0,0 +1,31 @@ +From 16ebb5e0b36ceadc8186f71d68b0c4fa4b6e781b Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Wed, 2 Sep 2009 02:40:09 +0000 +Subject: tc: Fix unitialized kernel memory leak + +From: Eric Dumazet + +commit 16ebb5e0b36ceadc8186f71d68b0c4fa4b6e781b upstream. + +Three bytes of uninitialized kernel memory are currently leaked to user + +Signed-off-by: Eric Dumazet +Reviewed-by: Jiri Pirko +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/sched/sch_api.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -1453,6 +1453,8 @@ static int tc_fill_tclass(struct sk_buff + nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); + tcm = NLMSG_DATA(nlh); + tcm->tcm_family = AF_UNSPEC; ++ tcm->tcm__pad1 = 0; ++ tcm->tcm__pad2 = 0; + tcm->tcm_ifindex = qdisc_dev(q)->ifindex; + tcm->tcm_parent = q->handle; + tcm->tcm_handle = q->handle;