2023-06-05
The Linux kernel will fix some peculiar argv usage in execve(2)
Suppose, not entirely hypothetically, that your Linux kernel has logged a kernel message to the effect of:
process 'syscall.test' launched '/dev/null' with NULL argv: empty string added
(This one was triggered by building Go from source.)
In a conventional call to execve(2), the argv
argument is a pointer to an array that will become the executed
program's argv
, with the array terminated with a NULL element (in
the grand C fashion, there is no explicit 'length' parameter passed).
The first (0th) element of this array is the nominal name of the
program and the remainder are the command line arguments. Since all
programs have some name, this array is normally at least one element
long. However, the execve(2) interface (plus C) allows for two
additional variations on the value of argv here.
First, you can pass in a zero-length argv (ie, where argv[0] is
NULL), in which case the executed program will have an argv[0] that
is NULL. A variety of programs will then be unhappy with you, as
people discovered in CVE-2021-4034.
This option exists more or less because this API was easy back
in the old days of Unix. Second, you can
pass in a NULL argv
argument to execve(2). This has the same net
effect (the exec'd program has no arguments and no argv[0] name for
itself), but it's probably even more unexpected since you can't
even dereference argv to check argv[0]. Probably any number of
programs will fault at this point (although they have a chance if
they check argc first, since argc will be 0 here).
What this Linux kernel message is saying is that the kernel detected an execve(2) with either a NULL argv or a zero-length argv, and it's changing the situation by adding an empty string as argv[0]. The specific change dates to early 2022, in exec: Force single empty string when argv is empty, and was first included (in the mainline) in kernel 5.18. The commit message has a long and informative discussion, and in fact this is a reaction to CVE-2021-4034.
This particular message is produced only once per kernel boot, so you're probably not going to see it very often. Since I build Go from source regularly, this is reassuring.
(Although the message talks about 'with NULL argv', it really means that there are no arguments; you get the same message if you call execve(2) with a zero-length argv array as if you call it with a genuinely NULL argv.)