Re: Question: livepatch failed for new fork() task stack unreliable

From: Wangshaobo (bobo)
Date: Wed Jun 03 2020 - 21:25:12 EST



å 2020/6/3 23:33, Josh Poimboeuf åé:
On Wed, Jun 03, 2020 at 10:06:07PM +0800, Wangshaobo (bobo) wrote:
To be honest, I don't remember what I meant by sibling calls. They
don't even leave anything on the stack.

For noreturns, the code might be laid out like this:

func1:
...
call noreturn_foo
func2:

func2 is immediately after the call to noreturn_foo. So the return
address on the stack will actually be 'func2'. We want to retrieve the
ORC data for the call instruction (inside func1), instead of the
instruction at the beginning of func2.

I should probably update that comment.

So, I want to ask is there any side effects if i modify like this ? this modification is based on

your fix. It looks like ok with proper test.

diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c
index e9cc182aa97e..ecce5051e8fd 100644
--- a/arch/x86/kernel/unwind_orc.c
+++ b/arch/x86/kernel/unwind_orc.c
@@ -620,6 +620,7 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ state->sp = task->thread.sp;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ state->bp = READ_ONCE_NOCHECK(frame->bp);
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ state->ip = READ_ONCE_NOCHECK(frame->ret_addr);
+ÂÂÂÂÂÂÂÂÂÂÂÂÂ state->signal = ((void *)state->ip == ret_from_fork);
ÂÂÂÂÂÂÂ }

diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c
index 7f969b2d240f..d7396431261a 100644
--- a/arch/x86/kernel/unwind_orc.c
+++ b/arch/x86/kernel/unwind_orc.c
@@ -540,7 +540,7 @@ bool unwind_next_frame(struct unwind_state *state)
ÂÂÂÂÂÂÂÂ state->sp = sp;
ÂÂÂÂÂÂÂÂ state->regs = NULL;
ÂÂÂÂÂÂÂÂ state->prev_regs = NULL;
-ÂÂÂÂÂÂÂ state->signal = ((void *)state->ip == ret_from_fork);
+ÂÂÂÂÂÂÂ state->signal = false;
ÂÂÂÂÂÂÂÂ break;

thanks,

Wang ShaoBo