finish_report: if (resume < utrace->resume) { spin_lock(utrace_lock); utrace->resume = resume;
this can race with utrace_control(). If we are going to change utrace->resume we must always check it under utrace->lock to ensure the new value is less than. Signed-off-by: Oleg Nesterov <o...@redhat.com> --- kernel/utrace.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) --- UTRACE-PTRACE/kernel/utrace.c~2_FINISH_REPORT_CK_RESUME_UNDER_LOCK 2009-11-19 02:24:41.000000000 +0100 +++ UTRACE-PTRACE/kernel/utrace.c 2009-11-19 02:40:52.000000000 +0100 @@ -1375,11 +1375,13 @@ static void finish_report(struct task_st if (resume < utrace->resume) { spin_lock(&utrace->lock); - utrace->resume = resume; - if (resume == UTRACE_INTERRUPT) - set_tsk_thread_flag(task, TIF_SIGPENDING); - else - set_tsk_thread_flag(task, TIF_NOTIFY_RESUME); + if (resume < utrace->resume) { + utrace->resume = resume; + if (resume == UTRACE_INTERRUPT) + set_tsk_thread_flag(task, TIF_SIGPENDING); + else + set_tsk_thread_flag(task, TIF_NOTIFY_RESUME); + } spin_unlock(&utrace->lock); }