Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 2 Aug 2015 00:11:57 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r286167 - head/sys/cddl/contrib/opensolaris/uts/common/dtrace
Message-ID:  <201508020011.t720Bvei018594@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Sun Aug  2 00:11:56 2015
New Revision: 286167
URL: https://svnweb.freebsd.org/changeset/base/286167

Log:
  Avoid dereferencing curthread->td_proc->p_cred in DTrace probe context.
  
  When a process is exiting, there is a narrow window where p_cred may be
  NULL while its threads are still executing. Specifically, the last thread
  to exit a process sets the process state to PRS_ZOMBIE with the proc
  spinlock held and then calls thread_exit(). thread_exit() drops the spin
  lock, permitting the process to be reaped and thus causing its cred struct
  to be released. However, the exiting thread may still cause DTrace probes
  to fire by calling sched_throw(), resulting in a double fault if such a
  probe enabling attempts to access the GID or UID DIF variables.
  
  The thread's cred reference is not susceptible to this race since it is not
  released until after the thread has exited.
  
  MFC after:	1 week

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c	Sun Aug  2 00:03:08 2015	(r286166)
+++ head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c	Sun Aug  2 00:11:56 2015	(r286167)
@@ -3510,7 +3510,6 @@ dtrace_dif_variable(dtrace_mstate_t *mst
 		 */
 		if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU))
 			return ((uint64_t)p0.p_cred->cr_uid);
-#endif
 
 		/*
 		 * It is always safe to dereference one's own t_procp pointer:
@@ -3522,6 +3521,9 @@ dtrace_dif_variable(dtrace_mstate_t *mst
 		 * credential, since this is never NULL after process birth.
 		 */
 		return ((uint64_t)curthread->t_procp->p_cred->cr_uid);
+#else
+		return ((uint64_t)curthread->td_ucred->cr_uid);
+#endif
 
 	case DIF_VAR_GID:
 		if (!dtrace_priv_proc(state))
@@ -3533,7 +3535,6 @@ dtrace_dif_variable(dtrace_mstate_t *mst
 		 */
 		if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU))
 			return ((uint64_t)p0.p_cred->cr_gid);
-#endif
 
 		/*
 		 * It is always safe to dereference one's own t_procp pointer:
@@ -3545,6 +3546,9 @@ dtrace_dif_variable(dtrace_mstate_t *mst
 		 * credential, since this is never NULL after process birth.
 		 */
 		return ((uint64_t)curthread->t_procp->p_cred->cr_gid);
+#else
+		return ((uint64_t)curthread->td_ucred->cr_gid);
+#endif
 
 	case DIF_VAR_ERRNO: {
 #ifdef illumos



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