kern/108071: [PATCH] Panic in [sg]etpriority() due to NULL pointer deference

Xin LI delphij at tarsier.delphij.net
Thu Jan 18 03:10:22 UTC 2007


>Number:         108071
>Category:       kern
>Synopsis:       [PATCH] Panic in [sg]etpriority() due to NULL pointer deference
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jan 18 03:10:20 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Xin LI
>Release:        FreeBSD 6.2-RELEASE i386
>Organization:
The FreeBSD Project
>Environment:
System: FreeBSD tarsier.delphij.net 6.2-RELEASE FreeBSD 6.2-RELEASE #0: Fri Jan 12 12:23:27 CST 2007 delphij at tarsier.delphij.net:/usr/obj/usr/src/sys/TARSIER i386


>Description:
	There is a race between fork(2) and [sg]etpriority where when a
newly born process in allproc list, [sg]etpriority could end up with a
NULL deference which would lead to a panic.
>How-To-Repeat:
	The following shell script would demostrate the race and can easily
trigger panic with non-privileged user, on a multi-core system, in my case
Dell 2950:

--- demo.sh begins here ---
#!/bin/sh

P=0

while [ ${P} -lt 200 ];
do
        sleep 3 &
        renice +4 -u delphij &
        sleep 3 &
        renice +4 -u delphij &
        sleep 3 &
        renice +4 -u delphij &
        sleep 3 &
        renice +4 -u delphij &
        P=`expr ${P} + 1`
done
--- demo.sh ends here ---

>Fix:
	An easy fix for this would be to guard with PRS_NEW state
by just skipping it.  However, we are still looking for better
solution for the issue.

--- patch-kern_resource.c begins here ---
Index: kern_resource.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_resource.c,v
retrieving revision 1.164
diff -u -p -r1.164 kern_resource.c
--- kern_resource.c	6 Dec 2006 06:34:55 -0000	1.164
+++ kern_resource.c	18 Jan 2007 02:27:53 -0000
@@ -143,6 +143,8 @@ getpriority(td, uap)
 			uap->who = td->td_ucred->cr_uid;
 		sx_slock(&allproc_lock);
 		LIST_FOREACH(p, &allproc, p_list) {
+			if (p->p_state == PRS_NEW)
+				continue;
 			PROC_LOCK(p);
 			if (!p_cansee(td, p) &&
 			    p->p_ucred->cr_uid == uap->who) {
@@ -230,6 +232,8 @@ setpriority(td, uap)
 			uap->who = td->td_ucred->cr_uid;
 		sx_slock(&allproc_lock);
 		FOREACH_PROC_IN_SYSTEM(p) {
+			if (p->p_state == PRS_NEW)
+				continue;
 			PROC_LOCK(p);
 			if (p->p_ucred->cr_uid == uap->who &&
 			    !p_cansee(td, p)) {
--- patch-kern_resource.c ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list