android_kernel_google_msm/fs
Zheng Liu 41f188e1c5 ext4: fix a BUG when opening a file with O_TMPFILE flag
When we try to open a file with O_TMPFILE flag, we will trigger a bug.
The root cause is that in ext4_orphan_add() we check ->i_nlink == 0 and
this check always fails because we set ->i_nlink = 1 in
inode_init_always().  We can use the following program to trigger it:

int main(int argc, char *argv[])
{
	int fd;

	fd = open(argv[1], O_TMPFILE, 0666);
	if (fd < 0) {
		perror("open ");
		return -1;
	}
	close(fd);
	return 0;
}

The oops message looks like this:

kernel BUG at fs/ext4/namei.c:2572!
invalid opcode: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
Modules linked in: dlci bridge stp hidp cmtp kernelcapi l2tp_ppp l2tp_netlink l2tp_core sctp libcrc32c rfcomm tun fuse nfnetli
nk can_raw ipt_ULOG can_bcm x25 scsi_transport_iscsi ipx p8023 p8022 appletalk phonet psnap vmw_vsock_vmci_transport af_key vmw_vmci rose vsock atm can netrom ax25 af_rxrpc ir
da pppoe pppox ppp_generic slhc bluetooth nfc rfkill rds caif_socket caif crc_ccitt af_802154 llc2 llc snd_hda_codec_realtek snd_hda_intel snd_hda_codec serio_raw snd_pcm pcsp
kr edac_core snd_page_alloc snd_timer snd soundcore r8169 mii sr_mod cdrom pata_atiixp radeon backlight drm_kms_helper ttm
CPU: 1 PID: 1812571 Comm: trinity-child2 Not tainted 3.11.0-rc1+ #12
Hardware name: Gigabyte Technology Co., Ltd. GA-MA78GM-S2H/GA-MA78GM-S2H, BIOS F12a 04/23/2010
task: ffff88007dfe69a0 ti: ffff88010f7b6000 task.ti: ffff88010f7b6000
RIP: 0010:[<ffffffff8125ce69>]  [<ffffffff8125ce69>] ext4_orphan_add+0x299/0x2b0
RSP: 0018:ffff88010f7b7cf8  EFLAGS: 00010202
RAX: 0000000000000000 RBX: ffff8800966d3020 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffff88007dfe70b8 RDI: 0000000000000001
RBP: ffff88010f7b7d40 R08: ffff880126a3c4e0 R09: ffff88010f7b7ca0
R10: 0000000000000000 R11: 0000000000000000 R12: ffff8801271fd668
R13: ffff8800966d2f78 R14: ffff88011d7089f0 R15: ffff88007dfe69a0
FS:  00007f70441a3740(0000) GS:ffff88012a800000(0000) knlGS:00000000f77c96c0
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000002834000 CR3: 0000000107964000 CR4: 00000000000007e0
DR0: 0000000000780000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000600
Stack:
 0000000000002000 00000020810b6dde 0000000000000000 ffff88011d46db00
 ffff8800966d3020 ffff88011d7089f0 ffff88009c7f4c10 ffff88010f7b7f2c
 ffff88007dfe69a0 ffff88010f7b7da8 ffffffff8125cfac ffff880100000004
Call Trace:
 [<ffffffff8125cfac>] ext4_tmpfile+0x12c/0x180
 [<ffffffff811cba78>] path_openat+0x238/0x700
 [<ffffffff8100afc4>] ? native_sched_clock+0x24/0x80
 [<ffffffff811cc647>] do_filp_open+0x47/0xa0
 [<ffffffff811db73f>] ? __alloc_fd+0xaf/0x200
 [<ffffffff811ba2e4>] do_sys_open+0x124/0x210
 [<ffffffff81010725>] ? syscall_trace_enter+0x25/0x290
 [<ffffffff811ba3ee>] SyS_open+0x1e/0x20
 [<ffffffff816ca8d4>] tracesys+0xdd/0xe2
 [<ffffffff81001001>] ? start_thread_common.constprop.6+0x1/0xa0
Code: 04 00 00 00 89 04 24 31 c0 e8 c4 77 04 00 e9 43 fe ff ff 66 25 00 d0 66 3d 00 80 0f 84 0e fe ff ff 83 7b 48 00 0f 84 04 fe ff ff <0f> 0b 49 8b 8c 24 50 07 00 00 e9 88 fe ff ff 0f 1f 84 00 00 00

Here we couldn't call clear_nlink() directly because in d_tmpfile() we
will call inode_dec_link_count() to decrease ->i_nlink.  So this commit
tries to call d_tmpfile() before ext4_orphan_add() to fix this problem.

Change-Id: I04dca79854fc9b4932df853251e28419721aabf5
Reported-by: Dave Jones <davej@redhat.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
Tested-by: Darrick J. Wong <darrick.wong@oracle.com>
Tested-by: Dave Jones <davej@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
2018-12-07 22:28:48 +04:00
..
9p don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
adfs stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
affs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
afs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
autofs4 stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
befs stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
bfs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
btrfs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
cachefiles don't pass nameidata * to vfs_create() 2018-12-07 22:28:48 +04:00
ceph don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
cifs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
coda don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
configfs stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
cramfs stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
crypto ext4/fscrypto: avoid RCU lookup in d_revalidate 2016-10-29 23:12:37 +08:00
debugfs BACKPORT: dentry name snapshots 2018-01-13 17:13:38 +03:00
devpts Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
dlm
ecryptfs don't pass nameidata * to vfs_create() 2018-12-07 22:28:48 +04:00
efs stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
exofs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
exportfs move d_rcu from overlapping d_child to overlapping d_alias 2017-09-22 19:11:55 +03:00
ext2 [O_TMPFILE] it's still short a few helpers, but infrastructure should be OK now... 2018-12-07 22:28:48 +04:00
ext3 ext3: fix a BUG when opening a file with O_TMPFILE flag 2018-12-07 22:28:48 +04:00
ext4 ext4: fix a BUG when opening a file with O_TMPFILE flag 2018-12-07 22:28:48 +04:00
f2fs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
fat don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
freevxfs stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
fscache FS-Cache: Handle a write to the page immediately beyond the EOF marker 2016-10-26 23:15:25 +08:00
fuse don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
gfs2 don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
hfs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
hfsplus don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
hostfs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
hpfs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
hppfs stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
hugetlbfs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
isofs stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
jbd
jbd2 jbd2: Fix unreclaimed pages after truncate in data=journal mode 2016-10-26 23:15:34 +08:00
jffs2 don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
jfs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
lockd lockd: Try to reconnect if statd has moved 2015-02-02 17:04:42 +08:00
logfs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
minix [O_TMPFILE] it's still short a few helpers, but infrastructure should be OK now... 2018-12-07 22:28:48 +04:00
ncpfs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
nfs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
nfs_common
nfsd don't pass nameidata * to vfs_create() 2018-12-07 22:28:48 +04:00
nilfs2 don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
nls
notify BACKPORT: dentry name snapshots 2018-01-13 17:13:38 +03:00
ntfs stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
ocfs2 pull mnt_want_write()/mnt_drop_write() into kern_path_create()/done_path_create() resp. 2018-12-07 22:28:48 +04:00
omfs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
openpromfs stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
proc proc: Use nd_jump_link in proc_ns_follow_link 2018-12-07 22:28:48 +04:00
pstore pstore: Avoid deadlock in panic and emergency-restart path 2013-03-04 06:06:43 +08:00
qnx4 stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
qnx6 stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
quota vfs: define struct filename and have getname() return it 2018-12-07 22:28:48 +04:00
ramfs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
reiserfs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
romfs stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
sdcardfs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
squashfs stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
sysfs stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
sysv don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
ubifs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
udf don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
ufs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
xfs don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
yaffs2
aio.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
anon_inodes.c
attr.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
bad_inode.c don't pass nameidata to ->create() 2018-12-07 22:28:00 +04:00
binfmt_aout.c
binfmt_elf.c binfmt_elf: Don't clobber passed executable's file header 2016-10-26 23:15:28 +08:00
binfmt_elf_fdpic.c
binfmt_em86.c exec: use -ELOOP for max recursion depth 2013-03-28 12:12:28 -07:00
binfmt_flat.c
binfmt_misc.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
binfmt_script.c exec: use -ELOOP for max recursion depth 2013-03-28 12:12:28 -07:00
binfmt_som.c
bio-integrity.c
bio.c SCSI: sg: Fix user memory corruption when SG_IO is interrupted by a signal 2013-09-07 21:58:16 -07:00
block_dev.c writeback: Fix periodic writeback after fs mount 2013-07-28 16:26:08 -07:00
buffer.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
char_dev.c
compat.c vfs: define struct filename and have getname() return it 2018-12-07 22:28:48 +04:00
compat_binfmt_elf.c
compat_ioctl.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
dcache.c [O_TMPFILE] it's still short a few helpers, but infrastructure should be OK now... 2018-12-07 22:28:48 +04:00
dcookies.c
direct-io.c
drop_caches.c
eventfd.c
eventpoll.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
exec.c vfs: make path_openat take a struct filename pointer 2018-12-07 22:28:48 +04:00
fcntl.c
fhandle.c vfs: read file_handle only once in handle_to_path 2016-10-29 23:12:11 +08:00
fifo.c
file.c fs/file.c:fdtable: avoid triggering OOMs from alloc_fdmem 2014-02-22 10:32:45 -08:00
file_table.c get rid of s_files and files_lock 2016-03-21 09:17:55 +08:00
filesystems.c vfs: define struct filename and have getname() return it 2018-12-07 22:28:48 +04:00
fs-writeback.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
fs_struct.c sdcardfs: override umask on mkdir and create 2017-09-22 19:12:02 +03:00
generic_acl.c BACKPORT: posix_acl: Clear SGID bit when setting file permissions 2017-06-26 20:26:17 +03:00
inode.c allow the temp files created by open() to be linked to 2018-12-07 22:28:48 +04:00
internal.h vfs: make path_openat take a struct filename pointer 2018-12-07 22:28:48 +04:00
ioctl.c
ioprio.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
Kconfig Included sdcardfs source code for kernel 3.0 2017-09-22 19:11:56 +03:00
Kconfig.binfmt
libfs.c stop passing nameidata to ->lookup() 2018-12-07 22:26:28 +04:00
locks.c locks: allow __break_lease to sleep even when break_time is 0 2014-05-13 14:11:31 +02:00
Makefile Included sdcardfs source code for kernel 3.0 2017-09-22 19:11:56 +03:00
mbcache.c
mount.h proc: Usable inode numbers for the namespace file descriptors. 2015-07-13 11:18:01 -07:00
mpage.c
namei.c Safer ABI for O_TMPFILE 2018-12-07 22:28:48 +04:00
namespace.c vfs: define struct filename and have getname() return it 2018-12-07 22:28:48 +04:00
no-block.c
open.c allow O_TMPFILE to work with O_WRONLY 2018-12-07 22:28:48 +04:00
pipe.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
pnode.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
pnode.h ANDROID: mnt: remount should propagate to slaves of slaves 2017-09-22 19:12:11 +03:00
posix_acl.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
proc_namespace.c vfs: Allow filesystems to access their private mount data 2017-09-22 19:12:06 +03:00
read_write.c
read_write.h
readdir.c kernel: Only expose su when daemon is running 2017-05-19 18:41:25 -06:00
select.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
seq_file.c fs/seq_file: Use vmalloc by default for allocations > PAGE_SIZE 2014-11-18 15:13:24 -08:00
signalfd.c
splice.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
stack.c
stat.c VFS: make vfs_fstat() use f[get|put]_light() 2014-06-07 16:02:04 -07:00
statfs.c vfs: allow O_PATH file descriptors for fstatfs() 2013-10-22 09:02:25 +01:00
super.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
sync.c fs/sync.c: make sync_file_range(2) use WB_SYNC_NONE writeback 2017-12-31 13:02:49 +03:00
timerfd.c timerfd: support CLOCK_BOOTTIME clock 2017-08-27 19:07:23 +03:00
utimes.c vfs: Add setattr2 for filesystems with per mount permissions 2017-09-22 19:12:07 +03:00
xattr.c
xattr_acl.c