From: Greg Kroah-Hartman Date: Thu, 12 Oct 2017 11:58:35 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v4.13.7~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=07664849594b34b95dc36e25dc6067aa1d3ee405;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: cifs-reconnect-expired-smb-sessions.patch ext4-in-ext4_seek_-hole-data-return-enxio-for-negative-offsets.patch nl80211-define-policy-for-packet-pattern-attributes.patch --- diff --git a/queue-4.9/cifs-reconnect-expired-smb-sessions.patch b/queue-4.9/cifs-reconnect-expired-smb-sessions.patch new file mode 100644 index 00000000000..5e74a60792a --- /dev/null +++ b/queue-4.9/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 +@@ -365,6 +365,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 +@@ -1457,6 +1457,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 +@@ -796,6 +796,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 +@@ -1018,6 +1018,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) +@@ -1609,6 +1621,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, +@@ -1690,6 +1703,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, +@@ -1773,6 +1787,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, +@@ -1862,6 +1877,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.9/ext4-in-ext4_seek_-hole-data-return-enxio-for-negative-offsets.patch b/queue-4.9/ext4-in-ext4_seek_-hole-data-return-enxio-for-negative-offsets.patch new file mode 100644 index 00000000000..ad316402f44 --- /dev/null +++ b/queue-4.9/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 +@@ -527,7 +527,7 @@ static loff_t ext4_seek_data(struct file + inode_lock(inode); + + isize = i_size_read(inode); +- if (offset >= isize) { ++ if (offset < 0 || offset >= isize) { + inode_unlock(inode); + return -ENXIO; + } +@@ -590,7 +590,7 @@ static loff_t ext4_seek_hole(struct file + inode_lock(inode); + + isize = i_size_read(inode); +- if (offset >= isize) { ++ if (offset < 0 || offset >= isize) { + inode_unlock(inode); + return -ENXIO; + } diff --git a/queue-4.9/nl80211-define-policy-for-packet-pattern-attributes.patch b/queue-4.9/nl80211-define-policy-for-packet-pattern-attributes.patch new file mode 100644 index 00000000000..007325609e5 --- /dev/null +++ b/queue-4.9/nl80211-define-policy-for-packet-pattern-attributes.patch @@ -0,0 +1,67 @@ +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. + +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 +@@ -541,6 +541,14 @@ nl80211_nan_srf_policy[NL80211_NAN_SRF_A + [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED }, + }; + ++/* 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, +@@ -10009,7 +10017,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]) +@@ -10259,7 +10267,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.9/series b/queue-4.9/series index de6a3698b7c..2c5fe05414a 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -1 +1,3 @@ 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