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);
        }
 

Reply via email to