Random rants by some guy.
I doubt I'll be able to present anything advanced or original as far as concepts go. I'll definitely write about stuff which annoys me and does not have a solid write-up I'm aware of.
As you can see my English is even worse than my code, corrections are most welcome.
Monday, February 8, 2016
kernel game #2
Consider a kernel where processes are represented with struct proc objects. The kernel implements unix-like interfaces and works with multiple CPUs.
The following syscall is provided: int sys_fork(void) { struct proc *p; int error;
That is, if error is 0 we know forking succeeded. in which case the functions stores the pid found in the object. Otherwise non-zero error value is returned and the retval field is not inspected.
Why would this code be incorrect?
This boils down to the question: what guarantees stability of the struct proc object we got the pointer to?
The new process can immediately exit and e.g. be waited on by another thread in the forking process, or be automatically reaped if SIGCHLD is ignored. Thus by the time we reach the p->pid deference, the process could have exited and the object could be freed or even reused.
This can be combated by having a lock or a reference which postpones destruction of the object. The lock would be released (or reference dropped) after the read, which would allow the struct proc object to be freed.
The code is highly suspicious specifically because there is nothing being done with the object after the deference, calling into question whether locks/references (if any) are correctly released or if the object is guaranteed to be valid in the first place.
An alternative fix would change the API to return the pid as opposed to the pointer.
No comments:
Post a Comment