From aaf49b40dd9a063b345d203ee7254592b997bc56 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 10 Jul 2018 14:18:40 +0200 Subject: [PATCH] 4.14-stable patches added patches: arm64-use-aarch64elf-and-aarch64elfb-emulation-mode-variants.patch cifs-fix-infinite-loop-when-using-hard-mount-option.patch cifs-fix-memory-leak-in-smb2_set_ea.patch cifs-fix-slab-out-of-bounds-in-send_set_info-on-smb2-ace-setting.patch cifs-fix-use-after-free-of-a-mid_q_entry.patch drbd-fix-access-after-free.patch s390-correct-register-corruption-in-critical-section-cleanup.patch scsi-target-fix-truncated-pr-in-readkeys-response.patch vfio-use-get_user_pages_longterm-correctly.patch --- ...-aarch64elfb-emulation-mode-variants.patch | 48 +++++ ...te-loop-when-using-hard-mount-option.patch | 129 +++++++++++++ .../cifs-fix-memory-leak-in-smb2_set_ea.patch | 32 +++ ...in-send_set_info-on-smb2-ace-setting.patch | 140 ++++++++++++++ ...-fix-use-after-free-of-a-mid_q_entry.patch | 182 ++++++++++++++++++ queue-4.14/drbd-fix-access-after-free.patch | 73 +++++++ ...rruption-in-critical-section-cleanup.patch | 51 +++++ ...ix-truncated-pr-in-readkeys-response.patch | 58 ++++++ queue-4.14/series | 9 + ...se-get_user_pages_longterm-correctly.patch | 68 +++++++ 10 files changed, 790 insertions(+) create mode 100644 queue-4.14/arm64-use-aarch64elf-and-aarch64elfb-emulation-mode-variants.patch create mode 100644 queue-4.14/cifs-fix-infinite-loop-when-using-hard-mount-option.patch create mode 100644 queue-4.14/cifs-fix-memory-leak-in-smb2_set_ea.patch create mode 100644 queue-4.14/cifs-fix-slab-out-of-bounds-in-send_set_info-on-smb2-ace-setting.patch create mode 100644 queue-4.14/cifs-fix-use-after-free-of-a-mid_q_entry.patch create mode 100644 queue-4.14/drbd-fix-access-after-free.patch create mode 100644 queue-4.14/s390-correct-register-corruption-in-critical-section-cleanup.patch create mode 100644 queue-4.14/scsi-target-fix-truncated-pr-in-readkeys-response.patch create mode 100644 queue-4.14/vfio-use-get_user_pages_longterm-correctly.patch diff --git a/queue-4.14/arm64-use-aarch64elf-and-aarch64elfb-emulation-mode-variants.patch b/queue-4.14/arm64-use-aarch64elf-and-aarch64elfb-emulation-mode-variants.patch new file mode 100644 index 00000000000..a7f3bbdea56 --- /dev/null +++ b/queue-4.14/arm64-use-aarch64elf-and-aarch64elfb-emulation-mode-variants.patch @@ -0,0 +1,48 @@ +From 38fc4248677552ce35efc09902fdcb06b61d7ef9 Mon Sep 17 00:00:00 2001 +From: Paul Kocialkowski +Date: Mon, 2 Jul 2018 11:16:59 +0200 +Subject: arm64: Use aarch64elf and aarch64elfb emulation mode variants + +From: Paul Kocialkowski + +commit 38fc4248677552ce35efc09902fdcb06b61d7ef9 upstream. + +The aarch64linux and aarch64linuxb emulation modes are not supported by +bare-metal toolchains and Linux using them forbids building the kernel +with these toolchains. + +Since there is apparently no reason to target these emulation modes, the +more generic elf modes are used instead, allowing to build on bare-metal +toolchains as well as the already-supported ones. + +Fixes: 3d6a7b99e3fa ("arm64: ensure the kernel is compiled for LP64") + +Cc: stable@vger.kernel.org +Acked-by: Will Deacon +Signed-off-by: Paul Kocialkowski +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm64/Makefile ++++ b/arch/arm64/Makefile +@@ -62,14 +62,14 @@ KBUILD_CPPFLAGS += -mbig-endian + CHECKFLAGS += -D__AARCH64EB__ + AS += -EB + LD += -EB +-LDFLAGS += -maarch64linuxb ++LDFLAGS += -maarch64elfb + UTS_MACHINE := aarch64_be + else + KBUILD_CPPFLAGS += -mlittle-endian + CHECKFLAGS += -D__AARCH64EL__ + AS += -EL + LD += -EL +-LDFLAGS += -maarch64linux ++LDFLAGS += -maarch64elf + UTS_MACHINE := aarch64 + endif + diff --git a/queue-4.14/cifs-fix-infinite-loop-when-using-hard-mount-option.patch b/queue-4.14/cifs-fix-infinite-loop-when-using-hard-mount-option.patch new file mode 100644 index 00000000000..bcdfc7a5872 --- /dev/null +++ b/queue-4.14/cifs-fix-infinite-loop-when-using-hard-mount-option.patch @@ -0,0 +1,129 @@ +From 7ffbe65578b44fafdef577a360eb0583929f7c6e Mon Sep 17 00:00:00 2001 +From: Paulo Alcantara +Date: Thu, 5 Jul 2018 13:46:34 -0300 +Subject: cifs: Fix infinite loop when using hard mount option + +From: Paulo Alcantara + +commit 7ffbe65578b44fafdef577a360eb0583929f7c6e upstream. + +For every request we send, whether it is SMB1 or SMB2+, we attempt to +reconnect tcon (cifs_reconnect_tcon or smb2_reconnect) before carrying +out the request. + +So, while server->tcpStatus != CifsNeedReconnect, we wait for the +reconnection to succeed on wait_event_interruptible_timeout(). If it +returns, that means that either the condition was evaluated to true, or +timeout elapsed, or it was interrupted by a signal. + +Since we're not handling the case where the process woke up due to a +received signal (-ERESTARTSYS), the next call to +wait_event_interruptible_timeout() will _always_ fail and we end up +looping forever inside either cifs_reconnect_tcon() or smb2_reconnect(). + +Here's an example of how to trigger that: + +$ mount.cifs //foo/share /mnt/test -o +username=foo,password=foo,vers=1.0,hard + +(break connection to server before executing bellow cmd) +$ stat -f /mnt/test & sleep 140 +[1] 2511 + +$ ps -aux -q 2511 +USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND +root 2511 0.0 0.0 12892 1008 pts/0 S 12:24 0:00 stat -f +/mnt/test + +$ kill -9 2511 + +(wait for a while; process is stuck in the kernel) +$ ps -aux -q 2511 +USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND +root 2511 83.2 0.0 12892 1008 pts/0 R 12:24 30:01 stat -f +/mnt/test + +By using 'hard' mount point means that cifs.ko will keep retrying +indefinitely, however we must allow the process to be killed otherwise +it would hang the system. + +Signed-off-by: Paulo Alcantara +Cc: stable@vger.kernel.org +Reviewed-by: Aurelien Aptel +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/cifssmb.c | 10 ++++++++-- + fs/cifs/smb2pdu.c | 18 ++++++++++++------ + 2 files changed, 20 insertions(+), 8 deletions(-) + +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -150,8 +150,14 @@ cifs_reconnect_tcon(struct cifs_tcon *tc + * greater than cifs socket timeout which is 7 seconds + */ + while (server->tcpStatus == CifsNeedReconnect) { +- wait_event_interruptible_timeout(server->response_q, +- (server->tcpStatus != CifsNeedReconnect), 10 * HZ); ++ rc = wait_event_interruptible_timeout(server->response_q, ++ (server->tcpStatus != CifsNeedReconnect), ++ 10 * HZ); ++ if (rc < 0) { ++ cifs_dbg(FYI, "%s: aborting reconnect due to a received" ++ " signal by the process\n", __func__); ++ return -ERESTARTSYS; ++ } + + /* are we still trying to reconnect? */ + if (server->tcpStatus != CifsNeedReconnect) +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -153,7 +153,7 @@ out: + static int + smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon) + { +- int rc = 0; ++ int rc; + struct nls_table *nls_codepage; + struct cifs_ses *ses; + struct TCP_Server_Info *server; +@@ -164,10 +164,10 @@ smb2_reconnect(__le16 smb2_command, stru + * for those three - in the calling routine. + */ + if (tcon == NULL) +- return rc; ++ return 0; + + if (smb2_command == SMB2_TREE_CONNECT) +- return rc; ++ return 0; + + if (tcon->tidStatus == CifsExiting) { + /* +@@ -210,8 +210,14 @@ smb2_reconnect(__le16 smb2_command, stru + return -EAGAIN; + } + +- wait_event_interruptible_timeout(server->response_q, +- (server->tcpStatus != CifsNeedReconnect), 10 * HZ); ++ rc = wait_event_interruptible_timeout(server->response_q, ++ (server->tcpStatus != CifsNeedReconnect), ++ 10 * HZ); ++ if (rc < 0) { ++ cifs_dbg(FYI, "%s: aborting reconnect due to a received" ++ " signal by the process\n", __func__); ++ return -ERESTARTSYS; ++ } + + /* are we still trying to reconnect? */ + if (server->tcpStatus != CifsNeedReconnect) +@@ -229,7 +235,7 @@ smb2_reconnect(__le16 smb2_command, stru + } + + if (!tcon->ses->need_reconnect && !tcon->need_reconnect) +- return rc; ++ return 0; + + nls_codepage = load_nls_default(); + diff --git a/queue-4.14/cifs-fix-memory-leak-in-smb2_set_ea.patch b/queue-4.14/cifs-fix-memory-leak-in-smb2_set_ea.patch new file mode 100644 index 00000000000..fcf3ee60e33 --- /dev/null +++ b/queue-4.14/cifs-fix-memory-leak-in-smb2_set_ea.patch @@ -0,0 +1,32 @@ +From 6aa0c114eceec8cc61715f74a4ce91b048d7561c Mon Sep 17 00:00:00 2001 +From: Paulo Alcantara +Date: Wed, 4 Jul 2018 14:16:16 -0300 +Subject: cifs: Fix memory leak in smb2_set_ea() + +From: Paulo Alcantara + +commit 6aa0c114eceec8cc61715f74a4ce91b048d7561c upstream. + +This patch fixes a memory leak when doing a setxattr(2) in SMB2+. + +Signed-off-by: Paulo Alcantara +Cc: stable@vger.kernel.org +Signed-off-by: Steve French +Reviewed-by: Aurelien Aptel +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/smb2ops.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -636,6 +636,8 @@ smb2_set_ea(const unsigned int xid, stru + + rc = SMB2_set_ea(xid, tcon, fid.persistent_fid, fid.volatile_fid, ea, + len); ++ kfree(ea); ++ + SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); + + return rc; diff --git a/queue-4.14/cifs-fix-slab-out-of-bounds-in-send_set_info-on-smb2-ace-setting.patch b/queue-4.14/cifs-fix-slab-out-of-bounds-in-send_set_info-on-smb2-ace-setting.patch new file mode 100644 index 00000000000..bf85a50a6ad --- /dev/null +++ b/queue-4.14/cifs-fix-slab-out-of-bounds-in-send_set_info-on-smb2-ace-setting.patch @@ -0,0 +1,140 @@ +From f46ecbd97f508e68a7806291a139499794874f3d Mon Sep 17 00:00:00 2001 +From: Stefano Brivio +Date: Thu, 5 Jul 2018 11:46:42 +0200 +Subject: cifs: Fix slab-out-of-bounds in send_set_info() on SMB2 ACE setting + +From: Stefano Brivio + +commit f46ecbd97f508e68a7806291a139499794874f3d upstream. + +A "small" CIFS buffer is not big enough in general to hold a +setacl request for SMB2, and we end up overflowing the buffer in +send_set_info(). For instance: + + # mount.cifs //127.0.0.1/test /mnt/test -o username=test,password=test,nounix,cifsacl + # touch /mnt/test/acltest + # getcifsacl /mnt/test/acltest + REVISION:0x1 + CONTROL:0x9004 + OWNER:S-1-5-21-2926364953-924364008-418108241-1000 + GROUP:S-1-22-2-1001 + ACL:S-1-5-21-2926364953-924364008-418108241-1000:ALLOWED/0x0/0x1e01ff + ACL:S-1-22-2-1001:ALLOWED/0x0/R + ACL:S-1-22-2-1001:ALLOWED/0x0/R + ACL:S-1-5-21-2926364953-924364008-418108241-1000:ALLOWED/0x0/0x1e01ff + ACL:S-1-1-0:ALLOWED/0x0/R + # setcifsacl -a "ACL:S-1-22-2-1004:ALLOWED/0x0/R" /mnt/test/acltest + +this setacl will cause the following KASAN splat: + +[ 330.777927] BUG: KASAN: slab-out-of-bounds in send_set_info+0x4dd/0xc20 [cifs] +[ 330.779696] Write of size 696 at addr ffff88010d5e2860 by task setcifsacl/1012 + +[ 330.781882] CPU: 1 PID: 1012 Comm: setcifsacl Not tainted 4.18.0-rc2+ #2 +[ 330.783140] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014 +[ 330.784395] Call Trace: +[ 330.784789] dump_stack+0xc2/0x16b +[ 330.786777] print_address_description+0x6a/0x270 +[ 330.787520] kasan_report+0x258/0x380 +[ 330.788845] memcpy+0x34/0x50 +[ 330.789369] send_set_info+0x4dd/0xc20 [cifs] +[ 330.799511] SMB2_set_acl+0x76/0xa0 [cifs] +[ 330.801395] set_smb2_acl+0x7ac/0xf30 [cifs] +[ 330.830888] cifs_xattr_set+0x963/0xe40 [cifs] +[ 330.840367] __vfs_setxattr+0x84/0xb0 +[ 330.842060] __vfs_setxattr_noperm+0xe6/0x370 +[ 330.843848] vfs_setxattr+0xc2/0xd0 +[ 330.845519] setxattr+0x258/0x320 +[ 330.859211] path_setxattr+0x15b/0x1b0 +[ 330.864392] __x64_sys_setxattr+0xc0/0x160 +[ 330.866133] do_syscall_64+0x14e/0x4b0 +[ 330.876631] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[ 330.878503] RIP: 0033:0x7ff2e507db0a +[ 330.880151] Code: 48 8b 0d 89 93 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 bc 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 56 93 2c 00 f7 d8 64 89 01 48 +[ 330.885358] RSP: 002b:00007ffdc4903c18 EFLAGS: 00000246 ORIG_RAX: 00000000000000bc +[ 330.887733] RAX: ffffffffffffffda RBX: 000055d1170de140 RCX: 00007ff2e507db0a +[ 330.890067] RDX: 000055d1170de7d0 RSI: 000055d115b39184 RDI: 00007ffdc4904818 +[ 330.892410] RBP: 0000000000000001 R08: 0000000000000000 R09: 000055d1170de7e4 +[ 330.894785] R10: 00000000000002b8 R11: 0000000000000246 R12: 0000000000000007 +[ 330.897148] R13: 000055d1170de0c0 R14: 0000000000000008 R15: 000055d1170de550 + +[ 330.901057] Allocated by task 1012: +[ 330.902888] kasan_kmalloc+0xa0/0xd0 +[ 330.904714] kmem_cache_alloc+0xc8/0x1d0 +[ 330.906615] mempool_alloc+0x11e/0x380 +[ 330.908496] cifs_small_buf_get+0x35/0x60 [cifs] +[ 330.910510] smb2_plain_req_init+0x4a/0xd60 [cifs] +[ 330.912551] send_set_info+0x198/0xc20 [cifs] +[ 330.914535] SMB2_set_acl+0x76/0xa0 [cifs] +[ 330.916465] set_smb2_acl+0x7ac/0xf30 [cifs] +[ 330.918453] cifs_xattr_set+0x963/0xe40 [cifs] +[ 330.920426] __vfs_setxattr+0x84/0xb0 +[ 330.922284] __vfs_setxattr_noperm+0xe6/0x370 +[ 330.924213] vfs_setxattr+0xc2/0xd0 +[ 330.926008] setxattr+0x258/0x320 +[ 330.927762] path_setxattr+0x15b/0x1b0 +[ 330.929592] __x64_sys_setxattr+0xc0/0x160 +[ 330.931459] do_syscall_64+0x14e/0x4b0 +[ 330.933314] entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +[ 330.936843] Freed by task 0: +[ 330.938588] (stack is not available) + +[ 330.941886] The buggy address belongs to the object at ffff88010d5e2800 + which belongs to the cache cifs_small_rq of size 448 +[ 330.946362] The buggy address is located 96 bytes inside of + 448-byte region [ffff88010d5e2800, ffff88010d5e29c0) +[ 330.950722] The buggy address belongs to the page: +[ 330.952789] page:ffffea0004357880 count:1 mapcount:0 mapping:ffff880108fdca80 index:0x0 compound_mapcount: 0 +[ 330.955665] flags: 0x17ffffc0008100(slab|head) +[ 330.957760] raw: 0017ffffc0008100 dead000000000100 dead000000000200 ffff880108fdca80 +[ 330.960356] raw: 0000000000000000 0000000080100010 00000001ffffffff 0000000000000000 +[ 330.963005] page dumped because: kasan: bad access detected + +[ 330.967039] Memory state around the buggy address: +[ 330.969255] ffff88010d5e2880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +[ 330.971833] ffff88010d5e2900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +[ 330.974397] >ffff88010d5e2980: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc +[ 330.976956] ^ +[ 330.979226] ffff88010d5e2a00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +[ 330.981755] ffff88010d5e2a80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +[ 330.984225] ================================================================== + +Fix this by allocating a regular CIFS buffer in +smb2_plain_req_init() if the request command is SMB2_SET_INFO. + +Reported-by: Jianhong Yin +Fixes: 366ed846df60 ("cifs: Use smb 2 - 3 and cifsacl mount options setacl function") +CC: Stable +Signed-off-by: Stefano Brivio +Reviewed-and-tested-by: Aurelien Aptel +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/smb2pdu.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -338,7 +338,10 @@ smb2_plain_req_init(__le16 smb2_command, + return rc; + + /* BB eventually switch this to SMB2 specific small buf size */ +- *request_buf = cifs_small_buf_get(); ++ if (smb2_command == SMB2_SET_INFO) ++ *request_buf = cifs_buf_get(); ++ else ++ *request_buf = cifs_small_buf_get(); + if (*request_buf == NULL) { + /* BB should we add a retry in here if not a writepage? */ + return -ENOMEM; +@@ -3168,7 +3171,7 @@ send_set_info(const unsigned int xid, st + } + + rc = SendReceive2(xid, ses, iov, num, &resp_buftype, flags, &rsp_iov); +- cifs_small_buf_release(req); ++ cifs_buf_release(req); + rsp = (struct smb2_set_info_rsp *)rsp_iov.iov_base; + + if (rc != 0) diff --git a/queue-4.14/cifs-fix-use-after-free-of-a-mid_q_entry.patch b/queue-4.14/cifs-fix-use-after-free-of-a-mid_q_entry.patch new file mode 100644 index 00000000000..c08dfb7e643 --- /dev/null +++ b/queue-4.14/cifs-fix-use-after-free-of-a-mid_q_entry.patch @@ -0,0 +1,182 @@ +From 696e420bb2a6624478105651d5368d45b502b324 Mon Sep 17 00:00:00 2001 +From: Lars Persson +Date: Mon, 25 Jun 2018 14:05:25 +0200 +Subject: cifs: Fix use after free of a mid_q_entry + +From: Lars Persson + +commit 696e420bb2a6624478105651d5368d45b502b324 upstream. + +With protocol version 2.0 mounts we have seen crashes with corrupt mid +entries. Either the server->pending_mid_q list becomes corrupt with a +cyclic reference in one element or a mid object fetched by the +demultiplexer thread becomes overwritten during use. + +Code review identified a race between the demultiplexer thread and the +request issuing thread. The demultiplexer thread seems to be written +with the assumption that it is the sole user of the mid object until +it calls the mid callback which either wakes the issuer task or +deletes the mid. + +This assumption is not true because the issuer task can be woken up +earlier by a signal. If the demultiplexer thread has proceeded as far +as setting the mid_state to MID_RESPONSE_RECEIVED then the issuer +thread will happily end up calling cifs_delete_mid while the +demultiplexer thread still is using the mid object. + +Inserting a delay in the cifs demultiplexer thread widens the race +window and makes reproduction of the race very easy: + + if (server->large_buf) + buf = server->bigbuf; + ++ usleep_range(500, 4000); + + server->lstrp = jiffies; + +To resolve this I think the proper solution involves putting a +reference count on the mid object. This patch makes sure that the +demultiplexer thread holds a reference until it has finished +processing the transaction. + +Cc: stable@vger.kernel.org +Signed-off-by: Lars Persson +Acked-by: Paulo Alcantara +Reviewed-by: Ronnie Sahlberg +Reviewed-by: Pavel Shilovsky +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/cifsglob.h | 1 + + fs/cifs/cifsproto.h | 1 + + fs/cifs/connect.c | 8 +++++++- + fs/cifs/smb1ops.c | 1 + + fs/cifs/smb2ops.c | 1 + + fs/cifs/smb2transport.c | 1 + + fs/cifs/transport.c | 18 +++++++++++++++++- + 7 files changed, 29 insertions(+), 2 deletions(-) + +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -1340,6 +1340,7 @@ typedef int (mid_handle_t)(struct TCP_Se + /* one of these for every pending CIFS request to the server */ + struct mid_q_entry { + struct list_head qhead; /* mids waiting on reply from this server */ ++ struct kref refcount; + struct TCP_Server_Info *server; /* server corresponding to this mid */ + __u64 mid; /* multiplex id */ + __u32 pid; /* process id */ +--- a/fs/cifs/cifsproto.h ++++ b/fs/cifs/cifsproto.h +@@ -76,6 +76,7 @@ extern struct mid_q_entry *AllocMidQEntr + struct TCP_Server_Info *server); + extern void DeleteMidQEntry(struct mid_q_entry *midEntry); + extern void cifs_delete_mid(struct mid_q_entry *mid); ++extern void cifs_mid_q_entry_release(struct mid_q_entry *midEntry); + extern void cifs_wake_up_task(struct mid_q_entry *mid); + extern int cifs_handle_standard(struct TCP_Server_Info *server, + struct mid_q_entry *mid); +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -889,6 +889,7 @@ cifs_demultiplex_thread(void *p) + continue; + server->total_read += length; + ++ mid_entry = NULL; + if (server->ops->is_transform_hdr && + server->ops->receive_transform && + server->ops->is_transform_hdr(buf)) { +@@ -903,8 +904,11 @@ cifs_demultiplex_thread(void *p) + length = mid_entry->receive(server, mid_entry); + } + +- if (length < 0) ++ if (length < 0) { ++ if (mid_entry) ++ cifs_mid_q_entry_release(mid_entry); + continue; ++ } + + if (server->large_buf) + buf = server->bigbuf; +@@ -920,6 +924,8 @@ cifs_demultiplex_thread(void *p) + + if (!mid_entry->multiRsp || mid_entry->multiEnd) + mid_entry->callback(mid_entry); ++ ++ cifs_mid_q_entry_release(mid_entry); + } else if (server->ops->is_oplock_break && + server->ops->is_oplock_break(buf, server)) { + cifs_dbg(FYI, "Received oplock break\n"); +--- a/fs/cifs/smb1ops.c ++++ b/fs/cifs/smb1ops.c +@@ -105,6 +105,7 @@ cifs_find_mid(struct TCP_Server_Info *se + if (compare_mid(mid->mid, buf) && + mid->mid_state == MID_REQUEST_SUBMITTED && + le16_to_cpu(mid->command) == buf->Command) { ++ kref_get(&mid->refcount); + spin_unlock(&GlobalMid_Lock); + return mid; + } +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -202,6 +202,7 @@ smb2_find_mid(struct TCP_Server_Info *se + if ((mid->mid == wire_mid) && + (mid->mid_state == MID_REQUEST_SUBMITTED) && + (mid->command == shdr->Command)) { ++ kref_get(&mid->refcount); + spin_unlock(&GlobalMid_Lock); + return mid; + } +--- a/fs/cifs/smb2transport.c ++++ b/fs/cifs/smb2transport.c +@@ -548,6 +548,7 @@ smb2_mid_entry_alloc(const struct smb2_s + + temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS); + memset(temp, 0, sizeof(struct mid_q_entry)); ++ kref_init(&temp->refcount); + temp->mid = le64_to_cpu(shdr->MessageId); + temp->pid = current->pid; + temp->command = shdr->Command; /* Always LE */ +--- a/fs/cifs/transport.c ++++ b/fs/cifs/transport.c +@@ -56,6 +56,7 @@ AllocMidQEntry(const struct smb_hdr *smb + + temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS); + memset(temp, 0, sizeof(struct mid_q_entry)); ++ kref_init(&temp->refcount); + temp->mid = get_mid(smb_buffer); + temp->pid = current->pid; + temp->command = cpu_to_le16(smb_buffer->Command); +@@ -77,6 +78,21 @@ AllocMidQEntry(const struct smb_hdr *smb + return temp; + } + ++static void _cifs_mid_q_entry_release(struct kref *refcount) ++{ ++ struct mid_q_entry *mid = container_of(refcount, struct mid_q_entry, ++ refcount); ++ ++ mempool_free(mid, cifs_mid_poolp); ++} ++ ++void cifs_mid_q_entry_release(struct mid_q_entry *midEntry) ++{ ++ spin_lock(&GlobalMid_Lock); ++ kref_put(&midEntry->refcount, _cifs_mid_q_entry_release); ++ spin_unlock(&GlobalMid_Lock); ++} ++ + void + DeleteMidQEntry(struct mid_q_entry *midEntry) + { +@@ -105,7 +121,7 @@ DeleteMidQEntry(struct mid_q_entry *midE + } + } + #endif +- mempool_free(midEntry, cifs_mid_poolp); ++ cifs_mid_q_entry_release(midEntry); + } + + void diff --git a/queue-4.14/drbd-fix-access-after-free.patch b/queue-4.14/drbd-fix-access-after-free.patch new file mode 100644 index 00000000000..a7fad65fc53 --- /dev/null +++ b/queue-4.14/drbd-fix-access-after-free.patch @@ -0,0 +1,73 @@ +From 64dafbc9530c10300acffc57fae3269d95fa8f93 Mon Sep 17 00:00:00 2001 +From: Lars Ellenberg +Date: Mon, 25 Jun 2018 11:39:52 +0200 +Subject: drbd: fix access after free + +From: Lars Ellenberg + +commit 64dafbc9530c10300acffc57fae3269d95fa8f93 upstream. + +We have + struct drbd_requests { ... struct bio *private_bio; ... } +to hold a bio clone for local submission. + +On local IO completion, we put that bio, and in case we want to use the +result later, we overload that member to hold the ERR_PTR() of the +completion result, + +Which, before v4.3, used to be the passed in "int error", +so we could first bio_put(), then assign. + +v4.3-rc1~100^2~21 4246a0b63bd8 block: add a bi_error field to struct bio +changed that: + bio_put(req->private_bio); + - req->private_bio = ERR_PTR(error); + + req->private_bio = ERR_PTR(bio->bi_error); + +Which introduces an access after free, +because it was non obvious that req->private_bio == bio. + +Impact of that was mostly unnoticable, because we only use that value +in a multiple-failure case, and even then map any "unexpected" error +code to EIO, so worst case we could potentially mask a more specific +error with EIO in a multiple failure case. + +Unless the pointed to memory region was unmapped, as is the case with +CONFIG_DEBUG_PAGEALLOC, in which case this results in + + BUG: unable to handle kernel paging request + +v4.13-rc1~70^2~75 4e4cbee93d56 block: switch bios to blk_status_t +changes it further to + bio_put(req->private_bio); + req->private_bio = ERR_PTR(blk_status_to_errno(bio->bi_status)); + +And blk_status_to_errno() now contains a WARN_ON_ONCE() for unexpected +values, which catches this "sometimes", if the memory has been reused +quickly enough for other things. + +Should also go into stable since 4.3, with the trivial change around 4.13. + +Cc: stable@vger.kernel.org +Fixes: 4246a0b63bd8 block: add a bi_error field to struct bio +Reported-by: Sarah Newman +Signed-off-by: Lars Ellenberg +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/drbd/drbd_worker.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/block/drbd/drbd_worker.c ++++ b/drivers/block/drbd/drbd_worker.c +@@ -282,8 +282,8 @@ void drbd_request_endio(struct bio *bio) + what = COMPLETED_OK; + } + +- bio_put(req->private_bio); + req->private_bio = ERR_PTR(blk_status_to_errno(bio->bi_status)); ++ bio_put(bio); + + /* not req_mod(), we need irqsave here! */ + spin_lock_irqsave(&device->resource->req_lock, flags); diff --git a/queue-4.14/s390-correct-register-corruption-in-critical-section-cleanup.patch b/queue-4.14/s390-correct-register-corruption-in-critical-section-cleanup.patch new file mode 100644 index 00000000000..95424b5ab36 --- /dev/null +++ b/queue-4.14/s390-correct-register-corruption-in-critical-section-cleanup.patch @@ -0,0 +1,51 @@ +From 891f6a726cacbb87e5b06076693ffab53bd378d7 Mon Sep 17 00:00:00 2001 +From: Christian Borntraeger +Date: Thu, 21 Jun 2018 14:49:38 +0200 +Subject: s390: Correct register corruption in critical section cleanup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Christian Borntraeger + +commit 891f6a726cacbb87e5b06076693ffab53bd378d7 upstream. + +In the critical section cleanup we must not mess with r1. For march=z9 +or older, larl + ex (instead of exrl) are used with r1 as a temporary +register. This can clobber r1 in several interrupt handlers. Fix this by +using r11 as a temp register. r11 is being saved by all callers of +cleanup_critical. + +Fixes: 6dd85fbb87 ("s390: move expoline assembler macros to a header") +Cc: stable@vger.kernel.org #v4.16 +Reported-by: Oliver Kurz +Reported-by: Petr Tesařík +Signed-off-by: Christian Borntraeger +Reviewed-by: Hendrik Brueckner +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/kernel/entry.S | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/s390/kernel/entry.S ++++ b/arch/s390/kernel/entry.S +@@ -1244,7 +1244,7 @@ cleanup_critical: + jl 0f + clg %r9,BASED(.Lcleanup_table+104) # .Lload_fpu_regs_end + jl .Lcleanup_load_fpu_regs +-0: BR_EX %r14 ++0: BR_EX %r14,%r11 + + .align 8 + .Lcleanup_table: +@@ -1280,7 +1280,7 @@ cleanup_critical: + ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE + lctlg %c1,%c1,__LC_USER_ASCE # load primary asce + larl %r9,sie_exit # skip forward to sie_exit +- BR_EX %r14 ++ BR_EX %r14,%r11 + #endif + + .Lcleanup_system_call: diff --git a/queue-4.14/scsi-target-fix-truncated-pr-in-readkeys-response.patch b/queue-4.14/scsi-target-fix-truncated-pr-in-readkeys-response.patch new file mode 100644 index 00000000000..c7d78e55c9f --- /dev/null +++ b/queue-4.14/scsi-target-fix-truncated-pr-in-readkeys-response.patch @@ -0,0 +1,58 @@ +From 63ce3c384db26494615e3c8972bcd419ed71f4c4 Mon Sep 17 00:00:00 2001 +From: David Disseldorp +Date: Tue, 19 Jun 2018 17:58:24 +0200 +Subject: scsi: target: Fix truncated PR-in ReadKeys response + +From: David Disseldorp + +commit 63ce3c384db26494615e3c8972bcd419ed71f4c4 upstream. + +SPC5r17 states that the contents of the ADDITIONAL LENGTH field are not +altered based on the allocation length, so always calculate and pack the +full key list length even if the list itself is truncated. + +According to Maged: + + Yes it fixes the "Storage Spaces Persistent Reservation" test in the + Windows 2016 Server Failover Cluster validation suites when having + many connections that result in more than 8 registrations. I tested + your patch on 4.17 with iblock. + +This behaviour can be tested using the libiscsi PrinReadKeys.Truncate test. + +Cc: stable@vger.kernel.org +Signed-off-by: David Disseldorp +Reviewed-by: Mike Christie +Tested-by: Maged Mokhtar +Reviewed-by: Christoph Hellwig +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_pr.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/drivers/target/target_core_pr.c ++++ b/drivers/target/target_core_pr.c +@@ -3729,11 +3729,16 @@ core_scsi3_pri_read_keys(struct se_cmd * + * Check for overflow of 8byte PRI READ_KEYS payload and + * next reservation key list descriptor. + */ +- if ((add_len + 8) > (cmd->data_length - 8)) +- break; +- +- put_unaligned_be64(pr_reg->pr_res_key, &buf[off]); +- off += 8; ++ if (off + 8 <= cmd->data_length) { ++ put_unaligned_be64(pr_reg->pr_res_key, &buf[off]); ++ off += 8; ++ } ++ /* ++ * SPC5r17: 6.16.2 READ KEYS service action ++ * The ADDITIONAL LENGTH field indicates the number of bytes in ++ * the Reservation key list. The contents of the ADDITIONAL ++ * LENGTH field are not altered based on the allocation length ++ */ + add_len += 8; + } + spin_unlock(&dev->t10_pr.registration_lock); diff --git a/queue-4.14/series b/queue-4.14/series index ebe1e788ada..6bcde2399c7 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -2,3 +2,12 @@ userfaultfd-hugetlbfs-fix-userfaultfd_huge_must_wait-pte-access.patch mm-hugetlb-yield-when-prepping-struct-pages.patch tracing-fix-missing-return-symbol-in-function_graph-output.patch scsi-sg-mitigate-read-write-abuse.patch +scsi-target-fix-truncated-pr-in-readkeys-response.patch +s390-correct-register-corruption-in-critical-section-cleanup.patch +drbd-fix-access-after-free.patch +vfio-use-get_user_pages_longterm-correctly.patch +arm64-use-aarch64elf-and-aarch64elfb-emulation-mode-variants.patch +cifs-fix-use-after-free-of-a-mid_q_entry.patch +cifs-fix-memory-leak-in-smb2_set_ea.patch +cifs-fix-infinite-loop-when-using-hard-mount-option.patch +cifs-fix-slab-out-of-bounds-in-send_set_info-on-smb2-ace-setting.patch diff --git a/queue-4.14/vfio-use-get_user_pages_longterm-correctly.patch b/queue-4.14/vfio-use-get_user_pages_longterm-correctly.patch new file mode 100644 index 00000000000..4b12402a8cc --- /dev/null +++ b/queue-4.14/vfio-use-get_user_pages_longterm-correctly.patch @@ -0,0 +1,68 @@ +From bb94b55af3461e26b32f0e23d455abeae0cfca5d Mon Sep 17 00:00:00 2001 +From: Jason Gunthorpe +Date: Fri, 29 Jun 2018 11:31:50 -0600 +Subject: vfio: Use get_user_pages_longterm correctly + +From: Jason Gunthorpe + +commit bb94b55af3461e26b32f0e23d455abeae0cfca5d upstream. + +The patch noted in the fixes below converted get_user_pages_fast() to +get_user_pages_longterm(), however the two calls differ in a few ways. + +First _fast() is documented to not require the mmap_sem, while _longterm() +is documented to need it. Hold the mmap sem as required. + +Second, _fast accepts an 'int write' while _longterm uses 'unsigned int +gup_flags', so the expression '!!(prot & IOMMU_WRITE)' is only working by +luck as FOLL_WRITE is currently == 0x1. Use the expected FOLL_WRITE +constant instead. + +Fixes: 94db151dc892 ("vfio: disable filesystem-dax page pinning") +Cc: +Signed-off-by: Jason Gunthorpe +Acked-by: Dan Williams +Signed-off-by: Alex Williamson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/vfio/vfio_iommu_type1.c | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +--- a/drivers/vfio/vfio_iommu_type1.c ++++ b/drivers/vfio/vfio_iommu_type1.c +@@ -339,18 +339,16 @@ static int vaddr_get_pfn(struct mm_struc + struct page *page[1]; + struct vm_area_struct *vma; + struct vm_area_struct *vmas[1]; ++ unsigned int flags = 0; + int ret; + ++ if (prot & IOMMU_WRITE) ++ flags |= FOLL_WRITE; ++ ++ down_read(&mm->mmap_sem); + if (mm == current->mm) { +- ret = get_user_pages_longterm(vaddr, 1, !!(prot & IOMMU_WRITE), +- page, vmas); ++ ret = get_user_pages_longterm(vaddr, 1, flags, page, vmas); + } else { +- unsigned int flags = 0; +- +- if (prot & IOMMU_WRITE) +- flags |= FOLL_WRITE; +- +- down_read(&mm->mmap_sem); + ret = get_user_pages_remote(NULL, mm, vaddr, 1, flags, page, + vmas, NULL); + /* +@@ -364,8 +362,8 @@ static int vaddr_get_pfn(struct mm_struc + ret = -EOPNOTSUPP; + put_page(page[0]); + } +- up_read(&mm->mmap_sem); + } ++ up_read(&mm->mmap_sem); + + if (ret == 1) { + *pfn = page_to_pfn(page[0]); -- 2.47.3