lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20090528204729.GA28564@omega>
Date:	Thu, 28 May 2009 22:47:29 +0200
From:	Lennart Poettering <lennart@...ttering.net>
To:	linux-lernel@...r.kernel.org
Cc:	Kay Sievers <kay.sievers@...y.org>
Subject: [PATCH/RFC] exit: PR_SET_ANCHOR for marking processes as reapers
	for child processes

Right now, if a process dies all its children are reparented to init.
This logic has good uses, i.e. for double forking when
daemonizing. However it also allows child processes to "escape" their
parents, which is a problem for software like session managers (such
as gnome-session) or other process supervisors [1].

This patch adds a simple flag for each process that marks it as an
"anchor" process for all its children and grandchildren. If a child of
such an anchor dies all its children will not be reparented to init, but
instead to this anchor, escaping this anchor process is not possible. A
task with this flag set hence acts as little "sub-init".

Anchors are fully recursive: if an anchor dies, all its children are
reparented to next higher anchor in the process tree.

This is orthogonal to PID namespaces. PID namespaces virtualize the
actual IDs in addition to introducing "sub-inits". This patch introduces
"sub-inits" inside the same PID namespace.

This patch is compile tested only. It's relatively trivial, and is
written in ignorance of the locking logic for accessing
task_struct->parent. This mail is primarily intended as a request for
comments. So please, I'd be happy about any comments!

Lennart

[1] To be fully useful for session managers/process supervisors we
    need one addition patch that makes the list of child processes of
    a processes easily accesible via /proc, so that a supervisor can
    keep track of its children.

---
 include/linux/prctl.h |    3 +++
 include/linux/sched.h |    4 ++++
 kernel/exit.c         |    7 ++++++-
 kernel/fork.c         |    2 ++
 kernel/sys.c          |    7 +++++++
 5 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/include/linux/prctl.h b/include/linux/prctl.h
index 48d887e..1820edc 100644
--- a/include/linux/prctl.h
+++ b/include/linux/prctl.h
@@ -85,4 +85,7 @@
 #define PR_SET_TIMERSLACK 29
 #define PR_GET_TIMERSLACK 30
 
+#define PR_SET_ANCHOR 31
+#define PR_GET_ANCHOR 32
+
 #endif /* _LINUX_PRCTL_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index c28c81b..c296328 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1189,6 +1189,10 @@ struct task_struct {
 	/* Canary value for the -fstack-protector gcc feature */
 	unsigned long stack_canary;
 
+	/* When a child of one of our children dies, reparent it to me, instead
+	 * of init. */
+	int child_anchor;
+
 	/* 
 	 * pointers to (original) parent process, youngest child, younger sibling,
 	 * older sibling, respectively.  (p->father can be replaced with 
diff --git a/kernel/exit.c b/kernel/exit.c
index abf9cf3..20ce9da 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -704,7 +704,7 @@ static void exit_mm(struct task_struct * tsk)
 static struct task_struct *find_new_reaper(struct task_struct *father)
 {
 	struct pid_namespace *pid_ns = task_active_pid_ns(father);
-	struct task_struct *thread;
+	struct task_struct *thread, *anchor;
 
 	thread = father;
 	while_each_thread(father, thread) {
@@ -715,6 +715,11 @@ static struct task_struct *find_new_reaper(struct task_struct *father)
 		return thread;
 	}
 
+	/* find the first ancestor which is marked child_anchor */
+	for (anchor = father->parent; anchor != &init_task; anchor = anchor->parent)
+		if (anchor->child_anchor)
+			return anchor;
+
 	if (unlikely(pid_ns->child_reaper == father)) {
 		write_unlock_irq(&tasklist_lock);
 		if (unlikely(pid_ns == &init_pid_ns))
diff --git a/kernel/fork.c b/kernel/fork.c
index b9e2edd..7c80680 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1218,6 +1218,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 		p->parent_exec_id = current->self_exec_id;
 	}
 
+	p->child_anchor = 0;
+
 	spin_lock(&current->sighand->siglock);
 
 	/*
diff --git a/kernel/sys.c b/kernel/sys.c
index e7998cf..a8aa952 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1804,6 +1804,13 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 				current->timer_slack_ns = arg2;
 			error = 0;
 			break;
+		case PR_SET_ANCHOR:
+			me->child_anchor = !!arg2;
+			error = 0;
+			break;
+		case PR_GET_ANCHOR:
+			error = put_user(me->child_anchor, (int __user *) arg2);
+			break;
 		default:
 			error = -EINVAL;
 			break;
-- 
1.6.2.2



Lennart

-- 
Lennart Poettering                        Red Hat, Inc.
lennart [at] poettering [dot] net         ICQ# 11060553
http://0pointer.net/lennart/           GnuPG 0x1A015CC4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ