From: Greg Kroah-Hartman Date: Tue, 25 Feb 2014 16:36:59 +0000 (-0800) Subject: 3.10-stable patches X-Git-Tag: v3.10.33~47 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7fc99fab6d6b4298a7ba1907b44003a9fcecce48;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: cifs-ensure-that-uncached-writes-handle-unmapped-areas-correctly.patch cifs-fix-too-big-maxbuf-size-for-smb3-mounts.patch rtl8187-fix-regression-on-mips-without-coherent-dma.patch rtlwifi-fix-incorrect-return-from-rtl_ps_enable_nic.patch rtlwifi-rtl8192ce-fix-too-long-disable-of-irqs.patch --- diff --git a/queue-3.10/cifs-ensure-that-uncached-writes-handle-unmapped-areas-correctly.patch b/queue-3.10/cifs-ensure-that-uncached-writes-handle-unmapped-areas-correctly.patch new file mode 100644 index 00000000000..84cff81f48a --- /dev/null +++ b/queue-3.10/cifs-ensure-that-uncached-writes-handle-unmapped-areas-correctly.patch @@ -0,0 +1,98 @@ +From 5d81de8e8667da7135d3a32a964087c0faf5483f Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Fri, 14 Feb 2014 07:20:35 -0500 +Subject: cifs: ensure that uncached writes handle unmapped areas correctly + +From: Jeff Layton + +commit 5d81de8e8667da7135d3a32a964087c0faf5483f upstream. + +It's possible for userland to pass down an iovec via writev() that has a +bogus user pointer in it. If that happens and we're doing an uncached +write, then we can end up getting less bytes than we expect from the +call to iov_iter_copy_from_user. This is CVE-2014-0069 + +cifs_iovec_write isn't set up to handle that situation however. It'll +blindly keep chugging through the page array and not filling those pages +with anything useful. Worse yet, we'll later end up with a negative +number in wdata->tailsz, which will confuse the sending routines and +cause an oops at the very least. + +Fix this by having the copy phase of cifs_iovec_write stop copying data +in this situation and send the last write as a short one. At the same +time, we want to avoid sending a zero-length write to the server, so +break out of the loop and set rc to -EFAULT if that happens. This also +allows us to handle the case where no address in the iovec is valid. + +[Note: Marking this for stable on v3.4+ kernels, but kernels as old as + v2.6.38 may have a similar problem and may need similar fix] + +Reviewed-by: Pavel Shilovsky +Reported-by: Al Viro +Signed-off-by: Jeff Layton +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/file.c | 37 ++++++++++++++++++++++++++++++++++--- + 1 file changed, 34 insertions(+), 3 deletions(-) + +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -2353,7 +2353,7 @@ cifs_iovec_write(struct file *file, cons + unsigned long nr_segs, loff_t *poffset) + { + unsigned long nr_pages, i; +- size_t copied, len, cur_len; ++ size_t bytes, copied, len, cur_len; + ssize_t total_written = 0; + loff_t offset; + struct iov_iter it; +@@ -2408,14 +2408,45 @@ cifs_iovec_write(struct file *file, cons + + save_len = cur_len; + for (i = 0; i < nr_pages; i++) { +- copied = min_t(const size_t, cur_len, PAGE_SIZE); ++ bytes = min_t(const size_t, cur_len, PAGE_SIZE); + copied = iov_iter_copy_from_user(wdata->pages[i], &it, +- 0, copied); ++ 0, bytes); + cur_len -= copied; + iov_iter_advance(&it, copied); ++ /* ++ * If we didn't copy as much as we expected, then that ++ * may mean we trod into an unmapped area. Stop copying ++ * at that point. On the next pass through the big ++ * loop, we'll likely end up getting a zero-length ++ * write and bailing out of it. ++ */ ++ if (copied < bytes) ++ break; + } + cur_len = save_len - cur_len; + ++ /* ++ * If we have no data to send, then that probably means that ++ * the copy above failed altogether. That's most likely because ++ * the address in the iovec was bogus. Set the rc to -EFAULT, ++ * free anything we allocated and bail out. ++ */ ++ if (!cur_len) { ++ for (i = 0; i < nr_pages; i++) ++ put_page(wdata->pages[i]); ++ kfree(wdata); ++ rc = -EFAULT; ++ break; ++ } ++ ++ /* ++ * i + 1 now represents the number of pages we actually used in ++ * the copy phase above. Bring nr_pages down to that, and free ++ * any pages that we didn't use. ++ */ ++ for ( ; nr_pages > i + 1; nr_pages--) ++ put_page(wdata->pages[nr_pages - 1]); ++ + wdata->sync_mode = WB_SYNC_ALL; + wdata->nr_pages = nr_pages; + wdata->offset = (__u64)offset; diff --git a/queue-3.10/cifs-fix-too-big-maxbuf-size-for-smb3-mounts.patch b/queue-3.10/cifs-fix-too-big-maxbuf-size-for-smb3-mounts.patch new file mode 100644 index 00000000000..b540f5c7ae9 --- /dev/null +++ b/queue-3.10/cifs-fix-too-big-maxbuf-size-for-smb3-mounts.patch @@ -0,0 +1,78 @@ +From 2365c4eaf077c48574ab6f143960048fc0f31518 Mon Sep 17 00:00:00 2001 +From: Pavel Shilovsky +Date: Fri, 14 Feb 2014 13:31:02 +0400 +Subject: CIFS: Fix too big maxBuf size for SMB3 mounts + +From: Pavel Shilovsky + +commit 2365c4eaf077c48574ab6f143960048fc0f31518 upstream. + +SMB3 servers can respond with MaxTransactSize of more than 4M +that can cause a memory allocation error returned from kmalloc +in a lock codepath. Also the client doesn't support multicredit +requests now and allows buffer sizes of 65536 bytes only. Set +MaxTransactSize to this maximum supported value. + +Signed-off-by: Pavel Shilovsky +Acked-by: Jeff Layton +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/smb2glob.h | 3 +++ + fs/cifs/smb2ops.c | 14 ++++---------- + fs/cifs/smb2pdu.c | 3 +++ + 3 files changed, 10 insertions(+), 10 deletions(-) + +--- a/fs/cifs/smb2glob.h ++++ b/fs/cifs/smb2glob.h +@@ -55,4 +55,7 @@ + #define SMB2_NTLMV2_SESSKEY_SIZE (16) + #define SMB2_HMACSHA256_SIZE (32) + ++/* Maximum buffer size value we can send with 1 credit */ ++#define SMB2_MAX_BUFFER_SIZE 65536 ++ + #endif /* _SMB2_GLOB_H */ +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -181,11 +181,8 @@ smb2_negotiate_wsize(struct cifs_tcon *t + /* start with specified wsize, or default */ + wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE; + wsize = min_t(unsigned int, wsize, server->max_write); +- /* +- * limit write size to 2 ** 16, because we don't support multicredit +- * requests now. +- */ +- wsize = min_t(unsigned int, wsize, 2 << 15); ++ /* set it to the maximum buffer size value we can send with 1 credit */ ++ wsize = min_t(unsigned int, wsize, SMB2_MAX_BUFFER_SIZE); + + return wsize; + } +@@ -199,11 +196,8 @@ smb2_negotiate_rsize(struct cifs_tcon *t + /* start with specified rsize, or default */ + rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE; + rsize = min_t(unsigned int, rsize, server->max_read); +- /* +- * limit write size to 2 ** 16, because we don't support multicredit +- * requests now. +- */ +- rsize = min_t(unsigned int, rsize, 2 << 15); ++ /* set it to the maximum buffer size value we can send with 1 credit */ ++ rsize = min_t(unsigned int, rsize, SMB2_MAX_BUFFER_SIZE); + + return rsize; + } +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -408,6 +408,9 @@ SMB2_negotiate(const unsigned int xid, s + server->dialect = le16_to_cpu(rsp->DialectRevision); + + server->maxBuf = le32_to_cpu(rsp->MaxTransactSize); ++ /* set it to the maximum buffer size value we can send with 1 credit */ ++ server->maxBuf = min_t(unsigned int, le32_to_cpu(rsp->MaxTransactSize), ++ SMB2_MAX_BUFFER_SIZE); + server->max_read = le32_to_cpu(rsp->MaxReadSize); + server->max_write = le32_to_cpu(rsp->MaxWriteSize); + /* BB Do we need to validate the SecurityMode? */ diff --git a/queue-3.10/rtl8187-fix-regression-on-mips-without-coherent-dma.patch b/queue-3.10/rtl8187-fix-regression-on-mips-without-coherent-dma.patch new file mode 100644 index 00000000000..b5744a260b9 --- /dev/null +++ b/queue-3.10/rtl8187-fix-regression-on-mips-without-coherent-dma.patch @@ -0,0 +1,83 @@ +From b6213e413a4e0c66548153516b074df14f9d08e0 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Mon, 10 Feb 2014 22:38:28 +0100 +Subject: rtl8187: fix regression on MIPS without coherent DMA + +From: Stanislaw Gruszka + +commit b6213e413a4e0c66548153516b074df14f9d08e0 upstream. + +This patch fixes regression caused by commit a16dad77634 "MIPS: Fix +potencial corruption". That commit fixes one corruption scenario in +cost of adding another one, which actually start to cause crashes +on Yeeloong laptop when rtl8187 driver is used. + +For correct DMA read operation on machines without DMA coherence, kernel +have to invalidate cache, such it will refill later with new data that +device wrote to memory, when that data is needed to process. We can only +invalidate full cache line. Hence when cache line includes both dma +buffer and some other data (written in cache, but not yet in main +memory), the other data can not hit memory due to invalidation. That +happen on rtl8187 where struct rtl8187_priv fields are located just +before and after small buffers that are passed to USB layer and DMA +is performed on them. + +To fix the problem we align buffers and reserve space after them to make +them match cache line. + +This patch does not resolve all possible MIPS problems entirely, for +that we have to assure that we always map cache aligned buffers for DMA, +what can be complex or even not possible. But patch fixes visible and +reproducible regression and seems other possible corruptions do not +happen in practice, since Yeeloong laptop works stable without rtl8187 +driver. + +Bug report: +https://bugzilla.kernel.org/show_bug.cgi?id=54391 + +Reported-by: Petr Pisar +Bisected-by: Tom Li +Reported-and-tested-by: Tom Li +Signed-off-by: Stanislaw Gruszka +Acked-by: Larry Finger +Acked-by: Hin-Tak Leung +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/rtl818x/rtl8187/rtl8187.h | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h ++++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h +@@ -15,6 +15,8 @@ + #ifndef RTL8187_H + #define RTL8187_H + ++#include ++ + #include "rtl818x.h" + #include "leds.h" + +@@ -139,7 +141,10 @@ struct rtl8187_priv { + u8 aifsn[4]; + u8 rfkill_mask; + struct { +- __le64 buf; ++ union { ++ __le64 buf; ++ u8 dummy1[L1_CACHE_BYTES]; ++ } ____cacheline_aligned; + struct sk_buff_head queue; + } b_tx_status; /* This queue is used by both -b and non-b devices */ + struct mutex io_mutex; +@@ -147,7 +152,8 @@ struct rtl8187_priv { + u8 bits8; + __le16 bits16; + __le32 bits32; +- } *io_dmabuf; ++ u8 dummy2[L1_CACHE_BYTES]; ++ } *io_dmabuf ____cacheline_aligned; + bool rfkill_off; + u16 seqno; + }; diff --git a/queue-3.10/rtlwifi-fix-incorrect-return-from-rtl_ps_enable_nic.patch b/queue-3.10/rtlwifi-fix-incorrect-return-from-rtl_ps_enable_nic.patch new file mode 100644 index 00000000000..30c345c4ca6 --- /dev/null +++ b/queue-3.10/rtlwifi-fix-incorrect-return-from-rtl_ps_enable_nic.patch @@ -0,0 +1,35 @@ +From 2e8c5e56b307271c2dab6f8bfd1d8a3822ca2390 Mon Sep 17 00:00:00 2001 +From: Olivier Langlois +Date: Sat, 1 Feb 2014 01:11:10 -0500 +Subject: rtlwifi: Fix incorrect return from rtl_ps_enable_nic() + +From: Olivier Langlois + +commit 2e8c5e56b307271c2dab6f8bfd1d8a3822ca2390 upstream. + +rtl_ps_enable_nic() is called from loops that will loop until this function returns true or a +maximum number of retries is performed. + +hw_init() returns non-zero on error. In that situation return false to +restore the original design intent to retry hw init when it fails. + +Signed-off-by: Olivier Langlois +Acked-by: Larry Finger +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/rtlwifi/ps.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/rtlwifi/ps.c ++++ b/drivers/net/wireless/rtlwifi/ps.c +@@ -48,7 +48,7 @@ bool rtl_ps_enable_nic(struct ieee80211_ + + /*<2> Enable Adapter */ + if (rtlpriv->cfg->ops->hw_init(hw)) +- return 1; ++ return false; + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + /*<3> Enable Interrupt */ diff --git a/queue-3.10/rtlwifi-rtl8192ce-fix-too-long-disable-of-irqs.patch b/queue-3.10/rtlwifi-rtl8192ce-fix-too-long-disable-of-irqs.patch new file mode 100644 index 00000000000..21d0d90fc51 --- /dev/null +++ b/queue-3.10/rtlwifi-rtl8192ce-fix-too-long-disable-of-irqs.patch @@ -0,0 +1,118 @@ +From f78bccd79ba3cd9d9664981b501d57bdb81ab8a4 Mon Sep 17 00:00:00 2001 +From: Olivier Langlois +Date: Sat, 1 Feb 2014 01:11:09 -0500 +Subject: rtlwifi: rtl8192ce: Fix too long disable of IRQs + +From: Olivier Langlois + +commit f78bccd79ba3cd9d9664981b501d57bdb81ab8a4 upstream. + +rtl8192ce is disabling for too long the local interrupts during hw initiatialisation when performing scans + +The observable symptoms in dmesg can be: + +- underruns from ALSA playback +- clock freezes (tstamps do not change for several dmesg entries until irqs are finaly reenabled): + +[ 250.817669] rtlwifi:rtl_op_config():<0-0-0> 0x100 +[ 250.817685] rtl8192ce:_rtl92ce_phy_set_rf_power_state():<0-1-0> IPS Set eRf nic enable +[ 250.817732] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 +[ 250.817796] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 +[ 250.817910] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 +[ 250.818024] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 +[ 250.818139] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 +[ 250.818253] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 +[ 250.818367] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 +[ 250.818472] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 +[ 250.818472] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 +[ 250.818472] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 +[ 250.818472] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 +[ 250.818472] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:98053f15:10 +[ 250.818472] rtl8192ce:rtl92ce_sw_led_on():<0-1-0> LedAddr:4E ledpin=1 +[ 250.818472] rtl8192c_common:rtl92c_download_fw():<0-1-0> Firmware Version(49), Signature(0x88c1),Size(32) +[ 250.818472] rtl8192ce:rtl92ce_enable_hw_security_config():<0-1-0> PairwiseEncAlgorithm = 0 GroupEncAlgorithm = 0 +[ 250.818472] rtl8192ce:rtl92ce_enable_hw_security_config():<0-1-0> The SECR-value cc +[ 250.818472] rtl8192c_common:rtl92c_dm_check_txpower_tracking_thermal_meter():<0-1-0> Schedule TxPowerTracking direct call!! +[ 250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> rtl92c_dm_txpower_tracking_callback_thermalmeter +[ 250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> Readback Thermal Meter = 0xe pre thermal meter 0xf eeprom_thermalmeter 0xf +[ 250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> Initial pathA ele_d reg0xc80 = 0x40000000, ofdm_index=0xc +[ 250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> Initial reg0xa24 = 0x90e1317, cck_index=0xc, ch14 0 +[ 250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> Readback Thermal Meter = 0xe pre thermal meter 0xf eeprom_thermalmeter 0xf delta 0x1 delta_lck 0x0 delta_iqk 0x0 +[ 250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> <=== +[ 250.818472] rtl8192c_common:rtl92c_dm_initialize_txpower_tracking_thermalmeter():<0-1-0> pMgntInfo->txpower_tracking = 1 +[ 250.818472] rtl8192ce:rtl92ce_led_control():<0-1-0> ledaction 3 +[ 250.818472] rtl8192ce:rtl92ce_sw_led_on():<0-1-0> LedAddr:4E ledpin=1 +[ 250.818472] rtlwifi:rtl_ips_nic_on():<0-1-0> before spin_unlock_irqrestore +[ 251.154656] PCM: Lost interrupts? [Q]-0 (stream=0, delta=15903, new_hw_ptr=293408, old_hw_ptr=277505) + +The exact code flow that causes that is: + +1. wpa_supplicant send a start_scan request to the nl80211 driver +2. mac80211 module call rtl_op_config with IEEE80211_CONF_CHANGE_IDLE +3. rtl_ips_nic_on is called which disable local irqs +4. rtl92c_phy_set_rf_power_state() is called +5. rtl_ps_enable_nic() is called and hw_init()is executed and then the interrupts on the device are enabled + +A good solution could be to refactor the code to avoid calling rtl92ce_hw_init() with the irqs disabled +but a quick and dirty solution that has proven to work is +to reenable the irqs during the function rtl92ce_hw_init(). + +I think that it is safe doing so since the device interrupt will only be enabled after the init function succeed. + +Signed-off-by: Olivier Langlois +Acked-by: Larry Finger +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +@@ -937,14 +937,26 @@ int rtl92ce_hw_init(struct ieee80211_hw + bool is92c; + int err; + u8 tmp_u1b; ++ unsigned long flags; + + rtlpci->being_init_adapter = true; ++ ++ /* Since this function can take a very long time (up to 350 ms) ++ * and can be called with irqs disabled, reenable the irqs ++ * to let the other devices continue being serviced. ++ * ++ * It is safe doing so since our own interrupts will only be enabled ++ * in a subsequent step. ++ */ ++ local_save_flags(flags); ++ local_irq_enable(); ++ + rtlpriv->intf_ops->disable_aspm(hw); + rtstatus = _rtl92ce_init_mac(hw); + if (!rtstatus) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); + err = 1; +- return err; ++ goto exit; + } + + err = rtl92c_download_fw(hw); +@@ -952,7 +964,7 @@ int rtl92ce_hw_init(struct ieee80211_hw + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "Failed to download FW. Init HW without FW now..\n"); + err = 1; +- return err; ++ goto exit; + } + + rtlhal->last_hmeboxnum = 0; +@@ -1032,6 +1044,8 @@ int rtl92ce_hw_init(struct ieee80211_hw + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); + } + rtl92c_dm_init(hw); ++exit: ++ local_irq_restore(flags); + rtlpci->being_init_adapter = false; + return err; + } diff --git a/queue-3.10/series b/queue-3.10/series index dcbfb48a022..7fe7ec40f02 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -12,3 +12,8 @@ arm-omap2-gpmc-fix-dt-nand-child-nodes-not-probed-when-mtd_nand-is-built-as-modu arm-omap2-gpmc-fix-dt-onenand-child-nodes-not-probed-when-mtd_onenand-is-built-as-module.patch avr32-fix-missing-module.h-causing-build-failure-in-mimc200-fram.c.patch avr32-makefile-add-d__linux__-flag-for-gcc-4.4.7-use.patch +cifs-ensure-that-uncached-writes-handle-unmapped-areas-correctly.patch +cifs-fix-too-big-maxbuf-size-for-smb3-mounts.patch +rtl8187-fix-regression-on-mips-without-coherent-dma.patch +rtlwifi-fix-incorrect-return-from-rtl_ps_enable_nic.patch +rtlwifi-rtl8192ce-fix-too-long-disable-of-irqs.patch