1. 05 3月, 2012 1 次提交
    • P
      BUG: headers with BUG/BUG_ON etc. need linux/bug.h · 187f1882
      Paul Gortmaker 提交于
      If a header file is making use of BUG, BUG_ON, BUILD_BUG_ON, or any
      other BUG variant in a static inline (i.e. not in a #define) then
      that header really should be including <linux/bug.h> and not just
      expecting it to be implicitly present.
      
      We can make this change risk-free, since if the files using these
      headers didn't have exposure to linux/bug.h already, they would have
      been causing compile failures/warnings.
      Signed-off-by: NPaul Gortmaker <paul.gortmaker@windriver.com>
      187f1882
  2. 18 1月, 2012 1 次提交
    • E
      Audit: push audit success and retcode into arch ptrace.h · d7e7528b
      Eric Paris 提交于
      The audit system previously expected arches calling to audit_syscall_exit to
      supply as arguments if the syscall was a success and what the return code was.
      Audit also provides a helper AUDITSC_RESULT which was supposed to simplify things
      by converting from negative retcodes to an audit internal magic value stating
      success or failure.  This helper was wrong and could indicate that a valid
      pointer returned to userspace was a failed syscall.  The fix is to fix the
      layering foolishness.  We now pass audit_syscall_exit a struct pt_reg and it
      in turns calls back into arch code to collect the return value and to
      determine if the syscall was a success or failure.  We also define a generic
      is_syscall_success() macro which determines success/failure based on if the
      value is < -MAX_ERRNO.  This works for arches like x86 which do not use a
      separate mechanism to indicate syscall failure.
      
      We make both the is_syscall_success() and regs_return_value() static inlines
      instead of macros.  The reason is because the audit function must take a void*
      for the regs.  (uml calls theirs struct uml_pt_regs instead of just struct
      pt_regs so audit_syscall_exit can't take a struct pt_regs).  Since the audit
      function takes a void* we need to use static inlines to cast it back to the
      arch correct structure to dereference it.
      
      The other major change is that on some arches, like ia64, MIPS and ppc, we
      change regs_return_value() to give us the negative value on syscall failure.
      THE only other user of this macro, kretprobe_example.c, won't notice and it
      makes the value signed consistently for the audit functions across all archs.
      
      In arch/sh/kernel/ptrace_64.c I see that we were using regs[9] in the old
      audit code as the return value.  But the ptrace_64.h code defined the macro
      regs_return_value() as regs[3].  I have no idea which one is correct, but this
      patch now uses the regs_return_value() function, so it now uses regs[3].
      
      For powerpc we previously used regs->result but now use the
      regs_return_value() function which uses regs->gprs[3].  regs->gprs[3] is
      always positive so the regs_return_value(), much like ia64 makes it negative
      before calling the audit code when appropriate.
      Signed-off-by: NEric Paris <eparis@redhat.com>
      Acked-by: H. Peter Anvin <hpa@zytor.com> [for x86 portion]
      Acked-by: Tony Luck <tony.luck@intel.com> [for ia64]
      Acked-by: Richard Weinberger <richard@nod.at> [for uml]
      Acked-by: David S. Miller <davem@davemloft.net> [for sparc]
      Acked-by: Ralf Baechle <ralf@linux-mips.org> [for mips]
      Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> [for ppc]
      d7e7528b
  3. 06 1月, 2012 1 次提交
    • E
      ptrace: do not audit capability check when outputing /proc/pid/stat · 69f594a3
      Eric Paris 提交于
      Reading /proc/pid/stat of another process checks if one has ptrace permissions
      on that process.  If one does have permissions it outputs some data about the
      process which might have security and attack implications.  If the current
      task does not have ptrace permissions the read still works, but those fields
      are filled with inocuous (0) values.  Since this check and a subsequent denial
      is not a violation of the security policy we should not audit such denials.
      
      This can be quite useful to removing ptrace broadly across a system without
      flooding the logs when ps is run or something which harmlessly walks proc.
      Signed-off-by: NEric Paris <eparis@redhat.com>
      Acked-by: NSerge E. Hallyn <serge.hallyn@canonical.com>
      69f594a3
  4. 18 7月, 2011 3 次提交
    • O
      ptrace: dont send SIGSTOP on auto-attach if PT_SEIZED · d184d6eb
      Oleg Nesterov 提交于
      The fake SIGSTOP during attach has numerous problems. PTRACE_SEIZE
      is already fine, but we have basically the same problems is SIGSTOP
      is sent on auto-attach, the tracer can't know if this signal signal
      should be cancelled or not.
      
      Change ptrace_event() to set JOBCTL_TRAP_STOP if the new child is
      PT_SEIZED, this triggers the PTRACE_EVENT_STOP report.
      
      Thereafter a PT_SEIZED task can never report the bogus SIGSTOP.
      
      Test-case:
      
      	#define PTRACE_SEIZE		0x4206
      	#define PTRACE_SEIZE_DEVEL	0x80000000
      	#define PTRACE_EVENT_STOP	7
      	#define WEVENT(s)		((s & 0xFF0000) >> 16)
      
      	int main(void)
      	{
      		int child, grand_child, status;
      		long message;
      
      		child = fork();
      		if (!child) {
      			kill(getpid(), SIGSTOP);
      			fork();
      			assert(0);
      			return 0x23;
      		}
      
      		assert(ptrace(PTRACE_SEIZE, child, 0,PTRACE_SEIZE_DEVEL) == 0);
      		assert(wait(&status) == child);
      		assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP);
      
      		assert(ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACEFORK) == 0);
      
      		assert(ptrace(PTRACE_CONT, child, 0,0) == 0);
      		assert(waitpid(child, &status, 0) == child);
      		assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP);
      		assert(WEVENT(status) == PTRACE_EVENT_FORK);
      
      		assert(ptrace(PTRACE_GETEVENTMSG, child, 0, &message) == 0);
      		grand_child = message;
      
      		assert(waitpid(grand_child, &status, 0) == grand_child);
      		assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP);
      		assert(WEVENT(status) == PTRACE_EVENT_STOP);
      
      		kill(child, SIGKILL);
      		kill(grand_child, SIGKILL);
      		return 0;
      	}
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Acked-by: NTejun Heo <tj@kernel.org>
      d184d6eb
    • O
      ptrace: mv send-SIGSTOP from do_fork() to ptrace_init_task() · dcace06c
      Oleg Nesterov 提交于
      If the new child is traced, do_fork() adds the pending SIGSTOP.
      It assumes that either it is traced because of auto-attach or the
      tracer attached later, in both cases sigaddset/set_thread_flag is
      correct even if SIGSTOP is already pending.
      
      Now that we have PTRACE_SEIZE this is no longer right in the latter
      case. If the tracer does PTRACE_SEIZE after copy_process() makes the
      child visible the queued SIGSTOP is wrong.
      
      We could check PT_SEIZED bit and change ptrace_attach() to set both
      PT_PTRACED and PT_SEIZED bits simultaneously but see the next patch,
      we need to know whether this child was auto-attached or not anyway.
      
      So this patch simply moves this code to ptrace_init_task(), this
      way we can never race with ptrace_attach().
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Acked-by: NTejun Heo <tj@kernel.org>
      dcace06c
    • O
      ptrace_init_task: initialize child->jobctl explicitly · 6634ae10
      Oleg Nesterov 提交于
      new_child->jobctl is not initialized during the fork, it is copied
      from parent->jobctl. Currently this is harmless, the forking task
      is running and copy_process() can't succeed if signal_pending() is
      true, so only JOBCTL_STOP_DEQUEUED can be copied. Still this is a
      bit fragile, it would be more clean to set ->jobctl = 0 explicitly.
      
      Also, check ->ptrace != 0 instead of PT_PTRACED, move the
      CONFIG_HAVE_HW_BREAKPOINT code up.
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Acked-by: NTejun Heo <tj@kernel.org>
      6634ae10
  5. 28 6月, 2011 1 次提交
    • O
      ptrace: ptrace_reparented() should check same_thread_group() · 0347e177
      Oleg Nesterov 提交于
      ptrace_reparented() naively does parent != real_parent, this means
      it returns true even if the tracer _is_ the real parent. This is per
      process thing, not per-thread. The only reason ->real_parent can
      point to the non-leader thread is that we have __WNOTHREAD.
      
      Change it to check !same_thread_group(parent, real_parent).
      
      It has two callers, and in both cases the current check does not
      look right.
      
      exit_notify: we should respect ->exit_signal if the exiting leader
      is traced by any thread from the parent thread group. It is the
      child of the whole group, and we are going to send the signal to
      the whole group.
      
      wait_task_zombie: without __WNOTHREAD do_wait() should do the same
      for any thread, only sys_ptrace() is "bound" to the single thread.
      However do_wait(WEXITED) succeeds but does not release a traced
      natural child unless the caller is the tracer.
      
      Test-case:
      
      	void *tfunc(void *arg)
      	{
      		assert(ptrace(PTRACE_ATTACH, (long)arg, 0,0) == 0);
      		pause();
      		return NULL;
      	}
      
      	int main(void)
      	{
      		pthread_t thr;
      		pid_t pid, stat, ret;
      
      		pid = fork();
      		if (!pid) {
      			pause();
      			assert(0);
      		}
      
      		assert(pthread_create(&thr, NULL, tfunc, (void*)(long)pid) == 0);
      
      		assert(waitpid(-1, &stat, 0) == pid);
      		assert(WIFSTOPPED(stat));
      
      		kill(pid, SIGKILL);
      
      		assert(waitpid(-1, &stat, 0) == pid);
      		assert(WIFSIGNALED(stat) && WTERMSIG(stat) == SIGKILL);
      
      		ret = waitpid(pid, &stat, 0);
      		if (ret < 0)
      			return 0;
      
      		printf("WTF? %d is dead, but: wait=%d stat=%x\n",
      				pid, ret, stat);
      
      		return 1;
      	}
      
      Note that the main thread simply does
      
      	pid = fork();
      	kill(pid, SIGKILL);
      
      and then without the patch wait4(WEXITED) succeeds twice and reports
      WTERMSIG(stat) == SIGKILL.
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Acked-by: NTejun Heo <tj@kernel.org>
      0347e177
  6. 23 6月, 2011 4 次提交
    • T
      ptrace: s/tracehook_tracer_task()/ptrace_parent()/ · 06d98473
      Tejun Heo 提交于
      tracehook.h is on the way out.  Rename tracehook_tracer_task() to
      ptrace_parent() and move it from tracehook.h to ptrace.h.
      Signed-off-by: NTejun Heo <tj@kernel.org>
      Cc: Christoph Hellwig <hch@infradead.org>
      Cc: John Johansen <john.johansen@canonical.com>
      Cc: Stephen Smalley <sds@tycho.nsa.gov>
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      06d98473
    • T
      ptrace: move SIGTRAP on exec(2) logic to ptrace_event() · f3c04b93
      Tejun Heo 提交于
      Move SIGTRAP on exec(2) logic from tracehook_report_exec() to
      ptrace_event().  This is part of changes to make ptrace_event()
      smarter and handle ptrace event related details in one place.
      
      This doesn't introduce any behavior change.
      Signed-off-by: NTejun Heo <tj@kernel.org>
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      f3c04b93
    • T
      ptrace: introduce ptrace_event_enabled() and simplify ptrace_event() and tracehook_prepare_clone() · 643ad838
      Tejun Heo 提交于
      This patch implements ptrace_event_enabled() which tests whether a
      given PTRACE_EVENT_* is enabled and use it to simplify ptrace_event()
      and tracehook_prepare_clone().
      
      PT_EVENT_FLAG() macro is added which calculates PT_TRACE_* flag from
      PTRACE_EVENT_*.  This is used to define PT_TRACE_* flags and by
      ptrace_event_enabled() to find the matching flag.
      
      This is used to make ptrace_event() and tracehook_prepare_clone()
      simpler.
      
      * ptrace_event() callers were responsible for providing mask to test
        whether the event was enabled.  This patch implements
        ptrace_event_enabled() and make ptrace_event() drop @mask and
        determine whether the event is enabled from @event.  Note that
        @event is constant and this conversion doesn't add runtime overhead.
      
        All conversions except tracehook_report_clone_complete() are
        trivial.  tracehook_report_clone_complete() used to use 0 for @mask
        (always enabled) but now tests whether the specified event is
        enabled.  This doesn't cause any behavior difference as it's
        guaranteed that the event specified by @trace is enabled.
      
      * tracehook_prepare_clone() now only determines which event is
        applicable and use ptrace_event_enabled() for enable test.
      
      This doesn't introduce any behavior change.
      Signed-off-by: NTejun Heo <tj@kernel.org>
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      643ad838
    • T
      ptrace: kill task_ptrace() · d21142ec
      Tejun Heo 提交于
      task_ptrace(task) simply dereferences task->ptrace and isn't even used
      consistently only adding confusion.  Kill it and directly access
      ->ptrace instead.
      
      This doesn't introduce any behavior change.
      Signed-off-by: NTejun Heo <tj@kernel.org>
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      d21142ec
  7. 17 6月, 2011 3 次提交
    • T
      ptrace: implement PTRACE_LISTEN · 544b2c91
      Tejun Heo 提交于
      The previous patch implemented async notification for ptrace but it
      only worked while trace is running.  This patch introduces
      PTRACE_LISTEN which is suggested by Oleg Nestrov.
      
      It's allowed iff tracee is in STOP trap and puts tracee into
      quasi-running state - tracee never really runs but wait(2) and
      ptrace(2) consider it to be running.  While ptracer is listening,
      tracee is allowed to re-enter STOP to notify an async event.
      Listening state is cleared on the first notification.  Ptracer can
      also clear it by issuing INTERRUPT - tracee will re-trap into STOP
      with listening state cleared.
      
      This allows ptracer to monitor group stop state without running tracee
      - use INTERRUPT to put tracee into STOP trap, issue LISTEN and then
      wait(2) to wait for the next group stop event.  When it happens,
      PTRACE_GETSIGINFO provides information to determine the current state.
      
      Test program follows.
      
        #define PTRACE_SEIZE		0x4206
        #define PTRACE_INTERRUPT	0x4207
        #define PTRACE_LISTEN		0x4208
      
        #define PTRACE_SEIZE_DEVEL	0x80000000
      
        static const struct timespec ts1s = { .tv_sec = 1 };
      
        int main(int argc, char **argv)
        {
      	  pid_t tracee, tracer;
      	  int i;
      
      	  tracee = fork();
      	  if (!tracee)
      		  while (1)
      			  pause();
      
      	  tracer = fork();
      	  if (!tracer) {
      		  siginfo_t si;
      
      		  ptrace(PTRACE_SEIZE, tracee, NULL,
      			 (void *)(unsigned long)PTRACE_SEIZE_DEVEL);
      		  ptrace(PTRACE_INTERRUPT, tracee, NULL, NULL);
      	  repeat:
      		  waitid(P_PID, tracee, NULL, WSTOPPED);
      
      		  ptrace(PTRACE_GETSIGINFO, tracee, NULL, &si);
      		  if (!si.si_code) {
      			  printf("tracer: SIG %d\n", si.si_signo);
      			  ptrace(PTRACE_CONT, tracee, NULL,
      				 (void *)(unsigned long)si.si_signo);
      			  goto repeat;
      		  }
      		  printf("tracer: stopped=%d signo=%d\n",
      			 si.si_signo != SIGTRAP, si.si_signo);
      		  if (si.si_signo != SIGTRAP)
      			  ptrace(PTRACE_LISTEN, tracee, NULL, NULL);
      		  else
      			  ptrace(PTRACE_CONT, tracee, NULL, NULL);
      		  goto repeat;
      	  }
      
      	  for (i = 0; i < 3; i++) {
      		  nanosleep(&ts1s, NULL);
      		  printf("mother: SIGSTOP\n");
      		  kill(tracee, SIGSTOP);
      		  nanosleep(&ts1s, NULL);
      		  printf("mother: SIGCONT\n");
      		  kill(tracee, SIGCONT);
      	  }
      	  nanosleep(&ts1s, NULL);
      
      	  kill(tracer, SIGKILL);
      	  kill(tracee, SIGKILL);
      	  return 0;
        }
      
      This is identical to the program to test TRAP_NOTIFY except that
      tracee is PTRACE_LISTEN'd instead of PTRACE_CONT'd when group stopped.
      This allows ptracer to monitor when group stop ends without running
      tracee.
      
        # ./test-listen
        tracer: stopped=0 signo=5
        mother: SIGSTOP
        tracer: SIG 19
        tracer: stopped=1 signo=19
        mother: SIGCONT
        tracer: stopped=0 signo=5
        tracer: SIG 18
        mother: SIGSTOP
        tracer: SIG 19
        tracer: stopped=1 signo=19
        mother: SIGCONT
        tracer: stopped=0 signo=5
        tracer: SIG 18
        mother: SIGSTOP
        tracer: SIG 19
        tracer: stopped=1 signo=19
        mother: SIGCONT
        tracer: stopped=0 signo=5
        tracer: SIG 18
      
      -v2: Moved JOBCTL_LISTENING check in wait_task_stopped() into
           task_stopped_code() as suggested by Oleg.
      Signed-off-by: NTejun Heo <tj@kernel.org>
      Cc: Oleg Nesterov <oleg@redhat.com>
      544b2c91
    • T
      ptrace: implement PTRACE_INTERRUPT · fca26f26
      Tejun Heo 提交于
      Currently, there's no way to trap a running ptracee short of sending a
      signal which has various side effects.  This patch implements
      PTRACE_INTERRUPT which traps ptracee without any signal or job control
      related side effect.
      
      The implementation is almost trivial.  It uses the group stop trap -
      SIGTRAP | PTRACE_EVENT_STOP << 8.  A new trap flag
      JOBCTL_TRAP_INTERRUPT is added, which is set on PTRACE_INTERRUPT and
      cleared when any trap happens.  As INTERRUPT should be useable
      regardless of the current state of tracee, task_is_traced() test in
      ptrace_check_attach() is skipped for INTERRUPT.
      
      PTRACE_INTERRUPT is available iff tracee is attached with
      PTRACE_SEIZE.
      
      Test program follows.
      
        #define PTRACE_SEIZE		0x4206
        #define PTRACE_INTERRUPT	0x4207
      
        #define PTRACE_SEIZE_DEVEL	0x80000000
      
        static const struct timespec ts100ms = { .tv_nsec = 100000000 };
        static const struct timespec ts1s = { .tv_sec = 1 };
        static const struct timespec ts3s = { .tv_sec = 3 };
      
        int main(int argc, char **argv)
        {
      	  pid_t tracee;
      
      	  tracee = fork();
      	  if (tracee == 0) {
      		  nanosleep(&ts100ms, NULL);
      		  while (1) {
      			  printf("tracee: alive pid=%d\n", getpid());
      			  nanosleep(&ts1s, NULL);
      		  }
      	  }
      
      	  if (argc > 1)
      		  kill(tracee, SIGSTOP);
      
      	  nanosleep(&ts100ms, NULL);
      
      	  ptrace(PTRACE_SEIZE, tracee, NULL,
      		 (void *)(unsigned long)PTRACE_SEIZE_DEVEL);
      	  if (argc > 1) {
      		  waitid(P_PID, tracee, NULL, WSTOPPED);
      		  ptrace(PTRACE_CONT, tracee, NULL, NULL);
      	  }
      	  nanosleep(&ts3s, NULL);
      
      	  printf("tracer: INTERRUPT and DETACH\n");
      	  ptrace(PTRACE_INTERRUPT, tracee, NULL, NULL);
      	  waitid(P_PID, tracee, NULL, WSTOPPED);
      	  ptrace(PTRACE_DETACH, tracee, NULL, NULL);
      	  nanosleep(&ts3s, NULL);
      
      	  printf("tracer: exiting\n");
      	  kill(tracee, SIGKILL);
      	  return 0;
        }
      
      When called without argument, tracee is seized from running state,
      interrupted and then detached back to running state.
      
        # ./test-interrupt
        tracee: alive pid=4546
        tracee: alive pid=4546
        tracee: alive pid=4546
        tracer: INTERRUPT and DETACH
        tracee: alive pid=4546
        tracee: alive pid=4546
        tracee: alive pid=4546
        tracer: exiting
      
      When called with argument, tracee is seized from stopped state,
      continued, interrupted and then detached back to stopped state.
      
        # ./test-interrupt  1
        tracee: alive pid=4548
        tracee: alive pid=4548
        tracee: alive pid=4548
        tracer: INTERRUPT and DETACH
        tracer: exiting
      
      Before PTRACE_INTERRUPT, once the tracee was running, there was no way
      to trap tracee and do PTRACE_DETACH without causing side effect.
      
      -v2: Updated to use task_set_jobctl_pending() so that it doesn't end
           up scheduling TRAP_STOP if child is dying which may make the
           child unkillable.  Spotted by Oleg.
      Signed-off-by: NTejun Heo <tj@kernel.org>
      Cc: Oleg Nesterov <oleg@redhat.com>
      fca26f26
    • T
      ptrace: implement PTRACE_SEIZE · 3544d72a
      Tejun Heo 提交于
      PTRACE_ATTACH implicitly issues SIGSTOP on attach which has side
      effects on tracee signal and job control states.  This patch
      implements a new ptrace request PTRACE_SEIZE which attaches a tracee
      without trapping it or affecting its signal and job control states.
      
      The usage is the same with PTRACE_ATTACH but it takes PTRACE_SEIZE_*
      flags in @data.  Currently, the only defined flag is
      PTRACE_SEIZE_DEVEL which is a temporary flag to enable PTRACE_SEIZE.
      PTRACE_SEIZE will change ptrace behaviors outside of attach itself.
      The changes will be implemented gradually and the DEVEL flag is to
      prevent programs which expect full SEIZE behavior from using it before
      all the behavior modifications are complete while allowing unit
      testing.  The flag will be removed once SEIZE behaviors are completely
      implemented.
      
      * PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap.  After
        attaching tracee continues to run unless a trap condition occurs.
      
      * PTRACE_SEIZE doesn't affect signal or group stop state.
      
      * If PTRACE_SEIZE'd, group stop uses PTRACE_EVENT_STOP trap which uses
        exit_code of (signr | PTRACE_EVENT_STOP << 8) where signr is one of
        the stopping signals if group stop is in effect or SIGTRAP
        otherwise, and returns usual trap siginfo on PTRACE_GETSIGINFO
        instead of NULL.
      
      Seizing sets PT_SEIZED in ->ptrace of the tracee.  This flag will be
      used to determine whether new SEIZE behaviors should be enabled.
      
      Test program follows.
      
        #define PTRACE_SEIZE		0x4206
        #define PTRACE_SEIZE_DEVEL	0x80000000
      
        static const struct timespec ts100ms = { .tv_nsec = 100000000 };
        static const struct timespec ts1s = { .tv_sec = 1 };
        static const struct timespec ts3s = { .tv_sec = 3 };
      
        int main(int argc, char **argv)
        {
      	  pid_t tracee;
      
      	  tracee = fork();
      	  if (tracee == 0) {
      		  nanosleep(&ts100ms, NULL);
      		  while (1) {
      			  printf("tracee: alive\n");
      			  nanosleep(&ts1s, NULL);
      		  }
      	  }
      
      	  if (argc > 1)
      		  kill(tracee, SIGSTOP);
      
      	  nanosleep(&ts100ms, NULL);
      
      	  ptrace(PTRACE_SEIZE, tracee, NULL,
      		 (void *)(unsigned long)PTRACE_SEIZE_DEVEL);
      	  if (argc > 1) {
      		  waitid(P_PID, tracee, NULL, WSTOPPED);
      		  ptrace(PTRACE_CONT, tracee, NULL, NULL);
      	  }
      	  nanosleep(&ts3s, NULL);
      	  printf("tracer: exiting\n");
      	  return 0;
        }
      
      When the above program is called w/o argument, tracee is seized while
      running and remains running.  When tracer exits, tracee continues to
      run and print out messages.
      
        # ./test-seize-simple
        tracee: alive
        tracee: alive
        tracee: alive
        tracer: exiting
        tracee: alive
        tracee: alive
      
      When called with an argument, tracee is seized from stopped state and
      continued, and returns to stopped state when tracer exits.
      
        # ./test-seize
        tracee: alive
        tracee: alive
        tracee: alive
        tracer: exiting
        # ps -el|grep test-seize
        1 T     0  4720     1  0  80   0 -   941 signal ttyS0    00:00:00 test-seize
      
      -v2: SEIZE doesn't schedule TRAP_STOP and leaves tracee running as Jan
           suggested.
      
      -v3: PTRACE_EVENT_STOP traps now report group stop state by signr.  If
           group stop is in effect the stop signal number is returned as
           part of exit_code; otherwise, SIGTRAP.  This was suggested by
           Denys and Oleg.
      Signed-off-by: NTejun Heo <tj@kernel.org>
      Cc: Jan Kratochvil <jan.kratochvil@redhat.com>
      Cc: Denys Vlasenko <vda.linux@googlemail.com>
      Cc: Oleg Nesterov <oleg@redhat.com>
      3544d72a
  8. 05 6月, 2011 1 次提交
  9. 25 4月, 2011 1 次提交
    • F
      ptrace: Prepare to fix racy accesses on task breakpoints · bf26c018
      Frederic Weisbecker 提交于
      When a task is traced and is in a stopped state, the tracer
      may execute a ptrace request to examine the tracee state and
      get its task struct. Right after, the tracee can be killed
      and thus its breakpoints released.
      This can happen concurrently when the tracer is in the middle
      of reading or modifying these breakpoints, leading to dereferencing
      a freed pointer.
      
      Hence, to prepare the fix, create a generic breakpoint reference
      holding API. When a reference on the breakpoints of a task is
      held, the breakpoints won't be released until the last reference
      is dropped. After that, no more ptrace request on the task's
      breakpoints can be serviced for the tracer.
      Reported-by: NOleg Nesterov <oleg@redhat.com>
      Signed-off-by: NFrederic Weisbecker <fweisbec@gmail.com>
      Cc: Ingo Molnar <mingo@elte.hu>
      Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
      Cc: Will Deacon <will.deacon@arm.com>
      Cc: Prasad <prasad@linux.vnet.ibm.com>
      Cc: Paul Mundt <lethal@linux-sh.org>
      Cc: v2.6.33.. <stable@kernel.org>
      Link: http://lkml.kernel.org/r/1302284067-7860-2-git-send-email-fweisbec@gmail.com
      bf26c018
  10. 05 3月, 2011 1 次提交
  11. 28 10月, 2010 2 次提交
  12. 26 3月, 2010 1 次提交
    • P
      x86, perf, bts, mm: Delete the never used BTS-ptrace code · faa4602e
      Peter Zijlstra 提交于
      Support for the PMU's BTS features has been upstreamed in
      v2.6.32, but we still have the old and disabled ptrace-BTS,
      as Linus noticed it not so long ago.
      
      It's buggy: TIF_DEBUGCTLMSR is trampling all over that MSR without
      regard for other uses (perf) and doesn't provide the flexibility
      needed for perf either.
      
      Its users are ptrace-block-step and ptrace-bts, since ptrace-bts
      was never used and ptrace-block-step can be implemented using a
      much simpler approach.
      
      So axe all 3000 lines of it. That includes the *locked_memory*()
      APIs in mm/mlock.c as well.
      Reported-by: NLinus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: NPeter Zijlstra <a.p.zijlstra@chello.nl>
      Cc: Roland McGrath <roland@redhat.com>
      Cc: Oleg Nesterov <oleg@redhat.com>
      Cc: Markus Metzger <markus.t.metzger@intel.com>
      Cc: Steven Rostedt <rostedt@goodmis.org>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      LKML-Reference: <20100325135413.938004390@chello.nl>
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      faa4602e
  13. 13 3月, 2010 1 次提交
    • C
      ptrace: move user_enable_single_step & co prototypes to linux/ptrace.h · dacbe41f
      Christoph Hellwig 提交于
      While in theory user_enable_single_step/user_disable_single_step/
      user_enable_blockstep could also be provided as an inline or macro there's
      no good reason to do so, and having the prototype in one places keeps code
      size and confusion down.
      
      Roland said:
      
        The original thought there was that user_enable_single_step() et al
        might well be only an instruction or three on a sane machine (as if we
        have any of those!), and since there is only one call site inlining
        would be beneficial.  But I agree that there is no strong reason to care
        about inlining it.
      
        As to the arch changes, there is only one thought I'd add to the
        record.  It was always my thinking that for an arch where
        PTRACE_SINGLESTEP does text-modifying breakpoint insertion,
        user_enable_single_step() should not be provided.  That is,
        arch_has_single_step()=>true means that there is an arch facility with
        "pure" semantics that does not have any unexpected side effects.
        Inserting a breakpoint might do very unexpected strange things in
        multi-threaded situations.  Aside from that, it is a peculiar side
        effect that user_{enable,disable}_single_step() should cause COW
        de-sharing of text pages and so forth.  For PTRACE_SINGLESTEP, all these
        peculiarities are the status quo ante for that arch, so having
        arch_ptrace() itself do those is one thing.  But for building other
        things in the future, it is nicer to have a uniform "pure" semantics
        that arch-independent code can expect.
      
        OTOH, all such arch issues are really up to the arch maintainer.  As
        of today, there is nothing but ptrace using user_enable_single_step() et
        al so it's a distinction without a practical difference.  If/when there
        are other facilities that use user_enable_single_step() and might care,
        the affected arch's can revisit the question when someone cares about
        the quality of the arch support for said new facility.
      Signed-off-by: NChristoph Hellwig <hch@lst.de>
      Cc: Oleg Nesterov <oleg@redhat.com>
      Cc: Roland McGrath <roland@redhat.com>
      Acked-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      dacbe41f
  14. 24 2月, 2010 1 次提交
  15. 12 2月, 2010 1 次提交
    • S
      ptrace: Add support for generic PTRACE_GETREGSET/PTRACE_SETREGSET · 2225a122
      Suresh Siddha 提交于
      Generic support for PTRACE_GETREGSET/PTRACE_SETREGSET commands which
      export the regsets supported by each architecture using the correponding
      NT_* types. These NT_* types are already part of the userland ABI, used
      in representing the architecture specific register sets as different NOTES
      in an ELF core file.
      
      'addr' parameter for the ptrace system call encode the REGSET type (using
      the corresppnding NT_* type) and the 'data' parameter points to the
      struct iovec having the user buffer and the length of that buffer.
      
      	struct iovec iov = { buf, len};
      	ret = ptrace(PTRACE_GETREGSET/PTRACE_SETREGSET, pid, NT_XXX_TYPE, &iov);
      
      On successful completion, iov.len will be updated by the kernel specifying
      how much the kernel has written/read to/from the user's iov.buf.
      
      x86 extended state registers are primarily exported using this interface.
      Signed-off-by: NSuresh Siddha <suresh.b.siddha@intel.com>
      LKML-Reference: <20100211195614.886724710@sbs-t61.sc.intel.com>
      Acked-by: NHongjiu Lu <hjl.tools@gmail.com>
      Cc: Roland McGrath <roland@redhat.com>
      Signed-off-by: NH. Peter Anvin <hpa@zytor.com>
      2225a122
  16. 16 12月, 2009 2 次提交
  17. 19 6月, 2009 1 次提交
  18. 07 4月, 2009 1 次提交
  19. 03 4月, 2009 2 次提交
  20. 20 12月, 2008 1 次提交
    • M
      x86, bts: add fork and exit handling · bf53de90
      Markus Metzger 提交于
      Impact: introduce new ptrace facility
      
      Add arch_ptrace_untrace() function that is called when the tracer
      detaches (either voluntarily or when the tracing task dies);
      ptrace_disable() is only called on a voluntary detach.
      
      Add ptrace_fork() and arch_ptrace_fork(). They are called when a
      traced task is forked.
      
      Clear DS and BTS related fields on fork.
      
      Release DS resources and reclaim memory in ptrace_untrace(). This
      releases resources already when the tracing task dies. We used to do
      that when the traced task dies.
      Signed-off-by: NMarkus Metzger <markus.t.metzger@intel.com>
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      bf53de90
  21. 20 10月, 2008 1 次提交
  22. 08 8月, 2008 1 次提交
    • R
      tracehook: fix CLONE_PTRACE · 5861bbfc
      Roland McGrath 提交于
      In the change in commit 09a05394, I
      overlooked two nits in the logic and this broke using CLONE_PTRACE
      when PTRACE_O_TRACE* are not being used.
      
      A parent that is itself traced at all but not using PTRACE_O_TRACE*,
      using CLONE_PTRACE would have its new child fail to be traced.
      
      A parent that is not itself traced at all that uses CLONE_PTRACE
      (which should be a no-op in this case) would confuse the bookkeeping
      and lead to a crash at exit time.
      
      This restores the missing checks and fixes both failure modes.
      Reported-by: NEduardo Habkost <ehabkost@redhat.com>
      Signed-off-by: NRoland McGrath <roland@redhat.com>
      5861bbfc
  23. 27 7月, 2008 4 次提交
    • R
      task_current_syscall · bbc69863
      Roland McGrath 提交于
      This adds the new function task_current_syscall() on machines where the
      asm/syscall.h interface is supported (CONFIG_HAVE_ARCH_TRACEHOOK).  It's
      exported for modules to use in the future.  This function safely samples
      the state of a blocked thread to collect what system call it is blocked
      in, and the six system call argument registers.
      Signed-off-by: NRoland McGrath <roland@redhat.com>
      Cc: Oleg Nesterov <oleg@tv-sign.ru>
      Reviewed-by: NIngo Molnar <mingo@elte.hu>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      bbc69863
    • R
      tracehook: release_task · dae33574
      Roland McGrath 提交于
      This moves the ptrace-related logic from release_task into tracehook.h and
      ptrace.h inlines.  It provides clean hooks both before and after locking
      tasklist_lock, for future tracing logic to do more cleanup without the
      lock.
      
      This also changes release_task() itself in the rare "zap_leader" case to
      set the leader to EXIT_DEAD before iterating.  This maintains the
      invariant that release_task() only ever handles a task in EXIT_DEAD.  This
      is a common-sense invariant that is already always true except in this one
      arcane case of zombie leader whose parent ignores SIGCHLD.
      
      This change is harmless and only costs one store in this one rare case.
      It keeps the expected state more consisently sane, which is nicer when
      debugging weirdness in release_task().  It also lets some future code in
      the tracehook entry points rely on this invariant for bookkeeping.
      Signed-off-by: NRoland McGrath <roland@redhat.com>
      Cc: Oleg Nesterov <oleg@tv-sign.ru>
      Reviewed-by: NIngo Molnar <mingo@elte.hu>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      dae33574
    • R
      tracehook: clone · 09a05394
      Roland McGrath 提交于
      This moves all the ptrace initialization and tracing logic for task
      creation into tracehook.h and ptrace.h inlines.  It reorganizes the code
      slightly, but should not change any behavior.
      
      There are four tracehook entry points, at each important stage of task
      creation.  This keeps the interface from the core fork.c code fairly
      clean, while supporting the complex setup required for ptrace or something
      like it.
      Signed-off-by: NRoland McGrath <roland@redhat.com>
      Cc: Oleg Nesterov <oleg@tv-sign.ru>
      Reviewed-by: NIngo Molnar <mingo@elte.hu>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      09a05394
    • R
      tracehook: add linux/tracehook.h · 88ac2921
      Roland McGrath 提交于
      This patch series introduces the "tracehook" interface layer of inlines in
      <linux/tracehook.h>.  There are more details in the log entry for patch
      01/23 and in the header file comments inside that patch.  Most of these
      changes move code around with little or no change, and they should not
      break anything or change any behavior.
      
      This sets a new standard for uniform arch support to enable clean
      arch-independent implementations of new debugging and tracing stuff,
      denoted by CONFIG_HAVE_ARCH_TRACEHOOK.  Patch 20/23 adds that symbol to
      arch/Kconfig, with comments listing everything an arch has to do before
      setting "select HAVE_ARCH_TRACEHOOK".  These are elaborted a bit at:
      
      	http://sourceware.org/systemtap/wiki/utrace/arch/HowTo
      
      The new inlines that arch code must define or call have detailed kerneldoc
      comments in the generic header files that say what is required.
      
      No arch is obligated to do any work, and no arch's build should be broken
      by these changes.  There are several steps that each arch should take so
      it can set HAVE_ARCH_TRACEHOOK.  Most of these are simple.  Providing this
      support will let new things people add for doing debugging and tracing of
      user-level threads "just work" for your arch in the future.  For an arch
      that does not provide HAVE_ARCH_TRACEHOOK, some new options for such
      features will not be available for config.
      
      I have done some arch work and will submit this to the arch maintainers
      after the generic tracehook series settles in.  For now, that work is
      available in my GIT repositories, and in patch and mbox-of-patches form at
      http://people.redhat.com/roland/utrace/2.6-current/
      
      This paves the way for my "utrace" work, to be submitted later.  But it is
      not innately tied to that.  I hope that the tracehook series can go in
      soon regardless of what eventually does or doesn't go on top of it.  For
      anyone implementing any kind of new tracing/debugging plan, or just
      understanding all the context of the existing ptrace implementation,
      having tracehook.h makes things much easier to find and understand.
      
      This patch:
      
      This adds the new kernel-internal header file <linux/tracehook.h>.  This
      is not yet used at all.  The comments in the header introduce what the
      following series of patches is about.
      
      The aim is to formalize and consolidate all the places that the core
      kernel code and the arch code now ties into the ptrace implementation.
      
      These patches mostly don't cause any functional change.  They just move
      the details of ptrace logic out of core code into tracehook.h inlines,
      where they are mostly compiled away to the same as before.  All that
      changes is that everything is thoroughly documented and any future
      reworking of ptrace, or addition of something new, would not have to touch
      core code all over, just change the tracehook.h inlines.
      
      The new linux/ptrace.h inlines are used by the following patches in the
      new tracehook_*() inlines.  Using these helpers for the ptrace event stops
      makes it simple to change or disable the old ptrace implementation of
      these stops conditionally later.
      Signed-off-by: NRoland McGrath <roland@redhat.com>
      Cc: Oleg Nesterov <oleg@tv-sign.ru>
      Reviewed-by: NIngo Molnar <mingo@elte.hu>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      88ac2921
  24. 14 7月, 2008 1 次提交
    • S
      Security: split proc ptrace checking into read vs. attach · 006ebb40
      Stephen Smalley 提交于
      Enable security modules to distinguish reading of process state via
      proc from full ptrace access by renaming ptrace_may_attach to
      ptrace_may_access and adding a mode argument indicating whether only
      read access or full attach access is requested.  This allows security
      modules to permit access to reading process state without granting
      full ptrace access.  The base DAC/capability checking remains unchanged.
      
      Read access to /proc/pid/mem continues to apply a full ptrace attach
      check since check_mem_permission() already requires the current task
      to already be ptracing the target.  The other ptrace checks within
      proc for elements like environ, maps, and fds are changed to pass the
      read mode instead of attach.
      
      In the SELinux case, we model such reading of process state as a
      reading of a proc file labeled with the target process' label.  This
      enables SELinux policy to permit such reading of process state without
      permitting control or manipulation of the target process, as there are
      a number of cases where programs probe for such information via proc
      but do not need to be able to control the target (e.g. procps,
      lsof, PolicyKit, ConsoleKit).  At present we have to choose between
      allowing full ptrace in policy (more permissive than required/desired)
      or breaking functionality (or in some cases just silencing the denials
      via dontaudit rules but this can hide genuine attacks).
      
      This version of the patch incorporates comments from Casey Schaufler
      (change/replace existing ptrace_may_attach interface, pass access
      mode), and Chris Wright (provide greater consistency in the checking).
      
      Note that like their predecessors __ptrace_may_attach and
      ptrace_may_attach, the __ptrace_may_access and ptrace_may_access
      interfaces use different return value conventions from each other (0
      or -errno vs. 1 or 0).  I retained this difference to avoid any
      changes to the caller logic but made the difference clearer by
      changing the latter interface to return a bool rather than an int and
      by adding a comment about it to ptrace.h for any future callers.
      Signed-off-by: NStephen Smalley <sds@tycho.nsa.gov>
      Acked-by: NChris Wright <chrisw@sous-sol.org>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      006ebb40
  25. 30 4月, 2008 1 次提交
  26. 09 2月, 2008 1 次提交
  27. 07 2月, 2008 1 次提交
    • R
      Add arch_ptrace_stop · 1a669c2f
      Roland McGrath 提交于
      This adds support to allow asm/ptrace.h to define two new macros,
      arch_ptrace_stop_needed and arch_ptrace_stop.  These control special
      machine-specific actions to be done before a ptrace stop.  The new code
      compiles away to nothing when the new macros are not defined.  This is the
      case on all machines to begin with.
      
      On ia64, these macros will be defined to solve the long-standing issue of
      ptrace vs register backing store.
      Signed-off-by: NRoland McGrath <roland@redhat.com>
      Cc: Petr Tesarik <ptesarik@suse.cz>
      Cc: Tony Luck <tony.luck@intel.com>
      Cc: Matthew Wilcox <willy@debian.org>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      1a669c2f