All of lore.kernel.org
 help / color / mirror / Atom feed
* [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 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 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

* 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 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 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 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

* [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 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: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 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

* 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

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.