Subject: WARNING: internal execve(2) change may cause lossage
To: None <tech-kern@NetBSD.ORG>
From: Charles M. Hannum <firstname.lastname@example.org>
Date: 09/11/1997 18:56:05
I just noticed (and fixed) a bug that was introduced in execve(2)
nearly 3.5 years ago. This is not a bug that most people would
notice; however, *fixing* it *may* break things. If you suddenly
observe programs failing to start up correctly (in particular,
executables running under emulation), this may be why.
The problem is that execve(2) may be expected to leave different
values in the process's registers than a normal system call would.
Thus, *setregs() was supposed to modify the registers, and
sys_execve() was supposed to return EJUSTRETURN, so that the system
call glue does not modify the registers again. However, someone (who
shall remain nameless) modified execve(2) to return 0, thus causing
the system call glue to put the values in retval into the registers
normally used for return values.
Not surprisingly, this caused cascaded lossage. In addition to the
*setregs() interface being kluged to pass down retval, at least one
bug was caused by this; the Alpha port uses the same register to pass
ps_strings to the process as it uses to store the `system called
errored' flag (usually the carry flag on other ports), and ps_strings
always ended up being null (and thus the default was used, so nobody
Anyway, as of today, *setregs() no longer takes a retval argument,
and sys_execve() once again returns EJUSTRETURN.
The practical effect of this is that some registers which used to be
initialized to 0, arguably by accident, may no longer be initialized.
I don't believe that any NetBSD executables rely on this, but some
emulated executables may.
(Aside: Arguably, all registers should be initialized on process
startup, but that's not what we've historically done. Perhaps it's
time to fix that.)