From: Greg Kroah-Hartman Date: Sat, 22 Jul 2017 13:02:08 +0000 (+0200) Subject: 4.12-stable patches X-Git-Tag: v3.18.63~46 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dc91de312746f3d5fd17bc114bf665d40daa96f1;p=thirdparty%2Fkernel%2Fstable-queue.git 4.12-stable patches added patches: ath9k-fix-an-invalid-pointer-dereference-in-ath9k_rng_stop.patch ath9k-fix-tx99-bus-error.patch ath9k-fix-tx99-use-after-free.patch iwlwifi-mvm-fix-the-recovery-flow-while-connecting.patch nfc-add-sockaddr-length-checks-before-accessing-sa_family-in-bind-handlers.patch nfc-ensure-presence-of-required-attributes-in-the-activate_target-handler.patch nfc-fix-broken-device-allocation.patch nfc-fix-the-sockaddr-length-sanitization-in-llcp_sock_connect.patch nfc-nfcmrvl-do-not-use-device-managed-resources.patch nfc-nfcmrvl-fix-firmware-management-initialisation.patch nfc-nfcmrvl-use-nfc-device-for-firmware-download.patch nfc-nfcmrvl_uart-add-missing-tty-device-sanity-check.patch thermal-cpu_cooling-avoid-accessing-potentially-freed-structures.patch thermal-max77620-fix-device-node-reference-imbalance.patch --- diff --git a/queue-4.12/ath9k-fix-an-invalid-pointer-dereference-in-ath9k_rng_stop.patch b/queue-4.12/ath9k-fix-an-invalid-pointer-dereference-in-ath9k_rng_stop.patch new file mode 100644 index 00000000000..bceb48eaf68 --- /dev/null +++ b/queue-4.12/ath9k-fix-an-invalid-pointer-dereference-in-ath9k_rng_stop.patch @@ -0,0 +1,66 @@ +From 07246c115801c27652700e3679bb58661ef7ed65 Mon Sep 17 00:00:00 2001 +From: Miaoqing Pan +Date: Tue, 27 Jun 2017 17:31:53 +0300 +Subject: ath9k: fix an invalid pointer dereference in ath9k_rng_stop() + +From: Miaoqing Pan + +commit 07246c115801c27652700e3679bb58661ef7ed65 upstream. + +The bug was triggered when do suspend/resuming continuously +on Dell XPS L322X/0PJHXN version 9333 (2013) with kernel +4.12.0-041200rc4-generic. But can't reproduce on DELL +E5440 + AR9300 PCIE chips. + +The warning is caused by accessing invalid pointer sc->rng_task. +sc->rng_task is not be cleared after kthread_stop(sc->rng_task) +be called in ath9k_rng_stop(). Because the kthread is stopped +before ath9k_rng_kthread() be scheduled. + +So set sc->rng_task to null after kthread_stop(sc->rng_task) to +resolve this issue. + +WARNING: CPU: 0 PID: 984 at linux/kernel/kthread.c:71 kthread_stop+0xf1/0x100 +CPU: 0 PID: 984 Comm: NetworkManager Not tainted 4.12.0-041200rc4-generic #201706042031 +Hardware name: Dell Inc. Dell System XPS L322X/0PJHXN, BIOS A09 05/15/2013 +task: ffff950170fdda00 task.stack: ffffa22c01538000 +RIP: 0010:kthread_stop+0xf1/0x100 +RSP: 0018:ffffa22c0153b5b0 EFLAGS: 00010246 +RAX: ffffffffa6257800 RBX: ffff950171b79560 RCX: 0000000000000000 +RDX: 0000000080000000 RSI: 000000007fffffff RDI: ffff9500ac9a9680 +RBP: ffffa22c0153b5c8 R08: 0000000000000000 R09: 0000000000000000 +R10: ffffa22c0153b648 R11: ffff9501768004b8 R12: ffff9500ac9a9680 +R13: ffff950171b79f70 R14: ffff950171b78780 R15: ffff9501749dc018 +FS: 00007f0d6bfd5540(0000) GS:ffff95017f200000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007fc190161a08 CR3: 0000000232906000 CR4: 00000000001406f0 +Call Trace: + ath9k_rng_stop+0x1a/0x20 [ath9k] + ath9k_stop+0x3b/0x1d0 [ath9k] + drv_stop+0x33/0xf0 [mac80211] + ieee80211_stop_device+0x43/0x50 [mac80211] + ieee80211_do_stop+0x4f2/0x810 [mac80211] + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=196043 +Reported-by: Giulio Genovese +Tested-by: Giulio Genovese +Signed-off-by: Miaoqing Pan +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/rng.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath9k/rng.c ++++ b/drivers/net/wireless/ath/ath9k/rng.c +@@ -120,6 +120,8 @@ void ath9k_rng_start(struct ath_softc *s + + void ath9k_rng_stop(struct ath_softc *sc) + { +- if (sc->rng_task) ++ if (sc->rng_task) { + kthread_stop(sc->rng_task); ++ sc->rng_task = NULL; ++ } + } diff --git a/queue-4.12/ath9k-fix-tx99-bus-error.patch b/queue-4.12/ath9k-fix-tx99-bus-error.patch new file mode 100644 index 00000000000..a2bf20e2819 --- /dev/null +++ b/queue-4.12/ath9k-fix-tx99-bus-error.patch @@ -0,0 +1,31 @@ +From bde717ab473668377fc65872398a102d40cb2d58 Mon Sep 17 00:00:00 2001 +From: Miaoqing Pan +Date: Tue, 27 Jun 2017 17:31:51 +0300 +Subject: ath9k: fix tx99 bus error + +From: Miaoqing Pan + +commit bde717ab473668377fc65872398a102d40cb2d58 upstream. + +The hard coded register 0x9864 and 0x9924 are invalid +for ar9300 chips. + +Signed-off-by: Miaoqing Pan +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/ar9003_phy.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c +@@ -1821,8 +1821,6 @@ static void ar9003_hw_spectral_scan_wait + static void ar9003_hw_tx99_start(struct ath_hw *ah, u32 qnum) + { + REG_SET_BIT(ah, AR_PHY_TEST, PHY_AGC_CLR); +- REG_SET_BIT(ah, 0x9864, 0x7f000); +- REG_SET_BIT(ah, 0x9924, 0x7f00fe); + REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); + REG_WRITE(ah, AR_CR, AR_CR_RXD); + REG_WRITE(ah, AR_DLCL_IFS(qnum), 0); diff --git a/queue-4.12/ath9k-fix-tx99-use-after-free.patch b/queue-4.12/ath9k-fix-tx99-use-after-free.patch new file mode 100644 index 00000000000..27e7b361260 --- /dev/null +++ b/queue-4.12/ath9k-fix-tx99-use-after-free.patch @@ -0,0 +1,62 @@ +From cf8ce1ea61b75712a154c93e40f2a5af2e4dd997 Mon Sep 17 00:00:00 2001 +From: Miaoqing Pan +Date: Tue, 27 Jun 2017 17:31:49 +0300 +Subject: ath9k: fix tx99 use after free + +From: Miaoqing Pan + +commit cf8ce1ea61b75712a154c93e40f2a5af2e4dd997 upstream. + +One scenario that could lead to UAF is two threads writing +simultaneously to the "tx99" debug file. One of them would +set the "start" value to true and follow to ath9k_tx99_init(). +Inside the function it would set the sc->tx99_state to true +after allocating sc->tx99skb. Then, the other thread would +execute write_file_tx99() and call ath9k_tx99_deinit(). +sc->tx99_state would be freed. After that, the first thread +would continue inside ath9k_tx99_init() and call +r = ath9k_tx99_send(sc, sc->tx99_skb, &txctl); +that would make use of the freed sc->tx99_skb memory. + +Signed-off-by: Miaoqing Pan +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/tx99.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/tx99.c ++++ b/drivers/net/wireless/ath/ath9k/tx99.c +@@ -189,22 +189,27 @@ static ssize_t write_file_tx99(struct fi + if (strtobool(buf, &start)) + return -EINVAL; + ++ mutex_lock(&sc->mutex); ++ + if (start == sc->tx99_state) { + if (!start) +- return count; ++ goto out; + ath_dbg(common, XMIT, "Resetting TX99\n"); + ath9k_tx99_deinit(sc); + } + + if (!start) { + ath9k_tx99_deinit(sc); +- return count; ++ goto out; + } + + r = ath9k_tx99_init(sc); +- if (r) ++ if (r) { ++ mutex_unlock(&sc->mutex); + return r; +- ++ } ++out: ++ mutex_unlock(&sc->mutex); + return count; + } + diff --git a/queue-4.12/iwlwifi-mvm-fix-the-recovery-flow-while-connecting.patch b/queue-4.12/iwlwifi-mvm-fix-the-recovery-flow-while-connecting.patch new file mode 100644 index 00000000000..3267a764776 --- /dev/null +++ b/queue-4.12/iwlwifi-mvm-fix-the-recovery-flow-while-connecting.patch @@ -0,0 +1,84 @@ +From 6b28f9784c394f0692e160f81b07c82cb64af160 Mon Sep 17 00:00:00 2001 +From: Emmanuel Grumbach +Date: Fri, 5 May 2017 08:51:24 +0300 +Subject: iwlwifi: mvm: fix the recovery flow while connecting + +From: Emmanuel Grumbach + +commit 6b28f9784c394f0692e160f81b07c82cb64af160 upstream. + +In BSS mode in the disconnection flow, mac80211 removes +the AP station before the vif is set to unassociated. +Our firmware wants it the other way around: first set +the vif as unassociated, and then remove the AP station. + +In order to bridge between those two different behaviors, +iwlmvm doesn't remove the station from the firmware when +mac80211 removes it, but only after the vif is set to +unassociated. The implementation is in +iwl_mvm_bss_info_changed_station: + +if (assoc state was modified && mvmvif->ap_sta_id is VALID + && assoc state is now UNASSC) + remove_the_station_from_the_firmware() + +During the recovery flow, mac80211 re-adds the AP station +and then reconfigures the vif. Since the vif is not +associated, and then, we enter the if above (which was +intended to be taken in the disconnection flow only) and +remove the station we just added. This defeats the +recovery flow. + +Fix this by not removing the AP station in this flow if +we are in recovery flow. + +Signed-off-by: Emmanuel Grumbach +Signed-off-by: Luca Coelho +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 32 +++++++++++++++++----- + 1 file changed, 25 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +@@ -1974,14 +1974,32 @@ static void iwl_mvm_bss_info_changed_sta + WARN_ONCE(iwl_mvm_sf_update(mvm, vif, false), + "Failed to update SF upon disassociation\n"); + +- /* remove AP station now that the MAC is unassoc */ +- ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); +- if (ret) +- IWL_ERR(mvm, "failed to remove AP station\n"); ++ /* ++ * If we get an assert during the connection (after the ++ * station has been added, but before the vif is set ++ * to associated), mac80211 will re-add the station and ++ * then configure the vif. Since the vif is not ++ * associated, we would remove the station here and ++ * this would fail the recovery. ++ */ ++ if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, ++ &mvm->status)) { ++ /* ++ * Remove AP station now that ++ * the MAC is unassoc ++ */ ++ ret = iwl_mvm_rm_sta_id(mvm, vif, ++ mvmvif->ap_sta_id); ++ if (ret) ++ IWL_ERR(mvm, ++ "failed to remove AP station\n"); ++ ++ if (mvm->d0i3_ap_sta_id == mvmvif->ap_sta_id) ++ mvm->d0i3_ap_sta_id = ++ IWL_MVM_INVALID_STA; ++ mvmvif->ap_sta_id = IWL_MVM_INVALID_STA; ++ } + +- if (mvm->d0i3_ap_sta_id == mvmvif->ap_sta_id) +- mvm->d0i3_ap_sta_id = IWL_MVM_INVALID_STA; +- mvmvif->ap_sta_id = IWL_MVM_INVALID_STA; + /* remove quota for this interface */ + ret = iwl_mvm_update_quotas(mvm, false, NULL); + if (ret) diff --git a/queue-4.12/nfc-add-sockaddr-length-checks-before-accessing-sa_family-in-bind-handlers.patch b/queue-4.12/nfc-add-sockaddr-length-checks-before-accessing-sa_family-in-bind-handlers.patch new file mode 100644 index 00000000000..4f2e4394f37 --- /dev/null +++ b/queue-4.12/nfc-add-sockaddr-length-checks-before-accessing-sa_family-in-bind-handlers.patch @@ -0,0 +1,45 @@ +From f6a5885fc4d68e7f25ffb42b9d8d80aebb3bacbb Mon Sep 17 00:00:00 2001 +From: Mateusz Jurczyk +Date: Tue, 13 Jun 2017 18:44:28 +0200 +Subject: NFC: Add sockaddr length checks before accessing sa_family in bind handlers + +From: Mateusz Jurczyk + +commit f6a5885fc4d68e7f25ffb42b9d8d80aebb3bacbb upstream. + +Verify that the caller-provided sockaddr structure is large enough to +contain the sa_family field, before accessing it in bind() handlers of the +AF_NFC socket. Since the syscall doesn't enforce a minimum size of the +corresponding memory region, very short sockaddrs (zero or one byte long) +result in operating on uninitialized memory while referencing .sa_family. + +Signed-off-by: Mateusz Jurczyk +Signed-off-by: Samuel Ortiz +Signed-off-by: Greg Kroah-Hartman + +--- + net/nfc/llcp_sock.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/net/nfc/llcp_sock.c ++++ b/net/nfc/llcp_sock.c +@@ -77,7 +77,8 @@ static int llcp_sock_bind(struct socket + struct sockaddr_nfc_llcp llcp_addr; + int len, ret = 0; + +- if (!addr || addr->sa_family != AF_NFC) ++ if (!addr || alen < offsetofend(struct sockaddr, sa_family) || ++ addr->sa_family != AF_NFC) + return -EINVAL; + + pr_debug("sk %p addr %p family %d\n", sk, addr, addr->sa_family); +@@ -151,7 +152,8 @@ static int llcp_raw_sock_bind(struct soc + struct sockaddr_nfc_llcp llcp_addr; + int len, ret = 0; + +- if (!addr || addr->sa_family != AF_NFC) ++ if (!addr || alen < offsetofend(struct sockaddr, sa_family) || ++ addr->sa_family != AF_NFC) + return -EINVAL; + + pr_debug("sk %p addr %p family %d\n", sk, addr, addr->sa_family); diff --git a/queue-4.12/nfc-ensure-presence-of-required-attributes-in-the-activate_target-handler.patch b/queue-4.12/nfc-ensure-presence-of-required-attributes-in-the-activate_target-handler.patch new file mode 100644 index 00000000000..a620b04b23b --- /dev/null +++ b/queue-4.12/nfc-ensure-presence-of-required-attributes-in-the-activate_target-handler.patch @@ -0,0 +1,37 @@ +From a0323b979f81ad2deb2c8836eab506534891876a Mon Sep 17 00:00:00 2001 +From: Mateusz Jurczyk +Date: Wed, 24 May 2017 12:42:26 +0200 +Subject: nfc: Ensure presence of required attributes in the activate_target handler + +From: Mateusz Jurczyk + +commit a0323b979f81ad2deb2c8836eab506534891876a upstream. + +Check that the NFC_ATTR_TARGET_INDEX and NFC_ATTR_PROTOCOLS attributes (in +addition to NFC_ATTR_DEVICE_INDEX) are provided by the netlink client +prior to accessing them. This prevents potential unhandled NULL pointer +dereference exceptions which can be triggered by malicious user-mode +programs, if they omit one or both of these attributes. + +Signed-off-by: Mateusz Jurczyk +Acked-by: Kees Cook +Signed-off-by: Samuel Ortiz +Signed-off-by: Greg Kroah-Hartman + +--- + net/nfc/netlink.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/nfc/netlink.c ++++ b/net/nfc/netlink.c +@@ -907,7 +907,9 @@ static int nfc_genl_activate_target(stru + u32 device_idx, target_idx, protocol; + int rc; + +- if (!info->attrs[NFC_ATTR_DEVICE_INDEX]) ++ if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || ++ !info->attrs[NFC_ATTR_TARGET_INDEX] || ++ !info->attrs[NFC_ATTR_PROTOCOLS]) + return -EINVAL; + + device_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); diff --git a/queue-4.12/nfc-fix-broken-device-allocation.patch b/queue-4.12/nfc-fix-broken-device-allocation.patch new file mode 100644 index 00000000000..ad22538069b --- /dev/null +++ b/queue-4.12/nfc-fix-broken-device-allocation.patch @@ -0,0 +1,139 @@ +From 20777bc57c346b6994f465e0d8261a7fbf213a09 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 30 Mar 2017 12:15:35 +0200 +Subject: NFC: fix broken device allocation + +From: Johan Hovold + +commit 20777bc57c346b6994f465e0d8261a7fbf213a09 upstream. + +Commit 7eda8b8e9677 ("NFC: Use IDR library to assing NFC devices IDs") +moved device-id allocation and struct-device initialisation from +nfc_allocate_device() to nfc_register_device(). + +This broke just about every nfc-device-registration error path, which +continue to call nfc_free_device() that tries to put the device +reference of the now uninitialised (but zeroed) struct device: + +kobject: '(null)' (ce316420): is not initialized, yet kobject_put() is being called. + +The late struct-device initialisation also meant that various work +queues whose names are derived from the nfc device name were also +misnamed: + + 421 root 0 SW< [(null)_nci_cmd_] + 422 root 0 SW< [(null)_nci_rx_w] + 423 root 0 SW< [(null)_nci_tx_w] + +Move the id-allocation and struct-device initialisation back to +nfc_allocate_device() and fix up the single call site which did not use +nfc_free_device() in its error path. + +Fixes: 7eda8b8e9677 ("NFC: Use IDR library to assing NFC devices IDs") +Cc: Samuel Ortiz +Signed-off-by: Johan Hovold +Signed-off-by: Samuel Ortiz +Signed-off-by: Greg Kroah-Hartman + +--- + net/nfc/core.c | 31 ++++++++++++++++++------------- + net/nfc/nci/core.c | 3 +-- + 2 files changed, 19 insertions(+), 15 deletions(-) + +--- a/net/nfc/core.c ++++ b/net/nfc/core.c +@@ -982,6 +982,8 @@ static void nfc_release(struct device *d + kfree(se); + } + ++ ida_simple_remove(&nfc_index_ida, dev->idx); ++ + kfree(dev); + } + +@@ -1056,6 +1058,7 @@ struct nfc_dev *nfc_allocate_device(stru + int tx_headroom, int tx_tailroom) + { + struct nfc_dev *dev; ++ int rc; + + if (!ops->start_poll || !ops->stop_poll || !ops->activate_target || + !ops->deactivate_target || !ops->im_transceive) +@@ -1068,6 +1071,15 @@ struct nfc_dev *nfc_allocate_device(stru + if (!dev) + return NULL; + ++ rc = ida_simple_get(&nfc_index_ida, 0, 0, GFP_KERNEL); ++ if (rc < 0) ++ goto err_free_dev; ++ dev->idx = rc; ++ ++ dev->dev.class = &nfc_class; ++ dev_set_name(&dev->dev, "nfc%d", dev->idx); ++ device_initialize(&dev->dev); ++ + dev->ops = ops; + dev->supported_protocols = supported_protocols; + dev->tx_headroom = tx_headroom; +@@ -1090,6 +1102,11 @@ struct nfc_dev *nfc_allocate_device(stru + } + + return dev; ++ ++err_free_dev: ++ kfree(dev); ++ ++ return ERR_PTR(rc); + } + EXPORT_SYMBOL(nfc_allocate_device); + +@@ -1104,14 +1121,6 @@ int nfc_register_device(struct nfc_dev * + + pr_debug("dev_name=%s\n", dev_name(&dev->dev)); + +- dev->idx = ida_simple_get(&nfc_index_ida, 0, 0, GFP_KERNEL); +- if (dev->idx < 0) +- return dev->idx; +- +- dev->dev.class = &nfc_class; +- dev_set_name(&dev->dev, "nfc%d", dev->idx); +- device_initialize(&dev->dev); +- + mutex_lock(&nfc_devlist_mutex); + nfc_devlist_generation++; + rc = device_add(&dev->dev); +@@ -1149,12 +1158,10 @@ EXPORT_SYMBOL(nfc_register_device); + */ + void nfc_unregister_device(struct nfc_dev *dev) + { +- int rc, id; ++ int rc; + + pr_debug("dev_name=%s\n", dev_name(&dev->dev)); + +- id = dev->idx; +- + if (dev->rfkill) { + rfkill_unregister(dev->rfkill); + rfkill_destroy(dev->rfkill); +@@ -1179,8 +1186,6 @@ void nfc_unregister_device(struct nfc_de + nfc_devlist_generation++; + device_del(&dev->dev); + mutex_unlock(&nfc_devlist_mutex); +- +- ida_simple_remove(&nfc_index_ida, id); + } + EXPORT_SYMBOL(nfc_unregister_device); + +--- a/net/nfc/nci/core.c ++++ b/net/nfc/nci/core.c +@@ -1173,8 +1173,7 @@ struct nci_dev *nci_allocate_device(stru + return ndev; + + free_nfc: +- kfree(ndev->nfc_dev); +- ++ nfc_free_device(ndev->nfc_dev); + free_nci: + kfree(ndev); + return NULL; diff --git a/queue-4.12/nfc-fix-the-sockaddr-length-sanitization-in-llcp_sock_connect.patch b/queue-4.12/nfc-fix-the-sockaddr-length-sanitization-in-llcp_sock_connect.patch new file mode 100644 index 00000000000..7ea91ce7727 --- /dev/null +++ b/queue-4.12/nfc-fix-the-sockaddr-length-sanitization-in-llcp_sock_connect.patch @@ -0,0 +1,51 @@ +From 608c4adfcabab220142ee335a2a003ccd1c0b25b Mon Sep 17 00:00:00 2001 +From: Mateusz Jurczyk +Date: Wed, 24 May 2017 12:26:20 +0200 +Subject: nfc: Fix the sockaddr length sanitization in llcp_sock_connect + +From: Mateusz Jurczyk + +commit 608c4adfcabab220142ee335a2a003ccd1c0b25b upstream. + +Fix the sockaddr length verification in the connect() handler of NFC/LLCP +sockets, to compare against the size of the actual structure expected on +input (sockaddr_nfc_llcp) instead of its shorter version (sockaddr_nfc). + +Both structures are defined in include/uapi/linux/nfc.h. The fields +specific to the _llcp extended struct are as follows: + + 276 __u8 dsap; /* Destination SAP, if known */ + 277 __u8 ssap; /* Source SAP to be bound to */ + 278 char service_name[NFC_LLCP_MAX_SERVICE_NAME]; /* Service name URI */; + 279 size_t service_name_len; + +If the caller doesn't provide a sufficiently long sockaddr buffer, these +fields remain uninitialized (and they currently originate from the stack +frame of the top-level sys_connect handler). They are then copied by +llcp_sock_connect() into internal storage (nfc_llcp_sock structure), and +could be subsequently read back through the user-mode getsockname() +function (handled by llcp_sock_getname()). This would result in the +disclosure of up to ~70 uninitialized bytes from the kernel stack to +user-mode clients capable of creating AFC_NFC sockets. + +Signed-off-by: Mateusz Jurczyk +Acked-by: Kees Cook +Signed-off-by: Samuel Ortiz +Signed-off-by: Greg Kroah-Hartman + +--- + net/nfc/llcp_sock.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/net/nfc/llcp_sock.c ++++ b/net/nfc/llcp_sock.c +@@ -662,8 +662,7 @@ static int llcp_sock_connect(struct sock + + pr_debug("sock %p sk %p flags 0x%x\n", sock, sk, flags); + +- if (!addr || len < sizeof(struct sockaddr_nfc) || +- addr->sa_family != AF_NFC) ++ if (!addr || len < sizeof(*addr) || addr->sa_family != AF_NFC) + return -EINVAL; + + if (addr->service_name_len == 0 && addr->dsap == 0) diff --git a/queue-4.12/nfc-nfcmrvl-do-not-use-device-managed-resources.patch b/queue-4.12/nfc-nfcmrvl-do-not-use-device-managed-resources.patch new file mode 100644 index 00000000000..e2224dea05e --- /dev/null +++ b/queue-4.12/nfc-nfcmrvl-do-not-use-device-managed-resources.patch @@ -0,0 +1,90 @@ +From 0cbe40112f42cf5e008f9127f6cd5952ba3946c7 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 30 Mar 2017 12:15:37 +0200 +Subject: NFC: nfcmrvl: do not use device-managed resources + +From: Johan Hovold + +commit 0cbe40112f42cf5e008f9127f6cd5952ba3946c7 upstream. + +This specifically fixes resource leaks in the registration error paths. + +Device-managed resources is a bad fit for this driver as devices can be +registered from the n_nci line discipline. Firstly, a tty may not even +have a corresponding device (should it be part of a Unix98 pty) +something which would lead to a NULL-pointer dereference when +registering resources. + +Secondly, if the tty has a class device, its lifetime exceeds that of +the line discipline, which means that resources would leak every time +the line discipline is closed (or if registration fails). + +Currently, the devres interface was only being used to request a reset +gpio despite the fact that it was already explicitly freed in +nfcmrvl_nci_unregister_dev() (along with the private data), something +which also prevented the resource leak at close. + +Note that the driver treats gpio number 0 as invalid despite it being +perfectly valid. This will be addressed in a follow-up patch. + +Fixes: b2fe288eac72 ("NFC: nfcmrvl: free reset gpio") +Fixes: 4a2b947f56b3 ("NFC: nfcmrvl: add chip reset management") +Cc: Vincent Cuissard +Signed-off-by: Johan Hovold +Signed-off-by: Samuel Ortiz +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/nfc/nfcmrvl/main.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +--- a/drivers/nfc/nfcmrvl/main.c ++++ b/drivers/nfc/nfcmrvl/main.c +@@ -124,12 +124,13 @@ struct nfcmrvl_private *nfcmrvl_nci_regi + memcpy(&priv->config, pdata, sizeof(*pdata)); + + if (priv->config.reset_n_io) { +- rc = devm_gpio_request_one(dev, +- priv->config.reset_n_io, +- GPIOF_OUT_INIT_LOW, +- "nfcmrvl_reset_n"); +- if (rc < 0) ++ rc = gpio_request_one(priv->config.reset_n_io, ++ GPIOF_OUT_INIT_LOW, ++ "nfcmrvl_reset_n"); ++ if (rc < 0) { ++ priv->config.reset_n_io = 0; + nfc_err(dev, "failed to request reset_n io\n"); ++ } + } + + if (phy == NFCMRVL_PHY_SPI) { +@@ -154,7 +155,7 @@ struct nfcmrvl_private *nfcmrvl_nci_regi + if (!priv->ndev) { + nfc_err(dev, "nci_allocate_device failed\n"); + rc = -ENOMEM; +- goto error; ++ goto error_free_gpio; + } + + nci_set_drvdata(priv->ndev, priv); +@@ -179,7 +180,9 @@ struct nfcmrvl_private *nfcmrvl_nci_regi + + error_free_dev: + nci_free_device(priv->ndev); +-error: ++error_free_gpio: ++ if (priv->config.reset_n_io) ++ gpio_free(priv->config.reset_n_io); + kfree(priv); + return ERR_PTR(rc); + } +@@ -195,7 +198,7 @@ void nfcmrvl_nci_unregister_dev(struct n + nfcmrvl_fw_dnld_deinit(priv); + + if (priv->config.reset_n_io) +- devm_gpio_free(priv->dev, priv->config.reset_n_io); ++ gpio_free(priv->config.reset_n_io); + + nci_unregister_device(ndev); + nci_free_device(ndev); diff --git a/queue-4.12/nfc-nfcmrvl-fix-firmware-management-initialisation.patch b/queue-4.12/nfc-nfcmrvl-fix-firmware-management-initialisation.patch new file mode 100644 index 00000000000..e91fee329f9 --- /dev/null +++ b/queue-4.12/nfc-nfcmrvl-fix-firmware-management-initialisation.patch @@ -0,0 +1,68 @@ +From 45dd39b974f6632222dd5cdcbea7358a077ab0b0 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 30 Mar 2017 12:15:39 +0200 +Subject: NFC: nfcmrvl: fix firmware-management initialisation + +From: Johan Hovold + +commit 45dd39b974f6632222dd5cdcbea7358a077ab0b0 upstream. + +The nci-device was never deregistered in the event that +fw-initialisation failed. + +Fix this by moving the firmware initialisation before device +registration since the firmware work queue should be available before +registering. + +Note that this depends on a recent fix that moved device-name +initialisation back to to nci_allocate_device() as the +firmware-workqueue name is now derived from the nfc-device name. + +Fixes: 3194c6870158 ("NFC: nfcmrvl: add firmware download support") +Cc: Vincent Cuissard +Signed-off-by: Johan Hovold +Signed-off-by: Samuel Ortiz +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/nfc/nfcmrvl/main.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +--- a/drivers/nfc/nfcmrvl/main.c ++++ b/drivers/nfc/nfcmrvl/main.c +@@ -158,26 +158,28 @@ struct nfcmrvl_private *nfcmrvl_nci_regi + goto error_free_gpio; + } + ++ rc = nfcmrvl_fw_dnld_init(priv); ++ if (rc) { ++ nfc_err(dev, "failed to initialize FW download %d\n", rc); ++ goto error_free_dev; ++ } ++ + nci_set_drvdata(priv->ndev, priv); + + rc = nci_register_device(priv->ndev); + if (rc) { + nfc_err(dev, "nci_register_device failed %d\n", rc); +- goto error_free_dev; ++ goto error_fw_dnld_deinit; + } + + /* Ensure that controller is powered off */ + nfcmrvl_chip_halt(priv); + +- rc = nfcmrvl_fw_dnld_init(priv); +- if (rc) { +- nfc_err(dev, "failed to initialize FW download %d\n", rc); +- goto error_free_dev; +- } +- + nfc_info(dev, "registered with nci successfully\n"); + return priv; + ++error_fw_dnld_deinit: ++ nfcmrvl_fw_dnld_deinit(priv); + error_free_dev: + nci_free_device(priv->ndev); + error_free_gpio: diff --git a/queue-4.12/nfc-nfcmrvl-use-nfc-device-for-firmware-download.patch b/queue-4.12/nfc-nfcmrvl-use-nfc-device-for-firmware-download.patch new file mode 100644 index 00000000000..149869127bf --- /dev/null +++ b/queue-4.12/nfc-nfcmrvl-use-nfc-device-for-firmware-download.patch @@ -0,0 +1,59 @@ +From e5834ac22948169bbd7c45996d8d4905edd20f5e Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 30 Mar 2017 12:15:38 +0200 +Subject: NFC: nfcmrvl: use nfc-device for firmware download + +From: Johan Hovold + +commit e5834ac22948169bbd7c45996d8d4905edd20f5e upstream. + +Use the nfc- rather than phy-device in firmware-management code that +needs a valid struct device. + +This specifically fixes a NULL-pointer dereference in +nfcmrvl_fw_dnld_init() during registration when the underlying tty is +one end of a Unix98 pty. + +Note that the driver still uses the phy device for any debugging, which +is fine for now. + +Fixes: 3194c6870158 ("NFC: nfcmrvl: add firmware download support") +Cc: Vincent Cuissard +Signed-off-by: Johan Hovold +Signed-off-by: Samuel Ortiz +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/nfc/nfcmrvl/fw_dnld.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/nfc/nfcmrvl/fw_dnld.c ++++ b/drivers/nfc/nfcmrvl/fw_dnld.c +@@ -458,7 +458,7 @@ int nfcmrvl_fw_dnld_init(struct nfcmrvl_ + + INIT_WORK(&priv->fw_dnld.rx_work, fw_dnld_rx_work); + snprintf(name, sizeof(name), "%s_nfcmrvl_fw_dnld_rx_wq", +- dev_name(priv->dev)); ++ dev_name(&priv->ndev->nfc_dev->dev)); + priv->fw_dnld.rx_wq = create_singlethread_workqueue(name); + if (!priv->fw_dnld.rx_wq) + return -ENOMEM; +@@ -495,6 +495,7 @@ int nfcmrvl_fw_dnld_start(struct nci_dev + { + struct nfcmrvl_private *priv = nci_get_drvdata(ndev); + struct nfcmrvl_fw_dnld *fw_dnld = &priv->fw_dnld; ++ int res; + + if (!priv->support_fw_dnld) + return -ENOTSUPP; +@@ -510,7 +511,9 @@ int nfcmrvl_fw_dnld_start(struct nci_dev + */ + + /* Retrieve FW binary */ +- if (request_firmware(&fw_dnld->fw, firmware_name, priv->dev) < 0) { ++ res = request_firmware(&fw_dnld->fw, firmware_name, ++ &ndev->nfc_dev->dev); ++ if (res < 0) { + nfc_err(priv->dev, "failed to retrieve FW %s", firmware_name); + return -ENOENT; + } diff --git a/queue-4.12/nfc-nfcmrvl_uart-add-missing-tty-device-sanity-check.patch b/queue-4.12/nfc-nfcmrvl_uart-add-missing-tty-device-sanity-check.patch new file mode 100644 index 00000000000..ecca1b162d3 --- /dev/null +++ b/queue-4.12/nfc-nfcmrvl_uart-add-missing-tty-device-sanity-check.patch @@ -0,0 +1,54 @@ +From 15e0c59f1535926a939d1df66d6edcf997d7c1b9 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 30 Mar 2017 12:15:36 +0200 +Subject: NFC: nfcmrvl_uart: add missing tty-device sanity check + +From: Johan Hovold + +commit 15e0c59f1535926a939d1df66d6edcf997d7c1b9 upstream. + +Make sure to check the tty-device pointer before trying to access the +parent device to avoid dereferencing a NULL-pointer when the tty is one +end of a Unix98 pty. + +Fixes: e097dc624f78 ("NFC: nfcmrvl: add UART driver") +Cc: Vincent Cuissard +Signed-off-by: Johan Hovold +Signed-off-by: Samuel Ortiz +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/nfc/nfcmrvl/uart.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/nfc/nfcmrvl/uart.c ++++ b/drivers/nfc/nfcmrvl/uart.c +@@ -109,6 +109,7 @@ static int nfcmrvl_nci_uart_open(struct + struct nfcmrvl_private *priv; + struct nfcmrvl_platform_data *pdata = NULL; + struct nfcmrvl_platform_data config; ++ struct device *dev = nu->tty->dev; + + /* + * Platform data cannot be used here since usually it is already used +@@ -116,9 +117,8 @@ static int nfcmrvl_nci_uart_open(struct + * and check if DT entries were added. + */ + +- if (nu->tty->dev->parent && nu->tty->dev->parent->of_node) +- if (nfcmrvl_uart_parse_dt(nu->tty->dev->parent->of_node, +- &config) == 0) ++ if (dev && dev->parent && dev->parent->of_node) ++ if (nfcmrvl_uart_parse_dt(dev->parent->of_node, &config) == 0) + pdata = &config; + + if (!pdata) { +@@ -131,7 +131,7 @@ static int nfcmrvl_nci_uart_open(struct + } + + priv = nfcmrvl_nci_register_dev(NFCMRVL_PHY_UART, nu, &uart_ops, +- nu->tty->dev, pdata); ++ dev, pdata); + if (IS_ERR(priv)) + return PTR_ERR(priv); + diff --git a/queue-4.12/series b/queue-4.12/series index 44cc16a107c..e0de56a609b 100644 --- a/queue-4.12/series +++ b/queue-4.12/series @@ -1,3 +1,17 @@ disable-new-gcc-7.1.1-warnings-for-now.patch ir-core-fix-gcc-7-warning-on-bool-arithmetic.patch s5p-jpeg-don-t-return-a-random-width-height.patch +thermal-max77620-fix-device-node-reference-imbalance.patch +thermal-cpu_cooling-avoid-accessing-potentially-freed-structures.patch +ath9k-fix-tx99-use-after-free.patch +ath9k-fix-tx99-bus-error.patch +ath9k-fix-an-invalid-pointer-dereference-in-ath9k_rng_stop.patch +iwlwifi-mvm-fix-the-recovery-flow-while-connecting.patch +nfc-fix-broken-device-allocation.patch +nfc-nfcmrvl_uart-add-missing-tty-device-sanity-check.patch +nfc-nfcmrvl-do-not-use-device-managed-resources.patch +nfc-nfcmrvl-use-nfc-device-for-firmware-download.patch +nfc-nfcmrvl-fix-firmware-management-initialisation.patch +nfc-ensure-presence-of-required-attributes-in-the-activate_target-handler.patch +nfc-fix-the-sockaddr-length-sanitization-in-llcp_sock_connect.patch +nfc-add-sockaddr-length-checks-before-accessing-sa_family-in-bind-handlers.patch diff --git a/queue-4.12/thermal-cpu_cooling-avoid-accessing-potentially-freed-structures.patch b/queue-4.12/thermal-cpu_cooling-avoid-accessing-potentially-freed-structures.patch new file mode 100644 index 00000000000..b20f7ceb289 --- /dev/null +++ b/queue-4.12/thermal-cpu_cooling-avoid-accessing-potentially-freed-structures.patch @@ -0,0 +1,39 @@ +From 289d72afddf83440117c35d864bf0c6309c1d011 Mon Sep 17 00:00:00 2001 +From: Viresh Kumar +Date: Tue, 25 Apr 2017 15:57:08 +0530 +Subject: thermal: cpu_cooling: Avoid accessing potentially freed structures + +From: Viresh Kumar + +commit 289d72afddf83440117c35d864bf0c6309c1d011 upstream. + +After the lock is dropped, it is possible that the cpufreq_dev gets +freed before we call get_level() and that can cause kernel to crash. + +Drop the lock after we are done using the structure. + +Fixes: 02373d7c69b4 ("thermal: cpu_cooling: fix lockdep problems in cpu_cooling") +Signed-off-by: Viresh Kumar +Reviewed-by: Lukasz Luba +Tested-by: Lukasz Luba +Signed-off-by: Eduardo Valentin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/thermal/cpu_cooling.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/thermal/cpu_cooling.c ++++ b/drivers/thermal/cpu_cooling.c +@@ -153,8 +153,10 @@ unsigned long cpufreq_cooling_get_level( + mutex_lock(&cooling_list_lock); + list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) { + if (cpumask_test_cpu(cpu, &cpufreq_dev->allowed_cpus)) { ++ unsigned long level = get_level(cpufreq_dev, freq); ++ + mutex_unlock(&cooling_list_lock); +- return get_level(cpufreq_dev, freq); ++ return level; + } + } + mutex_unlock(&cooling_list_lock); diff --git a/queue-4.12/thermal-max77620-fix-device-node-reference-imbalance.patch b/queue-4.12/thermal-max77620-fix-device-node-reference-imbalance.patch new file mode 100644 index 00000000000..7a3e4f8a57b --- /dev/null +++ b/queue-4.12/thermal-max77620-fix-device-node-reference-imbalance.patch @@ -0,0 +1,63 @@ +From c592fafbdbb6b1279b76a54722d1465ca77e5bde Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 6 Jun 2017 17:59:03 +0200 +Subject: thermal: max77620: fix device-node reference imbalance + +From: Johan Hovold + +commit c592fafbdbb6b1279b76a54722d1465ca77e5bde upstream. + +The thermal child device reuses the parent MFD-device device-tree node +when registering a thermal zone, but did not take a reference to the +node. + +This leads to a reference imbalance, and potential use-after-free, when +the node reference is dropped by the platform-bus device destructor +(once for the child and later again for the parent). + +Fix this by dropping any reference already held to a device-tree node +and getting a reference to the parent's node which will be balanced on +reprobe or on platform-device release, whichever comes first. + +Note that simply clearing the of_node pointer on probe errors and on +driver unbind would not allow the use of device-managed resources as +specifically thermal_zone_of_sensor_unregister() claims that a valid +device-tree node pointer is needed during deregistration (even if it +currently does not seem to use it). + +Fixes: ec4664b3fd6d ("thermal: max77620: Add thermal driver for reporting junction temp") +Cc: Laxman Dewangan +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/thermal/max77620_thermal.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/thermal/max77620_thermal.c ++++ b/drivers/thermal/max77620_thermal.c +@@ -104,8 +104,6 @@ static int max77620_thermal_probe(struct + return -EINVAL; + } + +- pdev->dev.of_node = pdev->dev.parent->of_node; +- + mtherm->dev = &pdev->dev; + mtherm->rmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!mtherm->rmap) { +@@ -113,6 +111,14 @@ static int max77620_thermal_probe(struct + return -ENODEV; + } + ++ /* ++ * Drop any current reference to a device-tree node and get a ++ * reference to the parent's node which will be balanced on reprobe or ++ * on platform-device release. ++ */ ++ of_node_put(pdev->dev.of_node); ++ pdev->dev.of_node = of_node_get(pdev->dev.parent->of_node); ++ + mtherm->tz_device = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, + mtherm, &max77620_thermal_ops); + if (IS_ERR(mtherm->tz_device)) {