* [PATCH] kobject: Access kobject name with caution if state is not initialized
@ 2018-08-20 17:09 Srikar Dronamraju
2018-08-20 19:22 ` Greg Kroah-Hartman
0 siblings, 1 reply; 5+ messages in thread
From: Srikar Dronamraju @ 2018-08-20 17:09 UTC (permalink / raw)
To: LKML, Greg Kroah-Hartman, Andrew Morton, Linus Torvalds
Cc: Srikar Dronamraju, Dmitry Torokhov, David S . Miller
If kobject state is not initialized, then its not even certain that
kobject'name is initialized. Hence when accessing the kobject's name
tread carefully.
A stupid module test like
https://github.com/srikard/tests/blob/master/modules/kobject_test.c
can panic the system.
With patch: We will see the correct warning.
[ 2058.129913] ------------[ cut here ]------------
[ 2058.129919] kobject: ' ' (00000000ad405b63): is not initialized, yet kobject_get() is being called.
[ 2058.129938] WARNING: CPU: 58 PID: 18529 at /home/srikar/work/linux.git/lib/kobject.c:620 kobject_get+0x90/0xb0
[ 2058.129946] Modules linked in: kobject_test(OE+) uio_pdrv_genirq(E) uio(E) leds_powernv(E) powernv_op_panel(E) ipmi_powernv(E) ipmi_devintf(E) powernv_rng(E) ibmpowernv(E) ipmi_msghandler(E) vmx_crypto(E) crct10dif_vpmsum(E) sch_fq_codel(E) ip_tables(E) x_tables(E) autofs4(E) ses enclosure scsi_transport_sas mlx4_ib mlx4_en ib_core lpfc crc32c_vpmsum mlx4_core nvmet_fc nvmet nvme_fc ipr nvme_fabrics devlink scsi_transport_fc tg3 [last unloaded: module_test]
[ 2058.130014] CPU: 58 PID: 18529 Comm: insmod Tainted: G W OEL 4.18.0-master+ #3
[ 2058.130022] NIP: c000000000d5f530 LR: c000000000d5f52c CTR: 0000000000000000
[ 2058.130029] REGS: c000002fd32f3640 TRAP: 0700 Tainted: G W OEL (4.18.0-master+)
[ 2058.130036] MSR: 9000000002029033 <SF,HV,VEC,EE,ME,IR,DR,RI,LE> CR: 48002282 XER: 20000000
[ 2058.130054] CFAR: c000000000114e10 IRQMASK: 0
GPR00: c000000000d5f52c c000002fd32f38c0 c0000000017bc200 0000000000000057
GPR04: 0000000000000001 000000000000107e 9000000002009033 00000000000000f2
GPR08: 0000000000000007 0000000000000007 0000000000000001 9000000002001003
GPR12: 0000000000002200 c000002ffffe0d00 0000000000000000 0000000000000000
GPR16: 0000000000000000 c0000000001e92e0 0000000000000000 0000000000000100
GPR20: 0000000000000001 c000000001662e60 c000000001662ed8 c000002feb4114a0
GPR24: 0000000000000001 c000000000dbd438 c000000001662ea0 c000000001662ec0
GPR28: c000002fe5f0cea0 d00000001ded03d0 c000002fd32f39a0 c000002fd32f39a0
[ 2058.130133] NIP [c000000000d5f530] kobject_get+0x90/0xb0
[ 2058.130140] LR [c000000000d5f52c] kobject_get+0x8c/0xb0
[ 2058.130146] Call Trace:
[ 2058.130150] [c000002fd32f38c0] [c000000000d5f52c] kobject_get+0x8c/0xb0 (unreliable)
[ 2058.130159] [c000002fd32f3940] [d00000001ded0088] kobject_test_init+0x80/0xb0 [kobject_test]
[ 2058.130168] [c000002fd32f39f0] [c0000000000101f8] do_one_initcall+0x58/0x240
[ 2058.130178] [c000002fd32f3ab0] [c0000000001ef2b0] do_init_module+0x90/0x260
[ 2058.130186] [c000002fd32f3b40] [c0000000001edec8] load_module+0x2d88/0x3320
[ 2058.130193] [c000002fd32f3d20] [c0000000001ee764] sys_finit_module+0xc4/0x130
[ 2058.130204] [c000002fd32f3e30] [c00000000000b288] system_call+0x5c/0x70
[ 2058.130210] Instruction dump:
[ 2058.130215] e89f0000 4b5b4c15 60000000 2f830000 419e0030 3c82ff8c 388491e0 3c62ff90
[ 2058.130228] 7fe5fb78 3863e9b0 4b3b5881 60000000 <0fe00000> e8010090 7c0803a6 4bffff88
[ 2058.130240] ---[ end trace 0f471c192555a013 ]---
[ 2070.084234] kobject_test module unloaded
Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
---
lib/kobject.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/lib/kobject.c b/lib/kobject.c
index 389829d3a1d1..2d65be37fd7b 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -16,6 +16,7 @@
#include <linux/stat.h>
#include <linux/slab.h>
#include <linux/random.h>
+#include <linux/uaccess.h>
/**
* kobject_namespace - return @kobj's namespace tag
@@ -417,8 +418,11 @@ int kobject_add(struct kobject *kobj, struct kobject *parent,
return -EINVAL;
if (!kobj->state_initialized) {
+ char tmp;
+ int ret = probe_kernel_address(kobject_name(kobj), tmp);
+
pr_err("kobject '%s' (%p): tried to add an uninitialized object, something is seriously wrong.\n",
- kobject_name(kobj), kobj);
+ ret ? " " : kobject_name(kobj), kobj);
dump_stack();
return -EINVAL;
}
@@ -606,10 +610,14 @@ EXPORT_SYMBOL(kobject_del);
struct kobject *kobject_get(struct kobject *kobj)
{
if (kobj) {
- if (!kobj->state_initialized)
+ if (!kobj->state_initialized) {
+ char tmp;
+ int ret = probe_kernel_address(kobject_name(kobj), tmp);
+
WARN(1, KERN_WARNING
"kobject: '%s' (%p): is not initialized, yet kobject_get() is being called.\n",
- kobject_name(kobj), kobj);
+ ret ? " " : kobject_name(kobj), kobj);
+ }
kref_get(&kobj->kref);
}
return kobj;
@@ -701,10 +709,14 @@ static void kobject_release(struct kref *kref)
void kobject_put(struct kobject *kobj)
{
if (kobj) {
- if (!kobj->state_initialized)
+ if (!kobj->state_initialized) {
+ char tmp;
+ int ret = probe_kernel_address(kobject_name(kobj), tmp);
+
WARN(1, KERN_WARNING
"kobject: '%s' (%p): is not initialized, yet kobject_put() is being called.\n",
- kobject_name(kobj), kobj);
+ ret ? " " : kobject_name(kobj), kobj);
+ }
kref_put(&kobj->kref, kobject_release);
}
}
--
2.17.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] kobject: Access kobject name with caution if state is not initialized
2018-08-20 17:09 [PATCH] kobject: Access kobject name with caution if state is not initialized Srikar Dronamraju
@ 2018-08-20 19:22 ` Greg Kroah-Hartman
2018-08-20 19:33 ` Dmitry Torokhov
2018-08-21 4:58 ` Srikar Dronamraju
0 siblings, 2 replies; 5+ messages in thread
From: Greg Kroah-Hartman @ 2018-08-20 19:22 UTC (permalink / raw)
To: Srikar Dronamraju
Cc: LKML, Andrew Morton, Linus Torvalds, Dmitry Torokhov,
David S . Miller
On Mon, Aug 20, 2018 at 10:39:47PM +0530, Srikar Dronamraju wrote:
> If kobject state is not initialized, then its not even certain that
> kobject'name is initialized. Hence when accessing the kobject's name
> tread carefully.
>
> A stupid module test like
> https://github.com/srikard/tests/blob/master/modules/kobject_test.c
> can panic the system.
Lots of stupid modules can do dumb things. Just don't do that. The
kernel is not built to keep you from doing stupid things in kernel code
:)
So I fail to see why this patch is needed. What in-kernel code path is
trying to print a kobject's name before it is initialized? Why not fix
that obvious bug instead of forcing the kernel core to protect from
stupid code?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] kobject: Access kobject name with caution if state is not initialized
2018-08-20 19:22 ` Greg Kroah-Hartman
@ 2018-08-20 19:33 ` Dmitry Torokhov
2018-08-21 6:46 ` Srikar Dronamraju
2018-08-21 4:58 ` Srikar Dronamraju
1 sibling, 1 reply; 5+ messages in thread
From: Dmitry Torokhov @ 2018-08-20 19:33 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: srikar, lkml, Andrew Morton, Linus Torvalds, David S. Miller
On Mon, Aug 20, 2018 at 12:22 PM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> On Mon, Aug 20, 2018 at 10:39:47PM +0530, Srikar Dronamraju wrote:
> > If kobject state is not initialized, then its not even certain that
> > kobject'name is initialized. Hence when accessing the kobject's name
> > tread carefully.
> >
> > A stupid module test like
> > https://github.com/srikard/tests/blob/master/modules/kobject_test.c
> > can panic the system.
>
> Lots of stupid modules can do dumb things. Just don't do that. The
> kernel is not built to keep you from doing stupid things in kernel code
> :)
>
> So I fail to see why this patch is needed. What in-kernel code path is
> trying to print a kobject's name before it is initialized? Why not fix
> that obvious bug instead of forcing the kernel core to protect from
> stupid code?
Kay decided to add some guards in:
commit 0f4dafc0563c6c49e17fe14b3f5f356e4c4b8806
Author: Kay Sievers <kay.sievers@vrfy.org>
Date: Wed Dec 19 01:40:42 2007 +0100
Kobject: auto-cleanup on final unref
...
+ if (!kobj->state_initialized) {
+ printk(KERN_ERR "kobject '%s' (%p): tried to add an "
+ "uninitialized object, something is seriously wrong.\n",
+ kobject_name(kobj), kobj);
+ dump_stack();
+ return -EINVAL;
Given that we have dump_stack() we can probably simply drop
kobject_name(kobj) instead of building even more elaborate checks. Or
just drop the whole check. Adding kobjects is somewhat uncommon
operation, plus "gabage in, garbage out".
Thanks.
--
Dmitry
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] kobject: Access kobject name with caution if state is not initialized
2018-08-20 19:22 ` Greg Kroah-Hartman
2018-08-20 19:33 ` Dmitry Torokhov
@ 2018-08-21 4:58 ` Srikar Dronamraju
1 sibling, 0 replies; 5+ messages in thread
From: Srikar Dronamraju @ 2018-08-21 4:58 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: LKML, Andrew Morton, Linus Torvalds, Dmitry Torokhov,
David S . Miller
* Greg Kroah-Hartman <gregkh@linuxfoundation.org> [2018-08-20 21:22:47]:
> On Mon, Aug 20, 2018 at 10:39:47PM +0530, Srikar Dronamraju wrote:
> > A stupid module test like
> > https://github.com/srikard/tests/blob/master/modules/kobject_test.c
> > can panic the system.
>
> Lots of stupid modules can do dumb things. Just don't do that. The
> kernel is not built to keep you from doing stupid things in kernel code
> :)
>
Completely agree. kernel/module code is not for doing stupid things.
However we seem to be hitting this once in a while in a weird case with
a slightly older kernel with no out of tree modules.
crash> bt
PID: 54813 TASK: c000000c4c76c160 CPU: 40 COMMAND: "lvm"
#0 [c00000004ac0eb50] crash_kexec at c0000000001a1be4
#1 [c00000004ac0eb80] die at c000000000025668
#2 [c00000004ac0ec20] bad_page_fault at c00000000005d7a0
#3 [c00000004ac0ec90] handle_page_fault at c000000000009608
Data Access [300] exception frame:
R0: c000000000521cb4 R1: c00000004ac0ef80 R2: c000000001274800
R3: 0000000200000000 R4: ffffffffffffffff R5: 0000000200000000
R6: 0000000000000000 R7: ffffffffffffffff R8: ffffffffffffffff
R9: 0000000000000004 R10: c000000000521c90 R11: c000000001434800
R12: c0000000000e3750 R13: c000000007b16800 R14: 00003fff85970520
R15: 00003fffd442c6c0 R16: 0000000000000000 R17: 000000000000005c
R18: 00003fff859797c8 R19: 00003fff859a28f0 R20: 00000100333c2400
R21: 00000100333c23d0 R22: 0000000000000025 R23: c00000000143a648
R24: 00000000000003e0 R25: 0000000000000020 R26: c00000004ac0f140
R27: 0000000000000000 R28: 0000000200000000 R29: ffffffffffffffff
R30: c00000000143aa28 R31: c00000000143a654
NIP: c00000000051bda8 MSR: 8000000100009033 OR3: c0000000000093ec
CTR: c000000000521c90 LR: c00000000051e7b8 XER: 0000000000000000
CCR: 0000000088048444 MQ: 0000000000000000 DAR: 0000000200000000
DSISR: 0000000040000000 Syscall Result: 0000000000000000
#4 [c00000004ac0ef80] strnlen at c00000000051bda8
[Link Register] [c00000004ac0ef80] string at c00000000051e7b8
#5 [c00000004ac0efd0] vsnprintf at c000000000521cb4
#6 [c00000004ac0f050] vscnprintf at c0000000005226e0
#7 [c00000004ac0f080] vprintk_default at c0000000000e381c
#8 [c00000004ac0f0f0] printk at c000000000a2047c
#9 [c00000004ac0f110] kobject_put at c000000000510c34
#10 [c00000004ac0f1a0] of_node_put at c000000000813034
#11 [c00000004ac0f1c0] pci_release_of_node at c0000000005ae724
#12 [c00000004ac0f1f0] pci_release_dev at c00000000056ff60
#13 [c00000004ac0f220] device_release at c00000000065a468
#14 [c00000004ac0f2a0] kobject_put at c000000000510abc
#15 [c00000004ac0f330] put_device at c00000000065aaf4
#16 [c00000004ac0f350] scsi_host_dev_release at c0000000006a2f10
#17 [c00000004ac0f390] device_release at c00000000065a468
#18 [c00000004ac0f410] kobject_put at c000000000510abc
#19 [c00000004ac0f4a0] put_device at c00000000065aaf4
#20 [c00000004ac0f4c0] scsi_target_dev_release at c0000000006b2bb4
#21 [c00000004ac0f4f0] device_release at c00000000065a468
#22 [c00000004ac0f570] kobject_put at c000000000510abc
#23 [c00000004ac0f600] put_device at c00000000065aaf4
#24 [c00000004ac0f620] scsi_device_dev_release_usercontext at c0000000006b8790
#25 [c00000004ac0f670] execute_in_process_context at c0000000001185b4
#26 [c00000004ac0f6a0] scsi_device_dev_release at c0000000006b8644
#27 [c00000004ac0f6c0] device_release at c00000000065a468
#28 [c00000004ac0f740] kobject_put at c000000000510abc
#29 [c00000004ac0f7d0] put_device at c00000000065aaf4
#30 [c00000004ac0f7f0] scsi_device_put at c00000000069ff98
#31 [c00000004ac0f820] sd_release at d000000008013f4c [sd_mod]
#32 [c00000004ac0f8a0] __blkdev_put at c0000000003a7318
#33 [c00000004ac0f900] dm_put_table_device at d000000006ed09fc [dm_mod]
#34 [c00000004ac0f940] dm_put_device at d000000006ed663c [dm_mod]
#35 [c00000004ac0f9b0] linear_dtr at d000000006eda2d4 [dm_mod]
#36 [c00000004ac0f9e0] dm_table_destroy at d000000006ed7380 [dm_mod]
#37 [c00000004ac0fa70] dev_suspend at d000000006edf114 [dm_mod]
#38 [c00000004ac0faf0] ctl_ioctl at d000000006edc2e0 [dm_mod]
#39 [c00000004ac0fcf0] dm_ctl_ioctl at d000000006edc548 [dm_mod]
#40 [c00000004ac0fd10] do_vfs_ioctl at c00000000035a9a8
#41 [c00000004ac0fdd0] sys_ioctl at c00000000035aea4
#42 [c00000004ac0fe30] system_call at c00000000000a284
System Call [c00] exception frame:
R0: 0000000000000036 R1: 00003fffd442c4b0 R2: 00003fff858a7400
R3: 0000000000000006 R4: 00000000c138fd06 R5: 00000100333c23d0
R6: 0000000000000004 R7: 00003fff8597a2f0 R8: 0000000000000006
R9: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000
R12: 0000000000000000 R13: 00003fff85b42ff0 R14: 00003fff85970520
R15: 00003fffd442c6c0 R16: 0000000000000000 R17: 000000000000005c
R18: 00003fff859797c8 R19: 00003fff859a28f0 R20: 00000100333c2400
R21: 00000100333c23d0 R22: 00003fff859a40e8 R23: 00003fff85970520
R24: 00003fff85970520 R25: 00003fff85970520 R26: 0000000000000007
R27: 00000100333c2480 R28: 00003fff85970520 R29: 0000000106da8290
R30: 00003fff85970520 R31: 00000100333bdb00
NIP: 00003fff857d9ecc MSR: 800000010000d033 OR3: 0000000000000006
CTR: 0000000000000000 LR: 00003fff8596dc08 XER: 0000000000000000
CCR: 0000000044022444 MQ: 0000000000000001 DAR: 0000010033dae5d0
DSISR: 0000000042000000 Syscall Result: 0000000000000004
Since this happens once in a bluemoon, there is no point in trying with
a newer/later kernel.
> So I fail to see why this patch is needed. What in-kernel code path is
> trying to print a kobject's name before it is initialized? Why not fix
> that obvious bug instead of forcing the kernel core to protect from
> stupid code?
By the time it has crashed, we don't have a clue on who created the
kobject, which thread tried to delete the object.
To see if two threads were racing, I looked at stack traces from other
threads but no other thread is in kobject_* calls. So there is a genuine
bug in a genuine module/kernel. The point that kobject state in
uninitialized itself means that the call was unexpected. So the question
now is should we detect and abort gracefully or should we allow it to
panic. By aborting, we are not masking the problem.
--
Thanks and Regards
Srikar
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] kobject: Access kobject name with caution if state is not initialized
2018-08-20 19:33 ` Dmitry Torokhov
@ 2018-08-21 6:46 ` Srikar Dronamraju
0 siblings, 0 replies; 5+ messages in thread
From: Srikar Dronamraju @ 2018-08-21 6:46 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Greg Kroah-Hartman, lkml, Andrew Morton, Linus Torvalds,
David S. Miller
* Dmitry Torokhov <dmitry.torokhov@gmail.com> [2018-08-20 12:33:50]:
> On Mon, Aug 20, 2018 at 12:22 PM Greg Kroah-Hartman
> <gregkh@linuxfoundation.org> wrote:
> >
> > On Mon, Aug 20, 2018 at 10:39:47PM +0530, Srikar Dronamraju wrote:
> > Lots of stupid modules can do dumb things. Just don't do that. The
> > kernel is not built to keep you from doing stupid things in kernel code
> > :)
> >
> > So I fail to see why this patch is needed. What in-kernel code path is
> > trying to print a kobject's name before it is initialized? Why not fix
> > that obvious bug instead of forcing the kernel core to protect from
> > stupid code?
>
> Kay decided to add some guards in:
>
> commit 0f4dafc0563c6c49e17fe14b3f5f356e4c4b8806
> Author: Kay Sievers <kay.sievers@vrfy.org>
> Date: Wed Dec 19 01:40:42 2007 +0100
>
> Kobject: auto-cleanup on final unref
> ...
>
> + if (!kobj->state_initialized) {
> + printk(KERN_ERR "kobject '%s' (%p): tried to add an "
> + "uninitialized object, something is seriously wrong.\n",
> + kobject_name(kobj), kobj);
> + dump_stack();
> + return -EINVAL;
>
> Given that we have dump_stack() we can probably simply drop
> kobject_name(kobj) instead of building even more elaborate checks. Or
> just drop the whole check. Adding kobjects is somewhat uncommon
> operation, plus "gabage in, garbage out".
>
Dropping the kobject_name(kobj) should also be okay.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2018-08-21 6:47 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-08-20 17:09 [PATCH] kobject: Access kobject name with caution if state is not initialized Srikar Dronamraju
2018-08-20 19:22 ` Greg Kroah-Hartman
2018-08-20 19:33 ` Dmitry Torokhov
2018-08-21 6:46 ` Srikar Dronamraju
2018-08-21 4:58 ` Srikar Dronamraju
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).