From: Greg Kroah-Hartman Date: Thu, 17 Dec 2015 22:43:25 +0000 (-0800) Subject: 4.3-stable patches X-Git-Tag: v3.10.95~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1c3c85787423b7c77ac21aa1fb17a060016b0676;p=thirdparty%2Fkernel%2Fstable-queue.git 4.3-stable patches added patches: acpi-pm-fix-incorrect-wakeup-irq-setting-during-suspend-to-idle.patch acpi-use-correct-irq-when-uninstalling-acpi-interrupt-handler.patch acpi-using-correct-irq-when-waiting-for-events.patch revert-vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch tipc-fix-kfree_skb-of-uninitialised-pointer.patch toshiba_acpi-initialize-hotkey_event_type-variable.patch tpm-tpm_tis-fix-tpm_tis-acpi-detection-issue-with-tpm-2.0.patch vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch --- diff --git a/queue-4.3/acpi-pm-fix-incorrect-wakeup-irq-setting-during-suspend-to-idle.patch b/queue-4.3/acpi-pm-fix-incorrect-wakeup-irq-setting-during-suspend-to-idle.patch new file mode 100644 index 00000000000..76be6f8b5ea --- /dev/null +++ b/queue-4.3/acpi-pm-fix-incorrect-wakeup-irq-setting-during-suspend-to-idle.patch @@ -0,0 +1,55 @@ +From 8c01275e0cdf1959aa25c322fd5870c097733195 Mon Sep 17 00:00:00 2001 +From: Chen Yu +Date: Sun, 25 Oct 2015 01:02:46 +0800 +Subject: ACPI / PM: Fix incorrect wakeup IRQ setting during suspend-to-idle + +From: Chen Yu + +commit 8c01275e0cdf1959aa25c322fd5870c097733195 upstream. + +For an ACPI compatible system, the SCI (ACPI System Control +Interrupt) is used to wake the system up from suspend-to-idle. +Once the CPU is woken up by the SCI, the interrupt handler will +first check if the current IRQ has been configured for system +wakeup, so irq_pm_check_wakeup() is invoked to validate the IRQ +number. However, during suspend-to-idle, enable_irq_wake() is +called for acpi_gbl_FADT.sci_interrupt, although the IRQ number +that the SCI handler has been installed for should be passed to +it instead. Thus, if acpi_gbl_FADT.sci_interrupt happens to be +different from that number, ACPI interrupts will not be able to +wake up the system from sleep. + +Fix this problem by passing the IRQ number returned by +acpi_gsi_to_irq() to enable_irq_wake() instead of +acpi_gbl_FADT.sci_interrupt. + +Acked-by: Lv Zheng +Signed-off-by: Chen Yu +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/sleep.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/acpi/sleep.c ++++ b/drivers/acpi/sleep.c +@@ -632,14 +632,16 @@ static int acpi_freeze_prepare(void) + acpi_enable_wakeup_devices(ACPI_STATE_S0); + acpi_enable_all_wakeup_gpes(); + acpi_os_wait_events_complete(); +- enable_irq_wake(acpi_gbl_FADT.sci_interrupt); ++ if (acpi_sci_irq_valid()) ++ enable_irq_wake(acpi_sci_irq); + return 0; + } + + static void acpi_freeze_restore(void) + { + acpi_disable_wakeup_devices(ACPI_STATE_S0); +- disable_irq_wake(acpi_gbl_FADT.sci_interrupt); ++ if (acpi_sci_irq_valid()) ++ disable_irq_wake(acpi_sci_irq); + acpi_enable_all_runtime_gpes(); + } + diff --git a/queue-4.3/acpi-use-correct-irq-when-uninstalling-acpi-interrupt-handler.patch b/queue-4.3/acpi-use-correct-irq-when-uninstalling-acpi-interrupt-handler.patch new file mode 100644 index 00000000000..e5f41d15615 --- /dev/null +++ b/queue-4.3/acpi-use-correct-irq-when-uninstalling-acpi-interrupt-handler.patch @@ -0,0 +1,76 @@ +From 49e4b84333f338d4f183f28f1f3c1131b9fb2b5a Mon Sep 17 00:00:00 2001 +From: Chen Yu +Date: Sun, 25 Oct 2015 01:02:19 +0800 +Subject: ACPI: Use correct IRQ when uninstalling ACPI interrupt handler + +From: Chen Yu + +commit 49e4b84333f338d4f183f28f1f3c1131b9fb2b5a upstream. + +Currently when the system is trying to uninstall the ACPI interrupt +handler, it uses acpi_gbl_FADT.sci_interrupt as the IRQ number. +However, the IRQ number that the ACPI interrupt handled is installed +for comes from acpi_gsi_to_irq() and that is the number that should +be used for the handler removal. + +Fix this problem by using the mapped IRQ returned from acpi_gsi_to_irq() +as appropriate. + +Acked-by: Lv Zheng +Signed-off-by: Chen Yu +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/osl.c | 9 ++++++--- + include/linux/acpi.h | 6 ++++++ + 2 files changed, 12 insertions(+), 3 deletions(-) + +--- a/drivers/acpi/osl.c ++++ b/drivers/acpi/osl.c +@@ -81,6 +81,7 @@ static struct workqueue_struct *kacpid_w + static struct workqueue_struct *kacpi_notify_wq; + static struct workqueue_struct *kacpi_hotplug_wq; + static bool acpi_os_initialized; ++unsigned int acpi_sci_irq = INVALID_ACPI_IRQ; + + /* + * This list of permanent mappings is for memory that may be accessed from +@@ -856,17 +857,19 @@ acpi_os_install_interrupt_handler(u32 gs + acpi_irq_handler = NULL; + return AE_NOT_ACQUIRED; + } ++ acpi_sci_irq = irq; + + return AE_OK; + } + +-acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler) ++acpi_status acpi_os_remove_interrupt_handler(u32 gsi, acpi_osd_handler handler) + { +- if (irq != acpi_gbl_FADT.sci_interrupt) ++ if (gsi != acpi_gbl_FADT.sci_interrupt || !acpi_sci_irq_valid()) + return AE_BAD_PARAMETER; + +- free_irq(irq, acpi_irq); ++ free_irq(acpi_sci_irq, acpi_irq); + acpi_irq_handler = NULL; ++ acpi_sci_irq = INVALID_ACPI_IRQ; + + return AE_OK; + } +--- a/include/linux/acpi.h ++++ b/include/linux/acpi.h +@@ -193,6 +193,12 @@ int acpi_ioapic_registered(acpi_handle h + void acpi_irq_stats_init(void); + extern u32 acpi_irq_handled; + extern u32 acpi_irq_not_handled; ++extern unsigned int acpi_sci_irq; ++#define INVALID_ACPI_IRQ ((unsigned)-1) ++static inline bool acpi_sci_irq_valid(void) ++{ ++ return acpi_sci_irq != INVALID_ACPI_IRQ; ++} + + extern int sbf_port; + extern unsigned long acpi_realmode_flags; diff --git a/queue-4.3/acpi-using-correct-irq-when-waiting-for-events.patch b/queue-4.3/acpi-using-correct-irq-when-waiting-for-events.patch new file mode 100644 index 00000000000..c339f5924e6 --- /dev/null +++ b/queue-4.3/acpi-using-correct-irq-when-waiting-for-events.patch @@ -0,0 +1,36 @@ +From efb1cf7d28b8aeacec53e9ba8f3f2809c5cb9686 Mon Sep 17 00:00:00 2001 +From: Chen Yu +Date: Sun, 25 Oct 2015 01:02:36 +0800 +Subject: ACPI: Using correct irq when waiting for events + +From: Chen Yu + +commit efb1cf7d28b8aeacec53e9ba8f3f2809c5cb9686 upstream. + +When the system is waiting for GPE/fixed event handler to finish, +it uses acpi_gbl_FADT.sci_interrupt directly as the IRQ number. +However, the remapped IRQ returned by acpi_gsi_to_irq() should be +passed to synchronize_hardirq() instead of it. + +Acked-by: Lv Zheng +Signed-off-by: Chen Yu +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/osl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/acpi/osl.c ++++ b/drivers/acpi/osl.c +@@ -1183,8 +1183,8 @@ void acpi_os_wait_events_complete(void) + * Make sure the GPE handler or the fixed event handler is not used + * on another CPU after removal. + */ +- if (acpi_irq_handler) +- synchronize_hardirq(acpi_gbl_FADT.sci_interrupt); ++ if (acpi_sci_irq_valid()) ++ synchronize_hardirq(acpi_sci_irq); + flush_workqueue(kacpid_wq); + flush_workqueue(kacpi_notify_wq); + } diff --git a/queue-4.3/revert-vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch b/queue-4.3/revert-vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch new file mode 100644 index 00000000000..92b56a4794d --- /dev/null +++ b/queue-4.3/revert-vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch @@ -0,0 +1,61 @@ +From ben@decadent.org.uk Thu Dec 17 14:12:57 2015 +From: Ben Hutchings +Date: Tue, 15 Dec 2015 15:31:49 +0000 +Subject: Revert "vrf: fix double free and memory corruption on register_netdevice failure" +To: Greg Kroah-Hartman +Cc: David Ahern , linux-kernel@vger.kernel.org, stable@vger.kernel.org, Nikolay Aleksandrov , "David S. Miller" +Message-ID: <20151215153149.GO28542@decadent.org.uk> + +From: Ben Hutchings + +This reverts commit b3abad339f8e268bb261e5844ab68b18a7797c29, which +was an attempt to backport commit 7f109f7cc37108cba7243bc832988525b0d85909 +upstream. The backport introduced a deadlock and other bugs. + +Signed-off-by: Ben Hutchings +Acked-by: David S. Miller +Acked-by: David Ahern +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/vrf.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +--- a/drivers/net/vrf.c ++++ b/drivers/net/vrf.c +@@ -581,6 +581,7 @@ static int vrf_newlink(struct net *src_n + { + struct net_vrf *vrf = netdev_priv(dev); + struct net_vrf_dev *vrf_ptr; ++ int err; + + if (!data || !data[IFLA_VRF_TABLE]) + return -EINVAL; +@@ -589,16 +590,26 @@ static int vrf_newlink(struct net *src_n + + dev->priv_flags |= IFF_VRF_MASTER; + ++ err = -ENOMEM; + vrf_ptr = kmalloc(sizeof(*dev->vrf_ptr), GFP_KERNEL); + if (!vrf_ptr) +- return -ENOMEM; ++ goto out_fail; + + vrf_ptr->ifindex = dev->ifindex; + vrf_ptr->tb_id = vrf->tb_id; + ++ err = register_netdevice(dev); ++ if (err < 0) ++ goto out_fail; ++ + rcu_assign_pointer(dev->vrf_ptr, vrf_ptr); + +- return register_netdev(dev); ++ return 0; ++ ++out_fail: ++ kfree(vrf_ptr); ++ free_netdev(dev); ++ return err; + } + + static size_t vrf_nl_getsize(const struct net_device *dev) diff --git a/queue-4.3/tipc-fix-kfree_skb-of-uninitialised-pointer.patch b/queue-4.3/tipc-fix-kfree_skb-of-uninitialised-pointer.patch new file mode 100644 index 00000000000..004ec990f70 --- /dev/null +++ b/queue-4.3/tipc-fix-kfree_skb-of-uninitialised-pointer.patch @@ -0,0 +1,34 @@ +From ben@decadent.org.uk Thu Dec 17 14:16:22 2015 +From: Ben Hutchings +Date: Tue, 15 Dec 2015 21:21:57 +0000 +Subject: tipc: Fix kfree_skb() of uninitialised pointer +To: Greg Kroah-Hartman +Cc: stable@vger.kernel.org, ying.xue@windriver.com, "David S. Miller" +Message-ID: <20151215212156.GQ28542@decadent.org.uk> +Content-Disposition: inline + +From: Ben Hutchings + +Commit 7098356baca7 ("tipc: fix error handling of expanding buffer +headroom") added a "goto tx_error". This is fine upstream, but +when backported to 4.3 it results in attempting to free the clone +before it has been allocated. In this early error case, no +cleanup is needed. + +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + net/tipc/udp_media.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/tipc/udp_media.c ++++ b/net/tipc/udp_media.c +@@ -162,7 +162,7 @@ static int tipc_udp_send_msg(struct net + if (skb_headroom(skb) < UDP_MIN_HEADROOM) { + err = pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC); + if (err) +- goto tx_error; ++ return err; + } + + clone = skb_clone(skb, GFP_ATOMIC); diff --git a/queue-4.3/toshiba_acpi-initialize-hotkey_event_type-variable.patch b/queue-4.3/toshiba_acpi-initialize-hotkey_event_type-variable.patch new file mode 100644 index 00000000000..85dbfc6cac7 --- /dev/null +++ b/queue-4.3/toshiba_acpi-initialize-hotkey_event_type-variable.patch @@ -0,0 +1,35 @@ +From d2f20619942fe4618160a7fa3dbdcbac335cff59 Mon Sep 17 00:00:00 2001 +From: Azael Avalos +Date: Wed, 4 Nov 2015 09:28:26 -0700 +Subject: toshiba_acpi: Initialize hotkey_event_type variable + +From: Azael Avalos + +commit d2f20619942fe4618160a7fa3dbdcbac335cff59 upstream. + +Commit 53147b6cabee5e8d1997b5682fcc0c3b72ddf9c2 ("toshiba_acpi: Fix +hotkeys registration on some toshiba models") fixed an issue on some +laptops regarding hotkeys registration, however, if failed to address +the initialization of the hotkey_event_type variable, and thus, it can +lead to potential unwanted effects as the variable is being checked. + +This patch initializes such variable to avoid such unwanted effects. + +Signed-off-by: Azael Avalos +Signed-off-by: Darren Hart +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/platform/x86/toshiba_acpi.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/platform/x86/toshiba_acpi.c ++++ b/drivers/platform/x86/toshiba_acpi.c +@@ -2676,6 +2676,7 @@ static int toshiba_acpi_add(struct acpi_ + ret = toshiba_function_keys_get(dev, &special_functions); + dev->kbd_function_keys_supported = !ret; + ++ dev->hotkey_event_type = 0; + if (toshiba_acpi_setup_keyboard(dev)) + pr_info("Unable to activate hotkeys\n"); + diff --git a/queue-4.3/tpm-tpm_tis-fix-tpm_tis-acpi-detection-issue-with-tpm-2.0.patch b/queue-4.3/tpm-tpm_tis-fix-tpm_tis-acpi-detection-issue-with-tpm-2.0.patch new file mode 100644 index 00000000000..e39c45e7c84 --- /dev/null +++ b/queue-4.3/tpm-tpm_tis-fix-tpm_tis-acpi-detection-issue-with-tpm-2.0.patch @@ -0,0 +1,443 @@ +From 399235dc6e95400a1322a9999e92073bc572f0c8 Mon Sep 17 00:00:00 2001 +From: Jarkko Sakkinen +Date: Tue, 29 Sep 2015 00:32:19 +0300 +Subject: tpm, tpm_tis: fix tpm_tis ACPI detection issue with TPM 2.0 + +From: Jarkko Sakkinen + +commit 399235dc6e95400a1322a9999e92073bc572f0c8 upstream. + +Both for FIFO and CRB interface TCG has decided to use the same HID +MSFT0101. They can be differentiated by looking at the start method from +TPM2 ACPI table. This patches makes necessary fixes to tpm_tis and +tpm_crb modules in order to correctly detect, which module should be +used. + +For MSFT0101 we must use struct acpi_driver because struct pnp_driver +has a 7 character limitation. + +It turned out that the root cause in b371616b8 was not correct for +https://bugzilla.kernel.org/show_bug.cgi?id=98181. + +v2: + +* One fixup was missing from v1: is_tpm2_fifo -> is_fifo + +v3: + +* Use pnp_driver for existing HIDs and acpi_driver only for MSFT0101 in + order ensure backwards compatibility. + +v4: + +* Check for FIFO before doing *anything* in crb_acpi_add(). +* There was return immediately after acpi_bus_unregister_driver() in + cleanup_tis(). This caused pnp_unregister_driver() not to be called. + +Reported-by: Michael Saunders +Reported-by: Michael Marley +Reported-by: Jethro Beekman +Reported-by: Matthew Garrett +Signed-off-by: Jarkko Sakkinen +Tested-by: Michael Marley +Tested-by: Mimi Zohar (on TPM 1.2) +Reviewed-by: Peter Huewe +Signed-off-by: Peter Huewe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm.h | 7 + + drivers/char/tpm/tpm_crb.c | 32 ++----- + drivers/char/tpm/tpm_tis.c | 192 ++++++++++++++++++++++++++++++++++++++------- + 3 files changed, 181 insertions(+), 50 deletions(-) + +--- a/drivers/char/tpm/tpm.h ++++ b/drivers/char/tpm/tpm.h +@@ -115,6 +115,13 @@ enum tpm2_startup_types { + TPM2_SU_STATE = 0x0001, + }; + ++enum tpm2_start_method { ++ TPM2_START_ACPI = 2, ++ TPM2_START_FIFO = 6, ++ TPM2_START_CRB = 7, ++ TPM2_START_CRB_WITH_ACPI = 8, ++}; ++ + struct tpm_chip; + + struct tpm_vendor_specific { +--- a/drivers/char/tpm/tpm_crb.c ++++ b/drivers/char/tpm/tpm_crb.c +@@ -34,12 +34,6 @@ enum crb_defaults { + CRB_ACPI_START_INDEX = 1, + }; + +-enum crb_start_method { +- CRB_SM_ACPI_START = 2, +- CRB_SM_CRB = 7, +- CRB_SM_CRB_WITH_ACPI_START = 8, +-}; +- + struct acpi_tpm2 { + struct acpi_table_header hdr; + u16 platform_class; +@@ -220,12 +214,6 @@ static int crb_acpi_add(struct acpi_devi + u64 pa; + int rc; + +- chip = tpmm_chip_alloc(dev, &tpm_crb); +- if (IS_ERR(chip)) +- return PTR_ERR(chip); +- +- chip->flags = TPM_CHIP_FLAG_TPM2; +- + status = acpi_get_table(ACPI_SIG_TPM2, 1, + (struct acpi_table_header **) &buf); + if (ACPI_FAILURE(status)) { +@@ -233,13 +221,15 @@ static int crb_acpi_add(struct acpi_devi + return -ENODEV; + } + +- /* At least some versions of AMI BIOS have a bug that TPM2 table has +- * zero address for the control area and therefore we must fail. +- */ +- if (!buf->control_area_pa) { +- dev_err(dev, "TPM2 ACPI table has a zero address for the control area\n"); +- return -EINVAL; +- } ++ /* Should the FIFO driver handle this? */ ++ if (buf->start_method == TPM2_START_FIFO) ++ return -ENODEV; ++ ++ chip = tpmm_chip_alloc(dev, &tpm_crb); ++ if (IS_ERR(chip)) ++ return PTR_ERR(chip); ++ ++ chip->flags = TPM_CHIP_FLAG_TPM2; + + if (buf->hdr.length < sizeof(struct acpi_tpm2)) { + dev_err(dev, "TPM2 ACPI table has wrong size"); +@@ -259,11 +249,11 @@ static int crb_acpi_add(struct acpi_devi + * report only ACPI start but in practice seems to require both + * ACPI start and CRB start. + */ +- if (sm == CRB_SM_CRB || sm == CRB_SM_CRB_WITH_ACPI_START || ++ if (sm == TPM2_START_CRB || sm == TPM2_START_FIFO || + !strcmp(acpi_device_hid(device), "MSFT0101")) + priv->flags |= CRB_FL_CRB_START; + +- if (sm == CRB_SM_ACPI_START || sm == CRB_SM_CRB_WITH_ACPI_START) ++ if (sm == TPM2_START_ACPI || sm == TPM2_START_CRB_WITH_ACPI) + priv->flags |= CRB_FL_ACPI_START; + + priv->cca = (struct crb_control_area __iomem *) +--- a/drivers/char/tpm/tpm_tis.c ++++ b/drivers/char/tpm/tpm_tis.c +@@ -1,6 +1,6 @@ + /* + * Copyright (C) 2005, 2006 IBM Corporation +- * Copyright (C) 2014 Intel Corporation ++ * Copyright (C) 2014, 2015 Intel Corporation + * + * Authors: + * Leendert van Doorn +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include "tpm.h" + + enum tis_access { +@@ -65,6 +66,17 @@ enum tis_defaults { + TIS_LONG_TIMEOUT = 2000, /* 2 sec */ + }; + ++struct tpm_info { ++ unsigned long start; ++ unsigned long len; ++ unsigned int irq; ++}; ++ ++static struct tpm_info tis_default_info = { ++ .start = TIS_MEM_BASE, ++ .len = TIS_MEM_LEN, ++ .irq = 0, ++}; + + /* Some timeout values are needed before it is known whether the chip is + * TPM 1.0 or TPM 2.0. +@@ -91,26 +103,54 @@ struct priv_data { + }; + + #if defined(CONFIG_PNP) && defined(CONFIG_ACPI) +-static int is_itpm(struct pnp_dev *dev) ++static int has_hid(struct acpi_device *dev, const char *hid) + { +- struct acpi_device *acpi = pnp_acpi_device(dev); + struct acpi_hardware_id *id; + +- if (!acpi) +- return 0; +- +- list_for_each_entry(id, &acpi->pnp.ids, list) { +- if (!strcmp("INTC0102", id->id)) ++ list_for_each_entry(id, &dev->pnp.ids, list) ++ if (!strcmp(hid, id->id)) + return 1; +- } + + return 0; + } ++ ++static inline int is_itpm(struct acpi_device *dev) ++{ ++ return has_hid(dev, "INTC0102"); ++} ++ ++static inline int is_fifo(struct acpi_device *dev) ++{ ++ struct acpi_table_tpm2 *tbl; ++ acpi_status st; ++ ++ /* TPM 1.2 FIFO */ ++ if (!has_hid(dev, "MSFT0101")) ++ return 1; ++ ++ st = acpi_get_table(ACPI_SIG_TPM2, 1, ++ (struct acpi_table_header **) &tbl); ++ if (ACPI_FAILURE(st)) { ++ dev_err(&dev->dev, "failed to get TPM2 ACPI table\n"); ++ return 0; ++ } ++ ++ if (le32_to_cpu(tbl->start_method) != TPM2_START_FIFO) ++ return 0; ++ ++ /* TPM 2.0 FIFO */ ++ return 1; ++} + #else +-static inline int is_itpm(struct pnp_dev *dev) ++static inline int is_itpm(struct acpi_device *dev) + { + return 0; + } ++ ++static inline int is_fifo(struct acpi_device *dev) ++{ ++ return 1; ++} + #endif + + /* Before we attempt to access the TPM we must see that the valid bit is set. +@@ -600,9 +640,8 @@ static void tpm_tis_remove(struct tpm_ch + release_locality(chip, chip->vendor.locality, 1); + } + +-static int tpm_tis_init(struct device *dev, acpi_handle acpi_dev_handle, +- resource_size_t start, resource_size_t len, +- unsigned int irq) ++static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, ++ acpi_handle acpi_dev_handle) + { + u32 vendor, intfcaps, intmask; + int rc, i, irq_s, irq_e, probe; +@@ -622,7 +661,7 @@ static int tpm_tis_init(struct device *d + chip->acpi_dev_handle = acpi_dev_handle; + #endif + +- chip->vendor.iobase = devm_ioremap(dev, start, len); ++ chip->vendor.iobase = devm_ioremap(dev, tpm_info->start, tpm_info->len); + if (!chip->vendor.iobase) + return -EIO; + +@@ -707,7 +746,7 @@ static int tpm_tis_init(struct device *d + chip->vendor.iobase + + TPM_INT_ENABLE(chip->vendor.locality)); + if (interrupts) +- chip->vendor.irq = irq; ++ chip->vendor.irq = tpm_info->irq; + if (interrupts && !chip->vendor.irq) { + irq_s = + ioread8(chip->vendor.iobase + +@@ -890,27 +929,27 @@ static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm + static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev, + const struct pnp_device_id *pnp_id) + { +- resource_size_t start, len; +- unsigned int irq = 0; ++ struct tpm_info tpm_info = tis_default_info; + acpi_handle acpi_dev_handle = NULL; + +- start = pnp_mem_start(pnp_dev, 0); +- len = pnp_mem_len(pnp_dev, 0); ++ tpm_info.start = pnp_mem_start(pnp_dev, 0); ++ tpm_info.len = pnp_mem_len(pnp_dev, 0); + + if (pnp_irq_valid(pnp_dev, 0)) +- irq = pnp_irq(pnp_dev, 0); ++ tpm_info.irq = pnp_irq(pnp_dev, 0); + else + interrupts = false; + +- if (is_itpm(pnp_dev)) +- itpm = true; +- + #ifdef CONFIG_ACPI +- if (pnp_acpi_device(pnp_dev)) ++ if (pnp_acpi_device(pnp_dev)) { ++ if (is_itpm(pnp_acpi_device(pnp_dev))) ++ itpm = true; ++ + acpi_dev_handle = pnp_acpi_device(pnp_dev)->handle; ++ } + #endif + +- return tpm_tis_init(&pnp_dev->dev, acpi_dev_handle, start, len, irq); ++ return tpm_tis_init(&pnp_dev->dev, &tpm_info, acpi_dev_handle); + } + + static struct pnp_device_id tpm_pnp_tbl[] = { +@@ -930,6 +969,7 @@ MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); + static void tpm_tis_pnp_remove(struct pnp_dev *dev) + { + struct tpm_chip *chip = pnp_get_drvdata(dev); ++ + tpm_chip_unregister(chip); + tpm_tis_remove(chip); + } +@@ -950,6 +990,79 @@ module_param_string(hid, tpm_pnp_tbl[TIS + MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); + #endif + ++#ifdef CONFIG_ACPI ++static int tpm_check_resource(struct acpi_resource *ares, void *data) ++{ ++ struct tpm_info *tpm_info = (struct tpm_info *) data; ++ struct resource res; ++ ++ if (acpi_dev_resource_interrupt(ares, 0, &res)) { ++ tpm_info->irq = res.start; ++ } else if (acpi_dev_resource_memory(ares, &res)) { ++ tpm_info->start = res.start; ++ tpm_info->len = resource_size(&res); ++ } ++ ++ return 1; ++} ++ ++static int tpm_tis_acpi_init(struct acpi_device *acpi_dev) ++{ ++ struct list_head resources; ++ struct tpm_info tpm_info = tis_default_info; ++ int ret; ++ ++ if (!is_fifo(acpi_dev)) ++ return -ENODEV; ++ ++ INIT_LIST_HEAD(&resources); ++ ret = acpi_dev_get_resources(acpi_dev, &resources, tpm_check_resource, ++ &tpm_info); ++ if (ret < 0) ++ return ret; ++ ++ acpi_dev_free_resource_list(&resources); ++ ++ if (!tpm_info.irq) ++ interrupts = false; ++ ++ if (is_itpm(acpi_dev)) ++ itpm = true; ++ ++ return tpm_tis_init(&acpi_dev->dev, &tpm_info, acpi_dev->handle); ++} ++ ++static int tpm_tis_acpi_remove(struct acpi_device *dev) ++{ ++ struct tpm_chip *chip = dev_get_drvdata(&dev->dev); ++ ++ tpm_chip_unregister(chip); ++ tpm_tis_remove(chip); ++ ++ return 0; ++} ++ ++static struct acpi_device_id tpm_acpi_tbl[] = { ++ {"MSFT0101", 0}, /* TPM 2.0 */ ++ /* Add new here */ ++ {"", 0}, /* User Specified */ ++ {"", 0} /* Terminator */ ++}; ++MODULE_DEVICE_TABLE(acpi, tpm_acpi_tbl); ++ ++static struct acpi_driver tis_acpi_driver = { ++ .name = "tpm_tis", ++ .ids = tpm_acpi_tbl, ++ .ops = { ++ .add = tpm_tis_acpi_init, ++ .remove = tpm_tis_acpi_remove, ++ }, ++ .drv = { ++ .pm = &tpm_tis_pm, ++ }, ++}; ++#endif ++ + static struct platform_driver tis_drv = { + .driver = { + .name = "tpm_tis", +@@ -966,9 +1079,25 @@ static int __init init_tis(void) + { + int rc; + #ifdef CONFIG_PNP +- if (!force) +- return pnp_register_driver(&tis_pnp_driver); ++ if (!force) { ++ rc = pnp_register_driver(&tis_pnp_driver); ++ if (rc) ++ return rc; ++ } ++#endif ++#ifdef CONFIG_ACPI ++ if (!force) { ++ rc = acpi_bus_register_driver(&tis_acpi_driver); ++ if (rc) { ++#ifdef CONFIG_PNP ++ pnp_unregister_driver(&tis_pnp_driver); + #endif ++ return rc; ++ } ++ } ++#endif ++ if (!force) ++ return 0; + + rc = platform_driver_register(&tis_drv); + if (rc < 0) +@@ -978,7 +1107,7 @@ static int __init init_tis(void) + rc = PTR_ERR(pdev); + goto err_dev; + } +- rc = tpm_tis_init(&pdev->dev, NULL, TIS_MEM_BASE, TIS_MEM_LEN, 0); ++ rc = tpm_tis_init(&pdev->dev, &tis_default_info, NULL); + if (rc) + goto err_init; + return 0; +@@ -992,9 +1121,14 @@ err_dev: + static void __exit cleanup_tis(void) + { + struct tpm_chip *chip; +-#ifdef CONFIG_PNP ++#if defined(CONFIG_PNP) || defined(CONFIG_ACPI) + if (!force) { ++#ifdef CONFIG_ACPI ++ acpi_bus_unregister_driver(&tis_acpi_driver); ++#endif ++#ifdef CONFIG_PNP + pnp_unregister_driver(&tis_pnp_driver); ++#endif + return; + } + #endif diff --git a/queue-4.3/vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch b/queue-4.3/vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch new file mode 100644 index 00000000000..20001ba4669 --- /dev/null +++ b/queue-4.3/vrf-fix-double-free-and-memory-corruption-on-register_netdevice-failure.patch @@ -0,0 +1,78 @@ +From ben@decadent.org.uk Thu Dec 17 14:14:13 2015 +From: Ben Hutchings +Date: Tue, 15 Dec 2015 15:32:20 +0000 +Subject: vrf: fix double free and memory corruption on register_netdevice failure +To: Greg Kroah-Hartman +Cc: David Ahern , linux-kernel@vger.kernel.org, stable@vger.kernel.org, Nikolay Aleksandrov , "David S. Miller" +Message-ID: <20151215153220.GP28542@decadent.org.uk> +Content-Disposition: inline + +From: Ben Hutchings + +commit 7f109f7cc37108cba7243bc832988525b0d85909 upstream. + +When vrf's ->newlink is called, if register_netdevice() fails then it +does free_netdev(), but that's also done by rtnl_newlink() so a second +free happens and memory gets corrupted, to reproduce execute the +following line a couple of times (1 - 5 usually is enough): +$ for i in `seq 1 5`; do ip link add vrf: type vrf table 1; done; +This works because we fail in register_netdevice() because of the wrong +name "vrf:". + +And here's a trace of one crash: +[ 28.792157] ------------[ cut here ]------------ +[ 28.792407] kernel BUG at fs/namei.c:246! +[ 28.792608] invalid opcode: 0000 [#1] SMP +[ 28.793240] Modules linked in: vrf nfsd auth_rpcgss oid_registry nfs_acl nfs lockd grace sunrpc crct10dif_pclmul crc32_pclmul crc32c_intel qxl drm_kms_helper ttm drm aesni_intel aes_x86_64 psmouse glue_helper lrw evdev gf128mul i2c_piix4 ablk_helper cryptd ppdev parport_pc parport serio_raw pcspkr virtio_balloon virtio_console i2c_core acpi_cpufreq button 9pnet_virtio 9p 9pnet fscache ipv6 autofs4 ext4 crc16 mbcache jbd2 virtio_blk virtio_net sg sr_mod cdrom ata_generic ehci_pci uhci_hcd ehci_hcd e1000 usbcore usb_common ata_piix libata virtio_pci virtio_ring virtio scsi_mod floppy +[ 28.796016] CPU: 0 PID: 1148 Comm: ld-linux-x86-64 Not tainted +4.4.0-rc1+ #24 +[ 28.796016] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.8.1-20150318_183358- 04/01/2014 +[ 28.796016] task: ffff8800352561c0 ti: ffff88003592c000 task.ti: ffff88003592c000 +[ 28.796016] RIP: 0010:[] [] putname+0x43/0x60 +[ 28.796016] RSP: 0018:ffff88003592fe88 EFLAGS: 00010246 +[ 28.796016] RAX: 0000000000000000 RBX: ffff8800352561c0 RCX: 0000000000000001 +[ 28.796016] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff88003784f000 +[ 28.796016] RBP: ffff88003592ff08 R08: 0000000000000001 R09: 0000000000000000 +[ 28.796016] R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000000 +[ 28.796016] R13: 000000000000047c R14: ffff88003784f000 R15: ffff8800358c4a00 +[ 28.796016] FS: 0000000000000000(0000) GS:ffff88003fc00000(0000) knlGS:0000000000000000 +[ 28.796016] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 28.796016] CR2: 00007ffd583bc2d9 CR3: 0000000035a99000 CR4: 00000000000406f0 +[ 28.796016] Stack: +[ 28.796016] ffffffff8121045d ffffffff812102d3 ffff8800352561c0 ffff880035a91660 +[ 28.796016] ffff8800008a9880 0000000000000000 ffffffff81a49940 00ffffff81218684 +[ 28.796016] ffff8800352561c0 000000000000047c 0000000000000000 ffff880035b36d80 +[ 28.796016] Call Trace: +[ 28.796016] [] ? do_execveat_common.isra.34+0x74d/0x930 +[ 28.796016] [] ? do_execveat_common.isra.34+0x5c3/0x930 +[ 28.796016] [] do_execve+0x2c/0x30 +[ 28.796016] [] call_usermodehelper_exec_async+0xf0/0x140 +[ 28.796016] [] ? umh_complete+0x40/0x40 +[ 28.796016] [] ret_from_fork+0x3f/0x70 +[ 28.796016] Code: 48 8d 47 1c 48 89 e5 53 48 8b 37 48 89 fb 48 39 c6 74 1a 48 8b 3d 7e e9 8f 00 e8 49 fa fc ff 48 89 df e8 f1 01 fd ff 5b 5d f3 c3 <0f> 0b 48 89 fe 48 8b 3d 61 e9 8f 00 e8 2c fa fc ff 5b 5d eb e9 +[ 28.796016] RIP [] putname+0x43/0x60 +[ 28.796016] RSP + +Fixes: 193125dbd8eb ("net: Introduce VRF device driver") +Signed-off-by: Nikolay Aleksandrov +Acked-by: David Ahern +Signed-off-by: David S. Miller +[bwh: For 4.3, retain the kfree() on failure] +Signed-off-by: Ben Hutchings +Acked-by: David S. Miller +Acked-by: David Ahern +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/vrf.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/vrf.c ++++ b/drivers/net/vrf.c +@@ -608,7 +608,6 @@ static int vrf_newlink(struct net *src_n + + out_fail: + kfree(vrf_ptr); +- free_netdev(dev); + return err; + } +