vfs: don't let do_last pass negative dentry to audit_inode
I can reliably reproduce the following panic by simply setting an audit
rule on a recent 3.5.0+ kernel:
BUG: unable to handle kernel NULL pointer dereference at
0000000000000040
IP: [<
ffffffff810d1250>] audit_copy_inode+0x10/0x90
PGD
7acd9067 PUD
7b8fb067 PMD 0
Oops: 0000 [#86] SMP
Modules linked in: nfs nfs_acl auth_rpcgss fscache lockd sunrpc tpm_bios btrfs zlib_deflate libcrc32c kvm_amd kvm joydev virtio_net pcspkr i2c_piix4 floppy virtio_balloon microcode virtio_blk cirrus drm_kms_helper ttm drm i2c_core [last unloaded: scsi_wait_scan]
CPU 0
Pid: 1286, comm: abrt-dump-oops Tainted: G D 3.5.0+ #1 Bochs Bochs
RIP: 0010:[<
ffffffff810d1250>] [<
ffffffff810d1250>] audit_copy_inode+0x10/0x90
RSP: 0018:
ffff88007aebfc38 EFLAGS:
00010282
RAX:
0000000000000000 RBX:
ffff88003692d860 RCX:
00000000000038c4
RDX:
0000000000000000 RSI:
ffff88006baf5d80 RDI:
ffff88003692d860
RBP:
ffff88007aebfc68 R08:
0000000000000000 R09:
0000000000000000
R10:
0000000000000000 R11:
0000000000000001 R12:
0000000000000000
R13:
ffff880036d30f00 R14:
ffff88006baf5d80 R15:
ffff88003692d800
FS:
00007f7562634740(0000) GS:
ffff88007fc00000(0000) knlGS:
0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0:
0000000080050033
CR2:
0000000000000040 CR3:
000000003643d000 CR4:
00000000000006f0
DR0:
0000000000000000 DR1:
0000000000000000 DR2:
0000000000000000
DR3:
0000000000000000 DR6:
00000000ffff0ff0 DR7:
0000000000000400
Process abrt-dump-oops (pid: 1286, threadinfo
ffff88007aebe000, task
ffff880079614530)
Stack:
ffff88007aebfdf8 ffff88007aebff28 ffff88007aebfc98 ffffffff81211358
ffff88003692d860 0000000000000000 ffff88007aebfcc8 ffffffff810d4968
ffff88007aebfcc8 ffff8800000038c4 0000000000000000 0000000000000000
Call Trace:
[<
ffffffff81211358>] ? ext4_lookup+0xe8/0x160
[<
ffffffff810d4968>] __audit_inode+0x118/0x2d0
[<
ffffffff811955a9>] do_last+0x999/0xe80
[<
ffffffff81191fe8>] ? inode_permission+0x18/0x50
[<
ffffffff81171efa>] ? kmem_cache_alloc_trace+0x11a/0x130
[<
ffffffff81195b4a>] path_openat+0xba/0x420
[<
ffffffff81196111>] do_filp_open+0x41/0xa0
[<
ffffffff811a24bd>] ? alloc_fd+0x4d/0x120
[<
ffffffff811855cd>] do_sys_open+0xed/0x1c0
[<
ffffffff810d40cc>] ? __audit_syscall_entry+0xcc/0x300
[<
ffffffff811856c1>] sys_open+0x21/0x30
[<
ffffffff81611ca9>] system_call_fastpath+0x16/0x1b
RSP <
ffff88007aebfc38>
CR2:
0000000000000040
The problem is that do_last is passing a negative dentry to audit_inode.
The comments on lookup_open note that it can pass back a negative dentry
if O_CREAT is not set.
This patch fixes the oops, but I'm not clear on whether there's a better
approach.
Cc: Miklos Szeredi <miklos@szeredi.hu>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>