diff mbox

kprobes/x86: opt: free optinsn cache when range check fails

Message ID 1406550019-70935-1-git-send-email-wangnan0@huawei.com
State Accepted
Commit 256aae5eac6d328067d1a986a7c5df6f19bdc8b4
Headers show

Commit Message

Wang Nan July 28, 2014, 12:20 p.m. UTC
This patch frees optinsn slot when range check error to prevent memory
leaks. Before this patch, cache entry in kprobe_insn_cache won't be
freed if kprobe optimizing fails due to range check failure.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
---
 arch/x86/kernel/kprobes/opt.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Comments

Masami Hiramatsu July 29, 2014, 1:43 a.m. UTC | #1
(2014/07/28 21:20), Wang Nan wrote:
> This patch frees optinsn slot when range check error to prevent memory
> leaks. Before this patch, cache entry in kprobe_insn_cache won't be
> freed if kprobe optimizing fails due to range check failure.
> 
> Signed-off-by: Wang Nan <wangnan0@huawei.com>

Oops, thank you for finding it!

Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>

BTW, would you really have hit this error?
I'd like to know the case if this really happens.

> ---
>  arch/x86/kernel/kprobes/opt.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
> index f304773..f1314d0 100644
> --- a/arch/x86/kernel/kprobes/opt.c
> +++ b/arch/x86/kernel/kprobes/opt.c
> @@ -338,8 +338,10 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op)
>  	 * a relative jump.
>  	 */
>  	rel = (long)op->optinsn.insn - (long)op->kp.addr + RELATIVEJUMP_SIZE;
> -	if (abs(rel) > 0x7fffffff)
> +	if (abs(rel) > 0x7fffffff) {
> +		__arch_remove_optimized_kprobe(op, 0);
>  		return -ERANGE;
> +	}
>  
>  	buf = (u8 *)op->optinsn.insn;
>  
>
Wang Nan July 29, 2014, 1:55 a.m. UTC | #2
On 2014/7/29 9:43, Masami Hiramatsu wrote:
> (2014/07/28 21:20), Wang Nan wrote:
>> This patch frees optinsn slot when range check error to prevent memory
>> leaks. Before this patch, cache entry in kprobe_insn_cache won't be
>> freed if kprobe optimizing fails due to range check failure.
>>
>> Signed-off-by: Wang Nan <wangnan0@huawei.com>
> 
> Oops, thank you for finding it!
> 
> Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> 
> BTW, would you really have hit this error?
> I'd like to know the case if this really happens.

I'm not really hit it on x86_64. I found this problem when trying to implement kprobe opt on arm.

On arm, relative jump can only branch on/backward 64MB, which makes it a realistic problem.

> 
>> ---
>>  arch/x86/kernel/kprobes/opt.c | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
>> index f304773..f1314d0 100644
>> --- a/arch/x86/kernel/kprobes/opt.c
>> +++ b/arch/x86/kernel/kprobes/opt.c
>> @@ -338,8 +338,10 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op)
>>  	 * a relative jump.
>>  	 */
>>  	rel = (long)op->optinsn.insn - (long)op->kp.addr + RELATIVEJUMP_SIZE;
>> -	if (abs(rel) > 0x7fffffff)
>> +	if (abs(rel) > 0x7fffffff) {
>> +		__arch_remove_optimized_kprobe(op, 0);
>>  		return -ERANGE;
>> +	}
>>  
>>  	buf = (u8 *)op->optinsn.insn;
>>  
>>
> 
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Masami Hiramatsu July 29, 2014, 11:36 a.m. UTC | #3
Hi Wang,

(2014/07/29 10:55), Wang Nan wrote:
> On 2014/7/29 9:43, Masami Hiramatsu wrote:
>> (2014/07/28 21:20), Wang Nan wrote:
>>> This patch frees optinsn slot when range check error to prevent memory
>>> leaks. Before this patch, cache entry in kprobe_insn_cache won't be
>>> freed if kprobe optimizing fails due to range check failure.
>>>
>>> Signed-off-by: Wang Nan <wangnan0@huawei.com>
>>
>> Oops, thank you for finding it!
>>
>> Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
>>
>> BTW, would you really have hit this error?
>> I'd like to know the case if this really happens.
> 
> I'm not really hit it on x86_64. I found this problem when trying to implement kprobe opt on arm.

That's interesting :)

> 
> On arm, relative jump can only branch on/backward 64MB, which makes it a realistic problem.

Yeah, that is what I expected on RISC processor such as ARM.

Perhaps you'll need to overwrite 2 words, one is for "ldr pc, [pc, #-4]" and one is for
the address data. In this case, you have no branch range limitation in 32bit mode. This
requires branch destination checking for safety as x86 optprobe does.
Plus, you'll have to use same technique of x86 to make a detour code and deferred
optimization for overwriting multiple instructions. Put a breakpoint at the probe point,
wait for synchronize_sched(), put the 2nd instruction(.data) and overwrite the breakpoint
with the "ldr". :)

However, that is only for arm32.
For ARM64, I'm not so sure about its ISA. I guess we need a scratchpad area for that..

Anyway, please CC to me when you've done the prototyping and sending RFC. I'll review
and test it. :)

Thank you,

> 
>>
>>> ---
>>>  arch/x86/kernel/kprobes/opt.c | 4 +++-
>>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
>>> index f304773..f1314d0 100644
>>> --- a/arch/x86/kernel/kprobes/opt.c
>>> +++ b/arch/x86/kernel/kprobes/opt.c
>>> @@ -338,8 +338,10 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op)
>>>  	 * a relative jump.
>>>  	 */
>>>  	rel = (long)op->optinsn.insn - (long)op->kp.addr + RELATIVEJUMP_SIZE;
>>> -	if (abs(rel) > 0x7fffffff)
>>> +	if (abs(rel) > 0x7fffffff) {
>>> +		__arch_remove_optimized_kprobe(op, 0);
>>>  		return -ERANGE;
>>> +	}
>>>  
>>>  	buf = (u8 *)op->optinsn.insn;
>>>  
>>>
>>
>>
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>
Wang Nan Aug. 5, 2014, 7:49 a.m. UTC | #4
On 2014/7/29 19:36, Masami Hiramatsu wrote:
> Hi Wang,
> 
> (2014/07/29 10:55), Wang Nan wrote:
>> On 2014/7/29 9:43, Masami Hiramatsu wrote:
>>> (2014/07/28 21:20), Wang Nan wrote:
>>>> This patch frees optinsn slot when range check error to prevent memory
>>>> leaks. Before this patch, cache entry in kprobe_insn_cache won't be
>>>> freed if kprobe optimizing fails due to range check failure.
>>>>
>>>> Signed-off-by: Wang Nan <wangnan0@huawei.com>
>>>
>>> Oops, thank you for finding it!
>>>
>>> Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
>>>
>>> BTW, would you really have hit this error?
>>> I'd like to know the case if this really happens.
>>
>> I'm not really hit it on x86_64. I found this problem when trying to implement kprobe opt on arm.
> 
> That's interesting :)
> 
>>
>> On arm, relative jump can only branch on/backward 64MB, which makes it a realistic problem.
> 
> Yeah, that is what I expected on RISC processor such as ARM.
> 
> Perhaps you'll need to overwrite 2 words, one is for "ldr pc, [pc, #-4]" and one is for
> the address data. In this case, you have no branch range limitation in 32bit mode. This
> requires branch destination checking for safety as x86 optprobe does.
> Plus, you'll have to use same technique of x86 to make a detour code and deferred
> optimization for overwriting multiple instructions. Put a breakpoint at the probe point,
> wait for synchronize_sched(), put the 2nd instruction(.data) and overwrite the breakpoint
> with the "ldr". :)
> 
> However, that is only for arm32.
> For ARM64, I'm not so sure about its ISA. I guess we need a scratchpad area for that..
> 
> Anyway, please CC to me when you've done the prototyping and sending RFC. I'll review
> and test it. :)
> 
> Thank you,
> 

Hi Masami,

I have posted my RFC patch on LKML and ARM mailing list, and also CC you.
Please see:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-August/277809.html

Please help me review my patch, Thank you!

>>
>>>
>>>> ---
>>>>  arch/x86/kernel/kprobes/opt.c | 4 +++-
>>>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
>>>> index f304773..f1314d0 100644
>>>> --- a/arch/x86/kernel/kprobes/opt.c
>>>> +++ b/arch/x86/kernel/kprobes/opt.c
>>>> @@ -338,8 +338,10 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op)
>>>>  	 * a relative jump.
>>>>  	 */
>>>>  	rel = (long)op->optinsn.insn - (long)op->kp.addr + RELATIVEJUMP_SIZE;
>>>> -	if (abs(rel) > 0x7fffffff)
>>>> +	if (abs(rel) > 0x7fffffff) {
>>>> +		__arch_remove_optimized_kprobe(op, 0);
>>>>  		return -ERANGE;
>>>> +	}
>>>>  
>>>>  	buf = (u8 *)op->optinsn.insn;
>>>>  
>>>>
>>>
>>>
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at  http://www.tux.org/lkml/
>>
> 
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Wang Nan Aug. 27, 2014, 12:15 p.m. UTC | #5
On 2014/7/29 9:43, Masami Hiramatsu wrote:
> (2014/07/28 21:20), Wang Nan wrote:
>> This patch frees optinsn slot when range check error to prevent memory
>> leaks. Before this patch, cache entry in kprobe_insn_cache won't be
>> freed if kprobe optimizing fails due to range check failure.
>>
>> Signed-off-by: Wang Nan <wangnan0@huawei.com>
> 
> Oops, thank you for finding it!
> 
> Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> 

Hi Masami Hiramatsu,

I don't find this patch in newest upstream. Is there any problem?

> BTW, would you really have hit this error?
> I'd like to know the case if this really happens.
> 
>> ---
>>  arch/x86/kernel/kprobes/opt.c | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
>> index f304773..f1314d0 100644
>> --- a/arch/x86/kernel/kprobes/opt.c
>> +++ b/arch/x86/kernel/kprobes/opt.c
>> @@ -338,8 +338,10 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op)
>>  	 * a relative jump.
>>  	 */
>>  	rel = (long)op->optinsn.insn - (long)op->kp.addr + RELATIVEJUMP_SIZE;
>> -	if (abs(rel) > 0x7fffffff)
>> +	if (abs(rel) > 0x7fffffff) {
>> +		__arch_remove_optimized_kprobe(op, 0);
>>  		return -ERANGE;
>> +	}
>>  
>>  	buf = (u8 *)op->optinsn.insn;
>>  
>>
> 
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Masami Hiramatsu Aug. 27, 2014, 1:37 p.m. UTC | #6
Hi Ingo,

Could you pull this for a bugfix of a memory leak?

(2014/08/27 21:15), Wang Nan wrote:
> On 2014/7/29 9:43, Masami Hiramatsu wrote:
>> (2014/07/28 21:20), Wang Nan wrote:
>>> This patch frees optinsn slot when range check error to prevent memory
>>> leaks. Before this patch, cache entry in kprobe_insn_cache won't be
>>> freed if kprobe optimizing fails due to range check failure.
>>>
>>> Signed-off-by: Wang Nan <wangnan0@huawei.com>
>>
>> Oops, thank you for finding it!
>>
>> Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
>>
> 
> Hi Masami Hiramatsu,
> 
> I don't find this patch in newest upstream. Is there any problem?
> 
>> BTW, would you really have hit this error?
>> I'd like to know the case if this really happens.
>>
>>> ---
>>>  arch/x86/kernel/kprobes/opt.c | 4 +++-
>>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
>>> index f304773..f1314d0 100644
>>> --- a/arch/x86/kernel/kprobes/opt.c
>>> +++ b/arch/x86/kernel/kprobes/opt.c
>>> @@ -338,8 +338,10 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op)
>>>  	 * a relative jump.
>>>  	 */
>>>  	rel = (long)op->optinsn.insn - (long)op->kp.addr + RELATIVEJUMP_SIZE;
>>> -	if (abs(rel) > 0x7fffffff)
>>> +	if (abs(rel) > 0x7fffffff) {
>>> +		__arch_remove_optimized_kprobe(op, 0);
>>>  		return -ERANGE;
>>> +	}
>>>  
>>>  	buf = (u8 *)op->optinsn.insn;
>>>  
>>>
>>
>>
> 
> 
>
Wang Nan Sept. 15, 2014, 1:26 a.m. UTC | #7
Hi Ingo and Masami,

I still unable to find this bugfix in mainline code. Is there any problem?

Thank you!

On 2014/8/27 21:37, Masami Hiramatsu wrote:
> 
> Hi Ingo,
> 
> Could you pull this for a bugfix of a memory leak?
> 
> (2014/08/27 21:15), Wang Nan wrote:
>> On 2014/7/29 9:43, Masami Hiramatsu wrote:
>>> (2014/07/28 21:20), Wang Nan wrote:
>>>> This patch frees optinsn slot when range check error to prevent memory
>>>> leaks. Before this patch, cache entry in kprobe_insn_cache won't be
>>>> freed if kprobe optimizing fails due to range check failure.
>>>>
>>>> Signed-off-by: Wang Nan <wangnan0@huawei.com>
>>>
>>> Oops, thank you for finding it!
>>>
>>> Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
>>>
>>
>> Hi Masami Hiramatsu,
>>
>> I don't find this patch in newest upstream. Is there any problem?
>>
>>> BTW, would you really have hit this error?
>>> I'd like to know the case if this really happens.
>>>
>>>> ---
>>>>  arch/x86/kernel/kprobes/opt.c | 4 +++-
>>>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
>>>> index f304773..f1314d0 100644
>>>> --- a/arch/x86/kernel/kprobes/opt.c
>>>> +++ b/arch/x86/kernel/kprobes/opt.c
>>>> @@ -338,8 +338,10 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op)
>>>>  	 * a relative jump.
>>>>  	 */
>>>>  	rel = (long)op->optinsn.insn - (long)op->kp.addr + RELATIVEJUMP_SIZE;
>>>> -	if (abs(rel) > 0x7fffffff)
>>>> +	if (abs(rel) > 0x7fffffff) {
>>>> +		__arch_remove_optimized_kprobe(op, 0);
>>>>  		return -ERANGE;
>>>> +	}
>>>>  
>>>>  	buf = (u8 *)op->optinsn.insn;
>>>>  
>>>>
>>>
>>>
>>
>>
>>
> 
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Ingo Molnar Sept. 16, 2014, 8:59 a.m. UTC | #8
* Wang Nan <wangnan0@huawei.com> wrote:

> Hi Ingo and Masami,
> 
> I still unable to find this bugfix in mainline code. Is there any problem?

It's in tip:perf/urgent, on its way to Linus.

Thanks,

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

Patch

diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
index f304773..f1314d0 100644
--- a/arch/x86/kernel/kprobes/opt.c
+++ b/arch/x86/kernel/kprobes/opt.c
@@ -338,8 +338,10 @@  int arch_prepare_optimized_kprobe(struct optimized_kprobe *op)
 	 * a relative jump.
 	 */
 	rel = (long)op->optinsn.insn - (long)op->kp.addr + RELATIVEJUMP_SIZE;
-	if (abs(rel) > 0x7fffffff)
+	if (abs(rel) > 0x7fffffff) {
+		__arch_remove_optimized_kprobe(op, 0);
 		return -ERANGE;
+	}
 
 	buf = (u8 *)op->optinsn.insn;