All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andy Lutomirski <luto@myrealbox.com>
To: Stephen Smalley <sds@epoch.ncsc.mil>
Cc: Chris Wright <chrisw@osdl.org>,
	Andy Lutomirski <luto@myrealbox.com>,
	Andrew Morton <akpm@osdl.org>, Linus Torvalds <torvalds@osdl.org>,
	James Morris <jmorris@redhat.com>,
	lkml <linux-kernel@vger.kernel.org>
Subject: Re: compute_creds fixup in -mm
Date: Wed, 21 Apr 2004 13:36:50 -0700	[thread overview]
Message-ID: <4086DB62.4000609@myrealbox.com> (raw)
In-Reply-To: <fa.f9m11dm.206fg4@ifi.uio.no>

[-- Attachment #1: Type: text/plain, Size: 160 bytes --]

Apparently my mailer converts single leading spaces into pairs of leading
spaces.  Time to find a new mailer.  Here's my patch again as an attachment.


--Andy

[-- Attachment #2: creds_fix_take2.patch --]
[-- Type: text/plain, Size: 9159 bytes --]

--- linux-2.6.5-mm5/include/linux/security.h.ptlock	2004-04-21 08:52:49.904877920 -0700
+++ linux-2.6.5-mm5/include/linux/security.h	2004-04-21 09:12:46.540961584 -0700
@@ -44,7 +44,7 @@
 extern int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted);
 extern void cap_capset_set (struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted);
 extern int cap_bprm_set_security (struct linux_binprm *bprm);
-extern void cap_bprm_apply_creds (struct linux_binprm *bprm);
+extern void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe);
 extern int cap_bprm_secureexec(struct linux_binprm *bprm);
 extern int cap_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags);
 extern int cap_inode_removexattr(struct dentry *dentry, char *name);
@@ -86,6 +86,11 @@
 struct sched_param;
 struct swap_info_struct;
 
+/* brpm_apply_creds unsafe reasons */
+#define LSM_UNSAFE_SHARE	1
+#define LSM_UNSAFE_PTRACE	2
+#define LSM_UNSAFE_PTRACE_CAP	4
+
 #ifdef CONFIG_SECURITY
 
 /**
@@ -112,6 +117,8 @@
  *	also perform other state changes on the process (e.g.  closing open
  *	file descriptors to which access is no longer granted if the attributes
  *	were changed). 
+ *	bprm_apply_creds is called under task_lock.  @unsafe indicates various
+ *	reasons why it may be unsafe to change security state.
  *	@bprm contains the linux_binprm structure.
  * @bprm_set_security:
  *	Save security information in the bprm->security field, typically based
@@ -1026,7 +1033,7 @@
 
 	int (*bprm_alloc_security) (struct linux_binprm * bprm);
 	void (*bprm_free_security) (struct linux_binprm * bprm);
-	void (*bprm_apply_creds) (struct linux_binprm * bprm);
+	void (*bprm_apply_creds) (struct linux_binprm * bprm, int unsafe);
 	int (*bprm_set_security) (struct linux_binprm * bprm);
 	int (*bprm_check_security) (struct linux_binprm * bprm);
 	int (*bprm_secureexec) (struct linux_binprm * bprm);
@@ -1290,9 +1297,9 @@
 {
 	security_ops->bprm_free_security (bprm);
 }
-static inline void security_bprm_apply_creds (struct linux_binprm *bprm)
+static inline void security_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
 {
-	security_ops->bprm_apply_creds (bprm);
+	security_ops->bprm_apply_creds (bprm, unsafe);
 }
 static inline int security_bprm_set (struct linux_binprm *bprm)
 {
@@ -1962,9 +1969,9 @@
 static inline void security_bprm_free (struct linux_binprm *bprm)
 { }
 
-static inline void security_bprm_apply_creds (struct linux_binprm *bprm)
+static inline void security_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
 { 
-	cap_bprm_apply_creds (bprm);
+	cap_bprm_apply_creds (bprm, unsafe);
 }
 
 static inline int security_bprm_set (struct linux_binprm *bprm)
--- linux-2.6.5-mm5/fs/exec.c.ptlock	2004-04-21 08:50:37.767965784 -0700
+++ linux-2.6.5-mm5/fs/exec.c	2004-04-21 12:23:01.915761696 -0700
@@ -919,24 +919,28 @@
 
 EXPORT_SYMBOL(prepare_binprm);
 
-/*
- * This function is used to produce the new IDs and capabilities
- * from the old ones and the file's capabilities.
- *
- * The formula used for evolving capabilities is:
- *
- *       pI' = pI
- * (***) pP' = (fP & X) | (fI & pI)
- *       pE' = pP' & fE          [NB. fE is 0 or ~0]
- *
- * I=Inheritable, P=Permitted, E=Effective // p=process, f=file
- * ' indicates post-exec(), and X is the global 'cap_bset'.
- *
- */
+static inline int must_not_trace_exec (struct task_struct *p)
+{
+	int unsafe = 0;
+	if (p->ptrace & PT_PTRACED) {
+		if(p->ptrace & PT_PTRACE_CAP)
+			unsafe |= LSM_UNSAFE_PTRACE_CAP;
+		else
+			unsafe |= LSM_UNSAFE_PTRACE;
+	}
+	if (atomic_read(&p->fs->count) > 1 ||
+	    atomic_read(&p->files->count) > 1 ||
+	    atomic_read(&p->sighand->count) > 1)
+		unsafe |= LSM_UNSAFE_SHARE;
+
+	return unsafe;
+}
 
 void compute_creds(struct linux_binprm *bprm)
 {
-	security_bprm_apply_creds(bprm);
+	task_lock(current);
+	security_bprm_apply_creds(bprm, must_not_trace_exec(current));
+	task_unlock(current);
 }
 
 EXPORT_SYMBOL(compute_creds);
--- linux-2.6.5-mm5/security/selinux/hooks.c.ptlock	2004-04-21 08:57:16.947281304 -0700
+++ linux-2.6.5-mm5/security/selinux/hooks.c	2004-04-21 12:23:58.245198320 -0700
@@ -1746,7 +1746,7 @@
 	spin_unlock(&files->file_lock);
 }
 
-static void selinux_bprm_apply_creds(struct linux_binprm *bprm)
+static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
 {
 	struct task_security_struct *tsec, *psec;
 	struct bprm_security_struct *bsec;
@@ -1756,7 +1756,7 @@
 	struct rlimit *rlim, *initrlim;
 	int rc, i;
 
-	secondary_ops->bprm_apply_creds(bprm);
+	secondary_ops->bprm_apply_creds(bprm, unsafe);
 
 	tsec = current->security;
 
@@ -1767,9 +1767,7 @@
 	if (tsec->sid != sid) {
 		/* Check for shared state.  If not ok, leave SID
 		   unchanged and kill. */
-		if ((atomic_read(&current->fs->count) > 1 ||
-		     atomic_read(&current->files->count) > 1 ||
-		     atomic_read(&current->sighand->count) > 1)) {
+		if (unsafe & LSM_UNSAFE_SHARE) {
 			rc = avc_has_perm(tsec->sid, sid,
 					  SECCLASS_PROCESS, PROCESS__SHARE,
 					  NULL, NULL);
@@ -1781,15 +1779,13 @@
 
 		/* Check for ptracing, and update the task SID if ok.
 		   Otherwise, leave SID unchanged and kill. */
-		task_lock(current);
-		if (current->ptrace & PT_PTRACED) {
+		if (unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
 			psec = current->parent->security;
 			rc = avc_has_perm_noaudit(psec->sid, sid,
 					  SECCLASS_PROCESS, PROCESS__PTRACE,
 					  NULL, &avd);
 			if (!rc)
 				tsec->sid = sid;
-			task_unlock(current);
 			avc_audit(psec->sid, sid, SECCLASS_PROCESS,
 				  PROCESS__PTRACE, &avd, rc, NULL);
 			if (rc) {
@@ -1798,7 +1794,6 @@
 			}
 		} else {
 			tsec->sid = sid;
-			task_unlock(current);
 		}
 
 		/* Close files for which the new task SID is not authorized. */
--- linux-2.6.5-mm5/security/commoncap.c.ptlock	2004-04-21 08:54:16.824664104 -0700
+++ linux-2.6.5-mm5/security/commoncap.c	2004-04-21 09:24:01.468357024 -0700
@@ -115,15 +115,7 @@
 	return 0;
 }
 
-static inline int must_not_trace_exec (struct task_struct *p)
-{
-	return ((p->ptrace & PT_PTRACED) && !(p->ptrace & PT_PTRACE_CAP))
-		|| atomic_read(&p->fs->count) > 1
-		|| atomic_read(&p->files->count) > 1
-		|| atomic_read(&p->sighand->count) > 1;
-}
-
-void cap_bprm_apply_creds (struct linux_binprm *bprm)
+void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
 {
 	/* Derived from fs/exec.c:compute_creds. */
 	kernel_cap_t new_permitted, working;
@@ -133,30 +125,25 @@
 				 current->cap_inheritable);
 	new_permitted = cap_combine (new_permitted, working);
 
-	task_lock(current);
-
-	if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) {
+	if (bprm->e_uid != current->uid || bprm->e_gid != current->gid ||
+	    !cap_issubset (new_permitted, current->cap_permitted)) {
 		current->mm->dumpable = 0;
 
-		if (must_not_trace_exec(current) && !capable(CAP_SETUID)) {
-			bprm->e_uid = current->uid;
-			bprm->e_gid = current->gid;
+		if (unsafe & ~LSM_UNSAFE_PTRACE_CAP) {
+			if (!capable(CAP_SETUID)) {
+				bprm->e_uid = current->uid;
+				bprm->e_gid = current->gid;
+			}
+			if (!capable (CAP_SETPCAP)) {
+				new_permitted = cap_intersect (new_permitted,
+							current->cap_permitted);
+			}
 		}
 	}
 
 	current->suid = current->euid = current->fsuid = bprm->e_uid;
 	current->sgid = current->egid = current->fsgid = bprm->e_gid;
 
-	if (!cap_issubset (new_permitted, current->cap_permitted)) {
-		current->mm->dumpable = 0;
-
-		if (must_not_trace_exec (current) && !capable (CAP_SETPCAP)) {
-			new_permitted = cap_intersect (new_permitted,
-						       current->
-						       cap_permitted);
-		}
-	}
-
 	/* For init, we want to retain the capabilities set
 	 * in the init_task struct. Thus we skip the usual
 	 * capability rules */
@@ -167,7 +154,6 @@
 	}
 
 	/* AUD: Audit candidate if current->cap_effective is set */
-	task_unlock(current);
 
 	current->keep_capabilities = 0;
 }
--- linux-2.6.5-mm5/security/dummy.c.ptlock	2004-04-21 08:56:00.608886504 -0700
+++ linux-2.6.5-mm5/security/dummy.c	2004-04-21 09:14:57.345076336 -0700
@@ -171,21 +171,12 @@
 	return;
 }
 
-static inline int must_not_trace_exec (struct task_struct *p)
+static void dummy_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
 {
-	return ((p->ptrace & PT_PTRACED) && !(p->ptrace & PT_PTRACE_CAP))
-		|| atomic_read(&p->fs->count) > 1
-		|| atomic_read(&p->files->count) > 1
-		|| atomic_read(&p->sighand->count) > 1;
-}
-
-static void dummy_bprm_apply_creds (struct linux_binprm *bprm)
-{
-	task_lock(current);
 	if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) {
 		current->mm->dumpable = 0;
 
-		if (must_not_trace_exec(current) && !capable(CAP_SETUID)) {
+		if (unsafe && !capable(CAP_SETUID)) {
 			bprm->e_uid = current->uid;
 			bprm->e_gid = current->gid;
 		}
@@ -193,8 +184,6 @@
 
 	current->suid = current->euid = current->fsuid = bprm->e_uid;
 	current->sgid = current->egid = current->fsgid = bprm->e_gid;
-
-	task_unlock(current);
 }
 
 static int dummy_bprm_set_security (struct linux_binprm *bprm)

       reply	other threads:[~2004-04-21 20:37 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <fa.n7n31hd.1k7ce37@ifi.uio.no>
     [not found] ` <fa.f9m11dm.206fg4@ifi.uio.no>
2004-04-21 20:36   ` Andy Lutomirski [this message]
     [not found] <20040421010621.L22989@build.pdx.osdl.net>
2004-04-21 17:27 ` compute_creds fixup in -mm Andy Lutomirski
2004-04-21 18:13   ` Stephen Smalley
2004-04-21 18:28     ` Chris Wright
2004-04-21 18:42       ` Stephen Smalley
2004-04-21 18:54         ` Chris Wright
2004-04-21 19:37         ` Andy Lutomirski
2004-04-21 20:10           ` Stephen Smalley
2004-04-21 19:07   ` Chris Wright

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=4086DB62.4000609@myrealbox.com \
    --to=luto@myrealbox.com \
    --cc=akpm@osdl.org \
    --cc=chrisw@osdl.org \
    --cc=jmorris@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sds@epoch.ncsc.mil \
    --cc=torvalds@osdl.org \
    /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.