cifs: prevent bad output lengths in smb2_ioctl_query_info()
When calling smb2_ioctl_query_info() with
smb_query_info::flags=PASSTHRU_FSCTL and
smb_query_info::output_buffer_length=0, the following would return
0x10
buffer = memdup_user(arg + sizeof(struct smb_query_info),
qi.output_buffer_length);
if (IS_ERR(buffer)) {
kfree(vars);
return PTR_ERR(buffer);
}
rather than a valid pointer thus making IS_ERR() check fail. This
would then cause a NULL ptr deference in @buffer when accessing it
later in smb2_ioctl_query_ioctl(). While at it, prevent having a
@buffer smaller than 8 bytes to correctly handle SMB2_SET_INFO
FileEndOfFileInformation requests when
smb_query_info::flags=PASSTHRU_SET_INFO.
Here is a small C reproducer which triggers a NULL ptr in @buffer when
passing an invalid smb_query_info::flags
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#define die(s) perror(s), exit(1)
#define QUERY_INFO 0xc018cf07
int main(int argc, char *argv[])
{
int fd;
if (argc < 2)
exit(1);
fd = open(argv[1], O_RDONLY);
if (fd == -1)
die("open");
if (ioctl(fd, QUERY_INFO, (uint32_t[]) { 0, 0, 0, 4, 0, 0}) == -1)
die("ioctl");
close(fd);
return 0;
}
mount.cifs //srv/share /mnt -o ...
gcc repro.c && ./a.out /mnt/f0
[ 114.138620] general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN NOPTI
[ 114.139310] KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
[ 114.139775] CPU: 2 PID: 995 Comm: a.out Not tainted 5.17.0-rc8 #1
[ 114.140148] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
rel-1.15.0-0-g2dd4b9b-rebuilt.opensuse.org 04/01/2014
[ 114.140818] RIP: 0010:smb2_ioctl_query_info+0x206/0x410 [cifs]
[ 114.141221] Code: 00 00 00 00 fc ff df 48 c1 ea 03 80 3c 02 00 0f 85 c8 01 00 00 48 b8 00 00 00 00 00 fc ff df 4c 8b 7b 28 4c 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 9c 01 00 00 49 8b 3f e8 58 02 fb ff 48 8b 14 24
[ 114.142348] RSP: 0018:
ffffc90000b47b00 EFLAGS:
00010256
[ 114.142692] RAX:
dffffc0000000000 RBX:
ffff888115503200 RCX:
ffffffffa020580d
[ 114.143119] RDX:
0000000000000000 RSI:
0000000000000004 RDI:
ffffffffa043a380
[ 114.143544] RBP:
ffff888115503278 R08:
0000000000000001 R09:
0000000000000003
[ 114.143983] R10:
fffffbfff4087470 R11:
0000000000000001 R12:
ffff888115503288
[ 114.144424] R13:
00000000ffffffea R14:
ffff888115503228 R15:
0000000000000000
[ 114.144852] FS:
00007f7aeabdf740(0000) GS:
ffff888151600000(0000) knlGS:
0000000000000000
[ 114.145338] CS: 0010 DS: 0000 ES: 0000 CR0:
0000000080050033
[ 114.145692] CR2:
00007f7aeacfdf5e CR3:
000000012000e000 CR4:
0000000000350ee0
[ 114.146131] Call Trace:
[ 114.146291] <TASK>
[ 114.146432] ? smb2_query_reparse_tag+0x890/0x890 [cifs]
[ 114.146800] ? cifs_mapchar+0x460/0x460 [cifs]
[ 114.147121] ? rcu_read_lock_sched_held+0x3f/0x70
[ 114.147412] ? cifs_strndup_to_utf16+0x15b/0x250 [cifs]
[ 114.147775] ? dentry_path_raw+0xa6/0xf0
[ 114.148024] ? cifs_convert_path_to_utf16+0x198/0x220 [cifs]
[ 114.148413] ? smb2_check_message+0x1080/0x1080 [cifs]
[ 114.148766] ? rcu_read_lock_sched_held+0x3f/0x70
[ 114.149065] cifs_ioctl+0x1577/0x3320 [cifs]
[ 114.149371] ? lock_downgrade+0x6f0/0x6f0
[ 114.149631] ? cifs_readdir+0x2e60/0x2e60 [cifs]
[ 114.149956] ? rcu_read_lock_sched_held+0x3f/0x70
[ 114.150250] ? __rseq_handle_notify_resume+0x80b/0xbe0
[ 114.150562] ? __up_read+0x192/0x710
[ 114.150791] ? __ia32_sys_rseq+0xf0/0xf0
[ 114.151025] ? __x64_sys_openat+0x11f/0x1d0
[ 114.151296] __x64_sys_ioctl+0x127/0x190
[ 114.151549] do_syscall_64+0x3b/0x90
[ 114.151768] entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 114.152079] RIP: 0033:0x7f7aead043df
[ 114.152306] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <41> 89 c0 3d 00 f0 ff ff 77 1f 48 8b 44 24 18 64 48 2b 04 25 28 00
[ 114.153431] RSP: 002b:
00007ffc2e0c1f80 EFLAGS:
00000246 ORIG_RAX:
0000000000000010
[ 114.153890] RAX:
ffffffffffffffda RBX:
0000000000000000 RCX:
00007f7aead043df
[ 114.154315] RDX:
00007ffc2e0c1ff0 RSI:
00000000c018cf07 RDI:
0000000000000003
[ 114.154747] RBP:
00007ffc2e0c2010 R08:
00007f7aeae03db0 R09:
00007f7aeae24c4e
[ 114.155192] R10:
00007f7aeabf7d40 R11:
0000000000000246 R12:
00007ffc2e0c2128
[ 114.155642] R13:
0000000000401176 R14:
0000000000403df8 R15:
00007f7aeae57000
[ 114.156071] </TASK>
[ 114.156218] Modules linked in: cifs cifs_arc4 cifs_md4 bpf_preload
[ 114.156608] ---[ end trace
0000000000000000 ]---
[ 114.156898] RIP: 0010:smb2_ioctl_query_info+0x206/0x410 [cifs]
[ 114.157792] Code: 00 00 00 00 fc ff df 48 c1 ea 03 80 3c 02 00 0f 85 c8 01 00 00 48 b8 00 00 00 00 00 fc ff df 4c 8b 7b 28 4c 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 9c 01 00 00 49 8b 3f e8 58 02 fb ff 48 8b 14 24
[ 114.159293] RSP: 0018:
ffffc90000b47b00 EFLAGS:
00010256
[ 114.159641] RAX:
dffffc0000000000 RBX:
ffff888115503200 RCX:
ffffffffa020580d
[ 114.160093] RDX:
0000000000000000 RSI:
0000000000000004 RDI:
ffffffffa043a380
[ 114.160699] RBP:
ffff888115503278 R08:
0000000000000001 R09:
0000000000000003
[ 114.161196] R10:
fffffbfff4087470 R11:
0000000000000001 R12:
ffff888115503288
[ 114.155642] R13:
0000000000401176 R14:
0000000000403df8 R15:
00007f7aeae57000
[ 114.156071] </TASK>
[ 114.156218] Modules linked in: cifs cifs_arc4 cifs_md4 bpf_preload
[ 114.156608] ---[ end trace
0000000000000000 ]---
[ 114.156898] RIP: 0010:smb2_ioctl_query_info+0x206/0x410 [cifs]
[ 114.157792] Code: 00 00 00 00 fc ff df 48 c1 ea 03 80 3c 02 00 0f 85 c8 01 00 00 48 b8 00 00 00 00 00 fc ff df 4c 8b 7b 28 4c 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 9c 01 00 00 49 8b 3f e8 58 02 fb ff 48 8b 14 24
[ 114.159293] RSP: 0018:
ffffc90000b47b00 EFLAGS:
00010256
[ 114.159641] RAX:
dffffc0000000000 RBX:
ffff888115503200 RCX:
ffffffffa020580d
[ 114.160093] RDX:
0000000000000000 RSI:
0000000000000004 RDI:
ffffffffa043a380
[ 114.160699] RBP:
ffff888115503278 R08:
0000000000000001 R09:
0000000000000003
[ 114.161196] R10:
fffffbfff4087470 R11:
0000000000000001 R12:
ffff888115503288
[ 114.161823] R13:
00000000ffffffea R14:
ffff888115503228 R15:
0000000000000000
[ 114.162274] FS:
00007f7aeabdf740(0000) GS:
ffff888151600000(0000) knlGS:
0000000000000000
[ 114.162853] CS: 0010 DS: 0000 ES: 0000 CR0:
0000000080050033
[ 114.163218] CR2:
00007f7aeacfdf5e CR3:
000000012000e000 CR4:
0000000000350ee0
[ 114.163691] Kernel panic - not syncing: Fatal exception
[ 114.164087] Kernel Offset: disabled
[ 114.164316] ---[ end Kernel panic - not syncing: Fatal exception ]---
Cc: stable@vger.kernel.org
Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Signed-off-by: Steve French <stfrench@microsoft.com>