--- /dev/null
+From 98128572084c3dd8067f48bb588aa3733d1355b5 Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <namjae.jeon@samsung.com>
+Date: Mon, 9 Nov 2020 17:35:33 +0900
+Subject: cifs: fix a memleak with modefromsid
+
+From: Namjae Jeon <namjae.jeon@samsung.com>
+
+commit 98128572084c3dd8067f48bb588aa3733d1355b5 upstream.
+
+kmemleak reported a memory leak allocated in query_info() when cifs is
+working with modefromsid.
+
+ backtrace:
+ [<00000000aeef6a1e>] slab_post_alloc_hook+0x58/0x510
+ [<00000000b2f7a440>] __kmalloc+0x1a0/0x390
+ [<000000006d470ebc>] query_info+0x5b5/0x700 [cifs]
+ [<00000000bad76ce0>] SMB2_query_acl+0x2b/0x30 [cifs]
+ [<000000001fa09606>] get_smb2_acl_by_path+0x2f3/0x720 [cifs]
+ [<000000001b6ebab7>] get_smb2_acl+0x75/0x90 [cifs]
+ [<00000000abf43904>] cifs_acl_to_fattr+0x13b/0x1d0 [cifs]
+ [<00000000a5372ec3>] cifs_get_inode_info+0x4cd/0x9a0 [cifs]
+ [<00000000388e0a04>] cifs_revalidate_dentry_attr+0x1cd/0x510 [cifs]
+ [<0000000046b6b352>] cifs_getattr+0x8a/0x260 [cifs]
+ [<000000007692c95e>] vfs_getattr_nosec+0xa1/0xc0
+ [<00000000cbc7d742>] vfs_getattr+0x36/0x40
+ [<00000000de8acf67>] vfs_statx_fd+0x4a/0x80
+ [<00000000a58c6adb>] __do_sys_newfstat+0x31/0x70
+ [<00000000300b3b4e>] __x64_sys_newfstat+0x16/0x20
+ [<000000006d8e9c48>] do_syscall_64+0x37/0x80
+
+This patch add missing kfree for pntsd when mounting modefromsid option.
+
+Cc: Stable <stable@vger.kernel.org> # v5.4+
+Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
+Reviewed-by: Aurelien Aptel <aaptel@suse.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/cifsacl.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/cifs/cifsacl.c
++++ b/fs/cifs/cifsacl.c
+@@ -1198,6 +1198,7 @@ cifs_acl_to_fattr(struct cifs_sb_info *c
+ cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
+ } else if (mode_from_special_sid) {
+ rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
++ kfree(pntsd);
+ } else {
+ /* get approximated mode from ACL */
+ rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
spi-bcm2835-fix-use-after-free-on-unbind.patch
ipv4-use-is_enabled-instead-of-ifdef.patch
wireless-use-linux-stddef.h-instead-of-stddef.h.patch
+smb3-call-cifs-reconnect-from-demultiplex-thread.patch
+smb3-avoid-mid-pending-list-corruption.patch
+smb3-handle-error-case-during-offload-read-path.patch
+cifs-fix-a-memleak-with-modefromsid.patch
--- /dev/null
+From ac873aa3dc21707c47db5db6608b38981c731afe Mon Sep 17 00:00:00 2001
+From: Rohith Surabattula <rohiths@microsoft.com>
+Date: Thu, 29 Oct 2020 05:03:10 +0000
+Subject: smb3: Avoid Mid pending list corruption
+
+From: Rohith Surabattula <rohiths@microsoft.com>
+
+commit ac873aa3dc21707c47db5db6608b38981c731afe upstream.
+
+When reconnect happens Mid queue can be corrupted when both
+demultiplex and offload thread try to dequeue the MID from the
+pending list.
+
+These patches address a problem found during decryption offload:
+ CIFS: VFS: trying to dequeue a deleted mid
+that could cause a refcount use after free:
+ Workqueue: smb3decryptd smb2_decrypt_offload [cifs]
+
+Signed-off-by: Rohith Surabattula <rohiths@microsoft.com>
+Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
+CC: Stable <stable@vger.kernel.org> #5.4+
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smb2ops.c | 55 +++++++++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 46 insertions(+), 9 deletions(-)
+
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -259,7 +259,7 @@ smb2_revert_current_mid(struct TCP_Serve
+ }
+
+ static struct mid_q_entry *
+-smb2_find_mid(struct TCP_Server_Info *server, char *buf)
++__smb2_find_mid(struct TCP_Server_Info *server, char *buf, bool dequeue)
+ {
+ struct mid_q_entry *mid;
+ struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
+@@ -276,6 +276,10 @@ smb2_find_mid(struct TCP_Server_Info *se
+ (mid->mid_state == MID_REQUEST_SUBMITTED) &&
+ (mid->command == shdr->Command)) {
+ kref_get(&mid->refcount);
++ if (dequeue) {
++ list_del_init(&mid->qhead);
++ mid->mid_flags |= MID_DELETED;
++ }
+ spin_unlock(&GlobalMid_Lock);
+ return mid;
+ }
+@@ -284,6 +288,18 @@ smb2_find_mid(struct TCP_Server_Info *se
+ return NULL;
+ }
+
++static struct mid_q_entry *
++smb2_find_mid(struct TCP_Server_Info *server, char *buf)
++{
++ return __smb2_find_mid(server, buf, false);
++}
++
++static struct mid_q_entry *
++smb2_find_dequeue_mid(struct TCP_Server_Info *server, char *buf)
++{
++ return __smb2_find_mid(server, buf, true);
++}
++
+ static void
+ smb2_dump_detail(void *buf, struct TCP_Server_Info *server)
+ {
+@@ -4028,7 +4044,10 @@ handle_read_data(struct TCP_Server_Info
+ cifs_dbg(FYI, "%s: server returned error %d\n",
+ __func__, rdata->result);
+ /* normal error on read response */
+- dequeue_mid(mid, false);
++ if (is_offloaded)
++ mid->mid_state = MID_RESPONSE_RECEIVED;
++ else
++ dequeue_mid(mid, false);
+ return 0;
+ }
+
+@@ -4052,7 +4071,10 @@ handle_read_data(struct TCP_Server_Info
+ cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
+ __func__, data_offset);
+ rdata->result = -EIO;
+- dequeue_mid(mid, rdata->result);
++ if (is_offloaded)
++ mid->mid_state = MID_RESPONSE_MALFORMED;
++ else
++ dequeue_mid(mid, rdata->result);
+ return 0;
+ }
+
+@@ -4068,21 +4090,30 @@ handle_read_data(struct TCP_Server_Info
+ cifs_dbg(FYI, "%s: data offset (%u) beyond 1st page of response\n",
+ __func__, data_offset);
+ rdata->result = -EIO;
+- dequeue_mid(mid, rdata->result);
++ if (is_offloaded)
++ mid->mid_state = MID_RESPONSE_MALFORMED;
++ else
++ dequeue_mid(mid, rdata->result);
+ return 0;
+ }
+
+ if (data_len > page_data_size - pad_len) {
+ /* data_len is corrupt -- discard frame */
+ rdata->result = -EIO;
+- dequeue_mid(mid, rdata->result);
++ if (is_offloaded)
++ mid->mid_state = MID_RESPONSE_MALFORMED;
++ else
++ dequeue_mid(mid, rdata->result);
+ return 0;
+ }
+
+ rdata->result = init_read_bvec(pages, npages, page_data_size,
+ cur_off, &bvec);
+ if (rdata->result != 0) {
+- dequeue_mid(mid, rdata->result);
++ if (is_offloaded)
++ mid->mid_state = MID_RESPONSE_MALFORMED;
++ else
++ dequeue_mid(mid, rdata->result);
+ return 0;
+ }
+
+@@ -4097,7 +4128,10 @@ handle_read_data(struct TCP_Server_Info
+ /* read response payload cannot be in both buf and pages */
+ WARN_ONCE(1, "buf can not contain only a part of read data");
+ rdata->result = -EIO;
+- dequeue_mid(mid, rdata->result);
++ if (is_offloaded)
++ mid->mid_state = MID_RESPONSE_MALFORMED;
++ else
++ dequeue_mid(mid, rdata->result);
+ return 0;
+ }
+
+@@ -4108,7 +4142,10 @@ handle_read_data(struct TCP_Server_Info
+ if (length < 0)
+ return length;
+
+- dequeue_mid(mid, false);
++ if (is_offloaded)
++ mid->mid_state = MID_RESPONSE_RECEIVED;
++ else
++ dequeue_mid(mid, false);
+ return length;
+ }
+
+@@ -4137,7 +4174,7 @@ static void smb2_decrypt_offload(struct
+ }
+
+ dw->server->lstrp = jiffies;
+- mid = smb2_find_mid(dw->server, dw->buf);
++ mid = smb2_find_dequeue_mid(dw->server, dw->buf);
+ if (mid == NULL)
+ cifs_dbg(FYI, "mid not found\n");
+ else {
--- /dev/null
+From de9ac0a6e9efdffc8cde18781f48fb56ca4157b7 Mon Sep 17 00:00:00 2001
+From: Rohith Surabattula <rohiths@microsoft.com>
+Date: Wed, 28 Oct 2020 13:42:21 +0000
+Subject: smb3: Call cifs reconnect from demultiplex thread
+
+From: Rohith Surabattula <rohiths@microsoft.com>
+
+commit de9ac0a6e9efdffc8cde18781f48fb56ca4157b7 upstream.
+
+cifs_reconnect needs to be called only from demultiplex thread.
+skip cifs_reconnect in offload thread. So, cifs_reconnect will be
+called by demultiplex thread in subsequent request.
+
+These patches address a problem found during decryption offload:
+ CIFS: VFS: trying to dequeue a deleted mid
+that can cause a refcount use after free:
+
+[ 1271.389453] Workqueue: smb3decryptd smb2_decrypt_offload [cifs]
+[ 1271.389456] RIP: 0010:refcount_warn_saturate+0xae/0xf0
+[ 1271.389457] Code: fa 1d 6a 01 01 e8 c7 44 b1 ff 0f 0b 5d c3 80 3d e7 1d 6a 01 00 75 91 48 c7 c7 d8 be 1d a2 c6 05 d7 1d 6a 01 01 e8 a7 44 b1 ff <0f> 0b 5d c3 80 3d c5 1d 6a 01 00 0f 85 6d ff ff ff 48 c7 c7 30 bf
+[ 1271.389458] RSP: 0018:ffffa4cdc1f87e30 EFLAGS: 00010286
+[ 1271.389458] RAX: 0000000000000000 RBX: ffff9974d2809f00 RCX: ffff9974df898cc8
+[ 1271.389459] RDX: 00000000ffffffd8 RSI: 0000000000000027 RDI: ffff9974df898cc0
+[ 1271.389460] RBP: ffffa4cdc1f87e30 R08: 0000000000000004 R09: 00000000000002c0
+[ 1271.389460] R10: 0000000000000000 R11: 0000000000000001 R12: ffff9974b7fdb5c0
+[ 1271.389461] R13: ffff9974d2809f00 R14: ffff9974ccea0a80 R15: ffff99748e60db80
+[ 1271.389462] FS: 0000000000000000(0000) GS:ffff9974df880000(0000) knlGS:0000000000000000
+[ 1271.389462] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 1271.389463] CR2: 000055c60f344fe4 CR3: 0000001031a3c002 CR4: 00000000003706e0
+[ 1271.389465] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[ 1271.389465] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[ 1271.389466] Call Trace:
+[ 1271.389483] cifs_mid_q_entry_release+0xce/0x110 [cifs]
+[ 1271.389499] smb2_decrypt_offload+0xa9/0x1c0 [cifs]
+[ 1271.389501] process_one_work+0x1e8/0x3b0
+[ 1271.389503] worker_thread+0x50/0x370
+[ 1271.389504] kthread+0x12f/0x150
+[ 1271.389506] ? process_one_work+0x3b0/0x3b0
+[ 1271.389507] ? __kthread_bind_mask+0x70/0x70
+[ 1271.389509] ret_from_fork+0x22/0x30
+
+Signed-off-by: Rohith Surabattula <rohiths@microsoft.com>
+Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
+CC: Stable <stable@vger.kernel.org> #5.4+
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smb2ops.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -3979,7 +3979,8 @@ init_read_bvec(struct page **pages, unsi
+ static int
+ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
+ char *buf, unsigned int buf_len, struct page **pages,
+- unsigned int npages, unsigned int page_data_size)
++ unsigned int npages, unsigned int page_data_size,
++ bool is_offloaded)
+ {
+ unsigned int data_offset;
+ unsigned int data_len;
+@@ -4001,7 +4002,8 @@ handle_read_data(struct TCP_Server_Info
+
+ if (server->ops->is_session_expired &&
+ server->ops->is_session_expired(buf)) {
+- cifs_reconnect(server);
++ if (!is_offloaded)
++ cifs_reconnect(server);
+ wake_up(&server->response_q);
+ return -1;
+ }
+@@ -4142,7 +4144,8 @@ static void smb2_decrypt_offload(struct
+ mid->decrypted = true;
+ rc = handle_read_data(dw->server, mid, dw->buf,
+ dw->server->vals->read_rsp_size,
+- dw->ppages, dw->npages, dw->len);
++ dw->ppages, dw->npages, dw->len,
++ true);
+ mid->callback(mid);
+ cifs_mid_q_entry_release(mid);
+ }
+@@ -4246,7 +4249,7 @@ non_offloaded_decrypt:
+ (*mid)->decrypted = true;
+ rc = handle_read_data(server, *mid, buf,
+ server->vals->read_rsp_size,
+- pages, npages, len);
++ pages, npages, len, false);
+ }
+
+ free_pages:
+@@ -4391,7 +4394,7 @@ smb3_handle_read_data(struct TCP_Server_
+ char *buf = server->large_buf ? server->bigbuf : server->smallbuf;
+
+ return handle_read_data(server, mid, buf, server->pdu_size,
+- NULL, 0, 0);
++ NULL, 0, 0, false);
+ }
+
+ static int
--- /dev/null
+From 1254100030b3377e8302f9c75090ab191d73ee7c Mon Sep 17 00:00:00 2001
+From: Rohith Surabattula <rohiths@microsoft.com>
+Date: Thu, 29 Oct 2020 06:07:56 +0000
+Subject: smb3: Handle error case during offload read path
+
+From: Rohith Surabattula <rohiths@microsoft.com>
+
+commit 1254100030b3377e8302f9c75090ab191d73ee7c upstream.
+
+Mid callback needs to be called only when valid data is
+read into pages.
+
+These patches address a problem found during decryption offload:
+ CIFS: VFS: trying to dequeue a deleted mid
+that could cause a refcount use after free:
+ Workqueue: smb3decryptd smb2_decrypt_offload [cifs]
+
+Signed-off-by: Rohith Surabattula <rohiths@microsoft.com>
+Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
+CC: Stable <stable@vger.kernel.org> #5.4+
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smb2ops.c | 20 +++++++++++++++++++-
+ 1 file changed, 19 insertions(+), 1 deletion(-)
+
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -4183,7 +4183,25 @@ static void smb2_decrypt_offload(struct
+ dw->server->vals->read_rsp_size,
+ dw->ppages, dw->npages, dw->len,
+ true);
+- mid->callback(mid);
++ if (rc >= 0) {
++#ifdef CONFIG_CIFS_STATS2
++ mid->when_received = jiffies;
++#endif
++ mid->callback(mid);
++ } else {
++ spin_lock(&GlobalMid_Lock);
++ if (dw->server->tcpStatus == CifsNeedReconnect) {
++ mid->mid_state = MID_RETRY_NEEDED;
++ spin_unlock(&GlobalMid_Lock);
++ mid->callback(mid);
++ } else {
++ mid->mid_state = MID_REQUEST_SUBMITTED;
++ mid->mid_flags &= ~(MID_DELETED);
++ list_add_tail(&mid->qhead,
++ &dw->server->pending_mid_q);
++ spin_unlock(&GlobalMid_Lock);
++ }
++ }
+ cifs_mid_q_entry_release(mid);
+ }
+