diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index f2ff60e..3963bd2 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -1559,6 +1559,9 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
        } else
                iov[0].iov_len = get_rfc1002_length(req) + 4;
 
+       /* validate negotiate request must be signed - see MS-SMB2 3.2.5.5 */
+       if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO)
+               req->hdr.Flags |= SMB2_FLAGS_SIGNED;
 
        rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
        rsp = (struct smb2_ioctl_rsp *)iov[0].iov_base;


This results in the following NULL pointer dereference when I try
mounting:

# mount -vvv -t cifs -o vers=3.0,credentials=.smbcred //<ip_addr>/TestSMB/ testdir

[   53.073057] BUG: unable to handle kernel NULL pointer dereference at 0000000000000050
[   53.073511] IP: [<ffffffff8138ee9a>] crypto_shash_setkey+0x1a/0xc0
[   53.073973] PGD 0 
[   53.074427] Oops: 0000 [#1] SMP 
[   53.074946] Modules linked in: arc4(E) ecb(E) md4(E) cifs(E) dns_resolver(E) vmw_vsock_vmci_transport(E) vsock(E) hid_generic(E) usbhid(E) hid(E) xt_conntrack(E) mousedev(E) iptable_nat(E) nf_conntrack_ipv4(E) nf_defrag_ipv4(E) nf_nat_ipv4(E) nf_nat(E) iptable_filter(E) ip_tables(E) crc32c_intel(E) xt_LOG(E) nf_conntrack(E) jitterentropy_rng(E) hmac(E) sha256_ssse3(E) sha256_generic(E) drbg(E) vmw_balloon(E) ansi_cprng(E) aesni_intel(E) aes_x86_64(E) glue_helper(E) lrw(E) gf128mul(E) ablk_helper(E) cryptd(E) psmouse(E) evdev(E) uhci_hcd(E) ehci_pci(E) ehci_hcd(E) usbcore(E) intel_agp(E) usb_common(E) vmw_vmci(E) i2c_piix4(E) intel_gtt(E) nfit(E) battery(E) tpm_tis(E) tpm(E) ac(E) button(E) sch_fq_codel(E) autofs4(E)
[   53.079435] CPU: 3 PID: 829 Comm: mount.cifs Tainted: G            E   4.4.109-possible-fix1+ #21
[   53.079983] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 04/05/2016
[   53.081086] task: ffff8800b4f41940 ti: ffff8800b92ac000 task.ti: ffff8800b92ac000
[   53.081667] RIP: 0010:[<ffffffff8138ee9a>]  [<ffffffff8138ee9a>] crypto_shash_setkey+0x1a/0xc0
[   53.082247] RSP: 0018:ffff8800b92af9a8  EFLAGS: 00010282
[   53.082604] systemd-journald[284]: Compressed data object 721 -> 468 using XZ
[   53.083419] RAX: ffff8800af5943c0 RBX: ffff8800b484a800 RCX: 00000000ffff0ec7
[   53.084001] RDX: 0000000000000010 RSI: ffff8800b900af18 RDI: 0000000000000000
[   53.084602] RBP: ffff8800b92af9e0 R08: ffff8800b92afb64 R09: 0000000000000000
[   53.085184] R10: 3031322e3030312e R11: 00000000000007f5 R12: 0000000000000002
[   53.085755] R13: 0000000000000000 R14: ffff8800b900af18 R15: 0000000000000010
[   53.086333] FS:  00007fb659b45740(0000) GS:ffff88013fcc0000(0000) knlGS:0000000000000000
[   53.086907] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   53.087480] CR2: 0000000000000050 CR3: 00000000b7970000 CR4: 00000000001606e0
[   53.088107] Stack:
[   53.088681]  ffff8800bba5d8c0 ffff8800b92afa08 ffff8800b484a800 0000000000000002
[   53.089281]  ffff8800b92afac8 000008012400007d ffff8800b484a800 ffff8800b92afa50
[   53.089871]  ffffffffa02194a6 ffff8800b92afb70 ffff8800af5943c0 ffff8800b7a2f800
[   53.090457] Call Trace:
[   53.091054]  [<ffffffffa02194a6>] smb3_calc_signature+0xb6/0x290 [cifs]
[   53.091650]  [<ffffffffa0218b5b>] smb2_sign_rqst+0x2b/0x40 [cifs]
[   53.092244]  [<ffffffffa0219981>] smb2_setup_request+0xd1/0x170 [cifs]
[   53.092838]  [<ffffffffa02082a7>] SendReceive2+0xc7/0x450 [cifs]
[   53.093435]  [<ffffffffa02057d5>] ? cifs_small_buf_get+0x15/0x30 [cifs]
[   53.094030]  [<ffffffffa021b83f>] ? small_smb2_init+0xdf/0x200 [cifs]
[   53.094616]  [<ffffffffa021d6d7>] SMB2_ioctl+0x147/0x310 [cifs]
[   53.095203]  [<ffffffffa021d99e>] smb3_validate_negotiate+0xfe/0x2d0 [cifs]
[   53.095792]  [<ffffffffa021b196>] SMB2_tcon+0x296/0x500 [cifs]
[   53.096362]  [<ffffffff817d7b49>] ? _raw_spin_unlock_irqrestore+0x9/0x10
[   53.096930]  [<ffffffffa01efe0b>] cifs_get_tcon+0x1bb/0x560 [cifs]
[   53.097486]  [<ffffffffa01f2b10>] cifs_mount+0x690/0xde0 [cifs]
[   53.098032]  [<ffffffff817d7b49>] ? _raw_spin_unlock_irqrestore+0x9/0x10
[   53.098570]  [<ffffffffa01de6eb>] cifs_do_mount+0xcb/0x5a0 [cifs]
[   53.099089]  [<ffffffff81193ef7>] ? alloc_pages_current+0x87/0x110
[   53.099598]  [<ffffffff811b7b03>] mount_fs+0x33/0x160
[   53.100091]  [<ffffffff811d1b62>] vfs_kern_mount+0x62/0x100
[   53.100574]  [<ffffffff811d3f1b>] do_mount+0x21b/0xd30
[   53.101050]  [<ffffffff81193ef7>] ? alloc_pages_current+0x87/0x110
[   53.101511]  [<ffffffff811d4d47>] SyS_mount+0x87/0xd0
[   53.101959]  [<ffffffff817d806e>] entry_SYSCALL_64_fastpath+0x12/0x71
[   53.102400] Code: 89 e5 8b 12 e8 78 d2 04 00 31 c0 5d c3 0f 1f 40 00 55 48 89 e5 41 57 41 56 41 55 41 54 49 89 fd 53 49 89 f6 41 89 d7 48 83 ec 10 <4c> 8b 67 50 41 8b 5c 24 2c 48 85 de 75 14 41 ff 54 24 e8 48 83 
[   53.103820] RIP  [<ffffffff8138ee9a>] crypto_shash_setkey+0x1a/0xc0
[   53.104288]  RSP <ffff8800b92af9a8>
[   53.104745] CR2: 0000000000000050
[   53.105225] ---[ end trace fc2de0ad7f229314 ]---


The CIFS config options enabled are:

CONFIG_CIFS=m
CONFIG_CIFS_STATS=y
CONFIG_CIFS_STATS2=y
CONFIG_CIFS_WEAK_PW_HASH=y
CONFIG_CIFS_UPCALL=y
CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
CONFIG_CIFS_ACL=y
CONFIG_CIFS_DEBUG=y
CONFIG_CIFS_DEBUG2=y
CONFIG_CIFS_DFS_UPCALL=y
CONFIG_CIFS_SMB2=y
# CONFIG_CIFS_SMB311 is not set
# CONFIG_CIFS_FSCACHE is not set


The problem seems to be that crypto_shash_setkey() is called without
calling smb3_crypto_shash_allocate() first.  So I looked up how mainline
avoids this issue, and it looks like the following commit makes a call
to generate_signingkey() even when server->sign == false, and this path
eventually calls smb3_crytpto_shash_allocate()), thus avoiding the NULL
pointer dereference.

cabfb3680f78 (CIFS: Enable encryption during session setup phase)


So, I adopted this change, and now my resulting patch looks like this:

diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index f2ff60e..19cc92c 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -833,7 +833,7 @@ ssetup_exit:
 
        if (!rc) {
                mutex_lock(&server->srv_mutex);
-               if (server->sign && server->ops->generate_signingkey) {
+               if (server->ops->generate_signingkey) {
                        rc = server->ops->generate_signingkey(ses);
                        kfree(ses->auth_key.response);
                        ses->auth_key.response = NULL;
@@ -1559,6 +1559,9 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
        } else
                iov[0].iov_len = get_rfc1002_length(req) + 4;
 
+       /* validate negotiate request must be signed - see MS-SMB2 3.2.5.5 */
+       if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO)
+               req->hdr.Flags |= SMB2_FLAGS_SIGNED;
 
        rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
        rsp = (struct smb2_ioctl_rsp *)iov[0].iov_base;
