All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jann Horn <jann@thejh.net>
To: Alexander Viro <viro@zeniv.linux.org.uk>,
	Roland McGrath <roland@hack.frob.com>,
	Oleg Nesterov <oleg@redhat.com>,
	John Johansen <john.johansen@canonical.com>,
	James Morris <james.l.morris@oracle.com>,
	"Serge E. Hallyn" <serge@hallyn.com>,
	Paul Moore <aul@paul-moore.com>,
	Stephen Smalley <sds@tycho.nsa.gov>,
	Eric Paris <eparis@parisplace.org>,
	Casey Schaufler <casey@schaufler-ca.com>,
	Kees Cook <eescook@chromium.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Janis Danisevskis <jdanis@google.com>,
	Seth Forshee <seth.forshee@canonical.com>,
	"Eric . Biederman" <ebiederm@xmission.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Benjamin LaHaise <bcrl@kvack.org>
Cc: linux-fsdevel@vger.kernel.org,
	linux-security-module@vger.kernel.org, security@kernel.org
Subject: [PATCH 2/9] exec: turn self_exec_id into self_privunit_id
Date: Sun, 18 Sep 2016 17:05:10 +0200	[thread overview]
Message-ID: <1474211117-16674-3-git-send-email-jann@thejh.net> (raw)
In-Reply-To: <1474211117-16674-1-git-send-email-jann@thejh.net>

This ensures that self_privunit_id ("privilege unit ID") is only shared by
processes that share the mm_struct and the signal_struct; not just
spatially, but also temporally. In other words, if you do execve() or
clone() without CLONE_THREAD, you get a new privunit_id that has never been
used before.

One reason for doing this is that it prevents an attacker from sending an
arbitrary signal to a parent process after performing 2^32-1 execve()
calls.

The second reason for this is that it permits using the self_exec_id in
a later patch to check during a ptrace access whether subject and object
are temporally and spatially equal for privilege checking purposes.

This patch was grabbed from grsecurity and modified. Credit for the
original patch goes to Brad Spengler <spender@grsecurity.net>.

Signed-off-by: Jann Horn <jann@thejh.net>
---
 fs/exec.c               | 21 ++++++++++++++++++++-
 include/linux/binfmts.h |  1 +
 include/linux/sched.h   |  4 ++--
 kernel/fork.c           |  5 +++--
 kernel/signal.c         |  2 +-
 5 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index 84430ee..1a15cb0 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1281,6 +1281,25 @@ void would_dump(struct linux_binprm *bprm, struct file *file)
 }
 EXPORT_SYMBOL(would_dump);
 
+static DEFINE_PER_CPU(u64, exec_counter);
+static int __init init_exec_counters(void)
+{
+	unsigned int cpu;
+
+	for_each_possible_cpu(cpu) {
+		per_cpu(exec_counter, cpu) = (u64)cpu;
+	}
+
+	return 0;
+}
+early_initcall(init_exec_counters);
+
+void increment_privunit_counter(void)
+{
+	BUILD_BUG_ON(NR_CPUS > (1 << 16));
+	current->self_privunit_id = this_cpu_add_return(exec_counter, NR_CPUS);
+}
+
 void setup_new_exec(struct linux_binprm * bprm)
 {
 	arch_pick_mmap_layout(current->mm);
@@ -1314,7 +1333,7 @@ void setup_new_exec(struct linux_binprm * bprm)
 
 	/* An exec changes our domain. We are no longer part of the thread
 	   group */
-	current->self_exec_id++;
+	increment_privunit_counter();
 	flush_signal_handlers(current, 0);
 	do_close_on_exec(current->files);
 }
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 1303b57..9570bd0 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -100,6 +100,7 @@ extern int prepare_binprm(struct linux_binprm *);
 extern int __must_check remove_arg_zero(struct linux_binprm *);
 extern int search_binary_handler(struct linux_binprm *);
 extern int flush_old_exec(struct linux_binprm * bprm);
+extern void increment_privunit_counter(void);
 extern void setup_new_exec(struct linux_binprm * bprm);
 extern void would_dump(struct linux_binprm *, struct file *);
 
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 2a1df2f..e4bf894 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1688,8 +1688,8 @@ struct task_struct {
 	struct seccomp seccomp;
 
 /* Thread group tracking */
-   	u32 parent_exec_id;
-   	u32 self_exec_id;
+	u64 parent_privunit_id;
+	u64 self_privunit_id;
 /* Protection of (de-)allocation: mm, files, fs, tty, keyrings, mems_allowed,
  * mempolicy */
 	spinlock_t alloc_lock;
diff --git a/kernel/fork.c b/kernel/fork.c
index 2d46f3a..537c117 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1567,6 +1567,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 			p->exit_signal = (clone_flags & CSIGNAL);
 		p->group_leader = p;
 		p->tgid = p->pid;
+		increment_privunit_counter();
 	}
 
 	p->nr_dirtied = 0;
@@ -1597,10 +1598,10 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 	/* CLONE_PARENT re-uses the old parent */
 	if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) {
 		p->real_parent = current->real_parent;
-		p->parent_exec_id = current->parent_exec_id;
+		p->parent_privunit_id = current->parent_privunit_id;
 	} else {
 		p->real_parent = current;
-		p->parent_exec_id = current->self_exec_id;
+		p->parent_privunit_id = current->self_privunit_id;
 	}
 
 	spin_lock(&current->sighand->siglock);
diff --git a/kernel/signal.c b/kernel/signal.c
index af21afc..e4e3e1b 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1590,7 +1590,7 @@ bool do_notify_parent(struct task_struct *tsk, int sig)
 		 * This is only possible if parent == real_parent.
 		 * Check if it has changed security domain.
 		 */
-		if (tsk->parent_exec_id != tsk->parent->self_exec_id)
+		if (tsk->parent_privunit_id != tsk->parent->self_privunit_id)
 			sig = SIGCHLD;
 	}
 
-- 
2.1.4


  parent reply	other threads:[~2016-09-18 15:05 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-18 15:05 [PATCH 0/9] Various fixes related to ptrace_may_access() Jann Horn
2016-09-18 15:05 ` [PATCH 1/9] exec: introduce cred_guard_light Jann Horn
2016-09-18 15:05 ` Jann Horn [this message]
2016-09-18 18:13   ` [PATCH 2/9] exec: turn self_exec_id into self_privunit_id Ben Hutchings
2016-09-18 18:31     ` Jann Horn
2016-09-18 18:45       ` Ben Hutchings
2016-09-18 19:08         ` Jann Horn
2016-09-18 19:57         ` Andy Lutomirski
2016-09-19 15:31           ` Jann Horn
2016-09-18 15:05 ` [PATCH 3/9] proc: use open()-time creds for ptrace checks Jann Horn
2016-09-19 13:01   ` Stephen Smalley
2016-09-19 14:32     ` Jann Horn
2016-09-19 14:45       ` Stephen Smalley
2016-09-18 15:05 ` [PATCH 4/9] futex: don't leak robust_list pointer Jann Horn
2016-09-18 18:28   ` Ben Hutchings
2016-09-18 18:33     ` Jann Horn
2016-09-18 15:05 ` [PATCH 5/9] proc: lock properly in ptrace_may_access callers Jann Horn
2016-09-18 19:15   ` Jann Horn
2016-09-18 15:05 ` [PATCH 6/9] ptrace: warn on ptrace_may_access without proper locking Jann Horn
2016-09-18 15:05 ` [PATCH 7/9] ptrace: forbid ptrace checks against current_cred() from VFS context Jann Horn
2016-09-18 18:38   ` Ben Hutchings
2016-09-18 18:40     ` Jann Horn
2016-09-18 19:57   ` Andy Lutomirski
2016-09-18 20:38     ` Jann Horn
2016-09-18 20:18   ` Linus Torvalds
2016-09-18 20:52     ` Jann Horn
2016-09-18 15:05 ` [PATCH 8/9] fs/proc: fix attr access check Jann Horn
2016-09-18 15:05 ` [PATCH 9/9] Documentation: add security/ptrace_checks.txt Jann Horn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1474211117-16674-3-git-send-email-jann@thejh.net \
    --to=jann@thejh.net \
    --cc=akpm@linux-foundation.org \
    --cc=aul@paul-moore.com \
    --cc=bcrl@kvack.org \
    --cc=casey@schaufler-ca.com \
    --cc=ebiederm@xmission.com \
    --cc=eescook@chromium.org \
    --cc=eparis@parisplace.org \
    --cc=james.l.morris@oracle.com \
    --cc=jdanis@google.com \
    --cc=john.johansen@canonical.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=oleg@redhat.com \
    --cc=roland@hack.frob.com \
    --cc=sds@tycho.nsa.gov \
    --cc=security@kernel.org \
    --cc=serge@hallyn.com \
    --cc=seth.forshee@canonical.com \
    --cc=tglx@linutronix.de \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.