[PATCH] cred: Fix kernel panic upon security_file_alloc() failure.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I injected error path like below

--- a/security/security.c
+++ b/security/security.c
@@ -623,6 +623,11 @@
 
 int security_file_alloc(struct file *file)
 {
+	static u8 counter = 255;
+	if (!--counter) {
+		printk(KERN_ERR "***** Injecting failure *****\n");
+		return -ENOMEM;
+	}
 	return security_ops->file_alloc_security(file);
 }
 

and got kernel panic due to put_cred(NULL) call within RCU callback.

SCSI subsystem initialized
PCI: Using ACPI for IRQ routing
pci 0000:00:18.2: no compatible bridge window for [io  0xf000-0xffff]
***** Injecting failure *****
BUG: unable to handle kernel NULL pointer dereference at   (null)
IP: [<c04bd01c>] file_free_rcu+0xc/0x30
*pde = 00000000 
Oops: 0002 [#1] SMP DEBUG_PAGEALLOC
last sysfs file: 
Modules linked in:

Pid: 1, comm: swapper Not tainted 2.6.38-rc3 #2 440BX Desktop Reference Platform/VMware Virtual Platform
EIP: 0060:[<c04bd01c>] EFLAGS: 00010282 CPU: 0
EIP is at file_free_rcu+0xc/0x30
EAX: de85cf20 EBX: de85cf20 ECX: 00000002 EDX: 00000000
ESI: de85cf20 EDI: df543220 EBP: df00df8c ESP: df00df88
 DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
Process swapper (pid: 1, ti=df00c000 task=df10c030 task.ti=df10e000)
Stack:
 df224714 df00dfb8 c0480d28 c0469db5 df543238 c080aa80 00000000 df29926c
 00000000 00000001 00000009 00000024 df00dfc0 c0480f1e df00dff8 c0444869
 00000000 00000000 00000000 00000000 00000000 00000000 0000000a 00000000
Call Trace:
 [<c0480d28>] __rcu_process_callbacks+0x128/0x300
 [<c0469db5>] ? mark_held_locks+0x55/0x70
 [<c0480f1e>] rcu_process_callbacks+0x1e/0x40
 [<c0444869>] __do_softirq+0x89/0x130
 [<c04447e0>] ? __do_softirq+0x0/0x130
 <IRQ> 
 [<c0444778>] ? irq_exit+0x38/0x50
 [<c042005b>] ? smp_apic_timer_interrupt+0x5b/0x90
 [<c053c054>] ? trace_hardirqs_off_thunk+0xc/0x18
 [<c06bb383>] ? apic_timer_interrupt+0x2f/0x34
 [<c0642bad>] ? fib_rules_event+0xd/0x180
 [<c06b93ba>] ? mutex_lock_nested+0x3a/0x50
 [<c063d43f>] ? rtnl_lock+0xf/0x20
 [<c062e456>] ? register_netdevice_notifier+0x96/0x1c0
 [<c06b8e38>] ? mutex_unlock+0x8/0x10
 [<c0861af6>] ? fib_rules_init+0x66/0xb0
 [<c0643a40>] ? fib_nl_dumprule+0x0/0x180
 [<c0401223>] ? do_one_initcall+0x123/0x170
 [<c0861a90>] ? fib_rules_init+0x0/0xb0
 [<c082ea8c>] ? kernel_init+0x13c/0x230
 [<c082e950>] ? kernel_init+0x0/0x230
 [<c040317a>] ? kernel_thread_helper+0x6/0x1c
Code: d0 e8 a9 82 01 00 83 8b cc 00 00 00 02 83 c4 04 5b 5d c3 8d b6 00 00 00 00 8d bf 00 00 00 00 55 89 e5 53 89 c3 8b 90 90 00 00 00 <f0> ff 0a 0f 94 c0 84 c0 74 07 89 d0 e8 53 12 fa ff a1 a0 cb 82 
EIP: [<c04bd01c>] file_free_rcu+0xc/0x30 SS:ESP 0068:df00df88
CR2: 0000000000000000
---[ end trace 4eaa2a86a8e2da22 ]---
Kernel panic - not syncing: Fatal exception in interrupt
Pid: 1, comm: swapper Tainted: G      D     2.6.38-rc3 #2
Call Trace:
 [<c043ebba>] ? panic+0x5a/0x180
 [<c0406398>] ? oops_end+0xb8/0xc0
 [<c04277fd>] ? no_context+0x11d/0x150
 [<c042792d>] ? __bad_area_nosemaphore+0x4d/0x130
 [<c0469db5>] ? mark_held_locks+0x55/0x70
 [<c0427e45>] ? do_page_fault+0x1b5/0x420
 [<c0427ab2>] ? bad_area_nosemaphore+0x12/0x20
 [<c0427e33>] ? do_page_fault+0x1a3/0x420
 [<c046bfdd>] ? __lock_acquire+0x4dd/0x6d0
 [<c0427c90>] ? do_page_fault+0x0/0x420
 [<c06bb5bf>] ? error_code+0x5f/0x64
 [<c0427c90>] ? do_page_fault+0x0/0x420
 [<c04bd01c>] ? file_free_rcu+0xc/0x30
 [<c0480d28>] ? __rcu_process_callbacks+0x128/0x300
 [<c0469db5>] ? mark_held_locks+0x55/0x70
 [<c0480f1e>] ? rcu_process_callbacks+0x1e/0x40
 [<c0444869>] ? __do_softirq+0x89/0x130
 [<c04447e0>] ? __do_softirq+0x0/0x130
 <IRQ>  [<c0444778>] ? irq_exit+0x38/0x50
 [<c042005b>] ? smp_apic_timer_interrupt+0x5b/0x90
 [<c053c054>] ? trace_hardirqs_off_thunk+0xc/0x18
 [<c06bb383>] ? apic_timer_interrupt+0x2f/0x34
 [<c0642bad>] ? fib_rules_event+0xd/0x180
 [<c06b93ba>] ? mutex_lock_nested+0x3a/0x50
 [<c063d43f>] ? rtnl_lock+0xf/0x20
 [<c062e456>] ? register_netdevice_notifier+0x96/0x1c0
 [<c06b8e38>] ? mutex_unlock+0x8/0x10
 [<c0861af6>] ? fib_rules_init+0x66/0xb0
 [<c0643a40>] ? fib_nl_dumprule+0x0/0x180
 [<c0401223>] ? do_one_initcall+0x123/0x170
 [<c0861a90>] ? fib_rules_init+0x0/0xb0
 [<c082ea8c>] ? kernel_init+0x13c/0x230
 [<c082e950>] ? kernel_init+0x0/0x230
 [<c040317a>] ? kernel_thread_helper+0x6/0x1c

I think below patch fixes this bug.
----------------------------------------
>From 6cc601487b076ea5c16b2d5828f00ad14d92c189 Mon Sep 17 00:00:00 2001
From: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 4 Feb 2011 22:09:09 +0900
Subject: [PATCH] cred: Fix kernel panic upon security_file_alloc() failure.

In get_empty_filp() since 2.6.29, file_free(f) is called with f->f_cred == NULL
when security_file_alloc() returned an error. As a result, kernel will panic()
due to put_cred(NULL) call within RCU callback.

Fix this bug by assigning f->f_cred before calling security_file_alloc().

Signed-off-by: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx>
---
 fs/file_table.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/fs/file_table.c b/fs/file_table.c
index c3e89ad..eb36b6b 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -125,13 +125,13 @@ struct file *get_empty_filp(void)
 		goto fail;
 
 	percpu_counter_inc(&nr_files);
+	f->f_cred = get_cred(cred);
 	if (security_file_alloc(f))
 		goto fail_sec;
 
 	INIT_LIST_HEAD(&f->f_u.fu_list);
 	atomic_long_set(&f->f_count, 1);
 	rwlock_init(&f->f_owner.lock);
-	f->f_cred = get_cred(cred);
 	spin_lock_init(&f->f_lock);
 	eventpoll_init_file(f);
 	/* f->f_version: 0 */
-- 
1.6.1
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux