diff mbox

VFS: Add back check for !inode in walk_component()

Message ID 20150507184343.GF889@ZenIV.linux.org.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Al Viro May 7, 2015, 6:43 p.m. UTC
On Thu, May 07, 2015 at 07:13:35PM +0100, Al Viro wrote:
> On Thu, May 07, 2015 at 01:39:35PM -0400, Steven Rostedt wrote:
> > I had them printed in my previous traces. The flags were 0x200088, and
> > they were 0 just before the call.
> 
> Not dentry->d_flags, nd->flags.  Most interesting part is bit 6 in those
> (LOOKUP_RCU, 0x40).
> 
> As for creation...  I think I see what might be going on:
> 
> A: finds a negative dentry, picks NULL ->d_inode from it and whatever
> ->d_seq it had.
> B: d_instantiate(): sets ->d_inode non-NULL, ->d_flags accordingly and
> bumps ->d_seq.
> A: fetches ->d_flags, sees non-negative, assumes ->d_inode is non-NULL.
> 
> In reality, the last assumption should've been "->d_inode is non-NULL or
> we have a stale ->d_seq and will end up discarding that fscker anyway".
> 
> Hmm...  Smells like we ought to
[snip]

Actually, could you try the following on top of -rc2?

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Steven Rostedt May 7, 2015, 7:33 p.m. UTC | #1
On Thu, 7 May 2015 19:43:43 +0100
Al Viro <viro@ZenIV.linux.org.uk> wrote:


> Actually, could you try the following on top of -rc2?

Gives me the following on boot up:

------------[ cut here ]------------
WARNING: CPU: 2 PID: 2920 at /home/rostedt/work/git/linux-trace.git/kernel/locking/lockdep.c:973 __bfs+0x112/0x1d5()
Modules linked in: ip6t_REJECT nf_reject_ipv6 nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_filter ip6_tables ipv6 microcode r8169 ppdev parport_pc parport
CPU: 2 PID: 2920 Comm: sendmail Not tainted 4.1.0-rc2-test+ #97
Hardware name: MSI MS-7823/CSM-H87M-G43 (MS-7823), BIOS V1.6 02/22/2014
 00000000 00000000 efcadb40 c0cba2de c0ff9437 efcadb70 c043fad6 c0ff263f
 00000002 00000b68 c0ff9437 000003cd c0472d05 c0472d05 00000000 c8d8c685
 c169e0f4 efcadb80 c043fb0f 00000009 00000000 efcadbb4 c0472d05 ffffe000
Call Trace:
 [<c0cba2de>] dump_stack+0x41/0x52
 [<c043fad6>] warn_slowpath_common+0x9d/0xb4
 [<c0472d05>] ? __bfs+0x112/0x1d5
 [<c0472d05>] ? __bfs+0x112/0x1d5
 [<c043fb0f>] warn_slowpath_null+0x22/0x24
 [<c0472d05>] __bfs+0x112/0x1d5
 [<c040d38c>] ? save_stack_address_nosched+0x21/0x21
 [<c047280f>] ? noop_count+0x9/0x9
 [<c0474b51>] check_usage_backwards+0x3d/0x94
 [<c040d30c>] ? save_stack_trace+0x30/0x4a
 [<c0475122>] mark_lock+0x10e/0x1f2
 [<c0474b14>] ? check_usage_forwards+0x94/0x94
 [<c04754ed>] __lock_acquire+0x2e7/0xd0c
 [<c0475556>] ? __lock_acquire+0x350/0xd0c
 [<c0408c1a>] ? native_sched_clock+0x46/0x4b
 [<c0541156>] ? dput+0x40/0x1b3
 [<c0476394>] lock_acquire+0xc6/0xe2
 [<c0541156>] ? dput+0x40/0x1b3
 [<c0cc40a5>] _raw_spin_lock+0x3b/0x68
 [<c0541156>] ? dput+0x40/0x1b3
 [<c0541156>] dput+0x40/0x1b3
 [<c0538743>] path_put_conditional.isra.18+0x16/0x25
 [<c0538990>] lookup_fast+0x23e/0x274
 [<c04767e1>] ? trace_hardirqs_on+0xb/0xd
 [<c05389f3>] walk_component+0x2d/0x148
 [<c05391a7>] ? path_init+0x2c6/0x2d2
 [<c0538b3b>] lookup_last+0x2d/0x30
 [<c0539269>] path_lookupat+0x38/0x1ed
 [<c0cc48e5>] ? _raw_spin_unlock+0x22/0x25
 [<c053962c>] filename_lookup+0x24/0x76
 [<c053b1ad>] kern_path+0x38/0x5a
 [<c0439ccb>] ? __phys_addr+0x4a/0x5a
 [<c0528512>] ? virt_to_head_page+0xf/0x24
 [<c052853c>] ? ksize+0x15/0x6b
 [<c0c8306d>] unix_find_other+0x2d/0x17c
 [<c0bea236>] ? sock_wmalloc+0x70/0x77
 [<c0c84eec>] unix_stream_connect+0xde/0x376
 [<c0be6fb3>] SYSC_connect+0x66/0x82
 [<c0be7369>] SyS_connect+0x16/0x18
 [<c0be7ab6>] SyS_socketcall+0xd4/0x2c6
 [<c0494b52>] ? current_kernel_time+0x10/0x4c
 [<c04b816b>] ? __audit_syscall_entry+0x9f/0xbd
 [<c0cc4c98>] sysenter_do_call+0x12/0x12
---[ end trace 9ea8d1ad66bfdb24 ]---
BUG: unable to handle kernel NULL pointer dereference at 00000008
IP: [<c0472d05>] __bfs+0x112/0x1d5
*pdpt = 0000000031dab001 *pde = 0000000000000000 
Oops: 0000 [#1] SMP 
Modules linked in: ip6t_REJECT nf_reject_ipv6 nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_filter ip6_tables ipv6 microcode r8169 ppdev parport_pc parport
CPU: 2 PID: 2920 Comm: sendmail Tainted: G        W       4.1.0-rc2-test+ #97
Hardware name: MSI MS-7823/CSM-H87M-G43 (MS-7823), BIOS V1.6 02/22/2014
task: efbd9610 ti: efcac000 task.ti: efcac000
EIP: 0060:[<c0472d05>] EFLAGS: 00210092 CPU: 2
EIP is at __bfs+0x112/0x1d5
EAX: f367bbb8 EBX: 00000000 ECX: f367bbb8 EDX: ffffffff
ESI: c8d8c685 EDI: c169e0f4 EBP: efcadbb4 ESP: efcadb88
 DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
CR0: 80050033 CR2: 00000008 CR3: 2fd5c9e0 CR4: 001407f0
Stack:
 ffffe000 efcadffc c040d38c efcac000 c047280f 00000000 efcadbcc 00000000
 00000000 efbd9bec efbd9610 efcadc00 c0474b51 efcadbf0 00000000 c133b144
 00000000 00000000 c169e03c c169dffc 00000000 efcadbf4 c040d30c 00000000
Call Trace:
 [<c040d38c>] ? save_stack_address_nosched+0x21/0x21
 [<c047280f>] ? noop_count+0x9/0x9
 [<c0474b51>] check_usage_backwards+0x3d/0x94
 [<c040d30c>] ? save_stack_trace+0x30/0x4a
 [<c0475122>] mark_lock+0x10e/0x1f2
 [<c0474b14>] ? check_usage_forwards+0x94/0x94
 [<c04754ed>] __lock_acquire+0x2e7/0xd0c
 [<c0475556>] ? __lock_acquire+0x350/0xd0c
 [<c0408c1a>] ? native_sched_clock+0x46/0x4b
 [<c0541156>] ? dput+0x40/0x1b3
 [<c0476394>] lock_acquire+0xc6/0xe2
 [<c0541156>] ? dput+0x40/0x1b3
 [<c0cc40a5>] _raw_spin_lock+0x3b/0x68
 [<c0541156>] ? dput+0x40/0x1b3
 [<c0541156>] dput+0x40/0x1b3
 [<c0538743>] path_put_conditional.isra.18+0x16/0x25
 [<c0538990>] lookup_fast+0x23e/0x274
 [<c04767e1>] ? trace_hardirqs_on+0xb/0xd
 [<c05389f3>] walk_component+0x2d/0x148
 [<c05391a7>] ? path_init+0x2c6/0x2d2
 [<c0538b3b>] lookup_last+0x2d/0x30
 [<c0539269>] path_lookupat+0x38/0x1ed
 [<c0cc48e5>] ? _raw_spin_unlock+0x22/0x25
 [<c053962c>] filename_lookup+0x24/0x76
 [<c053b1ad>] kern_path+0x38/0x5a
 [<c0439ccb>] ? __phys_addr+0x4a/0x5a
 [<c0528512>] ? virt_to_head_page+0xf/0x24
 [<c052853c>] ? ksize+0x15/0x6b
 [<c0c8306d>] unix_find_other+0x2d/0x17c
 [<c0bea236>] ? sock_wmalloc+0x70/0x77
 [<c0c84eec>] unix_stream_connect+0xde/0x376
 [<c0be6fb3>] SYSC_connect+0x66/0x82
 [<c0be7369>] SyS_connect+0x16/0x18
 [<c0be7ab6>] SyS_socketcall+0xd4/0x2c6
 [<c0494b52>] ? current_kernel_time+0x10/0x4c
 [<c04b816b>] ? __audit_syscall_entry+0x9f/0xbd
 [<c0cc4c98>] sysenter_do_call+0x12/0x12
Code: 00 00 00 89 de 81 ee 4c 15 84 c1 c1 fe 02 69 f6 39 8e e3 38 3b 35 68 d6 5d c1 72 0f ba cd 03 00 00 b8 37 94 ff c0 e8 e8 cd fc ff <8b> 43 08 8b 15 48 15 84 c1 39 50 18 74 76 3b 35 68 d6 5d c1 72
EIP: [<c0472d05>] __bfs+0x112/0x1d5 SS:ESP 0068:efcadb88
CR2: 0000000000000008
---[ end trace 9ea8d1ad66bfdb25 ]---


-- Steve
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/namei.c b/fs/namei.c
index 4a8d998b..421e597 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1415,6 +1415,7 @@  static int lookup_fast(struct nameidata *nd,
 	 */
 	if (nd->flags & LOOKUP_RCU) {
 		unsigned seq;
+		bool negative;
 		dentry = __d_lookup_rcu(parent, &nd->last, &seq);
 		if (!dentry)
 			goto unlazy;
@@ -1424,8 +1425,11 @@  static int lookup_fast(struct nameidata *nd,
 		 * the dentry name information from lookup.
 		 */
 		*inode = dentry->d_inode;
+		negative = d_is_negative(dentry);
 		if (read_seqcount_retry(&dentry->d_seq, seq))
 			return -ECHILD;
+		if (negative)
+			return -ENOENT;
 
 		/*
 		 * This sequence count validates that the parent had no
@@ -1472,9 +1476,13 @@  unlazy:
 		goto need_lookup;
 	}
 
-	path->mnt = mnt;
-	path->dentry = dentry;
-	err = follow_managed(path, nd->flags);
+	if (unlikely(d_is_negative(dentry))) {
+		err = -ENOENT;
+	} else {
+		path->mnt = mnt;
+		path->dentry = dentry;
+		err = follow_managed(path, nd->flags);
+	}
 	if (unlikely(err < 0)) {
 		path_put_conditional(path, nd);
 		return err;
@@ -1583,10 +1591,10 @@  static inline int walk_component(struct nameidata *nd, struct path *path,
 			goto out_err;
 
 		inode = path->dentry->d_inode;
+		err = -ENOENT;
+		if (d_is_negative(path->dentry))
+			goto out_path_put;
 	}
-	err = -ENOENT;
-	if (d_is_negative(path->dentry))
-		goto out_path_put;
 
 	if (should_follow_link(path->dentry, follow)) {
 		if (nd->flags & LOOKUP_RCU) {
@@ -3036,14 +3044,13 @@  retry_lookup:
 
 	BUG_ON(nd->flags & LOOKUP_RCU);
 	inode = path->dentry->d_inode;
-finish_lookup:
-	/* we _can_ be in RCU mode here */
 	error = -ENOENT;
 	if (d_is_negative(path->dentry)) {
 		path_to_nameidata(path, nd);
 		goto out;
 	}
-
+finish_lookup:
+	/* we _can_ be in RCU mode here */
 	if (should_follow_link(path->dentry, !symlink_ok)) {
 		if (nd->flags & LOOKUP_RCU) {
 			if (unlikely(nd->path.mnt != path->mnt ||