Subject: timing hole in process creation
To: None <tech-kern@netbsd.org>
From: David Laight <david@l8s.co.uk>
List: tech-kern
Date: 07/03/2002 21:19:52
I found this due to some extra sanity checks in some re-written code.
(I'll probably submit a PR for my changes when I've sorted the next
consequential change...)

It is possible for kernel code to access a 'proc' structure that
is only parially setup (by fork1).

In particular schedcpu() (kern/kern_synch.c) traverses the
'allprocs' list during the timer tick.

Now fork1() does:
	p2->p_stat = SIDL;			/* protect against others */
	p2->p_pid = nextpid;
	p2->p_exitsig = exitsig;		/* signal for parent on exit */
	p2->p_forw = p2->p_back = NULL;		/* shouldn't be necessary */
	LIST_INSERT_HEAD(&allproc, p2, p_list);
	LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash);
before zeroing the rest of the proc structure, or copying anything
from the parent.

Adding to the PIDHASH() list allows pfind() to look up the proc
structure by number.
Adding to the allproc list stops the pid being allocated by
another fork1() call, but also allows many bits of code
that want to look at 'all processes' to find the process.

I don't think that the proc structure should be locatable
by other code until MUCH later down the fork path.

What I'm not sure of is how far this can/should be deferred?
My guess is to just before the process is added to the
pgrp and child lists.

Obviously this is more important with a fully SMP system...

In any case schedcpu does need a check for p->p_state == SIDL
- or maybe add another list for processes being created
(cf zombproc).

Comments?


	David

-- 
David Laight: david@l8s.co.uk