]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 12 Oct 2017 11:58:17 +0000 (13:58 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 12 Oct 2017 11:58:17 +0000 (13:58 +0200)
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

queue-4.4/brcmfmac-add-length-check-in-brcmf_cfg80211_escan_handler.patch [new file with mode: 0644]
queue-4.4/cifs-reconnect-expired-smb-sessions.patch [new file with mode: 0644]
queue-4.4/ext4-in-ext4_seek_-hole-data-return-enxio-for-negative-offsets.patch [new file with mode: 0644]
queue-4.4/iwlwifi-mvm-use-iwl_hcmd_nocopy-for-mcast_filter_cmd.patch [new file with mode: 0644]
queue-4.4/nl80211-define-policy-for-packet-pattern-attributes.patch [new file with mode: 0644]
queue-4.4/series

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 (file)
index 0000000..d37004f
--- /dev/null
@@ -0,0 +1,71 @@
+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;
+               }
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 (file)
index 0000000..cf68ade
--- /dev/null
@@ -0,0 +1,123 @@
+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,
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 (file)
index 0000000..2118ae0
--- /dev/null
@@ -0,0 +1,42 @@
+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;
+       }
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 (file)
index 0000000..83ba249
--- /dev/null
@@ -0,0 +1,52 @@
+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);
+ }
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 (file)
index 0000000..7934f7d
--- /dev/null
@@ -0,0 +1,68 @@
+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;
index 4f7549e59b32480c8dc63399e2a033b15677c089..5a776b2e1a634921af601baaf68d063662f0004f 100644 (file)
@@ -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