* [PATCH] kernel/kprobes: add check to avoid kprobe memory leak
@ 2017-10-24 12:17 JianKang Chen
2017-10-25 16:54 ` Masami Hiramatsu
0 siblings, 1 reply; 6+ messages in thread
From: JianKang Chen @ 2017-10-24 12:17 UTC (permalink / raw)
To: nanth, anil.s.keshavamurthy, mhiramat, linux-kernel
Cc: xieyisheng1, wangkefeng.wang
The function register_kretprobe is used to initialize a struct
kretprobe and allocate a list table for kprobe instance.
However,in this function, there is a memory leak.
The test case:
static struct kretprobe rp;
struct kretprobe *rps[10]={&rp ,&rp ,&rp ,
&rp ,&rp ,&rp ,&rp ,&rp ,&rp,&rp};
static int ret_handler(struct kretprobe_instance *ri, struct pt_regs
*regs)
{
printk(KERN_DEBUG "ret_handler\n");
return 0;
}
static int entry_handler(struct kretprobe_instance *ri, struct pt_regs
*regs)
{
printk(KERN_DEBUG "entry_handler\n");
return 0;
}
static int __init kretprobe_init(void)
{
int ret;
rp.kp.addr = (kprobe_opcode_t *)kallsyms_lookup_name("do_fork");
rp.handler=ret_handler;
rp.entry_handler=entry_handler;
rp.maxactive = 1;
ret = register_kretprobes(rps,10);
if (ret < 0)
{
return -1;
}
Result:
unreferenced object 0xffff8012aea35500 (size 64):
comm "insmod", pid 31966, jiffies 4309153380 (age 111.356s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 85 37 fc ff 7f ff ff ..........7.....
08 55 a3 ae 12 80 ff ff 01 00 00 00 00 00 00 00 .U..............
backtrace:
[<ffff8000002cd880>] create_object+0x1e0/0x3f0
[<ffff800000fa47ac>] kmemleak_alloc+0x6c/0xf0
[<ffff8000002ac97c>] __kmalloc+0x23c/0x2e0
[<ffff8000001a6f2c>] register_kretprobe+0x12c/0x350
[<ffff8000001a7198>] register_kretprobes+0x48/0xa0
[<ffff7ffffc380058>] 0xffff7ffffc380058
[<ffff800000084be0>] do_one_initcall+0x120/0x260
[<ffff800000faa1a4>] do_init_module+0xf0/0x288
[<ffff8000001736f4>] load_module+0x1824/0x1b50
[<ffff800000173cc8>] SyS_finit_module+0xc8/0x100
[<ffff800000084778>] __sys_trace_return+0x0/0x4
[<ffffffffffffffff>] 0xffffffffffffffff
when there are two same struct kretprobe rp,
the INIT_HLIST_HEAD() will result
in a empty list table rp->free_instances.
The memory leak will happen.
So it needs to check the list table before INIT_HLIST_HEAD().
Reported-and-tested-by: Wen Kang <kangwen1@huawei.com>
Signed-off-by: JianKang Chen <chenjiankang1@huawei.com>
Signed-off-by: xie yisheng <xieyisheng1@huawei.com>
Signed-off-by: Bixuan Cui <cuibixuan@huawei.com>
---
kernel/kprobes.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index a1606a4..8b3330c 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1948,6 +1948,10 @@ int register_kretprobe(struct kretprobe *rp)
#endif
}
raw_spin_lock_init(&rp->lock);
+
+ if (!hlist_empty(&rp->free_instances))
+ return -EBUSY;
+
INIT_HLIST_HEAD(&rp->free_instances);
for (i = 0; i < rp->maxactive; i++) {
inst = kmalloc(sizeof(struct kretprobe_instance) +
--
1.7.12.4
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] kernel/kprobes: add check to avoid kprobe memory leak
2017-10-24 12:17 [PATCH] kernel/kprobes: add check to avoid kprobe memory leak JianKang Chen
@ 2017-10-25 16:54 ` Masami Hiramatsu
2017-10-26 1:22 ` chenjiankang
0 siblings, 1 reply; 6+ messages in thread
From: Masami Hiramatsu @ 2017-10-25 16:54 UTC (permalink / raw)
To: JianKang Chen
Cc: nanth, anil.s.keshavamurthy, linux-kernel, xieyisheng1, wangkefeng.wang
On Tue, 24 Oct 2017 20:17:02 +0800
JianKang Chen <chenjiankang1@huawei.com> wrote:
> The function register_kretprobe is used to initialize a struct
> kretprobe and allocate a list table for kprobe instance.
> However,in this function, there is a memory leak.
>
> The test case:
>
> static struct kretprobe rp;
> struct kretprobe *rps[10]={&rp ,&rp ,&rp ,
> &rp ,&rp ,&rp ,&rp ,&rp ,&rp,&rp};
What ? this is buggy code. you must not list same kretprobe.
But, year, since register_kprobe() already has similar protection against
reusing, register_kretprobe() should do so.
[..]
> raw_spin_lock_init(&rp->lock);
> +
> + if (!hlist_empty(&rp->free_instances))
> + return -EBUSY;
> +
Hmm, but can you use check_kprobe_rereg() before raw_spin_lock_init()?
If user reuses rp after it starts, rp->lock can already be used.
Thank you,
> INIT_HLIST_HEAD(&rp->free_instances);
> for (i = 0; i < rp->maxactive; i++) {
> inst = kmalloc(sizeof(struct kretprobe_instance) +
> --
> 1.7.12.4
>
--
Masami Hiramatsu <mhiramat@kernel.org>
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] kernel/kprobes: add check to avoid kprobe memory leak
2017-10-25 16:54 ` Masami Hiramatsu
@ 2017-10-26 1:22 ` chenjiankang
2017-10-26 6:21 ` Masami Hiramatsu
0 siblings, 1 reply; 6+ messages in thread
From: chenjiankang @ 2017-10-26 1:22 UTC (permalink / raw)
To: Masami Hiramatsu
Cc: ananth, anil.s.keshavamurthy, linux-kernel, xieyisheng1,
wangkefeng.wang, davem
> On Tue, 24 Oct 2017 20:17:02 +0800
> JianKang Chen <chenjiankang1@huawei.com> wrote:
>
>> The function register_kretprobe is used to initialize a struct
>> kretprobe and allocate a list table for kprobe instance.
>> However,in this function, there is a memory leak.
>>
>> The test case:
>>
>> static struct kretprobe rp;
>> struct kretprobe *rps[10]={&rp ,&rp ,&rp ,
>> &rp ,&rp ,&rp ,&rp ,&rp ,&rp,&rp};
>
> What ? this is buggy code. you must not list same kretprobe.
> But, year, since register_kprobe() already has similar protection against
> reusing, register_kretprobe() should do so.
>
> [..]
>> raw_spin_lock_init(&rp->lock);
>> +
>> + if (!hlist_empty(&rp->free_instances))
>> + return -EBUSY;
>> +
>
> Hmm, but can you use check_kprobe_rereg() before raw_spin_lock_init()?
> If user reuses rp after it starts, rp->lock can already be used.
Hmm, your advice is very good, we can use check_kprobe_rereg() at
the beginning of the register_kretprobe();
For example:
int register_kretprobe(struct kretprobe *rp)
{
int ret = 0;
struct kretprobe_instance *inst;
int i;
void *addr;
ret = check_kprobe_rereg(&rp->kp);
if (ret)
return ret;
Thank you!
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] kernel/kprobes: add check to avoid kprobe memory leak
2017-10-26 1:22 ` chenjiankang
@ 2017-10-26 6:21 ` Masami Hiramatsu
[not found] ` <701DBEAC0F0CEF4095614CC8188DF8158920C0@DGGEMM506-MBS.china.huawei.com>
0 siblings, 1 reply; 6+ messages in thread
From: Masami Hiramatsu @ 2017-10-26 6:21 UTC (permalink / raw)
To: chenjiankang
Cc: ananth, anil.s.keshavamurthy, linux-kernel, xieyisheng1,
wangkefeng.wang, davem
On Thu, 26 Oct 2017 09:22:23 +0800
chenjiankang <chenjiankang1@huawei.com> wrote:
> > On Tue, 24 Oct 2017 20:17:02 +0800
> > JianKang Chen <chenjiankang1@huawei.com> wrote:
> >
> >> The function register_kretprobe is used to initialize a struct
> >> kretprobe and allocate a list table for kprobe instance.
> >> However,in this function, there is a memory leak.
> >>
> >> The test case:
> >>
> >> static struct kretprobe rp;
> >> struct kretprobe *rps[10]={&rp ,&rp ,&rp ,
> >> &rp ,&rp ,&rp ,&rp ,&rp ,&rp,&rp};
> >
> > What ? this is buggy code. you must not list same kretprobe.
> > But, year, since register_kprobe() already has similar protection against
> > reusing, register_kretprobe() should do so.
> >
> > [..]
> >> raw_spin_lock_init(&rp->lock);
> >> +
> >> + if (!hlist_empty(&rp->free_instances))
> >> + return -EBUSY;
> >> +
> >
> > Hmm, but can you use check_kprobe_rereg() before raw_spin_lock_init()?
> > If user reuses rp after it starts, rp->lock can already be used.
>
> Hmm, your advice is very good, we can use check_kprobe_rereg() at
> the beginning of the register_kretprobe();
>
> For example:
>
> int register_kretprobe(struct kretprobe *rp)
> {
> int ret = 0;
> struct kretprobe_instance *inst;
> int i;
> void *addr;
>
> ret = check_kprobe_rereg(&rp->kp);
> if (ret)
> return ret;
Yeah, this looks much better for me :)
Thanks,
>
> Thank you!
>
>
--
Masami Hiramatsu <mhiramat@kernel.org>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] kernel/kprobes: add check to avoid kprobe memory leak
@ 2017-10-24 12:23 JianKang Chen
0 siblings, 0 replies; 6+ messages in thread
From: JianKang Chen @ 2017-10-24 12:23 UTC (permalink / raw)
To: ananth, anil.s.keshavamurthy, mhiramat, davem, linux-kernel
Cc: xieyisheng1, wangkefeng.wang, chenjiankang1
The function register_kretprobe is used to initialize a struct
kretprobe and allocate a list table for kprobe instance.
However,in this function, there is a memory leak.
The test case:
static struct kretprobe rp;
struct kretprobe *rps[10]={&rp ,&rp ,&rp ,
&rp ,&rp ,&rp ,&rp ,&rp ,&rp,&rp};
static int ret_handler(struct kretprobe_instance *ri, struct pt_regs
*regs)
{
printk(KERN_DEBUG "ret_handler\n");
return 0;
}
static int entry_handler(struct kretprobe_instance *ri, struct pt_regs
*regs)
{
printk(KERN_DEBUG "entry_handler\n");
return 0;
}
static int __init kretprobe_init(void)
{
int ret;
rp.kp.addr = (kprobe_opcode_t *)kallsyms_lookup_name("do_fork");
rp.handler=ret_handler;
rp.entry_handler=entry_handler;
rp.maxactive = 1;
ret = register_kretprobes(rps,10);
if (ret < 0)
{
return -1;
}
Result:
unreferenced object 0xffff8012aea35500 (size 64):
comm "insmod", pid 31966, jiffies 4309153380 (age 111.356s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 85 37 fc ff 7f ff ff ..........7.....
08 55 a3 ae 12 80 ff ff 01 00 00 00 00 00 00 00 .U..............
backtrace:
[<ffff8000002cd880>] create_object+0x1e0/0x3f0
[<ffff800000fa47ac>] kmemleak_alloc+0x6c/0xf0
[<ffff8000002ac97c>] __kmalloc+0x23c/0x2e0
[<ffff8000001a6f2c>] register_kretprobe+0x12c/0x350
[<ffff8000001a7198>] register_kretprobes+0x48/0xa0
[<ffff7ffffc380058>] 0xffff7ffffc380058
[<ffff800000084be0>] do_one_initcall+0x120/0x260
[<ffff800000faa1a4>] do_init_module+0xf0/0x288
[<ffff8000001736f4>] load_module+0x1824/0x1b50
[<ffff800000173cc8>] SyS_finit_module+0xc8/0x100
[<ffff800000084778>] __sys_trace_return+0x0/0x4
[<ffffffffffffffff>] 0xffffffffffffffff
when there are two same struct kretprobe rp,
the INIT_HLIST_HEAD() will result
in a empty list table rp->free_instances.
The memory leak will happen.
So it needs to check the list table before INIT_HLIST_HEAD().
Reported-and-tested-by: Wen Kang <kangwen1@huawei.com>
Signed-off-by: JianKang Chen <chenjiankang1@huawei.com>
Signed-off-by: xie yisheng <xieyisheng1@huawei.com>
Signed-off-by: Bixuan Cui <cuibixuan@huawei.com>
---
kernel/kprobes.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index a1606a4..8b3330c 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1948,6 +1948,10 @@ int register_kretprobe(struct kretprobe *rp)
#endif
}
raw_spin_lock_init(&rp->lock);
+
+ if (!hlist_empty(&rp->free_instances))
+ return -EBUSY;
+
INIT_HLIST_HEAD(&rp->free_instances);
for (i = 0; i < rp->maxactive; i++) {
inst = kmalloc(sizeof(struct kretprobe_instance) +
--
1.7.12.4
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2017-11-10 0:57 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-24 12:17 [PATCH] kernel/kprobes: add check to avoid kprobe memory leak JianKang Chen
2017-10-25 16:54 ` Masami Hiramatsu
2017-10-26 1:22 ` chenjiankang
2017-10-26 6:21 ` Masami Hiramatsu
[not found] ` <701DBEAC0F0CEF4095614CC8188DF8158920C0@DGGEMM506-MBS.china.huawei.com>
2017-11-10 0:57 ` 答复: " Masami Hiramatsu
2017-10-24 12:23 JianKang Chen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome