Re: [RFT PATCH -next v2] [BUGFIX] kprobes: Fix "Failed to find blacklist" error on ia64 and ppc64

From: Masami Hiramatsu
Date: Thu May 29 2014 - 22:48:01 EST


(2014/05/30 4:13), Suzuki K. Poulose wrote:
>> @@ -2042,7 +2043,8 @@ static int __init populate_kprobe_blacklist(unsigned long *start,
>> unsigned long offset = 0, size = 0;
>>
>> for (iter = start; iter < end; iter++) {
>> - if (!kallsyms_lookup_size_offset(*iter, &size, &offset)) {
>> + if (!kallsyms_lookup_size_offset(function_entry(*iter),
>> + &size, &offset)) {
>
> On powerpc we will be able to resolve the *iter to func_descr and won't
> get the below error with/without this patch. So we have to actually
> verify the kprobe_blacklist contents to make sure everything is alright.
>
>> pr_err("Failed to find blacklist %p\n", (void *)*iter);
>> continue;
>> }
>>
>
> There is a bug here.
> You need to set the ent->start using the function_entry(*iter) and not
> *iter. Or else you just avoid the 'Warning' and still have an invalid
> black list. As shown below :
>
> 2e:mon> ls kprobe_blacklist
> kprobe_blacklist: c00000000104dad0
> 2e:mon> d c00000000104dad0 10
> c00000000104dad0: c0000003aff800a0 c0000003aff809a0
> 2e:mon> d c0000003aff800a0 20 (struct kprobe_blacklist *)
> c0000003aff800a0: c0000003aff800c0 c00000000104dad0
> c0000003aff800b0: c0000000010ef138 c0000000010ef188
> start ^^ end ^^
> 2e:mon> la c0000000010ef138 (start)
> c0000000010ef138: notify_die+0x0/0x10 <- still points to the
> function descriptor
> 2e:mon> la c0000000010ef188 (end)
> c0000000010ef188: __blocking_notifier_call_chain+0x0/0x10
>
>
> Following patch fixes the issue, with the patch :
>
> 1:mon> ls kprobe_blacklist
> kprobe_blacklist: c00000000104dad0
> 1:mon> d c00000000104dad0 10
> c00000000104dad0: c0000003ae1a00a0 c0000003ae1a09a0
> 1:mon> d c0000003ae1a00a0 20 (struct kprobe_blacklist *)
> c0000003ae1a00a0: c0000003ae1a00c0 c00000000104dad0
> c0000003ae1a00b0: c0000000000b14d0 c0000000000b1520
> start ^^ end ^^
> 1:mon> la c0000000000b14d0
> c0000000000b14d0: .notify_die+0x0/0x50
> 1:mon> la c0000000000b1520
> c0000000000b1520: .atomic_notifier_chain_register+0x0/0xa0
>
> 1:mon> di c0000000000b14d0 10 (.notify_die)
> c0000000000b14d0 7c0802a6 mflr r0
> c0000000000b14d4 7c691b78 mr r9,r3
>
> commit ed51674aca8e0496641f565421ab6691a873e80a
> Author: Suzuki K. Poulose <suzuki@xxxxxxxxxx>
> Date: Fri May 30 00:23:01 2014 +0530
>
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index 3859c88..b81d626 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -2043,7 +2043,8 @@ static int __init
> populate_kprobe_blacklist(unsigned long *start,
> unsigned long offset = 0, size = 0;
>
> for (iter = start; iter < end; iter++) {
> - if (!kallsyms_lookup_size_offset(function_entry(*iter),
> + unsigned long entry = function_entry(*iter);
> + if (!kallsyms_lookup_size_offset(entry,
> &size, &offset)) {
> pr_err("Failed to find blacklist %p\n", (void
> *)*iter);
> continue;
> @@ -2052,8 +2053,8 @@ static int __init
> populate_kprobe_blacklist(unsigned long *start,
> ent = kmalloc(sizeof(*ent), GFP_KERNEL);
> if (!ent)
> return -ENOMEM;
> - ent->start_addr = *iter;
> - ent->end_addr = *iter + size;
> + ent->start_addr = entry;
> + ent->end_addr = entry + size;

Oops! right, I missed it :(
I'll update the patch including your fix and signed-off-by.

thank you!


--
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Research Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt@xxxxxxxxxxx


--
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/