Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 Mar 2015 00:10:04 +0000 (UTC)
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r280130 - in head/sys: compat/linux kern security/audit security/mac security/mac_lomac sys
Message-ID:  <201503160010.t2G0A43G022898@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjg
Date: Mon Mar 16 00:10:03 2015
New Revision: 280130
URL: https://svnweb.freebsd.org/changeset/base/280130

Log:
  cred: add proc_set_cred helper
  
  The goal here is to provide one place altering process credentials.
  
  This eases debugging and opens up posibilities to do additional work when such
  an action is performed.

Modified:
  head/sys/compat/linux/linux_misc.c
  head/sys/compat/linux/linux_uid16.c
  head/sys/kern/init_main.c
  head/sys/kern/kern_exec.c
  head/sys/kern/kern_exit.c
  head/sys/kern/kern_fork.c
  head/sys/kern/kern_jail.c
  head/sys/kern/kern_loginclass.c
  head/sys/kern/kern_prot.c
  head/sys/kern/sys_capability.c
  head/sys/security/audit/audit_syscalls.c
  head/sys/security/mac/mac_syscalls.c
  head/sys/security/mac_lomac/mac_lomac.c
  head/sys/sys/ucred.h

Modified: head/sys/compat/linux/linux_misc.c
==============================================================================
--- head/sys/compat/linux/linux_misc.c	Sun Mar 15 23:40:50 2015	(r280129)
+++ head/sys/compat/linux/linux_misc.c	Mon Mar 16 00:10:03 2015	(r280130)
@@ -1138,7 +1138,7 @@ linux_setgroups(struct thread *td, struc
 		newcred->cr_ngroups = 1;
 
 	setsugid(p);
-	p->p_ucred = newcred;
+	proc_set_cred(p, newcred);
 	PROC_UNLOCK(p);
 	crfree(oldcred);
 	error = 0;

Modified: head/sys/compat/linux/linux_uid16.c
==============================================================================
--- head/sys/compat/linux/linux_uid16.c	Sun Mar 15 23:40:50 2015	(r280129)
+++ head/sys/compat/linux/linux_uid16.c	Mon Mar 16 00:10:03 2015	(r280130)
@@ -213,7 +213,7 @@ linux_setgroups16(struct thread *td, str
 		newcred->cr_ngroups = 1;
 
 	setsugid(td->td_proc);
-	p->p_ucred = newcred;
+	proc_set_cred(p, newcred);
 	PROC_UNLOCK(p);
 	crfree(oldcred);
 	error = 0;

Modified: head/sys/kern/init_main.c
==============================================================================
--- head/sys/kern/init_main.c	Sun Mar 15 23:40:50 2015	(r280129)
+++ head/sys/kern/init_main.c	Mon Mar 16 00:10:03 2015	(r280130)
@@ -432,6 +432,7 @@ proc0_init(void *dummy __unused)
 {
 	struct proc *p;
 	struct thread *td;
+	struct ucred *newcred;
 	vm_paddr_t pageablemem;
 	int i;
 
@@ -508,19 +509,20 @@ proc0_init(void *dummy __unused)
 	callout_init(&td->td_slpcallout, CALLOUT_MPSAFE);
 
 	/* Create credentials. */
-	p->p_ucred = crget();
-	p->p_ucred->cr_ngroups = 1;	/* group 0 */
-	p->p_ucred->cr_uidinfo = uifind(0);
-	p->p_ucred->cr_ruidinfo = uifind(0);
-	p->p_ucred->cr_prison = &prison0;
-	p->p_ucred->cr_loginclass = loginclass_find("default");
+	newcred = crget();
+	newcred->cr_ngroups = 1;	/* group 0 */
+	newcred->cr_uidinfo = uifind(0);
+	newcred->cr_ruidinfo = uifind(0);
+	newcred->cr_prison = &prison0;
+	newcred->cr_loginclass = loginclass_find("default");
+	proc_set_cred(p, newcred);
 #ifdef AUDIT
-	audit_cred_kproc0(p->p_ucred);
+	audit_cred_kproc0(newcred);
 #endif
 #ifdef MAC
-	mac_cred_create_swapper(p->p_ucred);
+	mac_cred_create_swapper(newcred);
 #endif
-	td->td_ucred = crhold(p->p_ucred);
+	td->td_ucred = crhold(newcred);
 
 	/* Create sigacts. */
 	p->p_sigacts = sigacts_alloc();
@@ -836,7 +838,7 @@ create_init(const void *udata __unused)
 #ifdef AUDIT
 	audit_cred_proc1(newcred);
 #endif
-	initproc->p_ucred = newcred;
+	proc_set_cred(initproc, newcred);
 	PROC_UNLOCK(initproc);
 	sx_xunlock(&proctree_lock);
 	crfree(oldcred);

Modified: head/sys/kern/kern_exec.c
==============================================================================
--- head/sys/kern/kern_exec.c	Sun Mar 15 23:40:50 2015	(r280129)
+++ head/sys/kern/kern_exec.c	Mon Mar 16 00:10:03 2015	(r280130)
@@ -725,7 +725,7 @@ interpret:
 		 */
 		change_svuid(newcred, newcred->cr_uid);
 		change_svgid(newcred, newcred->cr_gid);
-		p->p_ucred = newcred;
+		proc_set_cred(p, newcred);
 	} else {
 		if (oldcred->cr_uid == oldcred->cr_ruid &&
 		    oldcred->cr_gid == oldcred->cr_rgid)
@@ -751,7 +751,7 @@ interpret:
 			PROC_LOCK(p);
 			change_svuid(newcred, newcred->cr_uid);
 			change_svgid(newcred, newcred->cr_gid);
-			p->p_ucred = newcred;
+			proc_set_cred(p, newcred);
 		}
 	}
 

Modified: head/sys/kern/kern_exit.c
==============================================================================
--- head/sys/kern/kern_exit.c	Sun Mar 15 23:40:50 2015	(r280129)
+++ head/sys/kern/kern_exit.c	Mon Mar 16 00:10:03 2015	(r280130)
@@ -916,7 +916,7 @@ proc_reap(struct thread *td, struct proc
 	 * Free credentials, arguments, and sigacts.
 	 */
 	crfree(p->p_ucred);
-	p->p_ucred = NULL;
+	proc_set_cred(p, NULL);
 	pargs_drop(p->p_args);
 	p->p_args = NULL;
 	sigacts_free(p->p_sigacts);

Modified: head/sys/kern/kern_fork.c
==============================================================================
--- head/sys/kern/kern_fork.c	Sun Mar 15 23:40:50 2015	(r280129)
+++ head/sys/kern/kern_fork.c	Mon Mar 16 00:10:03 2015	(r280130)
@@ -410,7 +410,8 @@ do_fork(struct thread *td, int flags, st
 	bzero(&p2->p_startzero,
 	    __rangeof(struct proc, p_startzero, p_endzero));
 
-	p2->p_ucred = crhold(td->td_ucred);
+	crhold(td->td_ucred);
+	proc_set_cred(p2, td->td_ucred);
 
 	/* Tell the prison that we exist. */
 	prison_proc_hold(p2->p_ucred->cr_prison);
@@ -869,7 +870,7 @@ fork1(struct thread *td, int flags, int 
 	 * XXX: This is ugly; when we copy resource usage, we need to bump
 	 *      per-cred resource counters.
 	 */
-	newproc->p_ucred = p1->p_ucred;
+	proc_set_cred(newproc, p1->p_ucred);
 
 	/*
 	 * Initialize resource accounting for the child process.

Modified: head/sys/kern/kern_jail.c
==============================================================================
--- head/sys/kern/kern_jail.c	Sun Mar 15 23:40:50 2015	(r280129)
+++ head/sys/kern/kern_jail.c	Mon Mar 16 00:10:03 2015	(r280130)
@@ -2445,7 +2445,7 @@ do_jail_attach(struct thread *td, struct
 	setsugid(p);
 	crcopy(newcred, oldcred);
 	newcred->cr_prison = pr;
-	p->p_ucred = newcred;
+	proc_set_cred(p, newcred);
 	PROC_UNLOCK(p);
 #ifdef RACCT
 	racct_proc_ucred_changed(p, oldcred, newcred);

Modified: head/sys/kern/kern_loginclass.c
==============================================================================
--- head/sys/kern/kern_loginclass.c	Sun Mar 15 23:40:50 2015	(r280129)
+++ head/sys/kern/kern_loginclass.c	Mon Mar 16 00:10:03 2015	(r280130)
@@ -221,7 +221,7 @@ sys_setloginclass(struct thread *td, str
 	PROC_LOCK(p);
 	oldcred = crcopysafe(p, newcred);
 	newcred->cr_loginclass = newlc;
-	p->p_ucred = newcred;
+	proc_set_cred(p, newcred);
 	PROC_UNLOCK(p);
 #ifdef RACCT
 	racct_proc_ucred_changed(p, oldcred, newcred);

Modified: head/sys/kern/kern_prot.c
==============================================================================
--- head/sys/kern/kern_prot.c	Sun Mar 15 23:40:50 2015	(r280129)
+++ head/sys/kern/kern_prot.c	Mon Mar 16 00:10:03 2015	(r280130)
@@ -579,7 +579,7 @@ sys_setuid(struct thread *td, struct set
 		change_euid(newcred, uip);
 		setsugid(p);
 	}
-	p->p_ucred = newcred;
+	proc_set_cred(p, newcred);
 	PROC_UNLOCK(p);
 #ifdef RACCT
 	racct_proc_ucred_changed(p, oldcred, newcred);
@@ -638,7 +638,7 @@ sys_seteuid(struct thread *td, struct se
 		change_euid(newcred, euip);
 		setsugid(p);
 	}
-	p->p_ucred = newcred;
+	proc_set_cred(p, newcred);
 	PROC_UNLOCK(p);
 	uifree(euip);
 	crfree(oldcred);
@@ -738,7 +738,7 @@ sys_setgid(struct thread *td, struct set
 		change_egid(newcred, gid);
 		setsugid(p);
 	}
-	p->p_ucred = newcred;
+	proc_set_cred(p, newcred);
 	PROC_UNLOCK(p);
 	crfree(oldcred);
 	return (0);
@@ -784,7 +784,7 @@ sys_setegid(struct thread *td, struct se
 		change_egid(newcred, egid);
 		setsugid(p);
 	}
-	p->p_ucred = newcred;
+	proc_set_cred(p, newcred);
 	PROC_UNLOCK(p);
 	crfree(oldcred);
 	return (0);
@@ -864,7 +864,7 @@ kern_setgroups(struct thread *td, u_int 
 		crsetgroups_locked(newcred, ngrp, groups);
 	}
 	setsugid(p);
-	p->p_ucred = newcred;
+	proc_set_cred(p, newcred);
 	PROC_UNLOCK(p);
 	crfree(oldcred);
 	return (0);
@@ -927,7 +927,7 @@ sys_setreuid(register struct thread *td,
 		change_svuid(newcred, newcred->cr_uid);
 		setsugid(p);
 	}
-	p->p_ucred = newcred;
+	proc_set_cred(p, newcred);
 	PROC_UNLOCK(p);
 #ifdef RACCT
 	racct_proc_ucred_changed(p, oldcred, newcred);
@@ -994,7 +994,7 @@ sys_setregid(register struct thread *td,
 		change_svgid(newcred, newcred->cr_groups[0]);
 		setsugid(p);
 	}
-	p->p_ucred = newcred;
+	proc_set_cred(p, newcred);
 	PROC_UNLOCK(p);
 	crfree(oldcred);
 	return (0);
@@ -1068,7 +1068,7 @@ sys_setresuid(register struct thread *td
 		change_svuid(newcred, suid);
 		setsugid(p);
 	}
-	p->p_ucred = newcred;
+	proc_set_cred(p, newcred);
 	PROC_UNLOCK(p);
 #ifdef RACCT
 	racct_proc_ucred_changed(p, oldcred, newcred);
@@ -1147,7 +1147,7 @@ sys_setresgid(register struct thread *td
 		change_svgid(newcred, sgid);
 		setsugid(p);
 	}
-	p->p_ucred = newcred;
+	proc_set_cred(p, newcred);
 	PROC_UNLOCK(p);
 	crfree(oldcred);
 	return (0);
@@ -1953,6 +1953,31 @@ cred_update_thread(struct thread *td)
 		crfree(cred);
 }
 
+/*
+ * Change process credentials.
+ * Callers are responsible for providing the reference for current credentials
+ * and for freeing old ones.
+ *
+ * Process has to be locked except when it does not have credentials (as it
+ * should not be visible just yet) or when newcred is NULL (as this can be
+ * only used when the process is about to be freed, at which point it should
+ * not be visible anymore).
+ */
+struct ucred *
+proc_set_cred(struct proc *p, struct ucred *newcred)
+{
+	struct ucred *oldcred;
+
+	if (newcred == NULL)
+		MPASS(p->p_state == PRS_ZOMBIE);
+	else if (p->p_ucred != NULL)
+		PROC_LOCK_ASSERT(p, MA_OWNED);
+
+	oldcred = p->p_ucred;
+	p->p_ucred = newcred;
+	return (oldcred);
+}
+
 struct ucred *
 crcopysafe(struct proc *p, struct ucred *cr)
 {

Modified: head/sys/kern/sys_capability.c
==============================================================================
--- head/sys/kern/sys_capability.c	Sun Mar 15 23:40:50 2015	(r280129)
+++ head/sys/kern/sys_capability.c	Mon Mar 16 00:10:03 2015	(r280130)
@@ -104,7 +104,7 @@ sys_cap_enter(struct thread *td, struct 
 	PROC_LOCK(p);
 	oldcred = crcopysafe(p, newcred);
 	newcred->cr_flags |= CRED_FLAG_CAPMODE;
-	p->p_ucred = newcred;
+	proc_set_cred(p, newcred);
 	PROC_UNLOCK(p);
 	crfree(oldcred);
 	return (0);

Modified: head/sys/security/audit/audit_syscalls.c
==============================================================================
--- head/sys/security/audit/audit_syscalls.c	Sun Mar 15 23:40:50 2015	(r280129)
+++ head/sys/security/audit/audit_syscalls.c	Mon Mar 16 00:10:03 2015	(r280130)
@@ -461,7 +461,7 @@ sys_auditon(struct thread *td, struct au
 		    udata.au_aupinfo.ap_mask.am_success;
 		newcred->cr_audit.ai_mask.am_failure =
 		    udata.au_aupinfo.ap_mask.am_failure;
-		tp->p_ucred = newcred;
+		proc_set_cred(tp, newcred);
 		PROC_UNLOCK(tp);
 		crfree(oldcred);
 		break;
@@ -600,7 +600,7 @@ sys_setauid(struct thread *td, struct se
 	if (error)
 		goto fail;
 	newcred->cr_audit.ai_auid = id;
-	td->td_proc->p_ucred = newcred;
+	proc_set_cred(td->td_proc, newcred);
 	PROC_UNLOCK(td->td_proc);
 	crfree(oldcred);
 	return (0);
@@ -671,7 +671,7 @@ sys_setaudit(struct thread *td, struct s
 	newcred->cr_audit.ai_termid.at_addr[0] = ai.ai_termid.machine;
 	newcred->cr_audit.ai_termid.at_port = ai.ai_termid.port;
 	newcred->cr_audit.ai_termid.at_type = AU_IPv4;
-	td->td_proc->p_ucred = newcred;
+	proc_set_cred(td->td_proc, newcred);
 	PROC_UNLOCK(td->td_proc);
 	crfree(oldcred);
 	return (0);
@@ -728,7 +728,7 @@ sys_setaudit_addr(struct thread *td, str
 	if (error)
 		goto fail;
 	newcred->cr_audit = aia;
-	td->td_proc->p_ucred = newcred;
+	proc_set_cred(td->td_proc, newcred);
 	PROC_UNLOCK(td->td_proc);
 	crfree(oldcred);
 	return (0);

Modified: head/sys/security/mac/mac_syscalls.c
==============================================================================
--- head/sys/security/mac/mac_syscalls.c	Sun Mar 15 23:40:50 2015	(r280129)
+++ head/sys/security/mac/mac_syscalls.c	Mon Mar 16 00:10:03 2015	(r280130)
@@ -208,7 +208,7 @@ sys___mac_set_proc(struct thread *td, st
 	setsugid(p);
 	crcopy(newcred, oldcred);
 	mac_cred_relabel(newcred, intlabel);
-	p->p_ucred = newcred;
+	proc_set_cred(p, newcred);
 
 	PROC_UNLOCK(p);
 	crfree(oldcred);

Modified: head/sys/security/mac_lomac/mac_lomac.c
==============================================================================
--- head/sys/security/mac_lomac/mac_lomac.c	Sun Mar 15 23:40:50 2015	(r280129)
+++ head/sys/security/mac_lomac/mac_lomac.c	Mon Mar 16 00:10:03 2015	(r280130)
@@ -2255,7 +2255,7 @@ lomac_thread_userret(struct thread *td)
 		crcopy(newcred, oldcred);
 		crhold(newcred);
 		lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label));
-		p->p_ucred = newcred;
+		proc_set_cred(p, newcred);
 		crfree(oldcred);
 		dodrop = 1;
 	out:

Modified: head/sys/sys/ucred.h
==============================================================================
--- head/sys/sys/ucred.h	Sun Mar 15 23:40:50 2015	(r280129)
+++ head/sys/sys/ucred.h	Mon Mar 16 00:10:03 2015	(r280130)
@@ -106,6 +106,7 @@ void	crcopy(struct ucred *dest, struct u
 struct ucred	*crcopysafe(struct proc *p, struct ucred *cr);
 struct ucred	*crdup(struct ucred *cr);
 void	cred_update_thread(struct thread *td);
+struct ucred	*proc_set_cred(struct proc *p, struct ucred *cr);
 void	crfree(struct ucred *cr);
 struct ucred	*crget(void);
 struct ucred	*crhold(struct ucred *cr);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201503160010.t2G0A43G022898>