1. 14 5月, 2011 1 次提交
    • T
      job control: reorganize wait_task_stopped() · 19e27463
      Tejun Heo 提交于
      wait_task_stopped() tested task_stopped_code() without acquiring
      siglock and, if stop condition existed, called wait_task_stopped() and
      directly returned the result.  This patch moves the initial
      task_stopped_code() testing into wait_task_stopped() and make
      wait_consider_task() fall through to wait_task_continue() on 0 return.
      
      This is for the following two reasons.
      
      * Because the initial task_stopped_code() test is done without
        acquiring siglock, it may race against SIGCONT generation.  The
        stopped condition might have been replaced by continued state by the
        time wait_task_stopped() acquired siglock.  This may lead to
        unexpected failure of WNOHANG waits.
      
        This reorganization addresses this single race case but there are
        other cases - TASK_RUNNING -> TASK_STOPPED transition and EXIT_*
        transitions.
      
      * Scheduled ptrace updates require changes to the initial test which
        would fit better inside wait_task_stopped().
      Signed-off-by: NTejun Heo <tj@kernel.org>
      Reviewed-by: NOleg Nesterov <oleg@redhat.com>
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      19e27463
  2. 09 5月, 2011 2 次提交
    • T
      ptrace: fix signal->wait_chldexit usage in task_clear_group_stop_trapping() · 40ae717d
      Tejun Heo 提交于
      GROUP_STOP_TRAPPING waiting mechanism piggybacks on
      signal->wait_chldexit which is primarily used to implement waiting for
      wait(2) and friends.  When do_wait() waits on signal->wait_chldexit,
      it uses a custom wake up callback, child_wait_callback(), which
      expects the child task which is waking up the parent to be passed in
      as @key to filter out spurious wakeups.
      
      task_clear_group_stop_trapping() used __wake_up_sync() which uses NULL
      @key causing the following oops if the parent was doing do_wait().
      
        BUG: unable to handle kernel NULL pointer dereference at 00000000000002d8
        IP: [<ffffffff810499f9>] child_wait_callback+0x29/0x80
        PGD 1d899067 PUD 1e418067 PMD 0
        Oops: 0000 [#1] PREEMPT SMP
        last sysfs file: /sys/devices/pci0000:00/0000:00:03.0/local_cpus
        CPU 2
        Modules linked in:
      
        Pid: 4498, comm: test-continued Not tainted 2.6.39-rc6-work+ #32 Bochs Bochs
        RIP: 0010:[<ffffffff810499f9>]  [<ffffffff810499f9>] child_wait_callback+0x29/0x80
        RSP: 0000:ffff88001b889bf8  EFLAGS: 00010046
        RAX: 0000000000000000 RBX: ffff88001fab3af8 RCX: 0000000000000000
        RDX: 0000000000000001 RSI: 0000000000000002 RDI: ffff88001d91df20
        RBP: ffff88001b889c08 R08: 0000000000000000 R09: 0000000000000000
        R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000000
        R13: ffff88001fb70550 R14: 0000000000000000 R15: 0000000000000001
        FS:  00007f26ccae4700(0000) GS:ffff88001fd00000(0000) knlGS:0000000000000000
        CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
        CR2: 00000000000002d8 CR3: 000000001b8ac000 CR4: 00000000000006e0
        DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
        DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
        Process test-continued (pid: 4498, threadinfo ffff88001b888000, task ffff88001fb88000)
        Stack:
         ffff88001b889c18 ffff88001fb70538 ffff88001b889c58 ffffffff810312f9
         0000000000000001 0000000200000001 ffff88001b889c58 ffff88001fb70518
         0000000000000002 0000000000000082 0000000000000001 0000000000000000
        Call Trace:
         [<ffffffff810312f9>] __wake_up_common+0x59/0x90
         [<ffffffff81035263>] __wake_up_sync_key+0x53/0x80
         [<ffffffff810352a0>] __wake_up_sync+0x10/0x20
         [<ffffffff8105a984>] task_clear_jobctl_trapping+0x44/0x50
         [<ffffffff8105bcbc>] ptrace_stop+0x7c/0x290
         [<ffffffff8105c20a>] do_signal_stop+0x28a/0x2d0
         [<ffffffff8105d27f>] get_signal_to_deliver+0x14f/0x5a0
         [<ffffffff81002175>] do_signal+0x75/0x7b0
         [<ffffffff8100292d>] do_notify_resume+0x5d/0x70
         [<ffffffff8182e36a>] retint_signal+0x46/0x8c
        Code: 00 00 55 48 89 e5 53 48 83 ec 08 0f 1f 44 00 00 8b 47 d8 83 f8 03 74 3a 85 c0 49 89 c8 75 23 89 c0 48 8b 5f e0 4c 8d 0c 40 31 c0 <4b> 39 9c c8 d8 02 00 00 74 1d 48 83 c4 08 5b c9 c3 66 0f 1f 44
      
      Fix it by using __wake_up_sync_key() and passing in the child as @key.
      
      I still think it's a mistake to piggyback on wait_chldexit for this.
      Given the relative low frequency of ptrace use, we would be much
      better off leaving already complex wait_chldexit alone and using bit
      waitqueue.
      Signed-off-by: NTejun Heo <tj@kernel.org>
      Reviewed-by: NOleg Nesterov <oleg@redhat.com>
      40ae717d
    • O
      signal: sys_sigprocmask() needs retarget_shared_pending() · 2e4f7c77
      Oleg Nesterov 提交于
      sys_sigprocmask() changes current->blocked by hand. Convert this code
      to use set_current_blocked().
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      2e4f7c77
  3. 28 4月, 2011 11 次提交
  4. 05 4月, 2011 2 次提交
  5. 04 4月, 2011 5 次提交
    • R
      ntp: fix non privileged system time shifting · 4352d9d4
      Richard Cochran 提交于
      The ADJ_SETOFFSET bit added in commit 094aa188 ("ntp: Add ADJ_SETOFFSET
      mode bit") also introduced a way for any user to change the system time.
      Sneaky or buggy calls to adjtimex() could set
      
          ADJ_OFFSET_SS_READ | ADJ_SETOFFSET
      
      which would result in a successful call to timekeeping_inject_offset().
      This patch fixes the issue by adding the capability check.
      Signed-off-by: NRichard Cochran <richard.cochran@omicron.at>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      4352d9d4
    • O
      ptrace: ptrace_check_attach() should not do s/STOPPED/TRACED/ · 321fb561
      Oleg Nesterov 提交于
      After "ptrace: Clean transitions between TASK_STOPPED and TRACED"
      d79fdd6d, ptrace_check_attach()
      should never see a TASK_STOPPED tracee and s/STOPPED/TRACED/ is
      no longer legal. Add the warning.
      
      Note: ptrace_check_attach() can be greatly simplified, in particular
      it doesn't need tasklist. But I'd prefer another patch for that.
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Signed-off-by: NTejun Heo <tj@kernel.org>
      321fb561
    • O
      signal: Turn SIGNAL_STOP_DEQUEUED into GROUP_STOP_DEQUEUED · ee77f075
      Oleg Nesterov 提交于
      This patch moves SIGNAL_STOP_DEQUEUED from signal_struct->flags to
      task_struct->group_stop, and thus makes it per-thread.
      
      Like SIGNAL_STOP_DEQUEUED, GROUP_STOP_DEQUEUED can be false-positive
      after return from get_signal_to_deliver(), this is fine. The only
      purpose of this bit is: we can drop ->siglock after __dequeue_signal()
      returns the sig_kernel_stop() signal and before we call
      do_signal_stop(), in this case we must not miss SIGCONT if it comes in
      between.
      
      But, unlike SIGNAL_STOP_DEQUEUED, GROUP_STOP_DEQUEUED can not be
      false-positive in do_signal_stop() if multiple threads dequeue the
      sig_kernel_stop() signal at the same time.
      
      Consider two threads T1 and T2, SIGTTIN has a hanlder.
      
      	- T1 dequeues SIGTSTP and sets SIGNAL_STOP_DEQUEUED, then
      	  it drops ->siglock
      
      	- SIGCONT comes and clears SIGNAL_STOP_DEQUEUED, SIGTSTP
      	  should be cancelled.
      
      	- T2 dequeues SIGTTIN and sets SIGNAL_STOP_DEQUEUED again.
      	  Since we have a handler we should not stop, T2 returns
      	  to usermode to run the handler.
      
      	- T1 continues, calls do_signal_stop() and wrongly starts
      	  the group stop because SIGNAL_STOP_DEQUEUED was restored
      	  in between.
      
      With or without this change:
      
      	- we need to do something with ptrace_signal() which can
      	  return SIGSTOP, but this needs another discussion
      
      	- SIGSTOP can be lost if it races with the mt exec, will
      	  be fixed later.
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Signed-off-by: NTejun Heo <tj@kernel.org>
      ee77f075
    • O
      signal: do_signal_stop: Remove the unneeded task_clear_group_stop_pending() · 780006ea
      Oleg Nesterov 提交于
      PF_EXITING or TASK_STOPPED has already called task_participate_group_stop()
      and cleared its ->group_stop. No need to do task_clear_group_stop_pending()
      when we start the new group stop.
      
      Add a small comment to explain the !task_is_stopped() check. Note that this
      check is not exactly right and it can lead to unnecessary stop later if the
      thread is TASK_PTRACED. What we need is task_participated_in_group_stop(),
      this will be solved later.
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Signed-off-by: NTejun Heo <tj@kernel.org>
      780006ea
    • O
      signal: prepare_signal(SIGCONT) shouldn't play with TIF_SIGPENDING · 1deac632
      Oleg Nesterov 提交于
      prepare_signal(SIGCONT) should never set TIF_SIGPENDING or wake up
      the TASK_INTERRUPTIBLE threads. We are going to call complete_signal()
      which should pick the right thread correctly. All we need is to wake
      up the TASK_STOPPED threads.
      
      If the task was stopped, it can't return to usermode without taking
      ->siglock. Otherwise we don't care, and the spurious TIF_SIGPENDING
      can't be useful.
      
      The comment says:
      
      	* If there is a handler for SIGCONT, we must make
      	* sure that no thread returns to user mode before
      	* we post the signal
      
      It is not clear what this means. Probably, "when there's only a single
      thread" and this continues to be true. Otherwise, even if this SIGCONT
      is not private, with or without this change only one thread can dequeue
      SIGCONT, other threads can happily return to user mode before before
      that thread handles this signal.
      
      Note also that wake_up_state(t, __TASK_STOPPED) can't race with the task
      which changes its state, TASK_STOPPED state is protected by ->siglock as
      well.
      
      In short: when it comes to signal delivery, SIGCONT is the normal signal
      and does not need any special support.
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Signed-off-by: NTejun Heo <tj@kernel.org>
      1deac632
  6. 01 4月, 2011 1 次提交
  7. 31 3月, 2011 4 次提交
  8. 30 3月, 2011 3 次提交
  9. 29 3月, 2011 8 次提交
  10. 28 3月, 2011 3 次提交