Update to Linux 3.1.10

This commit is contained in:
Josh Boyer 2012-01-18 11:45:38 -05:00
parent 4a39227a15
commit e9822a3383
7 changed files with 5 additions and 659 deletions

View File

@ -1,206 +0,0 @@
From 423873736b78f549fbfa2f715f2e4de7e6c5e1e9 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 1/2] KVM: Remove ability to assign a device without iommu
support
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>
---
virt/kvm/assigned-dev.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c
index 3ad0925..a251a28 100644
--- a/virt/kvm/assigned-dev.c
+++ b/virt/kvm/assigned-dev.c
@@ -487,6 +487,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);
@@ -544,16 +547,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);
@@ -593,8 +594,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.7.5
From 3d27e23b17010c668db311140b17bbbb70c78fb9 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 2/2] KVM: Device assignment permission checks
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>
---
virt/kvm/assigned-dev.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 75 insertions(+), 0 deletions(-)
diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c
index a251a28..758e3b3 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,
@@ -480,12 +482,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;
@@ -516,6 +579,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.7.5

View File

@ -1,69 +0,0 @@
From 0924ab2cfa98b1ece26c033d696651fd62896c69 Mon Sep 17 00:00:00 2001
From: Jan Kiszka <jan.kiszka@siemens.com>
Date: Wed, 14 Dec 2011 19:25:13 +0100
Subject: [PATCH] KVM: x86: Prevent starting PIT timers in the absence of
irqchip support
User space may create the PIT and forgets about setting up the irqchips.
In that case, firing PIT IRQs will crash the host:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000128
IP: [<ffffffffa10f6280>] kvm_set_irq+0x30/0x170 [kvm]
...
Call Trace:
[<ffffffffa11228c1>] pit_do_work+0x51/0xd0 [kvm]
[<ffffffff81071431>] process_one_work+0x111/0x4d0
[<ffffffff81071bb2>] worker_thread+0x152/0x340
[<ffffffff81075c8e>] kthread+0x7e/0x90
[<ffffffff815a4474>] kernel_thread_helper+0x4/0x10
Prevent this by checking the irqchip mode before starting a timer. We
can't deny creating the PIT if the irqchips aren't set up yet as
current user land expects this order to work.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
arch/x86/kvm/i8254.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 76e3f1c..405f262 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -338,11 +338,15 @@ static enum hrtimer_restart pit_timer_fn(struct hrtimer *data)
return HRTIMER_NORESTART;
}
-static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period)
+static void create_pit_timer(struct kvm *kvm, u32 val, int is_period)
{
+ struct kvm_kpit_state *ps = &kvm->arch.vpit->pit_state;
struct kvm_timer *pt = &ps->pit_timer;
s64 interval;
+ if (!irqchip_in_kernel(kvm))
+ return;
+
interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ);
pr_debug("create pit timer, interval is %llu nsec\n", interval);
@@ -394,13 +398,13 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val)
/* FIXME: enhance mode 4 precision */
case 4:
if (!(ps->flags & KVM_PIT_FLAGS_HPET_LEGACY)) {
- create_pit_timer(ps, val, 0);
+ create_pit_timer(kvm, val, 0);
}
break;
case 2:
case 3:
if (!(ps->flags & KVM_PIT_FLAGS_HPET_LEGACY)){
- create_pit_timer(ps, val, 1);
+ create_pit_timer(kvm, val, 1);
}
break;
default:
--
1.7.6.2

View File

@ -1,205 +0,0 @@
x86, amd: factor out MMCONFIG discovery
This factors out the AMD native MMCONFIG discovery so we can use it
outside amd_bus.c.
amd_bus.c reads AMD MSRs so it can remove the MMCONFIG area from the
PCI resources. We may also need the MMCONFIG information to work
around BIOS defects in the ACPI MCFG table.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
--- a/arch/x86/include/asm/amd_nb.h
+++ a/arch/x86/include/asm/amd_nb.h
@@ -13,6 +13,7 @@ extern const struct pci_device_id amd_nb_misc_ids[];
extern const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[];
extern bool early_is_amd_nb(u32 value);
+extern void amd_get_mmconfig_range(u64 *start, u64 *end);
extern int amd_cache_northbridges(void);
extern void amd_flush_garts(void);
extern int amd_numa_init(void);
--- a/arch/x86/kernel/amd_nb.c
+++ a/arch/x86/kernel/amd_nb.c
@@ -119,6 +119,38 @@ bool __init early_is_amd_nb(u32 device)
return false;
}
+void amd_get_mmconfig_range(u64 *start, u64 *end)
+{
+ u32 address;
+ u64 base, msr;
+ unsigned segn_busn_bits;
+
+ *start = 0;
+ *end = 0;
+
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+ return;
+
+ /* assume all cpus from fam10h have mmconfig */
+ if (boot_cpu_data.x86 < 0x10)
+ return;
+
+ address = MSR_FAM10H_MMIO_CONF_BASE;
+ rdmsrl(address, msr);
+
+ /* mmconfig is not enabled */
+ if (!(msr & FAM10H_MMIO_CONF_ENABLE))
+ return;
+
+ base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
+
+ segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
+ FAM10H_MMIO_CONF_BUSRANGE_MASK;
+
+ *start = base;
+ *end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
+}
+
int amd_get_subcaches(int cpu)
{
struct pci_dev *link = node_to_amd_nb(amd_get_nb_id(cpu))->link;
--- a/arch/x86/pci/amd_bus.c
+++ a/arch/x86/pci/amd_bus.c
@@ -30,34 +30,6 @@ static struct pci_hostbridge_probe pci_probes[] __initdata = {
{ 0, 0x18, PCI_VENDOR_ID_AMD, 0x1300 },
};
-static u64 __initdata fam10h_mmconf_start;
-static u64 __initdata fam10h_mmconf_end;
-static void __init get_pci_mmcfg_amd_fam10h_range(void)
-{
- u32 address;
- u64 base, msr;
- unsigned segn_busn_bits;
-
- /* assume all cpus from fam10h have mmconf */
- if (boot_cpu_data.x86 < 0x10)
- return;
-
- address = MSR_FAM10H_MMIO_CONF_BASE;
- rdmsrl(address, msr);
-
- /* mmconfig is not enable */
- if (!(msr & FAM10H_MMIO_CONF_ENABLE))
- return;
-
- base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
-
- segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
- FAM10H_MMIO_CONF_BUSRANGE_MASK;
-
- fam10h_mmconf_start = base;
- fam10h_mmconf_end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
-}
-
#define RANGE_NUM 16
/**
@@ -85,6 +57,8 @@ static int __init early_fill_mp_bus_info(void)
u64 val;
u32 address;
bool found;
+ u64 fam10h_mmconf_start;
+ u64 fam10h_mmconf_end;
if (!early_pci_allowed())
return -1;
@@ -211,7 +185,7 @@ static int __init early_fill_mp_bus_info(void)
subtract_range(range, RANGE_NUM, 0, end);
/* get mmconfig */
- get_pci_mmcfg_amd_fam10h_range();
+ amd_get_mmconfig_range(&fam10h_mmconf_start, &fam10h_mmconf_end);
/* need to take out mmconf range */
if (fam10h_mmconf_end) {
printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n", fam10h_mmconf_start, fam10h_mmconf_end);
PNP: work around Dell 1536/1546 BIOS MMCONFIG bug that breaks USB
Some Dell BIOSes have MCFG tables that don't report the entire
MMCONFIG area claimed by the chipset. If we move PCI devices into
that claimed-but-unreported area, they don't work.
This quirk reads the AMD MMCONFIG MSRs and adds PNP0C01 resources as
needed to cover the entire area.
Example problem scenario:
BIOS-e820: 00000000cfec5400 - 00000000d4000000 (reserved)
Fam 10h mmconf [d0000000, dfffffff]
PCI: MMCONFIG for domain 0000 [bus 00-3f] at [mem 0xd0000000-0xd3ffffff] (base 0xd0000000)
pnp 00:0c: [mem 0xd0000000-0xd3ffffff]
pci 0000:00:12.0: reg 10: [mem 0xffb00000-0xffb00fff]
pci 0000:00:12.0: no compatible bridge window for [mem 0xffb00000-0xffb00fff]
pci 0000:00:12.0: BAR 0: assigned [mem 0xd4000000-0xd40000ff]
Reported-by: Lisa Salimbas <lisa.salimbas@canonical.com>
Reported-by: <thuban@singularity.fr>
References: https://bugzilla.kernel.org/show_bug.cgi?id=31602
References: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/647043
References: https://bugzilla.redhat.com/show_bug.cgi?id=770308
Cc: stable@kernel.org # 2.6.34+
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
--- a/drivers/pnp/quirks.c
+++ a/drivers/pnp/quirks.c
@@ -295,6 +295,46 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
}
}
+#ifdef CONFIG_AMD_NB
+
+#include <asm/amd_nb.h>
+
+static void quirk_amd_mmconfig_area(struct pnp_dev *dev)
+{
+ u64 mmconfig_start, mmconfig_end;
+ resource_size_t start, end;
+ struct pnp_resource *pnp_res;
+ struct resource *res;
+
+ amd_get_mmconfig_range(&mmconfig_start, &mmconfig_end);
+ if (!mmconfig_end)
+ return;
+
+ list_for_each_entry(pnp_res, &dev->resources, list) {
+ res = &pnp_res->res;
+ if (res->end < mmconfig_start || res->start > mmconfig_end ||
+ (res->start == mmconfig_start && res->end == mmconfig_end))
+ continue;
+
+ dev_warn(&dev->dev, FW_BUG
+ "%pR covers only part of AMD MMCONFIG area [mem %#010llx-%#010llx]; adding more reservations\n",
+ res, (unsigned long long) mmconfig_start,
+ (unsigned long long) mmconfig_end);
+ if (mmconfig_start < res->start) {
+ start = mmconfig_start;
+ end = res->start - 1;
+ pnp_add_mem_resource(dev, start, end, 0);
+ }
+ if (mmconfig_end > res->end) {
+ start = res->end + 1;
+ end = mmconfig_end;
+ pnp_add_mem_resource(dev, start, end, 0);
+ }
+ break;
+ }
+}
+#endif
+
/*
* PnP Quirks
* Cards or devices that need some tweaking due to incomplete resource info
@@ -322,6 +362,9 @@ static struct pnp_fixup pnp_fixups[] = {
/* PnP resources that might overlap PCI BARs */
{"PNP0c01", quirk_system_pci_resources},
{"PNP0c02", quirk_system_pci_resources},
+#ifdef CONFIG_AMD_NB
+ {"PNP0c01", quirk_amd_mmconfig_area},
+#endif
{""}
};

View File

@ -1,31 +0,0 @@
From d4afc7754a60b885b63ef23fd194984e2d53a4e6 Mon Sep 17 00:00:00 2001
From: Rene Bollford <xsecute@googlemail.com>
Date: Sun, 23 Oct 2011 09:56:42 +0200
Subject: [PATCH] [PATCH] ideapad: Check if acpi already handle backlight
power to avoid a page fault
This patch avoid a page fault in the ideapad-laptop extras when
turning the backlight power on or off.
Signed-off-by: Rene Bolldorf <xsecute@googlemail.com>
Signed-off-by: Matthew Garrett <mjg@redhat.com>
---
drivers/platform/x86/ideapad-laptop.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 0c59541..0d94eec 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -493,6 +493,8 @@ static void ideapad_backlight_notify_power(struct ideapad_private *priv)
unsigned long power;
struct backlight_device *blightdev = priv->blightdev;
+ if (!blightdev)
+ return;
if (read_ec_data(ideapad_handle, 0x18, &power))
return;
blightdev->props.power = power ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
--
1.7.6.4

View File

@ -54,7 +54,7 @@ Summary: The Linux kernel
# For non-released -rc kernels, this will be appended after the rcX and
# gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
#
%global baserelease 4
%global baserelease 1
%global fedora_build %{baserelease}
# base_sublevel is the kernel version we're starting with and patching
@ -66,7 +66,7 @@ Summary: The Linux kernel
%if 0%{?released_kernel}
# Do we have a -stable update to apply?
%define stable_update 9
%define stable_update 10
# Is it a -stable RC?
%define stable_rc 0
# Set rpm version accordingly
@ -764,9 +764,6 @@ Patch3500: jbd-jbd2-validate-sb-s_first-in-journal_get_superblo.patch
# NFSv4
#rhbz 753236
Patch4000: nfsv4-include-bitmap-in-nfsv4_get_acl_data.patch
# patches headed upstream
Patch12010: add-appleir-usb-driver.patch
@ -806,9 +803,6 @@ Patch21040: x86-code-dump-fix-truncation.patch
#rhbz 728607
Patch21060: elantech.patch
#rhbz 748210
Patch21061: ideapad-Check-if-acpi-already-handle-backlight.patch
#rhbz752176
Patch21080: sysfs-msi-irq-per-device.patch
@ -826,7 +820,6 @@ Patch21220: mac80211_offchannel_rework_revert.patch
Patch21225: pci-Rework-ASPM-disable-code.patch
Patch21226: pci-crs-blacklist.patch
Patch21227: dell-mmconfig-quirk.patch
#rhbz #757839
Patch21230: net-sky2-88e8059-fix-link-speed.patch
@ -846,12 +839,6 @@ Patch21049: tpm_tis-delay-after-aborting-cmd.patch
#rhbz 771006
Patch21050: thp-reduce-khugepaged-freezing-latency.patch
#rhbz 771387
Patch21055: KVM-x86-Prevent-starting-PIT-timers-in-the-absence-of.patch
#rhbz 771678
Patch21056: KVM-fix-device-assignment-permissions.patch
#rhbz 770233
Patch21065: Bluetooth-Add-support-for-BCM20702A0.patch
@ -1424,7 +1411,6 @@ ApplyPatch jbd-jbd2-validate-sb-s_first-in-journal_get_superblo.patch
# eCryptfs
# NFSv4
ApplyPatch nfsv4-include-bitmap-in-nfsv4_get_acl_data.patch
# USB
@ -1561,9 +1547,6 @@ ApplyPatch x86-code-dump-fix-truncation.patch
#rhbz 728607
ApplyPatch elantech.patch
#rhbz 748210
ApplyPatch ideapad-Check-if-acpi-already-handle-backlight.patch
#rhbz 752176
ApplyPatch sysfs-msi-irq-per-device.patch
@ -1584,7 +1567,6 @@ ApplyPatch mac80211_offchannel_rework_revert.patch
ApplyPatch pci-Rework-ASPM-disable-code.patch
#ApplyPatch pci-crs-blacklist.patch
ApplyPatch dell-mmconfig-quirk.patch
#rhbz #757839
ApplyPatch net-sky2-88e8059-fix-link-speed.patch
@ -1604,15 +1586,9 @@ ApplyPatch tpm_tis-delay-after-aborting-cmd.patch
#rhbz 771006
ApplyPatch thp-reduce-khugepaged-freezing-latency.patch
#rhbz 771387
ApplyPatch KVM-x86-Prevent-starting-PIT-timers-in-the-absence-of.patch
#rhbz 770233
ApplyPatch Bluetooth-Add-support-for-BCM20702A0.patch
#rhbz 771678
ApplyPatch KVM-fix-device-assignment-permissions.patch
#rhbz 771058
ApplyPatch msi-irq-sysfs-warning.patch
@ -1620,8 +1596,6 @@ ApplyPatch ext4-Support-check-none-nocheck-mount-options.patch
ApplyPatch ext4-Fix-error-handling-on-inode-bitmap-corruption.patch
ApplyPatch mac80211-fix-rx-key-NULL-ptr-deref-in-promiscuous-mode.patch
#rhbz 773392
ApplyPatch KVM-x86-extend-struct-x86_emulate_ops-with-get_cpuid.patch
ApplyPatch KVM-x86-fix-missing-checks-in-syscall-emulation.patch
@ -2414,7 +2388,8 @@ fi
# and build.
%changelog
* Wed Jan 18 2012 Josh Boyer <jwboyer@redhat.com>
* Wed Jan 18 2012 Josh Boyer <jwboyer@redhat.com> 3.1.10-1
- Linux 3.1.10
- CVE-2012-0056 proc: clean up and fix /proc/<pid>/mem (rhbz 782681)
- loop: prevent information leak after failed read (rhbz 782687)

View File

@ -1,118 +0,0 @@
From: Andy Adamson <andros@xxxxxxxxxx>
The NFSv4 bitmap size is unbounded: a server can return an arbitrary
sized bitmap in an FATTR4_WORD0_ACL request. Replace using the
nfs4_fattr_bitmap_maxsz as a guess to the maximum bitmask returned by a server
with the inclusion of the bitmap (xdr length plus bitmasks) and the acl data
xdr length to the (cached) acl page data.
This is a general solution to commit e5012d1f "NFSv4.1: update
nfs4_fattr_bitmap_maxsz" and fixes hitting a BUG_ON in xdr_shrink_bufhead
when getting ACLs.
Cc:stable@xxxxxxxxxx
Signed-off-by: Andy Adamson <andros@xxxxxxxxxx>
---
fs/nfs/nfs4proc.c | 20 ++++++++++++++++++--
fs/nfs/nfs4xdr.c | 15 ++++++++++++---
2 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index deb88d9..97014dd 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3671,6 +3671,22 @@ static void nfs4_zap_acl_attr(struct inode *inode)
nfs4_set_cached_acl(inode, NULL);
}
+/*
+ * The bitmap xdr length, bitmasks, and the attr xdr length are stored in
+ * the acl cache to handle variable length bitmasks. Just copy the acl data.
+ */
+static void nfs4_copy_acl(char *buf, char *acl_data, size_t acl_len)
+{
+ __be32 *q, *p = (__be32 *)acl_data;
+ int32_t len;
+
+ len = be32_to_cpup(p); /* number of bitmasks */
+ len += 2; /* add words for bitmap and attr xdr len */
+ q = p + len;
+ len = len << 2; /* convert to bytes for acl_len math */
+ memcpy(buf, (char *)q, acl_len - len);
+}
+
static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_t buflen)
{
struct nfs_inode *nfsi = NFS_I(inode);
@@ -3688,7 +3704,7 @@ static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_
ret = -ERANGE; /* see getxattr(2) man page */
if (acl->len > buflen)
goto out;
- memcpy(buf, acl->data, acl->len);
+ nfs4_copy_acl(buf, acl->data, acl->len);
out_len:
ret = acl->len;
out:
@@ -3763,7 +3779,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
if (res.acl_len > buflen)
goto out_free;
if (localpage)
- memcpy(buf, resp_buf, res.acl_len);
+ nfs4_copy_acl(buf, resp_buf, res.acl_len);
}
ret = res.acl_len;
out_free:
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index f9fd96d..9c07380 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -2513,7 +2513,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
encode_compound_hdr(xdr, req, &hdr);
encode_sequence(xdr, &args->seq_args, &hdr);
encode_putfh(xdr, args->fh, &hdr);
- replen = hdr.replen + op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz + 1;
+ replen = hdr.replen + op_decode_hdr_maxsz + 1;
encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr);
xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
@@ -4955,7 +4955,7 @@ decode_restorefh(struct xdr_stream *xdr)
static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
size_t *acl_len)
{
- __be32 *savep;
+ __be32 *savep, *bm_p;
uint32_t attrlen,
bitmap[3] = {0};
struct kvec *iov = req->rq_rcv_buf.head;
@@ -4964,6 +4964,7 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
*acl_len = 0;
if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
goto out;
+ bm_p = xdr->p;
if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
goto out;
if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
@@ -4972,12 +4973,20 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U)))
return -EIO;
if (likely(bitmap[0] & FATTR4_WORD0_ACL)) {
- size_t hdrlen;
+ size_t hdrlen, len;
u32 recvd;
+ /*The bitmap (xdr len + bitmasks) and the attr xdr len words
+ * are stored with the acl data to handle the problem of
+ * variable length bitmasks.*/
+ xdr->p = bm_p;
+ len = be32_to_cpup(bm_p);
+ len += 2; /* add bitmap and attr xdr len words */
+
/* We ignore &savep and don't do consistency checks on
* the attr length. Let userspace figure it out.... */
hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base;
+ attrlen += len << 2; /* attrlen is in bytes */
recvd = req->rq_rcv_buf.len - hdrlen;
if (attrlen > recvd) {
dprintk("NFS: server cheating in getattr"
--
1.7.6.4

View File

@ -1,3 +1,3 @@
8d43453f8159b2332ad410b19d86a931 linux-3.1.tar.bz2
204381bc537b689edcb15df0efed6467 compat-wireless-3.2-1.tar.bz2
fae6176f187628bcc5b330cdadc60f9e patch-3.1.9.bz2
a8e1c25a93a685ec2a1c3a808715fe9d patch-3.1.10.bz2