* [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 a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).