On Mon, Oct 5, 2015 at 1:23 PM, Ingo Molnar <mi...@kernel.org> wrote: > > * Andrey Ryabinin <aryabi...@virtuozzo.com> wrote: > >> get_wchan() is racy by design, it may access volatile stack >> of running task, thus it may access redzone in a stack frame >> and cause KASAN to warn about this. >> >> Use kasan_disable_current()/kasan_enable_current() to silence >> these warnings. >> >> Reported-by: Sasha Levin <sasha.le...@oracle.com> >> Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com> >> --- >> >> Perhaps it would be better to add something like this: >> READ_ONCE_NOCHECK() >> { >> kasan_disable_current(); >> READ_ONCE(); >> kasan_enable_current(); >> } >> ? >> >> arch/x86/kernel/process.c | 18 +++++++++++++----- >> 1 file changed, 13 insertions(+), 5 deletions(-) >> >> diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c >> index 39e585a..0488eb9 100644 >> --- a/arch/x86/kernel/process.c >> +++ b/arch/x86/kernel/process.c >> @@ -13,6 +13,7 @@ >> #include <linux/random.h> >> #include <linux/user-return-notifier.h> >> #include <linux/dmi.h> >> +#include <linux/kasan.h> >> #include <linux/utsname.h> >> #include <linux/stackprotector.h> >> #include <linux/tick.h> >> @@ -514,7 +515,7 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) >> */ >> unsigned long get_wchan(struct task_struct *p) >> { >> - unsigned long start, bottom, top, sp, fp, ip; >> + unsigned long start, bottom, top, sp, fp, ip, ret = 0; >> int count = 0; >> >> if (!p || p == current || p->state == TASK_RUNNING) >> @@ -550,14 +551,21 @@ unsigned long get_wchan(struct task_struct *p) >> if (sp < bottom || sp > top) >> return 0; >> >> + kasan_disable_current(); >> fp = READ_ONCE(*(unsigned long *)sp); >> do { >> if (fp < bottom || fp > top) >> - return 0; >> + goto out; > > a break would do just fine too. > >> + >> ip = READ_ONCE(*(unsigned long *)(fp + sizeof(unsigned long))); >> - if (!in_sched_functions(ip)) >> - return ip; >> + if (!in_sched_functions(ip)) { >> + ret = ip; >> + goto out; > > ditto. > >> + } >> fp = READ_ONCE(*(unsigned long *)fp); >> } while (count++ < 16 && p->state != TASK_RUNNING); >> - return 0; >> + >> +out: > > and then the label would not be needed. > >> + kasan_enable_current(); >> + return ret; > > But that's all pretty disgusting really. > > Cannot we do better, such as annotating the function and then KASAN sorting > out > its false positives, or something like that?
We also plug __attribute__((no_sanitize_address)) on the function. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/