Alexey Dobriyan 5a622f2d0f proc: fix proc_dir_entry refcounting
Creating PDEs with refcount 0 and "deleted" flag has problems (see below).
Switch to usual scheme:
* PDE is created with refcount 1
* every de_get does +1
* every de_put() and remove_proc_entry() do -1
* once refcount reaches 0, PDE is freed.

This elegantly fixes at least two following races (both observed) without
introducing new locks, without abusing old locks, without spreading
lock_kernel():

1) PDE leak

remove_proc_entry			de_put
-----------------			------
			[refcnt = 1]
if (atomic_read(&de->count) == 0)
					if (atomic_dec_and_test(&de->count))
						if (de->deleted)
							/* also not taken! */
							free_proc_entry(de);
else
	de->deleted = 1;
		[refcount=0, deleted=1]

2) use after free

remove_proc_entry			de_put
-----------------			------
			[refcnt = 1]

					if (atomic_dec_and_test(&de->count))
if (atomic_read(&de->count) == 0)
	free_proc_entry(de);
						/* boom! */
						if (de->deleted)
							free_proc_entry(de);

BUG: unable to handle kernel paging request at virtual address 6b6b6b6b
printing eip: c10acdda *pdpt = 00000000338f8001 *pde = 0000000000000000
Oops: 0000 [#1] PREEMPT SMP
Modules linked in: af_packet ipv6 cpufreq_ondemand loop serio_raw psmouse k8temp hwmon sr_mod cdrom
Pid: 23161, comm: cat Not tainted (2.6.24-rc2-8c0863403f109a43d7000b4646da4818220d501f #4)
EIP: 0060:[<c10acdda>] EFLAGS: 00210097 CPU: 1
EIP is at strnlen+0x6/0x18
EAX: 6b6b6b6b EBX: 6b6b6b6b ECX: 6b6b6b6b EDX: fffffffe
ESI: c128fa3b EDI: f380bf34 EBP: ffffffff ESP: f380be44
 DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Process cat (pid: 23161, ti=f380b000 task=f38f2570 task.ti=f380b000)
Stack: c10ac4f0 00000278 c12ce000 f43cd2a8 00000163 00000000 7da86067 00000400
       c128fa20 00896b18 f38325a8 c128fe20 ffffffff 00000000 c11f291e 00000400
       f75be300 c128fa20 f769c9a0 c10ac779 f380bf34 f7bfee70 c1018e6b f380bf34
Call Trace:
 [<c10ac4f0>] vsnprintf+0x2ad/0x49b
 [<c10ac779>] vscnprintf+0x14/0x1f
 [<c1018e6b>] vprintk+0xc5/0x2f9
 [<c10379f1>] handle_fasteoi_irq+0x0/0xab
 [<c1004f44>] do_IRQ+0x9f/0xb7
 [<c117db3b>] preempt_schedule_irq+0x3f/0x5b
 [<c100264e>] need_resched+0x1f/0x21
 [<c10190ba>] printk+0x1b/0x1f
 [<c107c8ad>] de_put+0x3d/0x50
 [<c107c8f8>] proc_delete_inode+0x38/0x41
 [<c107c8c0>] proc_delete_inode+0x0/0x41
 [<c1066298>] generic_delete_inode+0x5e/0xc6
 [<c1065aa9>] iput+0x60/0x62
 [<c1063c8e>] d_kill+0x2d/0x46
 [<c1063fa9>] dput+0xdc/0xe4
 [<c10571a1>] __fput+0xb0/0xcd
 [<c1054e49>] filp_close+0x48/0x4f
 [<c1055ee9>] sys_close+0x67/0xa5
 [<c10026b6>] sysenter_past_esp+0x5f/0x85
=======================
Code: c9 74 0c f2 ae 74 05 bf 01 00 00 00 4f 89 fa 5f 89 d0 c3 85 c9 57 89 c7 89 d0 74 05 f2 ae 75 01 4f 89 f8 5f c3 89 c1 89 c8 eb 06 <80> 38 00 74 07 40 4a 83 fa ff 75 f4 29 c8 c3 90 90 90 57 83 c9
EIP: [<c10acdda>] strnlen+0x6/0x18 SS:ESP 0068:f380be44

Also, remove broken usage of ->deleted from reiserfs: if sget() succeeds,
module is already pinned and remove_proc_entry() can't happen => nobody
can mark PDE deleted.

Dummy proc root in netns code is not marked with refcount 1. AFAICS, we
never get it, it's just for proper /proc/net removal. I double checked
CLONE_NETNS continues to work.

Patch survives many hours of modprobe/rmmod/cat loops without new bugs
which can be attributed to refcounting.

Signed-off-by: Alexey Dobriyan <adobriyan@sw.ru>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-12-05 09:21:20 -08:00
..
2007-10-14 20:17:39 -07:00
2007-10-17 22:51:13 +02:00
2007-10-17 08:43:03 -07:00
2007-10-10 16:53:11 -07:00
2007-10-15 17:56:36 -07:00
2006-12-04 02:00:22 -05:00
2007-09-11 04:22:16 -07:00
2007-10-18 14:37:20 -07:00
2007-10-10 16:51:59 -07:00
2007-11-05 18:10:28 -05:00
2006-12-02 21:22:55 -08:00
2006-12-02 21:22:55 -08:00
2007-10-21 02:37:45 -04:00
2007-02-20 17:10:15 -08:00
2007-10-17 08:42:45 -07:00
2007-10-17 08:43:07 -07:00
2007-10-18 14:37:29 -07:00
2007-10-19 11:53:42 -07:00
2007-10-19 11:53:42 -07:00
2006-12-08 08:28:39 -08:00
2006-12-07 08:39:20 -08:00
2007-07-31 10:43:05 -05:00
2007-10-16 09:42:58 -07:00
2007-01-30 08:26:45 -08:00
2007-10-20 03:10:57 +02:00
2007-10-19 11:53:36 -07:00
2007-10-19 11:53:36 -07:00
2007-07-10 17:18:59 -07:00
2007-10-16 09:43:13 -07:00
2007-10-17 08:42:52 -07:00
2007-11-19 21:43:22 -05:00
2007-07-17 10:23:04 -07:00
2007-05-10 18:24:13 +02:00
2007-10-19 23:07:36 +02:00
2007-10-16 09:43:09 -07:00
2007-10-21 02:37:45 -04:00
2007-10-19 11:53:36 -07:00
2007-11-02 08:47:25 +01:00
2007-05-08 11:15:26 -07:00
2007-07-09 08:22:54 +01:00
2007-07-09 08:23:17 +01:00
2007-10-20 02:00:58 +01:00
2007-10-18 14:37:21 -07:00
2007-02-09 17:39:36 -05:00
2007-02-11 11:18:07 -08:00
2007-07-19 10:04:54 -07:00
2007-10-22 08:13:19 -07:00
2007-10-22 08:13:20 -07:00
2007-10-17 08:42:51 -07:00
2007-06-01 08:18:29 -07:00
2007-10-29 07:41:32 -07:00
2007-10-22 08:13:21 -07:00
2007-10-17 08:43:02 -07:00
2007-05-09 08:57:56 +02:00
2007-10-17 08:42:48 -07:00
2007-10-17 08:43:01 -07:00
2007-07-18 18:29:37 -04:00
2007-11-29 09:24:54 -08:00
2007-07-10 00:35:17 -04:00
2007-07-09 18:51:58 +02:00
2007-04-28 11:01:07 -04:00
2007-10-19 11:53:42 -07:00
2007-07-19 10:04:41 -07:00
2007-03-16 00:59:29 -04:00
2007-11-14 18:45:40 -08:00
2006-12-10 21:21:29 +01:00
2007-11-15 19:24:02 +01:00
2007-10-16 11:21:00 +02:00
2007-10-22 00:56:52 -04:00
2007-07-16 09:05:34 -07:00
2007-10-10 16:51:59 -07:00
2007-10-17 08:42:52 -07:00
2007-07-14 18:55:06 -07:00
2007-10-10 16:52:04 -07:00
2007-04-25 22:24:41 -07:00
2007-04-25 22:29:10 -07:00
2007-10-14 12:41:52 -07:00
2007-07-16 09:05:50 -07:00
2006-10-10 15:37:22 -07:00
2007-10-16 09:43:01 -07:00
2006-12-02 21:21:21 -08:00
2006-12-07 08:39:47 -08:00
2007-10-18 14:37:32 -07:00
2006-10-04 00:31:09 -07:00
2007-07-31 15:39:41 -07:00
2006-11-30 05:24:39 +01:00
2007-07-11 15:03:53 +01:00
2007-04-25 22:25:52 -07:00
2007-10-16 09:42:49 -07:00
2007-11-05 15:12:32 -08:00
2007-10-17 08:42:52 -07:00
2007-11-29 09:24:52 -08:00
2007-10-17 08:43:01 -07:00
2007-10-19 11:53:49 -07:00
2007-07-18 08:47:40 -07:00
2007-10-12 14:51:12 -07:00
2007-10-16 09:43:10 -07:00
2007-05-09 12:30:53 -07:00
2007-10-13 10:18:29 +02:00
2007-09-11 22:24:45 +01:00
2007-10-25 15:02:50 +10:00
2007-10-25 15:02:50 +10:00
2007-07-17 10:23:03 -07:00
2007-07-17 10:23:13 -07:00
2007-07-24 12:24:59 -07:00
2007-07-16 09:05:34 -07:00
2007-07-18 08:47:45 -07:00
2007-10-19 11:53:55 -07:00
2007-05-09 12:30:49 -07:00
2007-10-10 16:54:03 -07:00
2007-05-03 10:52:22 +03:00
2007-10-17 08:42:55 -07:00
2007-10-23 15:49:54 +10:00
2007-10-19 11:53:54 -07:00
2006-11-30 04:40:22 +01:00
2007-07-16 09:05:42 -07:00
2007-10-19 11:53:44 -07:00
2007-01-23 00:34:54 -05:00
2007-07-16 09:05:51 -07:00
2007-11-07 04:15:12 -08:00
2007-05-09 12:30:54 -07:00
2007-10-09 17:15:11 -04:00
2007-10-17 08:42:58 -07:00
2007-10-19 11:53:34 -07:00
2007-05-04 17:59:07 -07:00
2007-10-19 11:53:41 -07:00
2007-10-16 09:43:02 -07:00
2007-05-08 11:15:05 -07:00
2007-05-05 14:15:32 -07:00
2007-11-23 20:54:01 -05:00
2007-10-17 08:42:44 -07:00
2007-10-19 11:53:41 -07:00
2007-10-19 11:53:41 -07:00
2007-04-17 16:36:26 -07:00
2007-07-26 11:35:21 -07:00
2006-10-03 23:01:26 +02:00
2007-07-16 09:05:50 -07:00
2007-10-19 11:53:41 -07:00
2007-12-05 09:21:20 -08:00
2007-10-17 08:42:45 -07:00
2007-07-17 10:23:03 -07:00
2007-05-07 12:12:54 -07:00
2007-10-17 08:42:56 -07:00
2007-10-16 09:42:53 -07:00
2007-07-18 08:47:40 -07:00
2007-10-22 08:13:20 -07:00
2007-07-21 18:37:10 -07:00
2007-05-17 05:23:06 -07:00
2007-11-29 09:24:54 -08:00
2007-11-27 09:30:39 +01:00
2007-07-16 09:05:50 -07:00
2007-10-16 09:43:17 -07:00
2007-10-19 11:53:44 -07:00
2007-11-29 09:24:53 -08:00
2007-10-19 11:53:44 -07:00
2007-07-22 11:03:37 -07:00
2007-10-17 08:43:01 -07:00
2007-02-20 17:10:14 -08:00
2007-05-21 21:47:27 -07:00
2007-11-09 22:39:38 +01:00
2007-07-16 09:05:46 -07:00
2007-07-19 10:04:49 -07:00
2007-07-16 09:05:40 -07:00
2007-05-08 11:15:18 -07:00
2007-05-09 12:30:57 -07:00
2007-02-20 17:10:13 -08:00
2007-05-11 08:29:34 -07:00
2007-10-12 14:51:12 -07:00
2007-10-15 12:59:43 -07:00
2006-11-30 05:32:19 +01:00
2007-10-17 08:42:53 -07:00
2007-05-11 08:29:36 -07:00
2007-11-26 20:42:19 +01:00
2006-12-02 21:21:08 -08:00
2007-05-11 08:29:35 -07:00
2007-05-11 08:29:35 -07:00
2007-10-29 07:41:33 -07:00
2007-07-18 15:57:15 -07:00
2006-12-15 08:47:51 -08:00
2007-09-19 11:24:18 -07:00
2007-10-23 13:47:31 -05:00
2007-10-23 15:49:54 +10:00
2007-10-23 15:49:54 +10:00
2007-10-23 15:49:55 +10:00
2007-10-23 15:49:54 +10:00
2007-10-23 15:49:54 +10:00
2007-07-17 10:22:59 -07:00
2007-10-17 08:42:56 -07:00
2007-10-19 11:53:34 -07:00
2007-07-09 18:52:01 +02:00
2007-10-17 08:43:02 -07:00
2007-02-11 11:18:05 -08:00
2007-05-04 12:55:39 -07:00