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?