* [PATCH 0/5] ptrace tweaks
@ 2012-02-10 14:43 Denys Vlasenko
2012-02-10 14:43 ` [PATCH 1/5] ptrace: don't modify flags on PTRACE_SETOPTIONS failure Denys Vlasenko
2012-02-10 17:32 ` [PATCH 0/2] more tweaks (Was: ptrace tweaks) Oleg Nesterov
0 siblings, 2 replies; 22+ messages in thread
From: Denys Vlasenko @ 2012-02-10 14:43 UTC (permalink / raw)
To: Andrew Morton, Oleg Nesterov, Tejun Heo, Pedro Alves,
Jan Kratochvil, linux-kernel
Cc: Denys Vlasenko
This patch set fixes a minor bug in PTRACE_SETOPTIONS,
slightly extends PTRACE_SEIZE (now it can take ptrace options),
changes PTRACE_EVENT_STOP value,
and enables PTRACE_SEIZE for non-development use.
Ptrace git tree on kernel.org is not restored yet,
so this patch set can't go through it.
Andrew, please consider taking this patch set.
Denys Vlasenko (5):
ptrace: don't modify flags on PTRACE_SETOPTIONS failure
ptrace: simplify PTRACE_foo constants and PTRACE_SETOPTIONS code
ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter
ptrace: renumber PTRACE_EVENT_STOP so that future new options and
events can match
ptrace: remove PTRACE_SEIZE_DEVEL bit
include/linux/ptrace.h | 39 ++++++++++++----------------
kernel/ptrace.c | 64 ++++++++++++++++++------------------------------
2 files changed, 41 insertions(+), 62 deletions(-)
--
1.7.7.6
^ permalink raw reply [flat|nested] 22+ messages in thread* [PATCH 1/5] ptrace: don't modify flags on PTRACE_SETOPTIONS failure 2012-02-10 14:43 [PATCH 0/5] ptrace tweaks Denys Vlasenko @ 2012-02-10 14:43 ` Denys Vlasenko 2012-02-10 14:43 ` [PATCH 2/5] ptrace: simplify PTRACE_foo constants and PTRACE_SETOPTIONS code Denys Vlasenko 2012-02-10 17:17 ` [PATCH 1/5] ptrace: don't modify flags on PTRACE_SETOPTIONS failure Oleg Nesterov 2012-02-10 17:32 ` [PATCH 0/2] more tweaks (Was: ptrace tweaks) Oleg Nesterov 1 sibling, 2 replies; 22+ messages in thread From: Denys Vlasenko @ 2012-02-10 14:43 UTC (permalink / raw) To: Andrew Morton, Oleg Nesterov, Tejun Heo, Pedro Alves, Jan Kratochvil, linux-kernel Cc: Denys Vlasenko On ptrace(PTRACE_SETOPTIONS, pid, 0, <opts>), we used to set those option bits which are known, and then fail with -EINVAL if there are some unknown bits in <opts>. This in inconsistent with typical error handling, which does not change any state if input is invalid. This patch changes PTRACE_SETOPTIONS behavior so that in this case, we return -EINVAL and don't change any bits in task->ptrace. It's very unlikely that there is userspace code in the wild which will be affected by this change: it should have the form ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_BOGUSOPT) where PTRACE_O_BOGUSOPT is a constant unknown to the kernel. But kernel headers, naturally, don't contain any PTRACE_O_BOGUSOPTs, thus the only way userspace can use one if it defines one itself. I can't see why anyone would do such a thing deliberately. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> Acked-by: Tejun Heo <tj@kernel.org> --- kernel/ptrace.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 00ab2ca..273f56e 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -528,6 +528,9 @@ int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long ds static int ptrace_setoptions(struct task_struct *child, unsigned long data) { + if (data & ~(unsigned long)PTRACE_O_MASK) + return -EINVAL; + child->ptrace &= ~PT_TRACE_MASK; if (data & PTRACE_O_TRACESYSGOOD) @@ -551,7 +554,7 @@ static int ptrace_setoptions(struct task_struct *child, unsigned long data) if (data & PTRACE_O_TRACEEXIT) child->ptrace |= PT_TRACE_EXIT; - return (data & ~PTRACE_O_MASK) ? -EINVAL : 0; + return 0; } static int ptrace_getsiginfo(struct task_struct *child, siginfo_t *info) -- 1.7.7.6 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 2/5] ptrace: simplify PTRACE_foo constants and PTRACE_SETOPTIONS code 2012-02-10 14:43 ` [PATCH 1/5] ptrace: don't modify flags on PTRACE_SETOPTIONS failure Denys Vlasenko @ 2012-02-10 14:43 ` Denys Vlasenko 2012-02-10 14:43 ` [PATCH 3/5] ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter Denys Vlasenko 2012-02-10 17:17 ` [PATCH 2/5] ptrace: simplify PTRACE_foo constants and PTRACE_SETOPTIONS code Oleg Nesterov 2012-02-10 17:17 ` [PATCH 1/5] ptrace: don't modify flags on PTRACE_SETOPTIONS failure Oleg Nesterov 1 sibling, 2 replies; 22+ messages in thread From: Denys Vlasenko @ 2012-02-10 14:43 UTC (permalink / raw) To: Andrew Morton, Oleg Nesterov, Tejun Heo, Pedro Alves, Jan Kratochvil, linux-kernel Cc: Denys Vlasenko Exchange PT_TRACESYSGOOD and PT_PTRACE_CAP bit positions, which makes PT_option bits contiguous and therefore makes code in ptrace_setoptions() much simpler. Every PTRACE_O_TRACEevent is defined to (1 << PTRACE_EVENT_event) instead of using explicit numeric constants, to ensure we don't mess up relationship between bit positions and event ids. PT_EVENT_FLAG_SHIFT was not particularly useful, PT_OPT_FLAG_SHIFT with value of PT_EVENT_FLAG_SHIFT-1 is easier to use. PT_TRACE_MASK constant is nuked, the only its use is replaced by (PTRACE_O_MASK << PT_OPT_FLAG_SHIFT). Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> Acked-by: Tejun Heo <tj@kernel.org> --- include/linux/ptrace.h | 33 +++++++++++++++------------------ kernel/ptrace.c | 31 ++++++++----------------------- 2 files changed, 23 insertions(+), 41 deletions(-) diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index c2f1f6a..06be6a3 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -54,17 +54,6 @@ /* flags in @data for PTRACE_SEIZE */ #define PTRACE_SEIZE_DEVEL 0x80000000 /* temp flag for development */ -/* options set using PTRACE_SETOPTIONS */ -#define PTRACE_O_TRACESYSGOOD 0x00000001 -#define PTRACE_O_TRACEFORK 0x00000002 -#define PTRACE_O_TRACEVFORK 0x00000004 -#define PTRACE_O_TRACECLONE 0x00000008 -#define PTRACE_O_TRACEEXEC 0x00000010 -#define PTRACE_O_TRACEVFORKDONE 0x00000020 -#define PTRACE_O_TRACEEXIT 0x00000040 - -#define PTRACE_O_MASK 0x0000007f - /* Wait extended result codes for the above trace options. */ #define PTRACE_EVENT_FORK 1 #define PTRACE_EVENT_VFORK 2 @@ -74,6 +63,17 @@ #define PTRACE_EVENT_EXIT 6 #define PTRACE_EVENT_STOP 7 +/* options set using PTRACE_SETOPTIONS */ +#define PTRACE_O_TRACESYSGOOD 1 +#define PTRACE_O_TRACEFORK (1 << PTRACE_EVENT_FORK) +#define PTRACE_O_TRACEVFORK (1 << PTRACE_EVENT_VFORK) +#define PTRACE_O_TRACECLONE (1 << PTRACE_EVENT_CLONE) +#define PTRACE_O_TRACEEXEC (1 << PTRACE_EVENT_EXEC) +#define PTRACE_O_TRACEVFORKDONE (1 << PTRACE_EVENT_VFORK_DONE) +#define PTRACE_O_TRACEEXIT (1 << PTRACE_EVENT_EXIT) + +#define PTRACE_O_MASK 0x0000007f + #include <asm/ptrace.h> #ifdef __KERNEL__ @@ -88,13 +88,12 @@ #define PT_SEIZED 0x00010000 /* SEIZE used, enable new behavior */ #define PT_PTRACED 0x00000001 #define PT_DTRACE 0x00000002 /* delayed trace (used on m68k, i386) */ -#define PT_TRACESYSGOOD 0x00000004 -#define PT_PTRACE_CAP 0x00000008 /* ptracer can follow suid-exec */ +#define PT_PTRACE_CAP 0x00000004 /* ptracer can follow suid-exec */ +#define PT_OPT_FLAG_SHIFT 3 /* PT_TRACE_* event enable flags */ -#define PT_EVENT_FLAG_SHIFT 4 -#define PT_EVENT_FLAG(event) (1 << (PT_EVENT_FLAG_SHIFT + (event) - 1)) - +#define PT_EVENT_FLAG(event) (1 << (PT_OPT_FLAG_SHIFT + (event))) +#define PT_TRACESYSGOOD PT_EVENT_FLAG(0) #define PT_TRACE_FORK PT_EVENT_FLAG(PTRACE_EVENT_FORK) #define PT_TRACE_VFORK PT_EVENT_FLAG(PTRACE_EVENT_VFORK) #define PT_TRACE_CLONE PT_EVENT_FLAG(PTRACE_EVENT_CLONE) @@ -102,8 +101,6 @@ #define PT_TRACE_VFORK_DONE PT_EVENT_FLAG(PTRACE_EVENT_VFORK_DONE) #define PT_TRACE_EXIT PT_EVENT_FLAG(PTRACE_EVENT_EXIT) -#define PT_TRACE_MASK 0x000003f4 - /* single stepping state bits (used on ARM and PA-RISC) */ #define PT_SINGLESTEP_BIT 31 #define PT_SINGLESTEP (1<<PT_SINGLESTEP_BIT) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 273f56e..9acd07a 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -262,7 +262,7 @@ static int ptrace_attach(struct task_struct *task, long request, /* * Protect exec's credential calculations against our interference; - * interference; SUID, SGID and LSM creds get determined differently + * SUID, SGID and LSM creds get determined differently * under ptrace. */ retval = -ERESTARTNOINTR; @@ -528,31 +528,16 @@ int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long ds static int ptrace_setoptions(struct task_struct *child, unsigned long data) { + unsigned flags; + if (data & ~(unsigned long)PTRACE_O_MASK) return -EINVAL; - child->ptrace &= ~PT_TRACE_MASK; - - if (data & PTRACE_O_TRACESYSGOOD) - child->ptrace |= PT_TRACESYSGOOD; - - if (data & PTRACE_O_TRACEFORK) - child->ptrace |= PT_TRACE_FORK; - - if (data & PTRACE_O_TRACEVFORK) - child->ptrace |= PT_TRACE_VFORK; - - if (data & PTRACE_O_TRACECLONE) - child->ptrace |= PT_TRACE_CLONE; - - if (data & PTRACE_O_TRACEEXEC) - child->ptrace |= PT_TRACE_EXEC; - - if (data & PTRACE_O_TRACEVFORKDONE) - child->ptrace |= PT_TRACE_VFORK_DONE; - - if (data & PTRACE_O_TRACEEXIT) - child->ptrace |= PT_TRACE_EXIT; + /* Avoid intermediate state when all opts are cleared */ + flags = child->ptrace; + flags &= ~(PTRACE_O_MASK << PT_OPT_FLAG_SHIFT); + flags |= (data << PT_OPT_FLAG_SHIFT); + child->ptrace = flags; return 0; } -- 1.7.7.6 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 3/5] ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter 2012-02-10 14:43 ` [PATCH 2/5] ptrace: simplify PTRACE_foo constants and PTRACE_SETOPTIONS code Denys Vlasenko @ 2012-02-10 14:43 ` Denys Vlasenko 2012-02-10 14:43 ` [PATCH 4/5] ptrace: renumber PTRACE_EVENT_STOP so that future new options and events can match Denys Vlasenko 2012-02-10 15:57 ` [PATCH 3/5] ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter Oleg Nesterov 2012-02-10 17:17 ` [PATCH 2/5] ptrace: simplify PTRACE_foo constants and PTRACE_SETOPTIONS code Oleg Nesterov 1 sibling, 2 replies; 22+ messages in thread From: Denys Vlasenko @ 2012-02-10 14:43 UTC (permalink / raw) To: Andrew Morton, Oleg Nesterov, Tejun Heo, Pedro Alves, Jan Kratochvil, linux-kernel Cc: Denys Vlasenko This can be used to close a few corner cases in strace where we get unwanted racy behavior after attach, but before we have a chance to set options (the notorious post-execve SIGTRAP comes to mind), and removes the need to track "did we set opts for this task" state in strace internals. While we are at it: Make it possible to extend SEIZE in the future with more functionality by passing non-zero 'addr' parameter. To that end, error out if 'addr' is non-zero. PTRACE_ATTACH did not (and still does not) have such check, and users (strace) do pass garbage there... let's avoid repeating this mistake with SEIZE. Set all task->ptrace bits in one operation - before this change, we were adding PT_SEIZED and PT_PTRACE_CAP with task->ptrace |= BIT ops. This was probably ok (not a bug), but let's be on a safer side. Changes since v2: use (unsigned long) casts instead of (long) ones, move PTRACE_SEIZE_DEVEL-related code to separate lines of code. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> Acked-by: Tejun Heo <tj@kernel.org> --- kernel/ptrace.c | 29 ++++++++++++++++++++--------- 1 files changed, 20 insertions(+), 9 deletions(-) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 9acd07a..99a18a0 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -231,6 +231,7 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode) } static int ptrace_attach(struct task_struct *task, long request, + unsigned long addr, unsigned long flags) { bool seize = (request == PTRACE_SEIZE); @@ -238,19 +239,29 @@ static int ptrace_attach(struct task_struct *task, long request, /* * SEIZE will enable new ptrace behaviors which will be implemented - * gradually. SEIZE_DEVEL is used to prevent applications + * gradually. SEIZE_DEVEL bit is used to prevent applications * expecting full SEIZE behaviors trapping on kernel commits which * are still in the process of implementing them. * * Only test programs for new ptrace behaviors being implemented * should set SEIZE_DEVEL. If unset, SEIZE will fail with -EIO. * - * Once SEIZE behaviors are completely implemented, this flag and - * the following test will be removed. + * Once SEIZE behaviors are completely implemented, this flag + * will be removed. */ retval = -EIO; - if (seize && !(flags & PTRACE_SEIZE_DEVEL)) - goto out; + if (seize) { + if (addr != 0) + goto out; + if (!(flags & PTRACE_SEIZE_DEVEL)) + goto out; + flags &= ~(unsigned long)PTRACE_SEIZE_DEVEL; + if (flags & ~(unsigned long)PTRACE_O_MASK) + goto out; + flags = PT_PTRACED | PT_SEIZED | (flags << PT_OPT_FLAG_SHIFT); + } else { + flags = PT_PTRACED; + } audit_ptrace(task); @@ -282,11 +293,11 @@ static int ptrace_attach(struct task_struct *task, long request, if (task->ptrace) goto unlock_tasklist; - task->ptrace = PT_PTRACED; if (seize) - task->ptrace |= PT_SEIZED; + flags |= PT_SEIZED; if (ns_capable(task_user_ns(task), CAP_SYS_PTRACE)) - task->ptrace |= PT_PTRACE_CAP; + flags |= PT_PTRACE_CAP; + task->ptrace = flags; __ptrace_link(task, current); @@ -879,7 +890,7 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, } if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) { - ret = ptrace_attach(child, request, data); + ret = ptrace_attach(child, request, addr, data); /* * Some architectures need to do book-keeping after * a ptrace attach. -- 1.7.7.6 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 4/5] ptrace: renumber PTRACE_EVENT_STOP so that future new options and events can match 2012-02-10 14:43 ` [PATCH 3/5] ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter Denys Vlasenko @ 2012-02-10 14:43 ` Denys Vlasenko 2012-02-10 14:43 ` [PATCH 5/5] ptrace: remove PTRACE_SEIZE_DEVEL bit Denys Vlasenko 2012-02-10 17:19 ` [PATCH 4/5] ptrace: renumber PTRACE_EVENT_STOP so that future new options and events can match Oleg Nesterov 2012-02-10 15:57 ` [PATCH 3/5] ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter Oleg Nesterov 1 sibling, 2 replies; 22+ messages in thread From: Denys Vlasenko @ 2012-02-10 14:43 UTC (permalink / raw) To: Andrew Morton, Oleg Nesterov, Tejun Heo, Pedro Alves, Jan Kratochvil, linux-kernel Cc: Denys Vlasenko PTRACE_EVENT_foo and PTRACE_O_TRACEfoo used to match. New PTRACE_EVENT_STOP is the first event which has no corresponding PTRACE_O_TRACE option. If we will ever want to add another such option, its PTRACE_EVENT's value will collide with PTRACE_EVENT_STOP's value. This patch changes PTRACE_EVENT_STOP value to prevent this. While at it, added a comment - the one atop PTRACE_EVENT block, saying "Wait extended result codes for the above trace options", is not true for PTRACE_EVENT_STOP. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- include/linux/ptrace.h | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index 06be6a3..ec6571c 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -61,7 +61,8 @@ #define PTRACE_EVENT_EXEC 4 #define PTRACE_EVENT_VFORK_DONE 5 #define PTRACE_EVENT_EXIT 6 -#define PTRACE_EVENT_STOP 7 +/* Extended result codes which enabled by means other than options. */ +#define PTRACE_EVENT_STOP 128 /* options set using PTRACE_SETOPTIONS */ #define PTRACE_O_TRACESYSGOOD 1 -- 1.7.7.6 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 5/5] ptrace: remove PTRACE_SEIZE_DEVEL bit 2012-02-10 14:43 ` [PATCH 4/5] ptrace: renumber PTRACE_EVENT_STOP so that future new options and events can match Denys Vlasenko @ 2012-02-10 14:43 ` Denys Vlasenko 2012-02-10 17:24 ` Oleg Nesterov 2012-02-10 17:19 ` [PATCH 4/5] ptrace: renumber PTRACE_EVENT_STOP so that future new options and events can match Oleg Nesterov 1 sibling, 1 reply; 22+ messages in thread From: Denys Vlasenko @ 2012-02-10 14:43 UTC (permalink / raw) To: Andrew Morton, Oleg Nesterov, Tejun Heo, Pedro Alves, Jan Kratochvil, linux-kernel Cc: Denys Vlasenko PTRACE_SEIZE code is tested and ready for production use, remove the code which requires special bit in data argument to make PTRACE_SEIZE work. Strace team prepares for a new release of strace, and we would like to ship the code which uses PTRACE_SEIZE, preferably after this change goes into released kernel. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- include/linux/ptrace.h | 5 +---- kernel/ptrace.c | 15 --------------- 2 files changed, 1 insertions(+), 19 deletions(-) diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index ec6571c..6dffe18 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -51,9 +51,6 @@ #define PTRACE_INTERRUPT 0x4207 #define PTRACE_LISTEN 0x4208 -/* flags in @data for PTRACE_SEIZE */ -#define PTRACE_SEIZE_DEVEL 0x80000000 /* temp flag for development */ - /* Wait extended result codes for the above trace options. */ #define PTRACE_EVENT_FORK 1 #define PTRACE_EVENT_VFORK 2 @@ -64,7 +61,7 @@ /* Extended result codes which enabled by means other than options. */ #define PTRACE_EVENT_STOP 128 -/* options set using PTRACE_SETOPTIONS */ +/* Options set using PTRACE_SETOPTIONS or using PTRACE_SEIZE @data param */ #define PTRACE_O_TRACESYSGOOD 1 #define PTRACE_O_TRACEFORK (1 << PTRACE_EVENT_FORK) #define PTRACE_O_TRACEVFORK (1 << PTRACE_EVENT_VFORK) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 99a18a0..32846f7 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -237,25 +237,10 @@ static int ptrace_attach(struct task_struct *task, long request, bool seize = (request == PTRACE_SEIZE); int retval; - /* - * SEIZE will enable new ptrace behaviors which will be implemented - * gradually. SEIZE_DEVEL bit is used to prevent applications - * expecting full SEIZE behaviors trapping on kernel commits which - * are still in the process of implementing them. - * - * Only test programs for new ptrace behaviors being implemented - * should set SEIZE_DEVEL. If unset, SEIZE will fail with -EIO. - * - * Once SEIZE behaviors are completely implemented, this flag - * will be removed. - */ retval = -EIO; if (seize) { if (addr != 0) goto out; - if (!(flags & PTRACE_SEIZE_DEVEL)) - goto out; - flags &= ~(unsigned long)PTRACE_SEIZE_DEVEL; if (flags & ~(unsigned long)PTRACE_O_MASK) goto out; flags = PT_PTRACED | PT_SEIZED | (flags << PT_OPT_FLAG_SHIFT); -- 1.7.7.6 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 5/5] ptrace: remove PTRACE_SEIZE_DEVEL bit 2012-02-10 14:43 ` [PATCH 5/5] ptrace: remove PTRACE_SEIZE_DEVEL bit Denys Vlasenko @ 2012-02-10 17:24 ` Oleg Nesterov 2012-02-10 17:46 ` Pedro Alves 2012-02-10 19:21 ` Tejun Heo 0 siblings, 2 replies; 22+ messages in thread From: Oleg Nesterov @ 2012-02-10 17:24 UTC (permalink / raw) To: Denys Vlasenko Cc: Andrew Morton, Tejun Heo, Pedro Alves, Jan Kratochvil, linux-kernel On 02/10, Denys Vlasenko wrote: > > PTRACE_SEIZE code is tested and ready for production use, > remove the code which requires special bit in data argument > to make PTRACE_SEIZE work. > > Strace team prepares for a new release of strace, and we > would like to ship the code which uses PTRACE_SEIZE, > preferably after this change goes into released kernel. > > Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> Personally I agree with this change. PTRACE_SEIZE_DEVEL complicates the testing/development for the user-space. Tejun, do you agree? Acked-by: Oleg Nesterov <oleg@redhat.com> - > include/linux/ptrace.h | 5 +---- > kernel/ptrace.c | 15 --------------- > 2 files changed, 1 insertions(+), 19 deletions(-) > > diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h > index ec6571c..6dffe18 100644 > --- a/include/linux/ptrace.h > +++ b/include/linux/ptrace.h > @@ -51,9 +51,6 @@ > #define PTRACE_INTERRUPT 0x4207 > #define PTRACE_LISTEN 0x4208 > > -/* flags in @data for PTRACE_SEIZE */ > -#define PTRACE_SEIZE_DEVEL 0x80000000 /* temp flag for development */ > - > /* Wait extended result codes for the above trace options. */ > #define PTRACE_EVENT_FORK 1 > #define PTRACE_EVENT_VFORK 2 > @@ -64,7 +61,7 @@ > /* Extended result codes which enabled by means other than options. */ > #define PTRACE_EVENT_STOP 128 > > -/* options set using PTRACE_SETOPTIONS */ > +/* Options set using PTRACE_SETOPTIONS or using PTRACE_SEIZE @data param */ > #define PTRACE_O_TRACESYSGOOD 1 > #define PTRACE_O_TRACEFORK (1 << PTRACE_EVENT_FORK) > #define PTRACE_O_TRACEVFORK (1 << PTRACE_EVENT_VFORK) > diff --git a/kernel/ptrace.c b/kernel/ptrace.c > index 99a18a0..32846f7 100644 > --- a/kernel/ptrace.c > +++ b/kernel/ptrace.c > @@ -237,25 +237,10 @@ static int ptrace_attach(struct task_struct *task, long request, > bool seize = (request == PTRACE_SEIZE); > int retval; > > - /* > - * SEIZE will enable new ptrace behaviors which will be implemented > - * gradually. SEIZE_DEVEL bit is used to prevent applications > - * expecting full SEIZE behaviors trapping on kernel commits which > - * are still in the process of implementing them. > - * > - * Only test programs for new ptrace behaviors being implemented > - * should set SEIZE_DEVEL. If unset, SEIZE will fail with -EIO. > - * > - * Once SEIZE behaviors are completely implemented, this flag > - * will be removed. > - */ > retval = -EIO; > if (seize) { > if (addr != 0) > goto out; > - if (!(flags & PTRACE_SEIZE_DEVEL)) > - goto out; > - flags &= ~(unsigned long)PTRACE_SEIZE_DEVEL; > if (flags & ~(unsigned long)PTRACE_O_MASK) > goto out; > flags = PT_PTRACED | PT_SEIZED | (flags << PT_OPT_FLAG_SHIFT); > -- > 1.7.7.6 > ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 5/5] ptrace: remove PTRACE_SEIZE_DEVEL bit 2012-02-10 17:24 ` Oleg Nesterov @ 2012-02-10 17:46 ` Pedro Alves 2012-02-10 17:42 ` Oleg Nesterov 2012-02-10 19:21 ` Tejun Heo 1 sibling, 1 reply; 22+ messages in thread From: Pedro Alves @ 2012-02-10 17:46 UTC (permalink / raw) To: Oleg Nesterov Cc: Denys Vlasenko, Andrew Morton, Tejun Heo, Jan Kratochvil, linux-kernel Hi, Do new auto-attached clones still generate SIGSTOP, or has than been fixed already? -- Pedro Alves ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 5/5] ptrace: remove PTRACE_SEIZE_DEVEL bit 2012-02-10 17:46 ` Pedro Alves @ 2012-02-10 17:42 ` Oleg Nesterov 2012-02-10 17:49 ` Pedro Alves 0 siblings, 1 reply; 22+ messages in thread From: Oleg Nesterov @ 2012-02-10 17:42 UTC (permalink / raw) To: Pedro Alves Cc: Denys Vlasenko, Andrew Morton, Tejun Heo, Jan Kratochvil, linux-kernel On 02/10, Pedro Alves wrote: > > Do new auto-attached clones still generate SIGSTOP, or has than been fixed already? Hopefully fixed by d184d6eb "ptrace: dont send SIGSTOP on auto-attach if PT_SEIZED" Oleg. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 5/5] ptrace: remove PTRACE_SEIZE_DEVEL bit 2012-02-10 17:42 ` Oleg Nesterov @ 2012-02-10 17:49 ` Pedro Alves 0 siblings, 0 replies; 22+ messages in thread From: Pedro Alves @ 2012-02-10 17:49 UTC (permalink / raw) To: Oleg Nesterov Cc: Denys Vlasenko, Andrew Morton, Tejun Heo, Jan Kratochvil, linux-kernel On 02/10/2012 05:42 PM, Oleg Nesterov wrote: > On 02/10, Pedro Alves wrote: >> >> Do new auto-attached clones still generate SIGSTOP, or has than been fixed already? > > Hopefully fixed by d184d6eb > "ptrace: dont send SIGSTOP on auto-attach if PT_SEIZED" Awesome, thanks. -- Pedro Alves ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 5/5] ptrace: remove PTRACE_SEIZE_DEVEL bit 2012-02-10 17:24 ` Oleg Nesterov 2012-02-10 17:46 ` Pedro Alves @ 2012-02-10 19:21 ` Tejun Heo 1 sibling, 0 replies; 22+ messages in thread From: Tejun Heo @ 2012-02-10 19:21 UTC (permalink / raw) To: Oleg Nesterov Cc: Denys Vlasenko, Andrew Morton, Pedro Alves, Jan Kratochvil, linux-kernel On Fri, Feb 10, 2012 at 06:24:27PM +0100, Oleg Nesterov wrote: > On 02/10, Denys Vlasenko wrote: > > > > PTRACE_SEIZE code is tested and ready for production use, > > remove the code which requires special bit in data argument > > to make PTRACE_SEIZE work. > > > > Strace team prepares for a new release of strace, and we > > would like to ship the code which uses PTRACE_SEIZE, > > preferably after this change goes into released kernel. > > > > Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> > > Personally I agree with this change. PTRACE_SEIZE_DEVEL complicates > the testing/development for the user-space. > > Tejun, do you agree? > > Acked-by: Oleg Nesterov <oleg@redhat.com> Yeah, I was thinking about sending a patch to remove DEVEL flag myself and other changes seem good to me too. For the whole series, Acked-by: Tejun Heo <tj@kernel.org> Thanks! -- tejun ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/5] ptrace: renumber PTRACE_EVENT_STOP so that future new options and events can match 2012-02-10 14:43 ` [PATCH 4/5] ptrace: renumber PTRACE_EVENT_STOP so that future new options and events can match Denys Vlasenko 2012-02-10 14:43 ` [PATCH 5/5] ptrace: remove PTRACE_SEIZE_DEVEL bit Denys Vlasenko @ 2012-02-10 17:19 ` Oleg Nesterov 1 sibling, 0 replies; 22+ messages in thread From: Oleg Nesterov @ 2012-02-10 17:19 UTC (permalink / raw) To: Denys Vlasenko Cc: Andrew Morton, Tejun Heo, Pedro Alves, Jan Kratochvil, linux-kernel On 02/10, Denys Vlasenko wrote: > > PTRACE_EVENT_foo and PTRACE_O_TRACEfoo used to match. > > New PTRACE_EVENT_STOP is the first event which has no corresponding > PTRACE_O_TRACE option. If we will ever want to add another such option, > its PTRACE_EVENT's value will collide with PTRACE_EVENT_STOP's value. > > This patch changes PTRACE_EVENT_STOP value to prevent this. > > While at it, added a comment - the one atop PTRACE_EVENT block, > saying "Wait extended result codes for the above trace options", > is not true for PTRACE_EVENT_STOP. > > Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> IIRC Tejun agreed with this change too. Reviewed-by: Oleg Nesterov <oleg@redhat.com> > --- > include/linux/ptrace.h | 3 ++- > 1 files changed, 2 insertions(+), 1 deletions(-) > > diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h > index 06be6a3..ec6571c 100644 > --- a/include/linux/ptrace.h > +++ b/include/linux/ptrace.h > @@ -61,7 +61,8 @@ > #define PTRACE_EVENT_EXEC 4 > #define PTRACE_EVENT_VFORK_DONE 5 > #define PTRACE_EVENT_EXIT 6 > -#define PTRACE_EVENT_STOP 7 > +/* Extended result codes which enabled by means other than options. */ > +#define PTRACE_EVENT_STOP 128 > > /* options set using PTRACE_SETOPTIONS */ > #define PTRACE_O_TRACESYSGOOD 1 > -- > 1.7.7.6 > ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 3/5] ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter 2012-02-10 14:43 ` [PATCH 3/5] ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter Denys Vlasenko 2012-02-10 14:43 ` [PATCH 4/5] ptrace: renumber PTRACE_EVENT_STOP so that future new options and events can match Denys Vlasenko @ 2012-02-10 15:57 ` Oleg Nesterov 2012-02-10 16:34 ` Denys Vlasenko 2012-02-10 16:36 ` [PATCH v2 " Denys Vlasenko 1 sibling, 2 replies; 22+ messages in thread From: Oleg Nesterov @ 2012-02-10 15:57 UTC (permalink / raw) To: Denys Vlasenko Cc: Andrew Morton, Tejun Heo, Pedro Alves, Jan Kratochvil, linux-kernel On 02/10, Denys Vlasenko wrote: > > @@ -879,7 +890,7 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, > } > > if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) { > - ret = ptrace_attach(child, request, data); > + ret = ptrace_attach(child, request, addr, data); There is another caller which should be updated, sys_compat_ptrace(). Otherwise looks good. Oleg. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 3/5] ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter 2012-02-10 15:57 ` [PATCH 3/5] ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter Oleg Nesterov @ 2012-02-10 16:34 ` Denys Vlasenko 2012-02-10 16:36 ` [PATCH v2 " Denys Vlasenko 1 sibling, 0 replies; 22+ messages in thread From: Denys Vlasenko @ 2012-02-10 16:34 UTC (permalink / raw) To: Oleg Nesterov Cc: Andrew Morton, Tejun Heo, Pedro Alves, Jan Kratochvil, linux-kernel On Fri, Feb 10, 2012 at 4:57 PM, Oleg Nesterov <oleg@redhat.com> wrote: > On 02/10, Denys Vlasenko wrote: >> >> @@ -879,7 +890,7 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, >> } >> >> if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) { >> - ret = ptrace_attach(child, request, data); >> + ret = ptrace_attach(child, request, addr, data); > > There is another caller which should be updated, sys_compat_ptrace(). Drats. I only tested the patch on i386, not on x86-64, and missed it. Updated patch follows in a minute. -- vda ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 3/5] ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter 2012-02-10 15:57 ` [PATCH 3/5] ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter Oleg Nesterov 2012-02-10 16:34 ` Denys Vlasenko @ 2012-02-10 16:36 ` Denys Vlasenko 2012-02-10 17:20 ` Oleg Nesterov 1 sibling, 1 reply; 22+ messages in thread From: Denys Vlasenko @ 2012-02-10 16:36 UTC (permalink / raw) To: Andrew Morton, Oleg Nesterov, Tejun Heo, Pedro Alves, Jan Kratochvil, linux-kernel Cc: Denys Vlasenko This can be used to close a few corner cases in strace where we get unwanted racy behavior after attach, but before we have a chance to set options (the notorious post-execve SIGTRAP comes to mind), and removes the need to track "did we set opts for this task" state in strace internals. While we are at it: Make it possible to extend SEIZE in the future with more functionality by passing non-zero 'addr' parameter. To that end, error out if 'addr' is non-zero. PTRACE_ATTACH did not (and still does not) have such check, and users (strace) do pass garbage there... let's avoid repeating this mistake with SEIZE. Set all task->ptrace bits in one operation - before this change, we were adding PT_SEIZED and PT_PTRACE_CAP with task->ptrace |= BIT ops. This was probably ok (not a bug), but let's be on a safer side. Changes in v2: update ptrace_attach() call in compat_sys_ptrace() too. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> Acked-by: Tejun Heo <tj@kernel.org> --- kernel/ptrace.c | 31 +++++++++++++++++++++---------- 1 files changed, 21 insertions(+), 10 deletions(-) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 9acd07a..4661c5b 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -231,6 +231,7 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode) } static int ptrace_attach(struct task_struct *task, long request, + unsigned long addr, unsigned long flags) { bool seize = (request == PTRACE_SEIZE); @@ -238,19 +239,29 @@ static int ptrace_attach(struct task_struct *task, long request, /* * SEIZE will enable new ptrace behaviors which will be implemented - * gradually. SEIZE_DEVEL is used to prevent applications + * gradually. SEIZE_DEVEL bit is used to prevent applications * expecting full SEIZE behaviors trapping on kernel commits which * are still in the process of implementing them. * * Only test programs for new ptrace behaviors being implemented * should set SEIZE_DEVEL. If unset, SEIZE will fail with -EIO. * - * Once SEIZE behaviors are completely implemented, this flag and - * the following test will be removed. + * Once SEIZE behaviors are completely implemented, this flag + * will be removed. */ retval = -EIO; - if (seize && !(flags & PTRACE_SEIZE_DEVEL)) - goto out; + if (seize) { + if (addr != 0) + goto out; + if (!(flags & PTRACE_SEIZE_DEVEL)) + goto out; + flags &= ~(unsigned long)PTRACE_SEIZE_DEVEL; + if (flags & ~(unsigned long)PTRACE_O_MASK) + goto out; + flags = PT_PTRACED | PT_SEIZED | (flags << PT_OPT_FLAG_SHIFT); + } else { + flags = PT_PTRACED; + } audit_ptrace(task); @@ -282,11 +293,11 @@ static int ptrace_attach(struct task_struct *task, long request, if (task->ptrace) goto unlock_tasklist; - task->ptrace = PT_PTRACED; if (seize) - task->ptrace |= PT_SEIZED; + flags |= PT_SEIZED; if (ns_capable(task_user_ns(task), CAP_SYS_PTRACE)) - task->ptrace |= PT_PTRACE_CAP; + flags |= PT_PTRACE_CAP; + task->ptrace = flags; __ptrace_link(task, current); @@ -879,7 +890,7 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, } if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) { - ret = ptrace_attach(child, request, data); + ret = ptrace_attach(child, request, addr, data); /* * Some architectures need to do book-keeping after * a ptrace attach. @@ -1022,7 +1033,7 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, } if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) { - ret = ptrace_attach(child, request, data); + ret = ptrace_attach(child, request, addr, data); /* * Some architectures need to do book-keeping after * a ptrace attach. -- 1.7.7.6 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v2 3/5] ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter 2012-02-10 16:36 ` [PATCH v2 " Denys Vlasenko @ 2012-02-10 17:20 ` Oleg Nesterov 0 siblings, 0 replies; 22+ messages in thread From: Oleg Nesterov @ 2012-02-10 17:20 UTC (permalink / raw) To: Denys Vlasenko Cc: Andrew Morton, Tejun Heo, Pedro Alves, Jan Kratochvil, linux-kernel On 02/10, Denys Vlasenko wrote: > > This can be used to close a few corner cases in strace where we get > unwanted racy behavior after attach, but before we have a chance > to set options (the notorious post-execve SIGTRAP comes to mind), > and removes the need to track "did we set opts for this task" state > in strace internals. > > While we are at it: > > Make it possible to extend SEIZE in the future with more functionality > by passing non-zero 'addr' parameter. > To that end, error out if 'addr' is non-zero. > PTRACE_ATTACH did not (and still does not) have such check, > and users (strace) do pass garbage there... let's avoid repeating > this mistake with SEIZE. > > Set all task->ptrace bits in one operation - before this change, > we were adding PT_SEIZED and PT_PTRACE_CAP with task->ptrace |= BIT ops. > This was probably ok (not a bug), but let's be on a safer side. > > Changes in v2: update ptrace_attach() call in compat_sys_ptrace() too. > > Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> > Acked-by: Tejun Heo <tj@kernel.org> Reviewed-by: Oleg Nesterov <oleg@redhat.com> > --- > kernel/ptrace.c | 31 +++++++++++++++++++++---------- > 1 files changed, 21 insertions(+), 10 deletions(-) > > diff --git a/kernel/ptrace.c b/kernel/ptrace.c > index 9acd07a..4661c5b 100644 > --- a/kernel/ptrace.c > +++ b/kernel/ptrace.c > @@ -231,6 +231,7 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode) > } > > static int ptrace_attach(struct task_struct *task, long request, > + unsigned long addr, > unsigned long flags) > { > bool seize = (request == PTRACE_SEIZE); > @@ -238,19 +239,29 @@ static int ptrace_attach(struct task_struct *task, long request, > > /* > * SEIZE will enable new ptrace behaviors which will be implemented > - * gradually. SEIZE_DEVEL is used to prevent applications > + * gradually. SEIZE_DEVEL bit is used to prevent applications > * expecting full SEIZE behaviors trapping on kernel commits which > * are still in the process of implementing them. > * > * Only test programs for new ptrace behaviors being implemented > * should set SEIZE_DEVEL. If unset, SEIZE will fail with -EIO. > * > - * Once SEIZE behaviors are completely implemented, this flag and > - * the following test will be removed. > + * Once SEIZE behaviors are completely implemented, this flag > + * will be removed. > */ > retval = -EIO; > - if (seize && !(flags & PTRACE_SEIZE_DEVEL)) > - goto out; > + if (seize) { > + if (addr != 0) > + goto out; > + if (!(flags & PTRACE_SEIZE_DEVEL)) > + goto out; > + flags &= ~(unsigned long)PTRACE_SEIZE_DEVEL; > + if (flags & ~(unsigned long)PTRACE_O_MASK) > + goto out; > + flags = PT_PTRACED | PT_SEIZED | (flags << PT_OPT_FLAG_SHIFT); > + } else { > + flags = PT_PTRACED; > + } > > audit_ptrace(task); > > @@ -282,11 +293,11 @@ static int ptrace_attach(struct task_struct *task, long request, > if (task->ptrace) > goto unlock_tasklist; > > - task->ptrace = PT_PTRACED; > if (seize) > - task->ptrace |= PT_SEIZED; > + flags |= PT_SEIZED; > if (ns_capable(task_user_ns(task), CAP_SYS_PTRACE)) > - task->ptrace |= PT_PTRACE_CAP; > + flags |= PT_PTRACE_CAP; > + task->ptrace = flags; > > __ptrace_link(task, current); > > @@ -879,7 +890,7 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, > } > > if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) { > - ret = ptrace_attach(child, request, data); > + ret = ptrace_attach(child, request, addr, data); > /* > * Some architectures need to do book-keeping after > * a ptrace attach. > @@ -1022,7 +1033,7 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, > } > > if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) { > - ret = ptrace_attach(child, request, data); > + ret = ptrace_attach(child, request, addr, data); > /* > * Some architectures need to do book-keeping after > * a ptrace attach. > -- > 1.7.7.6 > ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/5] ptrace: simplify PTRACE_foo constants and PTRACE_SETOPTIONS code 2012-02-10 14:43 ` [PATCH 2/5] ptrace: simplify PTRACE_foo constants and PTRACE_SETOPTIONS code Denys Vlasenko 2012-02-10 14:43 ` [PATCH 3/5] ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter Denys Vlasenko @ 2012-02-10 17:17 ` Oleg Nesterov 1 sibling, 0 replies; 22+ messages in thread From: Oleg Nesterov @ 2012-02-10 17:17 UTC (permalink / raw) To: Denys Vlasenko Cc: Andrew Morton, Tejun Heo, Pedro Alves, Jan Kratochvil, linux-kernel On 02/10, Denys Vlasenko wrote: > > Exchange PT_TRACESYSGOOD and PT_PTRACE_CAP bit positions, which makes > PT_option bits contiguous and therefore makes code in ptrace_setoptions() > much simpler. > > Every PTRACE_O_TRACEevent is defined to (1 << PTRACE_EVENT_event) > instead of using explicit numeric constants, to ensure we don't > mess up relationship between bit positions and event ids. > > PT_EVENT_FLAG_SHIFT was not particularly useful, PT_OPT_FLAG_SHIFT with > value of PT_EVENT_FLAG_SHIFT-1 is easier to use. > > PT_TRACE_MASK constant is nuked, the only its use is replaced by > (PTRACE_O_MASK << PT_OPT_FLAG_SHIFT). > > Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> > Acked-by: Tejun Heo <tj@kernel.org> Reviewed-by: Oleg Nesterov <oleg@redhat.com> > --- > include/linux/ptrace.h | 33 +++++++++++++++------------------ > kernel/ptrace.c | 31 ++++++++----------------------- > 2 files changed, 23 insertions(+), 41 deletions(-) > > diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h > index c2f1f6a..06be6a3 100644 > --- a/include/linux/ptrace.h > +++ b/include/linux/ptrace.h > @@ -54,17 +54,6 @@ > /* flags in @data for PTRACE_SEIZE */ > #define PTRACE_SEIZE_DEVEL 0x80000000 /* temp flag for development */ > > -/* options set using PTRACE_SETOPTIONS */ > -#define PTRACE_O_TRACESYSGOOD 0x00000001 > -#define PTRACE_O_TRACEFORK 0x00000002 > -#define PTRACE_O_TRACEVFORK 0x00000004 > -#define PTRACE_O_TRACECLONE 0x00000008 > -#define PTRACE_O_TRACEEXEC 0x00000010 > -#define PTRACE_O_TRACEVFORKDONE 0x00000020 > -#define PTRACE_O_TRACEEXIT 0x00000040 > - > -#define PTRACE_O_MASK 0x0000007f > - > /* Wait extended result codes for the above trace options. */ > #define PTRACE_EVENT_FORK 1 > #define PTRACE_EVENT_VFORK 2 > @@ -74,6 +63,17 @@ > #define PTRACE_EVENT_EXIT 6 > #define PTRACE_EVENT_STOP 7 > > +/* options set using PTRACE_SETOPTIONS */ > +#define PTRACE_O_TRACESYSGOOD 1 > +#define PTRACE_O_TRACEFORK (1 << PTRACE_EVENT_FORK) > +#define PTRACE_O_TRACEVFORK (1 << PTRACE_EVENT_VFORK) > +#define PTRACE_O_TRACECLONE (1 << PTRACE_EVENT_CLONE) > +#define PTRACE_O_TRACEEXEC (1 << PTRACE_EVENT_EXEC) > +#define PTRACE_O_TRACEVFORKDONE (1 << PTRACE_EVENT_VFORK_DONE) > +#define PTRACE_O_TRACEEXIT (1 << PTRACE_EVENT_EXIT) > + > +#define PTRACE_O_MASK 0x0000007f > + > #include <asm/ptrace.h> > > #ifdef __KERNEL__ > @@ -88,13 +88,12 @@ > #define PT_SEIZED 0x00010000 /* SEIZE used, enable new behavior */ > #define PT_PTRACED 0x00000001 > #define PT_DTRACE 0x00000002 /* delayed trace (used on m68k, i386) */ > -#define PT_TRACESYSGOOD 0x00000004 > -#define PT_PTRACE_CAP 0x00000008 /* ptracer can follow suid-exec */ > +#define PT_PTRACE_CAP 0x00000004 /* ptracer can follow suid-exec */ > > +#define PT_OPT_FLAG_SHIFT 3 > /* PT_TRACE_* event enable flags */ > -#define PT_EVENT_FLAG_SHIFT 4 > -#define PT_EVENT_FLAG(event) (1 << (PT_EVENT_FLAG_SHIFT + (event) - 1)) > - > +#define PT_EVENT_FLAG(event) (1 << (PT_OPT_FLAG_SHIFT + (event))) > +#define PT_TRACESYSGOOD PT_EVENT_FLAG(0) > #define PT_TRACE_FORK PT_EVENT_FLAG(PTRACE_EVENT_FORK) > #define PT_TRACE_VFORK PT_EVENT_FLAG(PTRACE_EVENT_VFORK) > #define PT_TRACE_CLONE PT_EVENT_FLAG(PTRACE_EVENT_CLONE) > @@ -102,8 +101,6 @@ > #define PT_TRACE_VFORK_DONE PT_EVENT_FLAG(PTRACE_EVENT_VFORK_DONE) > #define PT_TRACE_EXIT PT_EVENT_FLAG(PTRACE_EVENT_EXIT) > > -#define PT_TRACE_MASK 0x000003f4 > - > /* single stepping state bits (used on ARM and PA-RISC) */ > #define PT_SINGLESTEP_BIT 31 > #define PT_SINGLESTEP (1<<PT_SINGLESTEP_BIT) > diff --git a/kernel/ptrace.c b/kernel/ptrace.c > index 273f56e..9acd07a 100644 > --- a/kernel/ptrace.c > +++ b/kernel/ptrace.c > @@ -262,7 +262,7 @@ static int ptrace_attach(struct task_struct *task, long request, > > /* > * Protect exec's credential calculations against our interference; > - * interference; SUID, SGID and LSM creds get determined differently > + * SUID, SGID and LSM creds get determined differently > * under ptrace. > */ > retval = -ERESTARTNOINTR; > @@ -528,31 +528,16 @@ int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long ds > > static int ptrace_setoptions(struct task_struct *child, unsigned long data) > { > + unsigned flags; > + > if (data & ~(unsigned long)PTRACE_O_MASK) > return -EINVAL; > > - child->ptrace &= ~PT_TRACE_MASK; > - > - if (data & PTRACE_O_TRACESYSGOOD) > - child->ptrace |= PT_TRACESYSGOOD; > - > - if (data & PTRACE_O_TRACEFORK) > - child->ptrace |= PT_TRACE_FORK; > - > - if (data & PTRACE_O_TRACEVFORK) > - child->ptrace |= PT_TRACE_VFORK; > - > - if (data & PTRACE_O_TRACECLONE) > - child->ptrace |= PT_TRACE_CLONE; > - > - if (data & PTRACE_O_TRACEEXEC) > - child->ptrace |= PT_TRACE_EXEC; > - > - if (data & PTRACE_O_TRACEVFORKDONE) > - child->ptrace |= PT_TRACE_VFORK_DONE; > - > - if (data & PTRACE_O_TRACEEXIT) > - child->ptrace |= PT_TRACE_EXIT; > + /* Avoid intermediate state when all opts are cleared */ > + flags = child->ptrace; > + flags &= ~(PTRACE_O_MASK << PT_OPT_FLAG_SHIFT); > + flags |= (data << PT_OPT_FLAG_SHIFT); > + child->ptrace = flags; > > return 0; > } > -- > 1.7.7.6 > ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/5] ptrace: don't modify flags on PTRACE_SETOPTIONS failure 2012-02-10 14:43 ` [PATCH 1/5] ptrace: don't modify flags on PTRACE_SETOPTIONS failure Denys Vlasenko 2012-02-10 14:43 ` [PATCH 2/5] ptrace: simplify PTRACE_foo constants and PTRACE_SETOPTIONS code Denys Vlasenko @ 2012-02-10 17:17 ` Oleg Nesterov 1 sibling, 0 replies; 22+ messages in thread From: Oleg Nesterov @ 2012-02-10 17:17 UTC (permalink / raw) To: Denys Vlasenko Cc: Andrew Morton, Tejun Heo, Pedro Alves, Jan Kratochvil, linux-kernel On 02/10, Denys Vlasenko wrote: > On ptrace(PTRACE_SETOPTIONS, pid, 0, <opts>), we used to set > those option bits which are known, and then fail with -EINVAL > if there are some unknown bits in <opts>. > > This in inconsistent with typical error handling, which > does not change any state if input is invalid. > > This patch changes PTRACE_SETOPTIONS behavior so that > in this case, we return -EINVAL and don't change any bits > in task->ptrace. > > It's very unlikely that there is userspace code in the wild which > will be affected by this change: it should have the form > > ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_BOGUSOPT) > > where PTRACE_O_BOGUSOPT is a constant unknown to the kernel. > But kernel headers, naturally, don't contain any > PTRACE_O_BOGUSOPTs, thus the only way userspace can use one > if it defines one itself. I can't see why anyone would do such > a thing deliberately. > > Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> > Acked-by: Tejun Heo <tj@kernel.org> Reviewed-by: Oleg Nesterov <oleg@redhat.com> > --- > kernel/ptrace.c | 5 ++++- > 1 files changed, 4 insertions(+), 1 deletions(-) > > diff --git a/kernel/ptrace.c b/kernel/ptrace.c > index 00ab2ca..273f56e 100644 > --- a/kernel/ptrace.c > +++ b/kernel/ptrace.c > @@ -528,6 +528,9 @@ int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long ds > > static int ptrace_setoptions(struct task_struct *child, unsigned long data) > { > + if (data & ~(unsigned long)PTRACE_O_MASK) > + return -EINVAL; > + > child->ptrace &= ~PT_TRACE_MASK; > > if (data & PTRACE_O_TRACESYSGOOD) > @@ -551,7 +554,7 @@ static int ptrace_setoptions(struct task_struct *child, unsigned long data) > if (data & PTRACE_O_TRACEEXIT) > child->ptrace |= PT_TRACE_EXIT; > > - return (data & ~PTRACE_O_MASK) ? -EINVAL : 0; > + return 0; > } > > static int ptrace_getsiginfo(struct task_struct *child, siginfo_t *info) > -- > 1.7.7.6 > ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 0/2] more tweaks (Was: ptrace tweaks) 2012-02-10 14:43 [PATCH 0/5] ptrace tweaks Denys Vlasenko 2012-02-10 14:43 ` [PATCH 1/5] ptrace: don't modify flags on PTRACE_SETOPTIONS failure Denys Vlasenko @ 2012-02-10 17:32 ` Oleg Nesterov 2012-02-10 17:32 ` [PATCH 1/2] ptrace: the killed tracee should not enter the syscall Oleg Nesterov ` (2 more replies) 1 sibling, 3 replies; 22+ messages in thread From: Oleg Nesterov @ 2012-02-10 17:32 UTC (permalink / raw) To: Denys Vlasenko, Andrew Morton Cc: Tejun Heo, Pedro Alves, Jan Kratochvil, linux-kernel, Chris Evans, Indan Zupancic On 02/10, Denys Vlasenko wrote: > > This patch set fixes a minor bug in PTRACE_SETOPTIONS, > slightly extends PTRACE_SEIZE (now it can take ptrace options), > changes PTRACE_EVENT_STOP value, > and enables PTRACE_SEIZE for non-development use. > > Ptrace git tree on kernel.org is not restored yet, > so this patch set can't go through it. > > Andrew, please consider taking this patch set. Yes, please... I was going to send 1-4 to Linus a long ago, but I can't restore my korg account. Plus I have a couple of other minor ptrace changes, could you take them too ? Chris, iirc you suggested to add PTRACE_O_KILL_TRACEE_IF_DEBUGGER_DIES. The necessary change is simple, please suggest the good name for the new option ;) Oleg. ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 1/2] ptrace: the killed tracee should not enter the syscall 2012-02-10 17:32 ` [PATCH 0/2] more tweaks (Was: ptrace tweaks) Oleg Nesterov @ 2012-02-10 17:32 ` Oleg Nesterov 2012-02-10 17:33 ` [PATCH 2/2] ptrace: don't send SIGTRAP on exec if SEIZED Oleg Nesterov 2012-02-10 17:48 ` [PATCH 0/2] more tweaks (Was: ptrace tweaks) Pedro Alves 2 siblings, 0 replies; 22+ messages in thread From: Oleg Nesterov @ 2012-02-10 17:32 UTC (permalink / raw) To: Denys Vlasenko, Andrew Morton Cc: Tejun Heo, Pedro Alves, Jan Kratochvil, linux-kernel, Chris Evans, Indan Zupancic Another old/known problem. If the tracee is killed after it reports syscall_entry, it starts the syscall and debugger can't control this. This confuses the users and this creates the security problems for ptrace jailers. Change tracehook_report_syscall_entry() to return non-zero if killed, this instructs syscall_trace_enter() to abort the syscall. Reported-by: Chris Evans <scarybeasts@gmail.com> Tested-by: Indan Zupancic <indan@nul.nu> Signed-off-by: Oleg Nesterov <oleg@redhat.com> --- include/linux/tracehook.h | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index a71a292..51bd91d 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -54,12 +54,12 @@ struct linux_binprm; /* * ptrace report for syscall entry and exit looks identical. */ -static inline void ptrace_report_syscall(struct pt_regs *regs) +static inline int ptrace_report_syscall(struct pt_regs *regs) { int ptrace = current->ptrace; if (!(ptrace & PT_PTRACED)) - return; + return 0; ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); @@ -72,6 +72,8 @@ static inline void ptrace_report_syscall(struct pt_regs *regs) send_sig(current->exit_code, current, 1); current->exit_code = 0; } + + return fatal_signal_pending(current); } /** @@ -96,8 +98,7 @@ static inline void ptrace_report_syscall(struct pt_regs *regs) static inline __must_check int tracehook_report_syscall_entry( struct pt_regs *regs) { - ptrace_report_syscall(regs); - return 0; + return ptrace_report_syscall(regs); } /** -- 1.5.5.1 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 2/2] ptrace: don't send SIGTRAP on exec if SEIZED 2012-02-10 17:32 ` [PATCH 0/2] more tweaks (Was: ptrace tweaks) Oleg Nesterov 2012-02-10 17:32 ` [PATCH 1/2] ptrace: the killed tracee should not enter the syscall Oleg Nesterov @ 2012-02-10 17:33 ` Oleg Nesterov 2012-02-10 17:48 ` [PATCH 0/2] more tweaks (Was: ptrace tweaks) Pedro Alves 2 siblings, 0 replies; 22+ messages in thread From: Oleg Nesterov @ 2012-02-10 17:33 UTC (permalink / raw) To: Denys Vlasenko, Andrew Morton Cc: Tejun Heo, Pedro Alves, Jan Kratochvil, linux-kernel, Chris Evans, Indan Zupancic ptrace_event(PTRACE_EVENT_EXEC) sends SIGTRAP if PT_TRACE_EXEC is not set. This is because this SIGTRAP predates PTRACE_O_TRACEEXEC option, we do not need/want this with PT_SEIZED which can set the options during attach. Suggested-by: Pedro Alves <palves@redhat.com> Signed-off-by: Oleg Nesterov <oleg@redhat.com> --- include/linux/ptrace.h | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index 6dffe18..407c678 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -194,9 +194,10 @@ static inline void ptrace_event(int event, unsigned long message) if (unlikely(ptrace_event_enabled(current, event))) { current->ptrace_message = message; ptrace_notify((event << 8) | SIGTRAP); - } else if (event == PTRACE_EVENT_EXEC && unlikely(current->ptrace)) { + } else if (event == PTRACE_EVENT_EXEC) { /* legacy EXEC report via SIGTRAP */ - send_sig(SIGTRAP, current, 0); + if ((current->ptrace & (PT_PTRACED|PT_SEIZED)) == PT_PTRACED) + send_sig(SIGTRAP, current, 0); } } -- 1.5.5.1 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 0/2] more tweaks (Was: ptrace tweaks) 2012-02-10 17:32 ` [PATCH 0/2] more tweaks (Was: ptrace tweaks) Oleg Nesterov 2012-02-10 17:32 ` [PATCH 1/2] ptrace: the killed tracee should not enter the syscall Oleg Nesterov 2012-02-10 17:33 ` [PATCH 2/2] ptrace: don't send SIGTRAP on exec if SEIZED Oleg Nesterov @ 2012-02-10 17:48 ` Pedro Alves 2 siblings, 0 replies; 22+ messages in thread From: Pedro Alves @ 2012-02-10 17:48 UTC (permalink / raw) To: Oleg Nesterov Cc: Denys Vlasenko, Andrew Morton, Tejun Heo, Jan Kratochvil, linux-kernel, Chris Evans, Indan Zupancic Yay, new bike shed! ;-) On 02/10/2012 05:32 PM, Oleg Nesterov wrote: > Chris, iirc you suggested to add PTRACE_O_KILL_TRACEE_IF_DEBUGGER_DIES. > The necessary change is simple, please suggest the good name for the > new option ;) PTRACE_O_KILL_ON_EXIT . Cause Windows has had DebugSetProcessKillOnExit(bool) for ages. -- Pedro Alves ^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2012-02-10 19:22 UTC | newest] Thread overview: 22+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-02-10 14:43 [PATCH 0/5] ptrace tweaks Denys Vlasenko 2012-02-10 14:43 ` [PATCH 1/5] ptrace: don't modify flags on PTRACE_SETOPTIONS failure Denys Vlasenko 2012-02-10 14:43 ` [PATCH 2/5] ptrace: simplify PTRACE_foo constants and PTRACE_SETOPTIONS code Denys Vlasenko 2012-02-10 14:43 ` [PATCH 3/5] ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter Denys Vlasenko 2012-02-10 14:43 ` [PATCH 4/5] ptrace: renumber PTRACE_EVENT_STOP so that future new options and events can match Denys Vlasenko 2012-02-10 14:43 ` [PATCH 5/5] ptrace: remove PTRACE_SEIZE_DEVEL bit Denys Vlasenko 2012-02-10 17:24 ` Oleg Nesterov 2012-02-10 17:46 ` Pedro Alves 2012-02-10 17:42 ` Oleg Nesterov 2012-02-10 17:49 ` Pedro Alves 2012-02-10 19:21 ` Tejun Heo 2012-02-10 17:19 ` [PATCH 4/5] ptrace: renumber PTRACE_EVENT_STOP so that future new options and events can match Oleg Nesterov 2012-02-10 15:57 ` [PATCH 3/5] ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter Oleg Nesterov 2012-02-10 16:34 ` Denys Vlasenko 2012-02-10 16:36 ` [PATCH v2 " Denys Vlasenko 2012-02-10 17:20 ` Oleg Nesterov 2012-02-10 17:17 ` [PATCH 2/5] ptrace: simplify PTRACE_foo constants and PTRACE_SETOPTIONS code Oleg Nesterov 2012-02-10 17:17 ` [PATCH 1/5] ptrace: don't modify flags on PTRACE_SETOPTIONS failure Oleg Nesterov 2012-02-10 17:32 ` [PATCH 0/2] more tweaks (Was: ptrace tweaks) Oleg Nesterov 2012-02-10 17:32 ` [PATCH 1/2] ptrace: the killed tracee should not enter the syscall Oleg Nesterov 2012-02-10 17:33 ` [PATCH 2/2] ptrace: don't send SIGTRAP on exec if SEIZED Oleg Nesterov 2012-02-10 17:48 ` [PATCH 0/2] more tweaks (Was: ptrace tweaks) Pedro Alves
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.