Subject: panic in sysctl(2) (#353) Index: sys/kern_sysctl.c 2.11BSD Description: Using sysctl(2) to retrieve the process table can panic when a process in the state SZOMB (a zombie process) is encountered. Repeat-By: Have a zombie process present in the system and then run a program which does something similar to: int mib[3], i, size; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_ALL; i = sysctl(mib, 3, NULL, &size, NULL, 0); Fix: Under 2.11BSD several pieces of information about a process are NOT kept in the "proc table". Some information about a process is kept in the 'u area' (which can be swapped out with the process). In 4.4BSD, from where sysctl() was ported, there is effectively no 'u area' because all process information was moved into the proc table (mushrooming the proc table entry size but what's a couple hundred kb of kernel address space these days?) and thus even 'zombie' processes have a 'real uid' and so on. When the process table is retrieved via sysctl() the 'real uid', 'controlling terminal', and 'controlling terminal device number' are obtained from the 'u area' (by reading the swap area if the process is swapped out at the time) of a process rather than the 'proc table'. The problem was that I forgot zombies do not have a 'u area' associated with them. Referring to the 'u area' of a zombie will give indeterminate results ranging from incorrect/bogus data to a kernel panic. This problem was spotted when testing the 'identd' server. Sysctl() is used by the 'libident' (the client side library of 'identd') to retrieve process table information and one of the test programs elicited a kernel panic rather than the user id associated with a network connection. Oops ;) When a 'zombie' process is encounted now the "nobody" (-2) uid is returned and the controlling terminal is set to 'NODEV' (-1). Cut where indicated, saving to a file (/tmp/353) and then: patch -p0 < /tmp/353 cd /sys/YOUR_KERNEL make make install reboot You should, if you keep a spare GENERIC kernel around, rebuild the generic kernel too: cd /sys/GENERIC make mv unix /genunix As always these, and all previous updates to 2.11BSD, are available via anonymous FTP to either FTP.IIPO.GTEGSC.COM or MOE.2BSD.COM in the directory /pub/2.11BSD. ========================cut here======================= *** /sys/sys/kern_sysctl.c.old Sun Oct 29 00:08:01 1995 --- /sys/sys/kern_sysctl.c Fri Dec 13 22:44:26 1996 *************** *** 33,39 **** * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ! * @(#)kern_sysctl.c 8.4.3 (2.11BSD GTE) 1995/10/29 */ /* --- 33,39 ---- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ! * @(#)kern_sysctl.c 8.4.4 (2.11BSD GTE) 1996/12/13 */ /* *************** *** 994,999 **** --- 994,1006 ---- struct tty *ttyp; struct user *up; + if (p->p_stat == SZOMB) + { + *rup = (uid_t)-2; + *ttp = NULL; + *tdp = NODEV; + return; + } if (p->p_flag & SLOAD) { mapseg5(p->p_addr, (((USIZE - 1) << 8) | RO)); *** /VERSION.old Mon Dec 9 21:59:50 1996 --- /VERSION Mon Dec 16 19:57:22 1996 *************** *** 1,4 **** ! Current Patch Level: 352 2.11 BSD ============ --- 1,4 ---- ! Current Patch Level: 353 2.11 BSD ============