diff options
author | Paul Gortmaker <paul.gortmaker@windriver.com> | 2012-07-24 17:36:06 -0400 |
---|---|---|
committer | Paul Gortmaker <paul.gortmaker@windriver.com> | 2012-07-24 17:36:06 -0400 |
commit | 68bdc0ab03bcfef35e9e45295a20eaf09c204124 (patch) | |
tree | ebed1d1d4d15d7d5f168e94e0de9fb1c436191a3 | |
parent | 933c1b3869fcb6c43e66a7d521fa6dae392a5320 (diff) | |
download | longterm-queue-2.6.34-68bdc0ab03bcfef35e9e45295a20eaf09c204124.tar.gz |
for-13: import 19 new patches.
Untested at this point, just the basic passes "git am" step.
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
20 files changed, 1540 insertions, 0 deletions
diff --git a/queue/KEYS-Fix-a-NULL-pointer-deref-in-the-user-defined-ke.patch b/queue/KEYS-Fix-a-NULL-pointer-deref-in-the-user-defined-ke.patch new file mode 100644 index 0000000..351eae9 --- /dev/null +++ b/queue/KEYS-Fix-a-NULL-pointer-deref-in-the-user-defined-ke.patch @@ -0,0 +1,68 @@ +From 7deb80439fb5cc91fd1aa211eda9caaaef130312 Mon Sep 17 00:00:00 2001 +From: David Howells <dhowells@redhat.com> +Date: Tue, 15 Nov 2011 22:09:45 +0000 +Subject: [PATCH] KEYS: Fix a NULL pointer deref in the user-defined key type + +commit 9f35a33b8d06263a165efe3541d9aa0cdbd70b3b upstream. + +Fix a NULL pointer deref in the user-defined key type whereby updating a +negative key into a fully instantiated key will cause an oops to occur +when the code attempts to free the non-existent old payload. + +This results in an oops that looks something like the following: + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 + IP: [<ffffffff81085fa1>] __call_rcu+0x11/0x13e + PGD 3391d067 PUD 3894a067 PMD 0 + Oops: 0002 [#1] SMP + CPU 1 + Pid: 4354, comm: keyctl Not tainted 3.1.0-fsdevel+ #1140 /DG965RY + RIP: 0010:[<ffffffff81085fa1>] [<ffffffff81085fa1>] __call_rcu+0x11/0x13e + RSP: 0018:ffff88003d591df8 EFLAGS: 00010246 + RAX: 0000000000000000 RBX: 0000000000000000 RCX: 000000000000006e + RDX: ffffffff8161d0c0 RSI: 0000000000000000 RDI: 0000000000000000 + RBP: ffff88003d591e18 R08: 0000000000000000 R09: ffffffff8152fa6c + R10: 0000000000000000 R11: 0000000000000300 R12: ffff88003b8f9538 + R13: ffffffff8161d0c0 R14: ffff88003b8f9d50 R15: ffff88003c69f908 + FS: 00007f97eb18c720(0000) GS:ffff88003bd00000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000008 CR3: 000000003d47a000 CR4: 00000000000006e0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 + Process keyctl (pid: 4354, threadinfo ffff88003d590000, task ffff88003c78a040) + Stack: + ffff88003e0ffde0 ffff88003b8f9538 0000000000000001 ffff88003b8f9d50 + ffff88003d591e28 ffffffff810860f0 ffff88003d591e68 ffffffff8117bfea + ffff88003d591e68 ffffffff00000000 ffff88003e0ffde1 ffff88003e0ffde0 + Call Trace: + [<ffffffff810860f0>] call_rcu_sched+0x10/0x12 + [<ffffffff8117bfea>] user_update+0x8d/0xa2 + [<ffffffff8117723a>] key_create_or_update+0x236/0x270 + [<ffffffff811789b1>] sys_add_key+0x123/0x17e + [<ffffffff813b84bb>] system_call_fastpath+0x16/0x1b + +Signed-off-by: David Howells <dhowells@redhat.com> +Acked-by: Jeff Layton <jlayton@redhat.com> +Acked-by: Neil Horman <nhorman@redhat.com> +Acked-by: Steve Dickson <steved@redhat.com> +Acked-by: James Morris <jmorris@namei.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c +index e4f04d1..9352229 100644 +--- a/security/keys/user_defined.c ++++ b/security/keys/user_defined.c +@@ -105,7 +105,8 @@ int user_update(struct key *key, const void *data, size_t datalen) + key->expiry = 0; + } + +- kfree_rcu(zap, rcu); ++ if (zap) ++ kfree_rcu(zap, rcu); + + error: + return ret; +-- +1.7.9.7 + diff --git a/queue/KVM-Device-assignment-permission-checks.patch b/queue/KVM-Device-assignment-permission-checks.patch new file mode 100644 index 0000000..991a35d --- /dev/null +++ b/queue/KVM-Device-assignment-permission-checks.patch @@ -0,0 +1,141 @@ +From 906f5fe6452d257990baad4177fb47f151c1a43b Mon Sep 17 00:00:00 2001 +From: Alex Williamson <alex.williamson@redhat.com> +Date: Tue, 20 Dec 2011 21:59:09 -0700 +Subject: [PATCH] KVM: Device assignment permission checks + +commit 3d27e23b17010c668db311140b17bbbb70c78fb9 upstream. + +Only allow KVM device assignment to attach to devices which: + + - Are not bridges + - Have BAR resources (assume others are special devices) + - The user has permissions to use + +Assigning a bridge is a configuration error, it's not supported, and +typically doesn't result in the behavior the user is expecting anyway. +Devices without BAR resources are typically chipset components that +also don't have host drivers. We don't want users to hold such devices +captive or cause system problems by fencing them off into an iommu +domain. We determine "permission to use" by testing whether the user +has access to the PCI sysfs resource files. By default a normal user +will not have access to these files, so it provides a good indication +that an administration agent has granted the user access to the device. + +[Yang Bai: add missing #include] +[avi: fix comment style] + +Signed-off-by: Alex Williamson <alex.williamson@redhat.com> +Signed-off-by: Yang Bai <hamo.by@gmail.com> +Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> +[PG: Drop Documentation api.txt chunk; 2.6.34 doesn't have the file] +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c +index 1f97473..f427ecc 100644 +--- a/virt/kvm/assigned-dev.c ++++ b/virt/kvm/assigned-dev.c +@@ -17,6 +17,8 @@ + #include <linux/pci.h> + #include <linux/interrupt.h> + #include <linux/slab.h> ++#include <linux/namei.h> ++#include <linux/fs.h> + #include "irq.h" + + static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head, +@@ -502,12 +504,73 @@ out: + return r; + } + ++/* ++ * We want to test whether the caller has been granted permissions to ++ * use this device. To be able to configure and control the device, ++ * the user needs access to PCI configuration space and BAR resources. ++ * These are accessed through PCI sysfs. PCI config space is often ++ * passed to the process calling this ioctl via file descriptor, so we ++ * can't rely on access to that file. We can check for permissions ++ * on each of the BAR resource files, which is a pretty clear ++ * indicator that the user has been granted access to the device. ++ */ ++static int probe_sysfs_permissions(struct pci_dev *dev) ++{ ++#ifdef CONFIG_SYSFS ++ int i; ++ bool bar_found = false; ++ ++ for (i = PCI_STD_RESOURCES; i <= PCI_STD_RESOURCE_END; i++) { ++ char *kpath, *syspath; ++ struct path path; ++ struct inode *inode; ++ int r; ++ ++ if (!pci_resource_len(dev, i)) ++ continue; ++ ++ kpath = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); ++ if (!kpath) ++ return -ENOMEM; ++ ++ /* Per sysfs-rules, sysfs is always at /sys */ ++ syspath = kasprintf(GFP_KERNEL, "/sys%s/resource%d", kpath, i); ++ kfree(kpath); ++ if (!syspath) ++ return -ENOMEM; ++ ++ r = kern_path(syspath, LOOKUP_FOLLOW, &path); ++ kfree(syspath); ++ if (r) ++ return r; ++ ++ inode = path.dentry->d_inode; ++ ++ r = inode_permission(inode, MAY_READ | MAY_WRITE | MAY_ACCESS); ++ path_put(&path); ++ if (r) ++ return r; ++ ++ bar_found = true; ++ } ++ ++ /* If no resources, probably something special */ ++ if (!bar_found) ++ return -EPERM; ++ ++ return 0; ++#else ++ return -EINVAL; /* No way to control the device without sysfs */ ++#endif ++} ++ + static int kvm_vm_ioctl_assign_device(struct kvm *kvm, + struct kvm_assigned_pci_dev *assigned_dev) + { + int r = 0, idx; + struct kvm_assigned_dev_kernel *match; + struct pci_dev *dev; ++ u8 header_type; + + if (!(assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU)) + return -EINVAL; +@@ -538,6 +601,18 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, + r = -EINVAL; + goto out_free; + } ++ ++ /* Don't allow bridges to be assigned */ ++ pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type); ++ if ((header_type & PCI_HEADER_TYPE) != PCI_HEADER_TYPE_NORMAL) { ++ r = -EPERM; ++ goto out_put; ++ } ++ ++ r = probe_sysfs_permissions(dev); ++ if (r) ++ goto out_put; ++ + if (pci_enable_device(dev)) { + printk(KERN_INFO "%s: Could not enable PCI device\n", __func__); + r = -EBUSY; +-- +1.7.9.7 + diff --git a/queue/KVM-Ensure-all-vcpus-are-consistent-with-in-kernel-i.patch b/queue/KVM-Ensure-all-vcpus-are-consistent-with-in-kernel-i.patch new file mode 100644 index 0000000..46e3825 --- /dev/null +++ b/queue/KVM-Ensure-all-vcpus-are-consistent-with-in-kernel-i.patch @@ -0,0 +1,103 @@ +From af9291a3df864a650a922600ca8d712a0f02d216 Mon Sep 17 00:00:00 2001 +From: Avi Kivity <avi@redhat.com> +Date: Mon, 5 Mar 2012 14:23:29 +0200 +Subject: [PATCH] KVM: Ensure all vcpus are consistent with in-kernel irqchip + settings + +commit 3e515705a1f46beb1c942bb8043c16f8ac7b1e9e upstream. + +If some vcpus are created before KVM_CREATE_IRQCHIP, then +irqchip_in_kernel() and vcpu->arch.apic will be inconsistent, leading +to potential NULL pointer dereferences. + +Fix by: +- ensuring that no vcpus are installed when KVM_CREATE_IRQCHIP is called +- ensuring that a vcpu has an apic if it is installed after KVM_CREATE_IRQCHIP + +This is somewhat long winded because vcpu->arch.apic is created without +kvm->lock held. + +Based on earlier patch by Michael Ellerman. + +Signed-off-by: Michael Ellerman <michael@ellerman.id.au> +Signed-off-by: Avi Kivity <avi@redhat.com> +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c +index 7f3c0a2..2b7adad 100644 +--- a/arch/ia64/kvm/kvm-ia64.c ++++ b/arch/ia64/kvm/kvm-ia64.c +@@ -1179,6 +1179,11 @@ out: + + #define PALE_RESET_ENTRY 0x80000000ffffffb0UL + ++bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) ++{ ++ return irqchip_in_kernel(vcpu->kcm) == (vcpu->arch.apic != NULL); ++} ++ + int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) + { + struct kvm_vcpu *v; +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 8ced130..c1e586d 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -2764,6 +2764,9 @@ long kvm_arch_vm_ioctl(struct file *filp, + r = -EEXIST; + if (kvm->arch.vpic) + goto create_irqchip_unlock; ++ r = -EINVAL; ++ if (atomic_read(&kvm->online_vcpus)) ++ goto create_irqchip_unlock; + r = -ENOMEM; + vpic = kvm_create_pic(kvm); + if (vpic) { +@@ -5586,6 +5589,11 @@ void kvm_arch_check_processor_compat(void *rtn) + kvm_x86_ops->check_processor_compatibility(rtn); + } + ++bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) ++{ ++ return irqchip_in_kernel(vcpu->kvm) == (vcpu->arch.apic != NULL); ++} ++ + int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) + { + struct page *page; +diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h +index 169d077..94cb72c 100644 +--- a/include/linux/kvm_host.h ++++ b/include/linux/kvm_host.h +@@ -599,6 +599,13 @@ static inline bool kvm_vcpu_is_bsp(struct kvm_vcpu *vcpu) + { + return vcpu->kvm->bsp_vcpu_id == vcpu->vcpu_id; + } ++ ++bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu); ++ ++#else ++ ++static inline bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) { return true; } ++ + #endif + + #ifdef __KVM_HAVE_DEVICE_ASSIGNMENT +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index c82ae24..559af38 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -1322,6 +1322,10 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id) + return r; + + mutex_lock(&kvm->lock); ++ if (!kvm_vcpu_compatible(vcpu)) { ++ r = -EINVAL; ++ goto unlock_vcpu_destroy; ++ } + if (atomic_read(&kvm->online_vcpus) == KVM_MAX_VCPUS) { + r = -EINVAL; + goto vcpu_destroy; +-- +1.7.9.7 + diff --git a/queue/KVM-Remove-ability-to-assign-a-device-without-iommu-.patch b/queue/KVM-Remove-ability-to-assign-a-device-without-iommu-.patch new file mode 100644 index 0000000..ac3e897 --- /dev/null +++ b/queue/KVM-Remove-ability-to-assign-a-device-without-iommu-.patch @@ -0,0 +1,65 @@ +From 740c9c966d7c9269d2283a93b6422a4217a6fa9b Mon Sep 17 00:00:00 2001 +From: Alex Williamson <alex.williamson@redhat.com> +Date: Tue, 20 Dec 2011 21:59:03 -0700 +Subject: [PATCH] KVM: Remove ability to assign a device without iommu support + +commit 423873736b78f549fbfa2f715f2e4de7e6c5e1e9 upstream. + +This option has no users and it exposes a security hole that we +can allow devices to be assigned without iommu protection. Make +KVM_DEV_ASSIGN_ENABLE_IOMMU a mandatory option. + +Signed-off-by: Alex Williamson <alex.williamson@redhat.com> +Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> +[PG: drop Documentation chunk; no api.txt file in .34 baseline] +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c +index 02ff2b1..1f97473 100644 +--- a/virt/kvm/assigned-dev.c ++++ b/virt/kvm/assigned-dev.c +@@ -509,6 +509,9 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, + struct kvm_assigned_dev_kernel *match; + struct pci_dev *dev; + ++ if (!(assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU)) ++ return -EINVAL; ++ + mutex_lock(&kvm->lock); + idx = srcu_read_lock(&kvm->srcu); + +@@ -564,16 +567,14 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, + + list_add(&match->list, &kvm->arch.assigned_dev_head); + +- if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) { +- if (!kvm->arch.iommu_domain) { +- r = kvm_iommu_map_guest(kvm); +- if (r) +- goto out_list_del; +- } +- r = kvm_assign_device(kvm, match); ++ if (!kvm->arch.iommu_domain) { ++ r = kvm_iommu_map_guest(kvm); + if (r) + goto out_list_del; + } ++ r = kvm_assign_device(kvm, match); ++ if (r) ++ goto out_list_del; + + out: + srcu_read_unlock(&kvm->srcu, idx); +@@ -610,8 +611,7 @@ static int kvm_vm_ioctl_deassign_device(struct kvm *kvm, + goto out; + } + +- if (match->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) +- kvm_deassign_device(kvm, match); ++ kvm_deassign_device(kvm, match); + + kvm_free_assigned_device(kvm, match); + +-- +1.7.9.7 + diff --git a/queue/cifs-fix-dentry-refcount-leak-when-opening-a-FIFO-on.patch b/queue/cifs-fix-dentry-refcount-leak-when-opening-a-FIFO-on.patch new file mode 100644 index 0000000..d613d06 --- /dev/null +++ b/queue/cifs-fix-dentry-refcount-leak-when-opening-a-FIFO-on.patch @@ -0,0 +1,60 @@ +From d67362d7f09db555297d609330c876e3bc37bb32 Mon Sep 17 00:00:00 2001 +From: Jeff Layton <jlayton@redhat.com> +Date: Thu, 23 Feb 2012 09:37:45 -0500 +Subject: [PATCH] cifs: fix dentry refcount leak when opening a FIFO on lookup + +commit 5bccda0ebc7c0331b81ac47d39e4b920b198b2cd upstream. + +The cifs code will attempt to open files on lookup under certain +circumstances. What happens though if we find that the file we opened +was actually a FIFO or other special file? + +Currently, the open filehandle just ends up being leaked leading to +a dentry refcount mismatch and oops on umount. Fix this by having the +code close the filehandle on the server if it turns out not to be a +regular file. While we're at it, change this spaghetti if statement +into a switch too. + +Reported-by: CAI Qian <caiqian@redhat.com> +Tested-by: CAI Qian <caiqian@redhat.com> +Reviewed-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com> +Signed-off-by: Jeff Layton <jlayton@redhat.com> +Signed-off-by: Steve French <smfrench@gmail.com> +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c +index ff3d891..fc79b95 100644 +--- a/fs/cifs/dir.c ++++ b/fs/cifs/dir.c +@@ -692,10 +692,26 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, + * If either that or op not supported returned, follow + * the normal lookup. + */ +- if ((rc == 0) || (rc == -ENOENT)) ++ switch (rc) { ++ case 0: ++ /* ++ * The server may allow us to open things like ++ * FIFOs, but the client isn't set up to deal ++ * with that. If it's not a regular file, just ++ * close it and proceed as if it were a normal ++ * lookup. ++ */ ++ if (newInode && !S_ISREG(newInode->i_mode)) { ++ CIFSSMBClose(xid, pTcon, fileHandle); ++ break; ++ } ++ case -ENOENT: + posix_open = true; +- else if ((rc == -EINVAL) || (rc != -EOPNOTSUPP)) ++ case -EOPNOTSUPP: ++ break; ++ default: + pTcon->broken_posix_open = true; ++ } + } + if (!posix_open) + rc = cifs_get_inode_info_unix(&newInode, full_path, +-- +1.7.9.7 + diff --git a/queue/cifs-fix-possible-memory-corruption-in-CIFSFindNext.patch b/queue/cifs-fix-possible-memory-corruption-in-CIFSFindNext.patch new file mode 100644 index 0000000..ea472e0 --- /dev/null +++ b/queue/cifs-fix-possible-memory-corruption-in-CIFSFindNext.patch @@ -0,0 +1,42 @@ +From 2bfe9af20ea55ad2f396004e8ee8b2a58410e78b Mon Sep 17 00:00:00 2001 +From: Jeff Layton <jlayton@redhat.com> +Date: Tue, 23 Aug 2011 07:21:28 -0400 +Subject: [PATCH] cifs: fix possible memory corruption in CIFSFindNext + +commit 9438fabb73eb48055b58b89fc51e0bc4db22fabd upstream. + +The name_len variable in CIFSFindNext is a signed int that gets set to +the resume_name_len in the cifs_search_info. The resume_name_len however +is unsigned and for some infolevels is populated directly from a 32 bit +value sent by the server. + +If the server sends a very large value for this, then that value could +look negative when converted to a signed int. That would make that +value pass the PATH_MAX check later in CIFSFindNext. The name_len would +then be used as a length value for a memcpy. It would then be treated +as unsigned again, and the memcpy scribbles over a ton of memory. + +Fix this by making the name_len an unsigned value in CIFSFindNext. + +Reported-by: Darren Lavender <dcl@hppine99.gbr.hp.com> +Signed-off-by: Jeff Layton <jlayton@redhat.com> +Signed-off-by: Steve French <sfrench@us.ibm.com> +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c +index 62e49ab..5171d86 100644 +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -3743,7 +3743,8 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, + T2_FNEXT_RSP_PARMS *parms; + char *response_data; + int rc = 0; +- int bytes_returned, name_len; ++ int bytes_returned; ++ unsigned int name_len; + __u16 params, byte_count; + + cFYI(1, ("In FindNext")); +-- +1.7.9.7 + diff --git a/queue/drm-integer-overflow-in-drm_mode_dirtyfb_ioctl.patch b/queue/drm-integer-overflow-in-drm_mode_dirtyfb_ioctl.patch new file mode 100644 index 0000000..43d04ce --- /dev/null +++ b/queue/drm-integer-overflow-in-drm_mode_dirtyfb_ioctl.patch @@ -0,0 +1,48 @@ +From 58173271e325e2573d87dbad61cba727716f4f4e Mon Sep 17 00:00:00 2001 +From: Xi Wang <xi.wang@gmail.com> +Date: Wed, 23 Nov 2011 01:12:01 -0500 +Subject: [PATCH] drm: integer overflow in drm_mode_dirtyfb_ioctl() + +commit a5cd335165e31db9dbab636fd29895d41da55dd2 upstream. + +There is a potential integer overflow in drm_mode_dirtyfb_ioctl() +if userspace passes in a large num_clips. The call to kmalloc would +allocate a small buffer, and the call to fb->funcs->dirty may result +in a memory corruption. + +Reported-by: Haogang Chen <haogangchen@gmail.com> +Signed-off-by: Xi Wang <xi.wang@gmail.com> +Signed-off-by: Dave Airlie <airlied@redhat.com> +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c +index 1a224f8..819d0dc 100644 +--- a/drivers/gpu/drm/drm_crtc.c ++++ b/drivers/gpu/drm/drm_crtc.c +@@ -1833,6 +1833,10 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, + } + + if (num_clips && clips_ptr) { ++ if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) { ++ ret = -EINVAL; ++ goto out_err1; ++ } + clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); + if (!clips) { + ret = -ENOMEM; +diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h +index c5ba163..9cf639c 100644 +--- a/include/drm/drm_mode.h ++++ b/include/drm/drm_mode.h +@@ -232,6 +232,8 @@ struct drm_mode_fb_cmd { + #define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02 + #define DRM_MODE_FB_DIRTY_FLAGS 0x03 + ++#define DRM_MODE_FB_DIRTY_MAX_CLIPS 256 ++ + /* + * Mark a region of a framebuffer as dirty. + * +-- +1.7.9.7 + diff --git a/queue/ext4-fix-undefined-behavior-in-ext4_fill_flex_info.patch b/queue/ext4-fix-undefined-behavior-in-ext4_fill_flex_info.patch new file mode 100644 index 0000000..ebfc69c --- /dev/null +++ b/queue/ext4-fix-undefined-behavior-in-ext4_fill_flex_info.patch @@ -0,0 +1,70 @@ +From dbef26165f5f1b37ea0099cd01128fb52821f62c Mon Sep 17 00:00:00 2001 +From: Xi Wang <xi.wang@gmail.com> +Date: Tue, 10 Jan 2012 11:51:10 -0500 +Subject: [PATCH] ext4: fix undefined behavior in ext4_fill_flex_info() + +commit d50f2ab6f050311dbf7b8f5501b25f0bf64a439b upstream. + +Commit 503358ae01b70ce6909d19dd01287093f6b6271c ("ext4: avoid divide by +zero when trying to mount a corrupted file system") fixes CVE-2009-4307 +by performing a sanity check on s_log_groups_per_flex, since it can be +set to a bogus value by an attacker. + + sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex; + groups_per_flex = 1 << sbi->s_log_groups_per_flex; + + if (groups_per_flex < 2) { ... } + +This patch fixes two potential issues in the previous commit. + +1) The sanity check might only work on architectures like PowerPC. +On x86, 5 bits are used for the shifting amount. That means, given a +large s_log_groups_per_flex value like 36, groups_per_flex = 1 << 36 +is essentially 1 << 4 = 16, rather than 0. This will bypass the check, +leaving s_log_groups_per_flex and groups_per_flex inconsistent. + +2) The sanity check relies on undefined behavior, i.e., oversized shift. +A standard-confirming C compiler could rewrite the check in unexpected +ways. Consider the following equivalent form, assuming groups_per_flex +is unsigned for simplicity. + + groups_per_flex = 1 << sbi->s_log_groups_per_flex; + if (groups_per_flex == 0 || groups_per_flex == 1) { + +We compile the code snippet using Clang 3.0 and GCC 4.6. Clang will +completely optimize away the check groups_per_flex == 0, leaving the +patched code as vulnerable as the original. GCC keeps the check, but +there is no guarantee that future versions will do the same. + +Signed-off-by: Xi Wang <xi.wang@gmail.com> +Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index cd35e34..6928d5a 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -1796,17 +1796,16 @@ static int ext4_fill_flex_info(struct super_block *sb) + struct ext4_group_desc *gdp = NULL; + ext4_group_t flex_group_count; + ext4_group_t flex_group; +- int groups_per_flex = 0; ++ unsigned int groups_per_flex = 0; + size_t size; + int i; + + sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex; +- groups_per_flex = 1 << sbi->s_log_groups_per_flex; +- +- if (groups_per_flex < 2) { ++ if (sbi->s_log_groups_per_flex < 1 || sbi->s_log_groups_per_flex > 31) { + sbi->s_log_groups_per_flex = 0; + return 1; + } ++ groups_per_flex = 1 << sbi->s_log_groups_per_flex; + + /* We allocate both existing and potentially added groups */ + flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) + +-- +1.7.9.7 + diff --git a/queue/fcaps-clear-the-same-personality-flags-as-suid-when-.patch b/queue/fcaps-clear-the-same-personality-flags-as-suid-when-.patch new file mode 100644 index 0000000..491af03 --- /dev/null +++ b/queue/fcaps-clear-the-same-personality-flags-as-suid-when-.patch @@ -0,0 +1,38 @@ +From b46ee58f8454058175e73646f45b80cda6592db6 Mon Sep 17 00:00:00 2001 +From: Eric Paris <eparis@redhat.com> +Date: Tue, 17 Apr 2012 16:26:54 -0400 +Subject: [PATCH] fcaps: clear the same personality flags as suid when fcaps + are used + +commit d52fc5dde171f030170a6cb78034d166b13c9445 upstream. + +If a process increases permissions using fcaps all of the dangerous +personality flags which are cleared for suid apps should also be cleared. +Thus programs given priviledge with fcaps will continue to have address space +randomization enabled even if the parent tried to disable it to make it +easier to attack. + +Signed-off-by: Eric Paris <eparis@redhat.com> +Reviewed-by: Serge Hallyn <serge.hallyn@canonical.com> +Signed-off-by: James Morris <james.l.morris@oracle.com> +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/security/commoncap.c b/security/commoncap.c +index 6166973..a8fc6ec 100644 +--- a/security/commoncap.c ++++ b/security/commoncap.c +@@ -465,6 +465,11 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) + } + skip: + ++ /* if we have fs caps, clear dangerous personality flags */ ++ if (!cap_issubset(new->cap_permitted, old->cap_permitted)) ++ bprm->per_clear |= PER_CLEAR_ON_SETID; ++ ++ + /* Don't let someone trace a set[ug]id/setpcap binary with the revised + * credentials unless they have the appropriate permit + */ +-- +1.7.9.7 + diff --git a/queue/fs-assign-sb-s_bdi-to-default_backing_dev_info-if-th.patch b/queue/fs-assign-sb-s_bdi-to-default_backing_dev_info-if-th.patch new file mode 100644 index 0000000..e754e45 --- /dev/null +++ b/queue/fs-assign-sb-s_bdi-to-default_backing_dev_info-if-th.patch @@ -0,0 +1,76 @@ +From 058d0ff02b84ee4658e8ecfd98689c1f38b14f01 Mon Sep 17 00:00:00 2001 +From: Jens Axboe <jaxboe@fusionio.com> +Date: Thu, 17 Mar 2011 11:13:12 +0100 +Subject: [PATCH] fs: assign sb->s_bdi to default_backing_dev_info if the bdi + is going away + +commit 95f28604a65b1c40b6c6cd95e58439cd7ded3add upstream. + +We don't have proper reference counting for this yet, so we run into +cases where the device is pulled and we OOPS on flushing the fs data. +This happens even though the dirty inodes have already been +migrated to the default_backing_dev_info. + +Reported-by: Torsten Hilbrich <torsten.hilbrich@secunet.com> +Tested-by: Torsten Hilbrich <torsten.hilbrich@secunet.com> +Signed-off-by: Jens Axboe <jaxboe@fusionio.com> +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/fs/super.c b/fs/super.c +index 53040a6..7123fa7 100644 +--- a/fs/super.c ++++ b/fs/super.c +@@ -64,6 +64,7 @@ static struct super_block *alloc_super(struct file_system_type *type) + goto out; + } + INIT_LIST_HEAD(&s->s_files); ++ s->s_bdi = &default_backing_dev_info; + INIT_LIST_HEAD(&s->s_instances); + INIT_HLIST_HEAD(&s->s_anon); + INIT_LIST_HEAD(&s->s_inodes); +@@ -962,6 +963,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void + goto out_free_secdata; + BUG_ON(!mnt->mnt_sb); + WARN_ON(!mnt->mnt_sb->s_bdi); ++ WARN_ON(mnt->mnt_sb->s_bdi == &default_backing_dev_info); + mnt->mnt_sb->s_flags |= MS_BORN; + + error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata); +diff --git a/fs/sync.c b/fs/sync.c +index 92b2281..5281fb3 100644 +--- a/fs/sync.c ++++ b/fs/sync.c +@@ -33,7 +33,7 @@ static int __sync_filesystem(struct super_block *sb, int wait) + * This should be safe, as we require bdi backing to actually + * write out data in the first place + */ +- if (!sb->s_bdi || sb->s_bdi == &noop_backing_dev_info) ++ if (sb->s_bdi == &noop_backing_dev_info) + return 0; + + if (sb->s_qcop && sb->s_qcop->quota_sync) +@@ -110,7 +110,7 @@ restart: + spin_unlock(&sb_lock); + + down_read(&sb->s_umount); +- if (!(sb->s_flags & MS_RDONLY) && sb->s_root && sb->s_bdi) ++ if (!(sb->s_flags & MS_RDONLY) && sb->s_root) + __sync_filesystem(sb, wait); + up_read(&sb->s_umount); + +diff --git a/mm/backing-dev.c b/mm/backing-dev.c +index 707d0dc..7bd17d2 100644 +--- a/mm/backing-dev.c ++++ b/mm/backing-dev.c +@@ -634,7 +634,7 @@ static void bdi_prune_sb(struct backing_dev_info *bdi) + spin_lock(&sb_lock); + list_for_each_entry(sb, &super_blocks, s_list) { + if (sb->s_bdi == bdi) +- sb->s_bdi = NULL; ++ sb->s_bdi = &default_backing_dev_info; + } + spin_unlock(&sb_lock); + } +-- +1.7.9.7 + diff --git a/queue/hfsplus-Fix-potential-buffer-overflows.patch b/queue/hfsplus-Fix-potential-buffer-overflows.patch new file mode 100644 index 0000000..e1604aa --- /dev/null +++ b/queue/hfsplus-Fix-potential-buffer-overflows.patch @@ -0,0 +1,75 @@ +From 5678897baaf3e6a6445be3a06d6e783a0ec405a5 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Date: Fri, 4 May 2012 12:09:39 -0700 +Subject: [PATCH] hfsplus: Fix potential buffer overflows + +commit 6f24f892871acc47b40dd594c63606a17c714f77 upstream. + +Commit ec81aecb2966 ("hfs: fix a potential buffer overflow") fixed a few +potential buffer overflows in the hfs filesystem. But as Timo Warns +pointed out, these changes also need to be made on the hfsplus +filesystem as well. + +Reported-by: Timo Warns <warns@pre-sense.de> +Acked-by: WANG Cong <amwang@redhat.com> +Cc: Alexey Khoroshilov <khoroshilov@ispras.ru> +Cc: Miklos Szeredi <mszeredi@suse.cz> +Cc: Sage Weil <sage@newdream.net> +Cc: Eugene Teo <eteo@redhat.com> +Cc: Roman Zippel <zippel@linux-m68k.org> +Cc: Al Viro <viro@zeniv.linux.org.uk> +Cc: Christoph Hellwig <hch@lst.de> +Cc: Alexey Dobriyan <adobriyan@gmail.com> +Cc: Dave Anderson <anderson@redhat.com> +Cc: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c +index f6874ac..a0786c6 100644 +--- a/fs/hfsplus/catalog.c ++++ b/fs/hfsplus/catalog.c +@@ -329,6 +329,10 @@ int hfsplus_rename_cat(u32 cnid, + err = hfs_brec_find(&src_fd); + if (err) + goto out; ++ if (src_fd.entrylength > sizeof(entry) || src_fd.entrylength < 0) { ++ err = -EIO; ++ goto out; ++ } + + hfs_bnode_read(src_fd.bnode, &entry, src_fd.entryoffset, + src_fd.entrylength); +diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c +index 5f40236..f4300ff7 100644 +--- a/fs/hfsplus/dir.c ++++ b/fs/hfsplus/dir.c +@@ -138,6 +138,11 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) + filp->f_pos++; + /* fall through */ + case 1: ++ if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { ++ err = -EIO; ++ goto out; ++ } ++ + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); + if (be16_to_cpu(entry.type) != HFSPLUS_FOLDER_THREAD) { + printk(KERN_ERR "hfs: bad catalog folder thread\n"); +@@ -168,6 +173,12 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) + err = -EIO; + goto out; + } ++ ++ if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { ++ err = -EIO; ++ goto out; ++ } ++ + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); + type = be16_to_cpu(entry.type); + len = HFSPLUS_MAX_STRLEN; +-- +1.7.9.7 + diff --git a/queue/net_sched-Fix-qdisc_notify.patch b/queue/net_sched-Fix-qdisc_notify.patch new file mode 100644 index 0000000..d5ea5ec --- /dev/null +++ b/queue/net_sched-Fix-qdisc_notify.patch @@ -0,0 +1,68 @@ +From a6a0f87941e458ac0e9190643edc429ea76a9fd8 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet <eric.dumazet@gmail.com> +Date: Sat, 22 May 2010 20:37:44 +0000 +Subject: [PATCH] net_sched: Fix qdisc_notify() + +commit 53b0f08042f04813cd1a7473dacd3edfacb28eb3 upstream. + +Ben Pfaff reported a kernel oops and provided a test program to +reproduce it. + +https://kerneltrap.org/mailarchive/linux-netdev/2010/5/21/6277805 + +tc_fill_qdisc() should not be called for builtin qdisc, or it +dereference a NULL pointer to get device ifindex. + +Fix is to always use tc_qdisc_dump_ignore() before calling +tc_fill_qdisc(). + +Reported-by: Ben Pfaff <blp@nicira.com> +Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c +index 145268c..df1dbf5 100644 +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -1196,6 +1196,11 @@ nla_put_failure: + return -1; + } + ++static bool tc_qdisc_dump_ignore(struct Qdisc *q) ++{ ++ return (q->flags & TCQ_F_BUILTIN) ? true : false; ++} ++ + static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, + u32 clid, struct Qdisc *old, struct Qdisc *new) + { +@@ -1206,11 +1211,11 @@ static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, + if (!skb) + return -ENOBUFS; + +- if (old && old->handle) { ++ if (old && !tc_qdisc_dump_ignore(old)) { + if (tc_fill_qdisc(skb, old, clid, pid, n->nlmsg_seq, 0, RTM_DELQDISC) < 0) + goto err_out; + } +- if (new) { ++ if (new && !tc_qdisc_dump_ignore(new)) { + if (tc_fill_qdisc(skb, new, clid, pid, n->nlmsg_seq, old ? NLM_F_REPLACE : 0, RTM_NEWQDISC) < 0) + goto err_out; + } +@@ -1223,11 +1228,6 @@ err_out: + return -EINVAL; + } + +-static bool tc_qdisc_dump_ignore(struct Qdisc *q) +-{ +- return (q->flags & TCQ_F_BUILTIN) ? true : false; +-} +- + static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb, + struct netlink_callback *cb, + int *q_idx_p, int s_q_idx) +-- +1.7.9.7 + diff --git a/queue/nl80211-fix-overflow-in-ssid_len.patch b/queue/nl80211-fix-overflow-in-ssid_len.patch new file mode 100644 index 0000000..8182721 --- /dev/null +++ b/queue/nl80211-fix-overflow-in-ssid_len.patch @@ -0,0 +1,46 @@ +From b3e0ff0d75b8c488ae9421a054f3ec446c9542af Mon Sep 17 00:00:00 2001 +From: Luciano Coelho <coelho@ti.com> +Date: Tue, 7 Jun 2011 20:42:26 +0300 +Subject: [PATCH] nl80211: fix overflow in ssid_len + +commit 57a27e1d6a3bb9ad4efeebd3a8c71156d6207536 upstream. + +When one of the SSID's length passed in a scan or sched_scan request +is larger than 255, there will be an overflow in the u8 that is used +to store the length before checking. This causes the check to fail +and we overrun the buffer when copying the SSID. + +Fix this by checking the nl80211 attribute length before copying it to +the struct. + +This is a follow up for the previous commit +208c72f4fe44fe09577e7975ba0e7fa0278f3d03, which didn't fix the problem +entirely. + +Reported-by: Ido Yariv <ido@wizery.com> +Signed-off-by: Luciano Coelho <coelho@ti.com> +Signed-off-by: John W. Linville <linville@tuxdriver.com> +[PG: 34 codebase does not have nl80211_start_sched_scan part] +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 0ba104f..56bc9b9 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -3072,11 +3072,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) + i = 0; + if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { + nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) { +- request->ssids[i].ssid_len = nla_len(attr); +- if (request->ssids[i].ssid_len > IEEE80211_MAX_SSID_LEN) { ++ if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) { + err = -EINVAL; + goto out_free; + } ++ request->ssids[i].ssid_len = nla_len(attr); + memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr)); + i++; + } +-- +1.7.9.7 + diff --git a/queue/perf-overflow-perf_count_sw_cpu_clock-crashes-recent.patch b/queue/perf-overflow-perf_count_sw_cpu_clock-crashes-recent.patch new file mode 100644 index 0000000..76a3b49 --- /dev/null +++ b/queue/perf-overflow-perf_count_sw_cpu_clock-crashes-recent.patch @@ -0,0 +1,41 @@ +From ab1b939d1a26dfa292a2d3f3ac558835abd62b37 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra <a.p.zijlstra@chello.nl> +Date: Wed, 3 Aug 2011 13:49:31 +0200 +Subject: [PATCH] perf: overflow/perf_count_sw_cpu_clock crashes recent + kernels + +The below patch is for -stable only, upstream has a much larger patch +that contains the below hunk in commit a8b0ca17b80e92faab46ee7179ba9e99ccb61233 + +Vince found that under certain circumstances software event overflows +go wrong and deadlock. Avoid trying to delete a timer from the timer +callback. + +Reported-by: Vince Weaver <vweaver1@eecs.utk.edu> +Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +[PG: backport from 2.6.32 queue, see https://lkml.org/lkml/2011/8/3/125 ] +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/kernel/perf_event.c b/kernel/perf_event.c +index b203546..540c26b 100644 +--- a/kernel/perf_event.c ++++ b/kernel/perf_event.c +@@ -3907,12 +3907,8 @@ static int __perf_event_overflow(struct perf_event *event, int nmi, + if (events && atomic_dec_and_test(&event->event_limit)) { + ret = 1; + event->pending_kill = POLL_HUP; +- if (nmi) { +- event->pending_disable = 1; +- perf_pending_queue(&event->pending, +- perf_pending_event); +- } else +- perf_event_disable(event); ++ event->pending_disable = 1; ++ perf_pending_queue(&event->pending, perf_pending_event); + } + + if (event->overflow_handler) +-- +1.7.9.7 + diff --git a/queue/regset-Prevent-null-pointer-reference-on-readonly-re.patch b/queue/regset-Prevent-null-pointer-reference-on-readonly-re.patch new file mode 100644 index 0000000..9e3452c --- /dev/null +++ b/queue/regset-Prevent-null-pointer-reference-on-readonly-re.patch @@ -0,0 +1,60 @@ +From a9e9465b093e12c33a13f04ce205cc90c4bb4a78 Mon Sep 17 00:00:00 2001 +From: "H. Peter Anvin" <hpa@zytor.com> +Date: Fri, 2 Mar 2012 10:43:48 -0800 +Subject: [PATCH] regset: Prevent null pointer reference on readonly regsets + +commit c8e252586f8d5de906385d8cf6385fee289a825e upstream. + +The regset common infrastructure assumed that regsets would always +have .get and .set methods, but not necessarily .active methods. +Unfortunately people have since written regsets without .set methods. + +Rather than putting in stub functions everywhere, handle regsets with +null .get or .set methods explicitly. + +Signed-off-by: H. Peter Anvin <hpa@zytor.com> +Reviewed-by: Oleg Nesterov <oleg@redhat.com> +Acked-by: Roland McGrath <roland@hack.frob.com> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c +index 535e763..c21da8a 100644 +--- a/fs/binfmt_elf.c ++++ b/fs/binfmt_elf.c +@@ -1414,7 +1414,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, + for (i = 1; i < view->n; ++i) { + const struct user_regset *regset = &view->regsets[i]; + do_thread_regset_writeback(t->task, regset); +- if (regset->core_note_type && ++ if (regset->core_note_type && regset->get && + (!regset->active || regset->active(t->task, regset))) { + int ret; + size_t size = regset->n * regset->size; +diff --git a/include/linux/regset.h b/include/linux/regset.h +index 8abee65..5150fd1 100644 +--- a/include/linux/regset.h ++++ b/include/linux/regset.h +@@ -335,6 +335,9 @@ static inline int copy_regset_to_user(struct task_struct *target, + { + const struct user_regset *regset = &view->regsets[setno]; + ++ if (!regset->get) ++ return -EOPNOTSUPP; ++ + if (!access_ok(VERIFY_WRITE, data, size)) + return -EIO; + +@@ -358,6 +361,9 @@ static inline int copy_regset_from_user(struct task_struct *target, + { + const struct user_regset *regset = &view->regsets[setno]; + ++ if (!regset->set) ++ return -EOPNOTSUPP; ++ + if (!access_ok(VERIFY_READ, data, size)) + return -EIO; + +-- +1.7.9.7 + diff --git a/queue/rose-Add-length-checks-to-CALL_REQUEST-parsing.patch b/queue/rose-Add-length-checks-to-CALL_REQUEST-parsing.patch new file mode 100644 index 0000000..7d912b4 --- /dev/null +++ b/queue/rose-Add-length-checks-to-CALL_REQUEST-parsing.patch @@ -0,0 +1,338 @@ +From 6eb34300ab20c8ff5a6ba557a3fb86165e01cac3 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sun, 20 Mar 2011 06:48:05 +0000 +Subject: [PATCH] rose: Add length checks to CALL_REQUEST parsing + +commit e0bccd315db0c2f919e7fcf9cb60db21d9986f52 upstream. + +Define some constant offsets for CALL_REQUEST based on the description +at <http://www.techfest.com/networking/wan/x25plp.htm> and the +definition of ROSE as using 10-digit (5-byte) addresses. Use them +consistently. Validate all implicit and explicit facilities lengths. +Validate the address length byte rather than either trusting or +assuming its value. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/include/net/rose.h b/include/net/rose.h +index 5ba9f02..555dd19 100644 +--- a/include/net/rose.h ++++ b/include/net/rose.h +@@ -14,6 +14,12 @@ + + #define ROSE_MIN_LEN 3 + ++#define ROSE_CALL_REQ_ADDR_LEN_OFF 3 ++#define ROSE_CALL_REQ_ADDR_LEN_VAL 0xAA /* each address is 10 digits */ ++#define ROSE_CALL_REQ_DEST_ADDR_OFF 4 ++#define ROSE_CALL_REQ_SRC_ADDR_OFF 9 ++#define ROSE_CALL_REQ_FACILITIES_OFF 14 ++ + #define ROSE_GFI 0x10 + #define ROSE_Q_BIT 0x80 + #define ROSE_D_BIT 0x40 +@@ -214,7 +220,7 @@ extern void rose_requeue_frames(struct sock *); + extern int rose_validate_nr(struct sock *, unsigned short); + extern void rose_write_internal(struct sock *, int); + extern int rose_decode(struct sk_buff *, int *, int *, int *, int *, int *); +-extern int rose_parse_facilities(unsigned char *, struct rose_facilities_struct *); ++extern int rose_parse_facilities(unsigned char *, unsigned int, struct rose_facilities_struct *); + extern void rose_disconnect(struct sock *, int, int, int); + + /* rose_timer.c */ +diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c +index d325c9d..547e5cd 100644 +--- a/net/rose/af_rose.c ++++ b/net/rose/af_rose.c +@@ -985,7 +985,7 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros + struct sock *make; + struct rose_sock *make_rose; + struct rose_facilities_struct facilities; +- int n, len; ++ int n; + + skb->sk = NULL; /* Initially we don't know who it's for */ + +@@ -994,9 +994,9 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros + */ + memset(&facilities, 0x00, sizeof(struct rose_facilities_struct)); + +- len = (((skb->data[3] >> 4) & 0x0F) + 1) >> 1; +- len += (((skb->data[3] >> 0) & 0x0F) + 1) >> 1; +- if (!rose_parse_facilities(skb->data + len + 4, &facilities)) { ++ if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF, ++ skb->len - ROSE_CALL_REQ_FACILITIES_OFF, ++ &facilities)) { + rose_transmit_clear_request(neigh, lci, ROSE_INVALID_FACILITY, 76); + return 0; + } +diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c +index ae4a9d9..3444562 100644 +--- a/net/rose/rose_loopback.c ++++ b/net/rose/rose_loopback.c +@@ -73,9 +73,20 @@ static void rose_loopback_timer(unsigned long param) + unsigned int lci_i, lci_o; + + while ((skb = skb_dequeue(&loopback_queue)) != NULL) { ++ if (skb->len < ROSE_MIN_LEN) { ++ kfree_skb(skb); ++ continue; ++ } + lci_i = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF); + frametype = skb->data[2]; +- dest = (rose_address *)(skb->data + 4); ++ if (frametype == ROSE_CALL_REQUEST && ++ (skb->len <= ROSE_CALL_REQ_FACILITIES_OFF || ++ skb->data[ROSE_CALL_REQ_ADDR_LEN_OFF] != ++ ROSE_CALL_REQ_ADDR_LEN_VAL)) { ++ kfree_skb(skb); ++ continue; ++ } ++ dest = (rose_address *)(skb->data + ROSE_CALL_REQ_DEST_ADDR_OFF); + lci_o = ROSE_DEFAULT_MAXVC + 1 - lci_i; + + skb_reset_transport_header(skb); +diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c +index cbc244a..ae3f06d 100644 +--- a/net/rose/rose_route.c ++++ b/net/rose/rose_route.c +@@ -855,7 +855,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) + unsigned int lci, new_lci; + unsigned char cause, diagnostic; + struct net_device *dev; +- int len, res = 0; ++ int res = 0; + char buf[11]; + + #if 0 +@@ -863,10 +863,17 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) + return res; + #endif + ++ if (skb->len < ROSE_MIN_LEN) ++ return res; + frametype = skb->data[2]; + lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF); +- src_addr = (rose_address *)(skb->data + 9); +- dest_addr = (rose_address *)(skb->data + 4); ++ if (frametype == ROSE_CALL_REQUEST && ++ (skb->len <= ROSE_CALL_REQ_FACILITIES_OFF || ++ skb->data[ROSE_CALL_REQ_ADDR_LEN_OFF] != ++ ROSE_CALL_REQ_ADDR_LEN_VAL)) ++ return res; ++ src_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_SRC_ADDR_OFF); ++ dest_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_DEST_ADDR_OFF); + + spin_lock_bh(&rose_neigh_list_lock); + spin_lock_bh(&rose_route_list_lock); +@@ -1004,12 +1011,11 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) + goto out; + } + +- len = (((skb->data[3] >> 4) & 0x0F) + 1) >> 1; +- len += (((skb->data[3] >> 0) & 0x0F) + 1) >> 1; +- + memset(&facilities, 0x00, sizeof(struct rose_facilities_struct)); + +- if (!rose_parse_facilities(skb->data + len + 4, &facilities)) { ++ if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF, ++ skb->len - ROSE_CALL_REQ_FACILITIES_OFF, ++ &facilities)) { + rose_transmit_clear_request(rose_neigh, lci, ROSE_INVALID_FACILITY, 76); + goto out; + } +diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c +index 174d51c..f6c71ca 100644 +--- a/net/rose/rose_subr.c ++++ b/net/rose/rose_subr.c +@@ -142,7 +142,7 @@ void rose_write_internal(struct sock *sk, int frametype) + *dptr++ = ROSE_GFI | lci1; + *dptr++ = lci2; + *dptr++ = frametype; +- *dptr++ = 0xAA; ++ *dptr++ = ROSE_CALL_REQ_ADDR_LEN_VAL; + memcpy(dptr, &rose->dest_addr, ROSE_ADDR_LEN); + dptr += ROSE_ADDR_LEN; + memcpy(dptr, &rose->source_addr, ROSE_ADDR_LEN); +@@ -246,12 +246,16 @@ static int rose_parse_national(unsigned char *p, struct rose_facilities_struct * + do { + switch (*p & 0xC0) { + case 0x00: ++ if (len < 2) ++ return -1; + p += 2; + n += 2; + len -= 2; + break; + + case 0x40: ++ if (len < 3) ++ return -1; + if (*p == FAC_NATIONAL_RAND) + facilities->rand = ((p[1] << 8) & 0xFF00) + ((p[2] << 0) & 0x00FF); + p += 3; +@@ -260,32 +264,48 @@ static int rose_parse_national(unsigned char *p, struct rose_facilities_struct * + break; + + case 0x80: ++ if (len < 4) ++ return -1; + p += 4; + n += 4; + len -= 4; + break; + + case 0xC0: ++ if (len < 2) ++ return -1; + l = p[1]; ++ if (len < 2 + l) ++ return -1; + if (*p == FAC_NATIONAL_DEST_DIGI) { + if (!fac_national_digis_received) { ++ if (l < AX25_ADDR_LEN) ++ return -1; + memcpy(&facilities->source_digis[0], p + 2, AX25_ADDR_LEN); + facilities->source_ndigis = 1; + } + } + else if (*p == FAC_NATIONAL_SRC_DIGI) { + if (!fac_national_digis_received) { ++ if (l < AX25_ADDR_LEN) ++ return -1; + memcpy(&facilities->dest_digis[0], p + 2, AX25_ADDR_LEN); + facilities->dest_ndigis = 1; + } + } + else if (*p == FAC_NATIONAL_FAIL_CALL) { ++ if (l < AX25_ADDR_LEN) ++ return -1; + memcpy(&facilities->fail_call, p + 2, AX25_ADDR_LEN); + } + else if (*p == FAC_NATIONAL_FAIL_ADD) { ++ if (l < 1 + ROSE_ADDR_LEN) ++ return -1; + memcpy(&facilities->fail_addr, p + 3, ROSE_ADDR_LEN); + } + else if (*p == FAC_NATIONAL_DIGIS) { ++ if (l % AX25_ADDR_LEN) ++ return -1; + fac_national_digis_received = 1; + facilities->source_ndigis = 0; + facilities->dest_ndigis = 0; +@@ -319,24 +339,32 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac + do { + switch (*p & 0xC0) { + case 0x00: ++ if (len < 2) ++ return -1; + p += 2; + n += 2; + len -= 2; + break; + + case 0x40: ++ if (len < 3) ++ return -1; + p += 3; + n += 3; + len -= 3; + break; + + case 0x80: ++ if (len < 4) ++ return -1; + p += 4; + n += 4; + len -= 4; + break; + + case 0xC0: ++ if (len < 2) ++ return -1; + l = p[1]; + + /* Prevent overflows*/ +@@ -365,49 +393,44 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac + return n; + } + +-int rose_parse_facilities(unsigned char *p, ++int rose_parse_facilities(unsigned char *p, unsigned packet_len, + struct rose_facilities_struct *facilities) + { + int facilities_len, len; + + facilities_len = *p++; + +- if (facilities_len == 0) ++ if (facilities_len == 0 || (unsigned)facilities_len > packet_len) + return 0; + +- while (facilities_len > 0) { +- if (*p == 0x00) { +- facilities_len--; +- p++; +- +- switch (*p) { +- case FAC_NATIONAL: /* National */ +- len = rose_parse_national(p + 1, facilities, facilities_len - 1); +- if (len < 0) +- return 0; +- facilities_len -= len + 1; +- p += len + 1; +- break; +- +- case FAC_CCITT: /* CCITT */ +- len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1); +- if (len < 0) +- return 0; +- facilities_len -= len + 1; +- p += len + 1; +- break; +- +- default: +- printk(KERN_DEBUG "ROSE: rose_parse_facilities - unknown facilities family %02X\n", *p); +- facilities_len--; +- p++; +- break; +- } +- } else +- break; /* Error in facilities format */ ++ while (facilities_len >= 3 && *p == 0x00) { ++ facilities_len--; ++ p++; ++ ++ switch (*p) { ++ case FAC_NATIONAL: /* National */ ++ len = rose_parse_national(p + 1, facilities, facilities_len - 1); ++ break; ++ ++ case FAC_CCITT: /* CCITT */ ++ len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1); ++ break; ++ ++ default: ++ printk(KERN_DEBUG "ROSE: rose_parse_facilities - unknown facilities family %02X\n", *p); ++ len = 1; ++ break; ++ } ++ ++ if (len < 0) ++ return 0; ++ if (WARN_ON(len >= facilities_len)) ++ return 0; ++ facilities_len -= len + 1; ++ p += len + 1; + } + +- return 1; ++ return facilities_len == 0; + } + + static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose) +-- +1.7.9.7 + diff --git a/queue/security-rcu-convert-call_rcu-user_update_rcu_dispos.patch b/queue/security-rcu-convert-call_rcu-user_update_rcu_dispos.patch new file mode 100644 index 0000000..1f99fe1 --- /dev/null +++ b/queue/security-rcu-convert-call_rcu-user_update_rcu_dispos.patch @@ -0,0 +1,64 @@ +From 5d49b69da20ce0bbf060e091fdbfb06972761a0f Mon Sep 17 00:00:00 2001 +From: Lai Jiangshan <laijs@cn.fujitsu.com> +Date: Fri, 18 Mar 2011 12:11:07 +0800 +Subject: [PATCH] security,rcu: convert call_rcu(user_update_rcu_disposal) to + kfree_rcu() + +commit 3acb458c32293405cf68985b7b3ac5dc0a5e7929 upstream. + +The rcu callback user_update_rcu_disposal() just calls a kfree(), +so we use kfree_rcu() instead of the call_rcu(user_update_rcu_disposal). + +Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> +Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> +Acked-by: David Howells <dhowells@redhat.com> +Reviewed-by: Josh Triplett <josh@joshtriplett.org> +[PG: diffstat slightly different due to comment format differences] +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c +index e9aa079..e4f04d1 100644 +--- a/security/keys/user_defined.c ++++ b/security/keys/user_defined.c +@@ -72,20 +72,6 @@ EXPORT_SYMBOL_GPL(user_instantiate); + + /*****************************************************************************/ + /* +- * dispose of the old data from an updated user defined key +- */ +-static void user_update_rcu_disposal(struct rcu_head *rcu) +-{ +- struct user_key_payload *upayload; +- +- upayload = container_of(rcu, struct user_key_payload, rcu); +- +- kfree(upayload); +- +-} /* end user_update_rcu_disposal() */ +- +-/*****************************************************************************/ +-/* + * update a user defined key + * - the key's semaphore is write-locked + */ +@@ -119,7 +105,7 @@ int user_update(struct key *key, const void *data, size_t datalen) + key->expiry = 0; + } + +- call_rcu(&zap->rcu, user_update_rcu_disposal); ++ kfree_rcu(zap, rcu); + + error: + return ret; +@@ -154,7 +140,7 @@ void user_revoke(struct key *key) + + if (upayload) { + rcu_assign_pointer(key->payload.data, NULL); +- call_rcu(&upayload->rcu, user_update_rcu_disposal); ++ kfree_rcu(upayload, rcu); + } + + } /* end user_revoke() */ +-- +1.7.9.7 + diff --git a/queue/series b/queue/series index e69de29..6c0d14c 100644 --- a/queue/series +++ b/queue/series @@ -0,0 +1,19 @@ +net_sched-Fix-qdisc_notify.patch +nl80211-fix-overflow-in-ssid_len.patch +fs-assign-sb-s_bdi-to-default_backing_dev_info-if-th.patch +vm-fix-vm_pgoff-wrap-in-stack-expansion.patch +rose-Add-length-checks-to-CALL_REQUEST-parsing.patch +drm-integer-overflow-in-drm_mode_dirtyfb_ioctl.patch +fcaps-clear-the-same-personality-flags-as-suid-when-.patch +perf-overflow-perf_count_sw_cpu_clock-crashes-recent.patch +regset-Prevent-null-pointer-reference-on-readonly-re.patch +ext4-fix-undefined-behavior-in-ext4_fill_flex_info.patch +cifs-fix-possible-memory-corruption-in-CIFSFindNext.patch +cifs-fix-dentry-refcount-leak-when-opening-a-FIFO-on.patch +hfsplus-Fix-potential-buffer-overflows.patch +xfs-Fix-possible-memory-corruption-in-xfs_readlink.patch +KVM-Remove-ability-to-assign-a-device-without-iommu-.patch +KVM-Device-assignment-permission-checks.patch +KVM-Ensure-all-vcpus-are-consistent-with-in-kernel-i.patch +security-rcu-convert-call_rcu-user_update_rcu_dispos.patch +KEYS-Fix-a-NULL-pointer-deref-in-the-user-defined-ke.patch diff --git a/queue/vm-fix-vm_pgoff-wrap-in-stack-expansion.patch b/queue/vm-fix-vm_pgoff-wrap-in-stack-expansion.patch new file mode 100644 index 0000000..1847a56 --- /dev/null +++ b/queue/vm-fix-vm_pgoff-wrap-in-stack-expansion.patch @@ -0,0 +1,50 @@ +From 53b47c4d3023d3f15fc1d4cf828d54a2251eb920 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds <torvalds@linux-foundation.org> +Date: Wed, 13 Apr 2011 08:07:28 -0700 +Subject: [PATCH] vm: fix vm_pgoff wrap in stack expansion +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit a626ca6a656450e9f4df91d0dda238fff23285f4 upstream. + +Commit 982134ba6261 ("mm: avoid wrapping vm_pgoff in mremap()") fixed +the case of a expanding mapping causing vm_pgoff wrapping when you used +mremap. But there was another case where we expand mappings hiding in +plain sight: the automatic stack expansion. + +This fixes that case too. + +This one also found by Robert Święcki, using his nasty system call +fuzzer tool. Good job. + +Reported-and-tested-by: Robert Święcki <robert@swiecki.net> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +[PG: .34 doesn't have perf call via 3af9e859 (in .36); adjust accordingly] +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/mm/mmap.c b/mm/mmap.c +index b42b469..fe9b76a 100644 +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -1784,10 +1784,13 @@ static int expand_downwards(struct vm_area_struct *vma, + size = vma->vm_end - address; + grow = (vma->vm_start - address) >> PAGE_SHIFT; + +- error = acct_stack_growth(vma, size, grow); +- if (!error) { +- vma->vm_start = address; +- vma->vm_pgoff -= grow; ++ error = -ENOMEM; ++ if (grow <= vma->vm_pgoff) { ++ error = acct_stack_growth(vma, size, grow); ++ if (!error) { ++ vma->vm_start = address; ++ vma->vm_pgoff -= grow; ++ } + } + } + anon_vma_unlock(vma); +-- +1.7.9.7 + diff --git a/queue/xfs-Fix-possible-memory-corruption-in-xfs_readlink.patch b/queue/xfs-Fix-possible-memory-corruption-in-xfs_readlink.patch new file mode 100644 index 0000000..4c491aa --- /dev/null +++ b/queue/xfs-Fix-possible-memory-corruption-in-xfs_readlink.patch @@ -0,0 +1,68 @@ +From 64a251ab341c86e6715912e1b01a89627ae56148 Mon Sep 17 00:00:00 2001 +From: Carlos Maiolino <cmaiolino@redhat.com> +Date: Mon, 7 Nov 2011 16:10:24 +0000 +Subject: [PATCH] xfs: Fix possible memory corruption in xfs_readlink + +commit b52a360b2aa1c59ba9970fb0f52bbb093fcc7a24 upstream. + +Fixes a possible memory corruption when the link is larger than +MAXPATHLEN and XFS_DEBUG is not enabled. This also remove the +S_ISLNK assert, since the inode mode is checked previously in +xfs_readlink_by_handle() and via VFS. + +Updated to address concerns raised by Ben Hutchings about the loose +attention paid to 32- vs 64-bit values, and the lack of handling a +potentially negative pathlen value: + - Changed type of "pathlen" to be xfs_fsize_t, to match that of + ip->i_d.di_size + - Added checking for a negative pathlen to the too-long pathlen + test, and generalized the message that gets reported in that case + to reflect the change +As a result, if a negative pathlen were encountered, this function +would return EFSCORRUPTED (and would fail an assertion for a debug +build)--just as would a too-long pathlen. + +Signed-off-by: Alex Elder <aelder@sgi.com> +Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> +Reviewed-by: Christoph Hellwig <hch@lst.de> +Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> + +diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c +index 4498f07..3ae59ee 100644 +--- a/fs/xfs/xfs_vnodeops.c ++++ b/fs/xfs/xfs_vnodeops.c +@@ -554,7 +554,7 @@ xfs_readlink( + char *link) + { + xfs_mount_t *mp = ip->i_mount; +- int pathlen; ++ xfs_fsize_t pathlen; + int error = 0; + + xfs_itrace_entry(ip); +@@ -564,13 +564,19 @@ xfs_readlink( + + xfs_ilock(ip, XFS_ILOCK_SHARED); + +- ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFLNK); +- ASSERT(ip->i_d.di_size <= MAXPATHLEN); +- + pathlen = ip->i_d.di_size; + if (!pathlen) + goto out; + ++ if (pathlen < 0 || pathlen > MAXPATHLEN) { ++ xfs_alert(mp, "%s: inode (%llu) bad symlink length (%lld)", ++ __func__, (unsigned long long) ip->i_ino, ++ (long long) pathlen); ++ ASSERT(0); ++ return XFS_ERROR(EFSCORRUPTED); ++ } ++ ++ + if (ip->i_df.if_flags & XFS_IFINLINE) { + memcpy(link, ip->i_df.if_u1.if_data, pathlen); + link[pathlen] = '\0'; +-- +1.7.9.7 + |