--- /dev/null
+From 17df6453d4be17910456e99c5a85025aa1b7a246 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Tue, 12 Sep 2017 10:47:53 +0200
+Subject: brcmfmac: add length check in brcmf_cfg80211_escan_handler()
+
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+
+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 <cernekee@chromium.org>
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
--- /dev/null
+From 511c54a2f69195b28afb9dd119f03787b1625bb4 Mon Sep 17 00:00:00 2001
+From: Pavel Shilovsky <pshilov@microsoft.com>
+Date: Sat, 8 Jul 2017 14:32:00 -0700
+Subject: CIFS: Reconnect expired SMB sessions
+
+From: Pavel Shilovsky <pshilov@microsoft.com>
+
+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 <pshilov@microsoft.com>
+Signed-off-by: Steve French <smfrench@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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,
--- /dev/null
+From 1bd8d6cd3e413d64e543ec3e69ff43e75a1cf1ea Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <darrick.wong@oracle.com>
+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 <darrick.wong@oracle.com>
+
+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 <muttdini@gmail.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
--- /dev/null
+From 97bce57bd7f96e1218751996f549a6e61f18cc8c Mon Sep 17 00:00:00 2001
+From: Luca Coelho <luciano.coelho@intel.com>
+Date: Fri, 1 Sep 2017 17:59:15 +0300
+Subject: iwlwifi: mvm: use IWL_HCMD_NOCOPY for MCAST_FILTER_CMD
+
+From: Luca Coelho <luciano.coelho@intel.com>
+
+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 <luciano.coelho@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ 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);
+ }
--- /dev/null
+From ad670233c9e1d5feb365d870e30083ef1b889177 Mon Sep 17 00:00:00 2001
+From: Peng Xu <pxu@qti.qualcomm.com>
+Date: Tue, 3 Oct 2017 23:21:51 +0300
+Subject: nl80211: Define policy for packet pattern attributes
+
+From: Peng Xu <pxu@qti.qualcomm.com>
+
+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 <pxu@qti.qualcomm.com>
+Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
+[rewrite description based on SKB allocation knowledge]
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
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