Re: kmemcheck: got WARNING when dynamicly adjust /proc/sys/kernel/kmemcheck to 0/1

From: Xishi Qiu
Date: Sun May 11 2014 - 23:34:58 EST


On 2014/5/9 18:02, Vegard Nossum wrote:

> On 05/09/2014 11:52 AM, Xishi Qiu wrote:
>> On 2014/5/9 15:57, Xishi Qiu wrote:
>>
>>> OS boot with kmemcheck=0, then set 1, do something, set 0, do something, set 1...
>>> then I got the WARNING log. Does kmemcheck support dynamicly adjust?
>>>
>>> Thanks,
>>> Xishi Qiu
>>>
>>> [ 20.200305] igb: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
>>> [ 20.208652] ADDRCONF(NETDEV_UP): eth0: link is not ready
>>> [ 20.216504] ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
>>> [ 22.647385] auditd (3116): /proc/3116/oom_adj is deprecated, please use /proc/3116/oom_score_adj instead.
>>> [ 24.845214] BIOS EDD facility v0.16 2004-Jun-25, 1 devices found
>>> [ 30.434764] eth0: no IPv6 routers present
>>> [ 340.154608] NOHZ: local_softirq_pending 01
>>> [ 340.154639] WARNING: kmemcheck: Caught 64-bit read from uninitialized memory (ffff88083f43a550)
>>> [ 340.154644] c000000002000000000000000000000080ff5d0100c9ffff400ed34e0888ffff
>>> [ 340.154667] u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u
>>> [ 340.154687] ^
>>> [ 340.154690]
>>> [ 340.154694] Pid: 3, comm: ksoftirqd/0 Tainted: G C 3.4.24-qiuxishi.19-0.1-default+ #2 Huawei Technologies Co., Ltd. Tecal RH2285 V2-24S/BC11SRSC1
>>> [ 340.154702] RIP: 0010:[<ffffffff81217d72>] [<ffffffff81217d72>] d_namespace_path+0x132/0x270
>>> [ 340.154714] RSP: 0018:ffff8808515a1c88 EFLAGS: 00010202
>>> [ 340.154718] RAX: ffff88083f43a540 RBX: ffff880852e718f3 RCX: 0000000000000001
>>> [ 340.154721] RDX: ffff8808515a1d28 RSI: 0000000000000000 RDI: ffff881053855a60
>>> [ 340.154725] RBP: ffff8808515a1ce8 R08: ffff8808515a1c50 R09: ffff880852e75800
>>> [ 340.154728] R10: 00000000000156f0 R11: 0000000000000000 R12: 0000000000000001
>>> [ 340.154731] R13: 0000000000000100 R14: ffff880852e71510 R15: ffff880852e71800
>>> [ 340.154736] FS: 0000000000000000(0000) GS:ffff88085f600000(0000) knlGS:0000000000000000
>>> [ 340.154740] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
>>> [ 340.154743] CR2: ffff880852e71570 CR3: 00000008513f2000 CR4: 00000000000407f0
>>> [ 340.154746] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
>>> [ 340.154750] DR3: 0000000000000000 DR6: 00000000ffff4ff0 DR7: 0000000000000400
>>> [ 340.154753] [<ffffffff81217f35>] aa_path_name+0x85/0x180
>>> [ 340.154758] [<ffffffff812187d6>] apparmor_bprm_set_creds+0x126/0x520
>>> [ 340.154763] [<ffffffff811f60ae>] security_bprm_set_creds+0xe/0x10
>>> [ 340.154771] [<ffffffff81170d65>] prepare_binprm+0xa5/0x100
>>> [ 340.154777] [<ffffffff811716c2>] do_execve_common+0x232/0x430
>>> [ 340.154781] [<ffffffff8117194a>] do_execve+0x3a/0x40
>>> [ 340.154785] [<ffffffff8100abb9>] sys_execve+0x49/0x70
>>> [ 340.154793] [<ffffffff814764bc>] stub_execve+0x6c/0xc0
>>> [ 340.154801] [<ffffffffffffffff>] 0xffffffffffffffff
>>> [ 340.154813] WARNING: kmemcheck: Caught 64-bit read from uninitialized memory (ffff88083f43a570)
>>> [ 340.154817] 746f70000300000078a5433f0888fffff86d433f0888ffff746f700000730000
>>> [ 340.154839] u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u
>>> [ 340.154858] ^
>>> [ 340.154861]
>>> [ 340.154864] Pid: 3, comm: ksoftirqd/0 Tainted: G C 3.4.24-qiuxishi.19-0.1-default+ #2 Huawei Technologies Co., Ltd. Tecal RH2285 V2-24S/BC11SRSC1
>>> [ 340.154871] RIP: 0010:[<ffffffff811691f4>] [<ffffffff811691f4>] rw_verify_area+0x24/0x100
>>> [ 340.154880] RSP: 0018:ffff8808515a1dc8 EFLAGS: 00010202
>>> [ 340.154883] RAX: ffff88083f43a540 RBX: 0000000000000080 RCX: 0000000000000080
>>> [ 340.154887] RDX: ffff8808515a1e30 RSI: ffff880852e71500 RDI: 0000000000000000
>>> [ 340.154890] RBP: ffff8808515a1de8 R08: ffff880852e73200 R09: ffff88085f004900
>>> [ 340.154894] R10: ffff880852e72600 R11: 0000000000000000 R12: ffff880852e71500
>>> [ 340.154897] R13: 0000000000000000 R14: ffff880852e73200 R15: 0000000000000001
>>> [ 340.154901] FS: 0000000000000000(0000) GS:ffff88085f600000(0000) knlGS:0000000000000000
>>> [ 340.154905] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
>>> [ 340.154908] CR2: ffff880852e71570 CR3: 00000008513f2000 CR4: 00000000000407f0
>>> [ 340.154911] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
>>> [ 340.154914] DR3: 0000000000000000 DR6: 00000000ffff4ff0 DR7: 0000000000000400
>>> [ 340.154917] [<ffffffff811698f4>] vfs_read+0xa4/0x130
>>> [ 340.154922] [<ffffffff81170ca4>] kernel_read+0x44/0x60
>>> [ 340.154926] [<ffffffff81170d90>] prepare_binprm+0xd0/0x100
>>> [ 340.154931] [<ffffffff811716c2>] do_execve_common+0x232/0x430
>>> [ 340.154935] [<ffffffff8117194a>] do_execve+0x3a/0x40
>>> [ 340.154939] [<ffffffff8100abb9>] sys_execve+0x49/0x70
>>> [ 340.154944] [<ffffffff814764bc>] stub_execve+0x6c/0xc0
>>> [ 340.154950] [<ffffffffffffffff>] 0xffffffffffffffff
>>> [ 340.154955] WARNING: kmemcheck: Caught 32-bit read from uninitialized memory (ffff88083f43a540)
>>> [ 340.154959] c000000002000000000000000000000080ff5d0100c9ffff400ed34e0888ffff
>>> [ 340.154981] u u u u u u u u u u u u u u u u i i i i i i i i u u u u u u u u
>>> [ 340.155000] ^
>>>
>>>
>>
>> Another problem, does there some way will initialize the shadow?
>> I only find the object has been initialized.
>>
>> kmemcheck_slab_alloc()
>> ...
>> /*
>> * Has already been memset(), which initializes the shadow for us
>> * as well.
>> */
>> if (gfpflags & __GFP_ZERO)
>> return; ----> add kmemcheck_mark_initialized() ?
>> ...
>>
>> slab:
>> slab_alloc()
>> ...
>> if (likely(objp))
>> kmemcheck_slab_alloc(cachep, flags, objp, cachep->object_size);
>>
>> if (unlikely((flags & __GFP_ZERO) && objp))
>> memset(objp, 0, cachep->object_size);
>>
>> return objp;
>>
>> slub:
>> slab_alloc_node()
>> ...
>> if (unlikely(gfpflags & __GFP_ZERO) && object)
>> memset(object, 0, s->object_size);
>>
>> slab_post_alloc_hook(s, gfpflags, object);
>>
>> return object;
>>
>> The shadow memory which used for slab/slub is called from kmemcheck_alloc_shadow(),
>> and it will initialized *only* in kmemcheck_slab_alloc(), right?
>>
>
> If you enable kmemcheck at run-time, there is no way to know what already-allocated objects have been initialised or not, so we assume that they have been. In that case, there is also very little point in allocating shadow memory for them, since it will all be marked as "initialised" anyway (one exception is if we later memcpy() uninitialised memory into them, but that seems like it would be a pretty rare occurrence).
>

> The use case for toggling kmemcheck at run-time is to check a particular piece of code (enable it, run a program/system call/insert a module/whatever, disable it -- this will basically check memory allocated while kmemcheck is enabled, but not memory allocated before or after).
>
> So to answer your original question, yes, toggling kmemcheck at run-time is supported, but there is an increased chance of false negatives (we don't spot a problem where there is one). About false positives (we spot a problem where there isn't one), I don't think runtime toggling should make a difference.
>

Hi Vegard,

Thanks for your reply.

"we spot a problem where there isn't one", like this case, right?
1. kmemcheck=off at run-time
2. allocate memory use kmalloc(), but not been initialized
3. kmemcheck_slab_alloc() will call kmemcheck_mark_initialized() because kmemcheck_enabled is off
4. enable kmemcheck
5. access the memory
6. we expect the access uninitialized memory warning, but there isn't one

"we don't spot a problem where there is one",
I wonder how does "WARNING: read from uninitialized memory" happen?
1. kmemcheck = on
2. allocate memory use kmalloc(), but not been initialized
3. kmemcheck_slab_alloc() will call kmemcheck_mark_uninitialized()
4. disable kmemcheck
5. first write access will call kmemcheck_fault(), this will mark the shadow to KMEMCHECK_SHADOW_INITIALIZED
6. then call kmemcheck_trap() -> kmemcheck_hide() -> kmemcheck_show_all()
7. so the pte is always _PAGE_PRESENT, and it will not triger page fault again even kmemcheck=on
8. how does the uninitialized warning happen?

Thanks,
Xishi Qiu

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/