Subject: P_SUGID flag forgotten at fork() time
To: None <tech-security@NetBSD.ORG>
From: Luke Mewburn <lukem@connect.com.au>
List: tech-security
Date: 03/24/1997 00:26:57
I've been investigating some stuff in the way that the P_SUGID flag
works in NetBSD, and comparing with other systems ({Free,Open}BSD-current,
BSD/OS 2.0.1)

A refresher; P_SUGID has the following properties:
	* in execve(), is set if set[gu]id, reset otherwise
	* is set if set{,e,re}[ug]id() or setgroups() is called
	* if set, prevents a coredump
	* if set, prevents ptrace()

It appears from source examination that P_SUGID is forgotten at fork()
time. I have verified this by whipping up a test program that prints
the {e,}uid, forks and does the same thing. By making this setuid and
running it, you can examine the 'regs' file in the relevant dir in
procfs: if P_SUGID is set, it's not writable, otherwise it is. The
child is writable, the parent is not. Therefore, P_SUGID is forgotten
for the child even though it is setuid.

I believe that in /sys/kern/kern_fork.c (relative to 1.30) we need:

*** kern_fork.c.orig	Mon Mar 24 01:14:20 1997
--- kern_fork.c	Mon Mar 24 01:15:30 1997
***************
*** 195,200 ****
--- 195,201 ----
  	p2->p_emul = p1->p_emul;
  	if (p1->p_flag & P_PROFIL)
  		startprofclock(p2);
+ 	p2->p_flag |= (p1->p_flag & P_SUGID);
  	MALLOC(p2->p_cred, struct pcred *, sizeof(struct pcred),
  	    M_SUBPROC, M_WAITOK);
  	bcopy(p1->p_cred, p2->p_cred, sizeof(*p2->p_cred));

Objections to fixing this?