From: Greg Kroah-Hartman Date: Thu, 12 Oct 2017 11:58:17 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v4.13.7~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=67307134c229a348b3ca98bda0fc3ca7cbc596fb;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: brcmfmac-add-length-check-in-brcmf_cfg80211_escan_handler.patch cifs-reconnect-expired-smb-sessions.patch ext4-in-ext4_seek_-hole-data-return-enxio-for-negative-offsets.patch iwlwifi-mvm-use-iwl_hcmd_nocopy-for-mcast_filter_cmd.patch nl80211-define-policy-for-packet-pattern-attributes.patch --- diff --git a/queue-4.4/brcmfmac-add-length-check-in-brcmf_cfg80211_escan_handler.patch b/queue-4.4/brcmfmac-add-length-check-in-brcmf_cfg80211_escan_handler.patch new file mode 100644 index 00000000000..d37004fc582 --- /dev/null +++ b/queue-4.4/brcmfmac-add-length-check-in-brcmf_cfg80211_escan_handler.patch @@ -0,0 +1,71 @@ +From 17df6453d4be17910456e99c5a85025aa1b7a246 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 12 Sep 2017 10:47:53 +0200 +Subject: brcmfmac: add length check in brcmf_cfg80211_escan_handler() + +From: Arend Van Spriel + +commit 17df6453d4be17910456e99c5a85025aa1b7a246 upstream. + +Upon handling the firmware notification for scans the length was +checked properly and may result in corrupting kernel heap memory +due to buffer overruns. This fix addresses CVE-2017-0786. + +Cc: Kevin Cernekee +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -2903,6 +2903,7 @@ brcmf_cfg80211_escan_handler(struct brcm + struct brcmf_cfg80211_info *cfg = ifp->drvr->config; + s32 status; + struct brcmf_escan_result_le *escan_result_le; ++ u32 escan_buflen; + struct brcmf_bss_info_le *bss_info_le; + struct brcmf_bss_info_le *bss = NULL; + u32 bi_length; +@@ -2919,11 +2920,23 @@ brcmf_cfg80211_escan_handler(struct brcm + + if (status == BRCMF_E_STATUS_PARTIAL) { + brcmf_dbg(SCAN, "ESCAN Partial result\n"); ++ if (e->datalen < sizeof(*escan_result_le)) { ++ brcmf_err("invalid event data length\n"); ++ goto exit; ++ } + escan_result_le = (struct brcmf_escan_result_le *) data; + if (!escan_result_le) { + brcmf_err("Invalid escan result (NULL pointer)\n"); + goto exit; + } ++ escan_buflen = le32_to_cpu(escan_result_le->buflen); ++ if (escan_buflen > WL_ESCAN_BUF_SIZE || ++ escan_buflen > e->datalen || ++ escan_buflen < sizeof(*escan_result_le)) { ++ brcmf_err("Invalid escan buffer length: %d\n", ++ escan_buflen); ++ goto exit; ++ } + if (le16_to_cpu(escan_result_le->bss_count) != 1) { + brcmf_err("Invalid bss_count %d: ignoring\n", + escan_result_le->bss_count); +@@ -2940,9 +2953,8 @@ brcmf_cfg80211_escan_handler(struct brcm + } + + bi_length = le32_to_cpu(bss_info_le->length); +- if (bi_length != (le32_to_cpu(escan_result_le->buflen) - +- WL_ESCAN_RESULTS_FIXED_SIZE)) { +- brcmf_err("Invalid bss_info length %d: ignoring\n", ++ if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) { ++ brcmf_err("Ignoring invalid bss_info length: %d\n", + bi_length); + goto exit; + } diff --git a/queue-4.4/cifs-reconnect-expired-smb-sessions.patch b/queue-4.4/cifs-reconnect-expired-smb-sessions.patch new file mode 100644 index 00000000000..cf68adecce1 --- /dev/null +++ b/queue-4.4/cifs-reconnect-expired-smb-sessions.patch @@ -0,0 +1,123 @@ +From 511c54a2f69195b28afb9dd119f03787b1625bb4 Mon Sep 17 00:00:00 2001 +From: Pavel Shilovsky +Date: Sat, 8 Jul 2017 14:32:00 -0700 +Subject: CIFS: Reconnect expired SMB sessions + +From: Pavel Shilovsky + +commit 511c54a2f69195b28afb9dd119f03787b1625bb4 upstream. + +According to the MS-SMB2 spec (3.2.5.1.6) once the client receives +STATUS_NETWORK_SESSION_EXPIRED error code from a server it should +reconnect the current SMB session. Currently the client doesn't do +that. This can result in subsequent client requests failing by +the server. The patch adds an additional logic to the demultiplex +thread to identify expired sessions and reconnect them. + +Signed-off-by: Pavel Shilovsky +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/cifsglob.h | 2 ++ + fs/cifs/cifssmb.c | 7 +++++++ + fs/cifs/connect.c | 7 +++++++ + fs/cifs/smb2ops.c | 16 ++++++++++++++++ + 4 files changed, 32 insertions(+) + +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -351,6 +351,8 @@ struct smb_version_operations { + unsigned int (*calc_smb_size)(void *); + /* check for STATUS_PENDING and process it in a positive case */ + bool (*is_status_pending)(char *, struct TCP_Server_Info *, int); ++ /* check for STATUS_NETWORK_SESSION_EXPIRED */ ++ bool (*is_session_expired)(char *); + /* send oplock break response */ + int (*oplock_response)(struct cifs_tcon *, struct cifs_fid *, + struct cifsInodeInfo *); +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -1460,6 +1460,13 @@ cifs_readv_receive(struct TCP_Server_Inf + return length; + server->total_read += length; + ++ if (server->ops->is_session_expired && ++ server->ops->is_session_expired(buf)) { ++ cifs_reconnect(server); ++ wake_up(&server->response_q); ++ return -1; ++ } ++ + if (server->ops->is_status_pending && + server->ops->is_status_pending(buf, server, 0)) { + discard_remaining_data(server); +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -850,6 +850,13 @@ standard_receive3(struct TCP_Server_Info + cifs_dump_mem("Bad SMB: ", buf, + min_t(unsigned int, server->total_read, 48)); + ++ if (server->ops->is_session_expired && ++ server->ops->is_session_expired(buf)) { ++ cifs_reconnect(server); ++ wake_up(&server->response_q); ++ return -1; ++ } ++ + if (server->ops->is_status_pending && + server->ops->is_status_pending(buf, server, length)) + return -1; +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -963,6 +963,18 @@ smb2_is_status_pending(char *buf, struct + return true; + } + ++static bool ++smb2_is_session_expired(char *buf) ++{ ++ struct smb2_hdr *hdr = (struct smb2_hdr *)buf; ++ ++ if (hdr->Status != STATUS_NETWORK_SESSION_EXPIRED) ++ return false; ++ ++ cifs_dbg(FYI, "Session expired\n"); ++ return true; ++} ++ + static int + smb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid, + struct cifsInodeInfo *cinode) +@@ -1552,6 +1564,7 @@ struct smb_version_operations smb20_oper + .close_dir = smb2_close_dir, + .calc_smb_size = smb2_calc_size, + .is_status_pending = smb2_is_status_pending, ++ .is_session_expired = smb2_is_session_expired, + .oplock_response = smb2_oplock_response, + .queryfs = smb2_queryfs, + .mand_lock = smb2_mand_lock, +@@ -1633,6 +1646,7 @@ struct smb_version_operations smb21_oper + .close_dir = smb2_close_dir, + .calc_smb_size = smb2_calc_size, + .is_status_pending = smb2_is_status_pending, ++ .is_session_expired = smb2_is_session_expired, + .oplock_response = smb2_oplock_response, + .queryfs = smb2_queryfs, + .mand_lock = smb2_mand_lock, +@@ -1715,6 +1729,7 @@ struct smb_version_operations smb30_oper + .close_dir = smb2_close_dir, + .calc_smb_size = smb2_calc_size, + .is_status_pending = smb2_is_status_pending, ++ .is_session_expired = smb2_is_session_expired, + .oplock_response = smb2_oplock_response, + .queryfs = smb2_queryfs, + .mand_lock = smb2_mand_lock, +@@ -1803,6 +1818,7 @@ struct smb_version_operations smb311_ope + .close_dir = smb2_close_dir, + .calc_smb_size = smb2_calc_size, + .is_status_pending = smb2_is_status_pending, ++ .is_session_expired = smb2_is_session_expired, + .oplock_response = smb2_oplock_response, + .queryfs = smb2_queryfs, + .mand_lock = smb2_mand_lock, diff --git a/queue-4.4/ext4-in-ext4_seek_-hole-data-return-enxio-for-negative-offsets.patch b/queue-4.4/ext4-in-ext4_seek_-hole-data-return-enxio-for-negative-offsets.patch new file mode 100644 index 00000000000..2118ae01e3c --- /dev/null +++ b/queue-4.4/ext4-in-ext4_seek_-hole-data-return-enxio-for-negative-offsets.patch @@ -0,0 +1,42 @@ +From 1bd8d6cd3e413d64e543ec3e69ff43e75a1cf1ea Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Thu, 24 Aug 2017 13:22:06 -0400 +Subject: ext4: in ext4_seek_{hole,data}, return -ENXIO for negative offsets + +From: Darrick J. Wong + +commit 1bd8d6cd3e413d64e543ec3e69ff43e75a1cf1ea upstream. + +In the ext4 implementations of SEEK_HOLE and SEEK_DATA, make sure we +return -ENXIO for negative offsets instead of banging around inside +the extent code and returning -EFSCORRUPTED. + +Reported-by: Mateusz S +Signed-off-by: Darrick J. Wong +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/file.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -559,7 +559,7 @@ static loff_t ext4_seek_data(struct file + mutex_lock(&inode->i_mutex); + + isize = i_size_read(inode); +- if (offset >= isize) { ++ if (offset < 0 || offset >= isize) { + mutex_unlock(&inode->i_mutex); + return -ENXIO; + } +@@ -632,7 +632,7 @@ static loff_t ext4_seek_hole(struct file + mutex_lock(&inode->i_mutex); + + isize = i_size_read(inode); +- if (offset >= isize) { ++ if (offset < 0 || offset >= isize) { + mutex_unlock(&inode->i_mutex); + return -ENXIO; + } diff --git a/queue-4.4/iwlwifi-mvm-use-iwl_hcmd_nocopy-for-mcast_filter_cmd.patch b/queue-4.4/iwlwifi-mvm-use-iwl_hcmd_nocopy-for-mcast_filter_cmd.patch new file mode 100644 index 00000000000..83ba249b098 --- /dev/null +++ b/queue-4.4/iwlwifi-mvm-use-iwl_hcmd_nocopy-for-mcast_filter_cmd.patch @@ -0,0 +1,52 @@ +From 97bce57bd7f96e1218751996f549a6e61f18cc8c Mon Sep 17 00:00:00 2001 +From: Luca Coelho +Date: Fri, 1 Sep 2017 17:59:15 +0300 +Subject: iwlwifi: mvm: use IWL_HCMD_NOCOPY for MCAST_FILTER_CMD + +From: Luca Coelho + +commit 97bce57bd7f96e1218751996f549a6e61f18cc8c upstream. + +The MCAST_FILTER_CMD can get quite large when we have many mcast +addresses to set (we support up to 255). So the command should be +send as NOCOPY to prevent a warning caused by too-long commands: + +WARNING: CPU: 0 PID: 9700 at /root/iwlwifi/stack-dev/drivers/net/wireless/intel/iwlwifi/pcie/tx.c:1550 iwl_pcie_enqueue_hcmd+0x8c7/0xb40 [iwlwifi] +Command MCAST_FILTER_CMD (0x1d0) is too large (328 bytes) + +This fixes: https://bugzilla.kernel.org/show_bug.cgi?id=196743 + +Signed-off-by: Luca Coelho +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/net/wireless/iwlwifi/mvm/mac80211.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c ++++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c +@@ -1906,6 +1906,11 @@ static void iwl_mvm_mc_iface_iterator(vo + struct iwl_mvm_mc_iter_data *data = _data; + struct iwl_mvm *mvm = data->mvm; + struct iwl_mcast_filter_cmd *cmd = mvm->mcast_filter_cmd; ++ struct iwl_host_cmd hcmd = { ++ .id = MCAST_FILTER_CMD, ++ .flags = CMD_ASYNC, ++ .dataflags[0] = IWL_HCMD_DFL_NOCOPY, ++ }; + int ret, len; + + /* if we don't have free ports, mcast frames will be dropped */ +@@ -1920,7 +1925,10 @@ static void iwl_mvm_mc_iface_iterator(vo + memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN); + len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4); + +- ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_ASYNC, len, cmd); ++ hcmd.len[0] = len; ++ hcmd.data[0] = cmd; ++ ++ ret = iwl_mvm_send_cmd(mvm, &hcmd); + if (ret) + IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret); + } diff --git a/queue-4.4/nl80211-define-policy-for-packet-pattern-attributes.patch b/queue-4.4/nl80211-define-policy-for-packet-pattern-attributes.patch new file mode 100644 index 00000000000..7934f7d9b4f --- /dev/null +++ b/queue-4.4/nl80211-define-policy-for-packet-pattern-attributes.patch @@ -0,0 +1,68 @@ +From ad670233c9e1d5feb365d870e30083ef1b889177 Mon Sep 17 00:00:00 2001 +From: Peng Xu +Date: Tue, 3 Oct 2017 23:21:51 +0300 +Subject: nl80211: Define policy for packet pattern attributes + +From: Peng Xu + +commit ad670233c9e1d5feb365d870e30083ef1b889177 upstream. + +Define a policy for packet pattern attributes in order to fix a +potential read over the end of the buffer during nla_get_u32() +of the NL80211_PKTPAT_OFFSET attribute. + +Note that the data there can always be read due to SKB allocation +(with alignment and struct skb_shared_info at the end), but the +data might be uninitialized. This could be used to leak some data +from uninitialized vmalloc() memory, but most drivers don't allow +an offset (so you'd just get -EINVAL if the data is non-zero) or +just allow it with a fixed value - 100 or 128 bytes, so anything +above that would get -EINVAL. With brcmfmac the limit is 1500 so +(at least) one byte could be obtained. + +Cc: stable@kernel.org +Signed-off-by: Peng Xu +Signed-off-by: Jouni Malinen +[rewrite description based on SKB allocation knowledge] +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/wireless/nl80211.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -485,6 +485,14 @@ nl80211_plan_policy[NL80211_SCHED_SCAN_P + [NL80211_SCHED_SCAN_PLAN_ITERATIONS] = { .type = NLA_U32 }, + }; + ++/* policy for packet pattern attributes */ ++static const struct nla_policy ++nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = { ++ [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, }, ++ [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, }, ++ [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 }, ++}; ++ + static int nl80211_prepare_wdev_dump(struct sk_buff *skb, + struct netlink_callback *cb, + struct cfg80211_registered_device **rdev, +@@ -9410,7 +9418,7 @@ static int nl80211_set_wowlan(struct sk_ + u8 *mask_pat; + + nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), +- nla_len(pat), NULL); ++ nla_len(pat), nl80211_packet_pattern_policy); + err = -EINVAL; + if (!pat_tb[NL80211_PKTPAT_MASK] || + !pat_tb[NL80211_PKTPAT_PATTERN]) +@@ -9660,7 +9668,7 @@ static int nl80211_parse_coalesce_rule(s + u8 *mask_pat; + + nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), +- nla_len(pat), NULL); ++ nla_len(pat), nl80211_packet_pattern_policy); + if (!pat_tb[NL80211_PKTPAT_MASK] || + !pat_tb[NL80211_PKTPAT_PATTERN]) + return -EINVAL; diff --git a/queue-4.4/series b/queue-4.4/series index 4f7549e59b3..5a776b2e1a6 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -1,2 +1,5 @@ brcmfmac-add-length-check-in-brcmf_cfg80211_escan_handler.patch ext4-in-ext4_seek_-hole-data-return-enxio-for-negative-offsets.patch +cifs-reconnect-expired-smb-sessions.patch +nl80211-define-policy-for-packet-pattern-attributes.patch +iwlwifi-mvm-use-iwl_hcmd_nocopy-for-mcast_filter_cmd.patch