[TUHS] the first busybox

Steffen Nurpmeso via TUHS tuhs at tuhs.org
Fri Oct 23 08:13:11 AEST 2026


segaloco via TUHS wrote in
 <JMkX4SbfymkIGY4JE0ACtNGDhvHm4oFfsqlGOzLFhDLI7XiK67-Lc3mkHwVZaBIazjGVblS\
 LFoQa672V60vwYNQxc2B-dbbbpNTJQk0GPqo=@protonmail.com>:
 |On Thursday, October 22nd, 2026 at 14:23, Steffen Nurpmeso via TUHS \
 |<tuhs at tuhs.org> wrote:
 |> And today "they" ("we") are about to add some getexecpath() into
 |> standards, and certain BSDs have week long runs to remove argv[0]
 |> in favour of that function in all programs (at least daemons) of
 |> the base system.  (Not to distress anyone again because of my
 |> shock not to ever have though about that argv can be NULL.)
 |
 |Interesting, had a double take at this one.  Took a look at ANSI and

Too much honour.  I think we were once there in the past already.
K&R says in "5.10 Command-line Arguments" 

  By convention, argv[0] is the name by which the program was
  invoked, so argc is at least 1.

But in 2021 there was CVE-2021-4034 --- through execve(2) one
could enforce another condition, and that caused quite some
trouble.  Now, if i ask Google AI it says

  Abstract: OS Handling of argc == 0 (Post-PwnKit)

  The PwnKit vulnerability (CVE-2021-4034) exposed a critical
  security flaw rooted in how operating system kernels handle
  processes executed with an empty argument vector (argc ==
  0). When a binary is executed via execve() with no arguments,
  a memory overlap can occur between the argument array (argv) and
  the environment array (envp), allowing local attackers to inject
  malicious environment variables into high-privilege SUID-root
  binaries.  Operating systems addressed this architectural risk
  differently:

      Linux Kernel:
        Historically permitted argc == 0. To prevent
        application-level crashes while eliminating the
        vulnerability, the Linux kernel was patched to proactively
        inject an empty string ("") as the first argument whenever
        a process attempts to execute with an empty argv. This
        forces argc to become 1 in user space, safely neutralizing
        the out-of-bounds memory read.
      OpenBSD:
        Was inherently immune to this vector because its kernel
        strictly enforces POSIX compliance at the system call
        level. OpenBSD’s execve() implementation rejects empty
        argument vectors outright and returns an error if at least
        one non-null argument is not present.
      FreeBSD:
        While traditionally less vulnerable due to a more
        restrictive memory mapping behavior and the absence of
        pkexec as a default SUID binary, FreeBSD developers
        audited and hardened the kernel's argument validation
        routines (kern_exec.c) to ensure robust checking of
        argument pointers during process creation.

 |indeed it looks like this can happen.  ANSI C says argc must be
 |non-negative, but can be zero apparently.  Only if it is non-zero then
 |is argv[0] guaranteed to be a pointer to a string representation of the
 |name of the invoked program.  Was this made flexible for environments in
 |hosted environments in which there is no way (or desire) to pass this
 |information to main()?  I could see this being the case for freestanding
 |environments, but an extension like POSIX I imagine wouldn't be layered
 |on top of a freestanding environment anyway.
 |
 |That said, I looked further and interestingly the April 1986 Trial Use
 |copy of POSIX 1003.1 in section 3.1.2.2 gives the main(argc, argv)
 |signature with a note:
 |
 |> where argc is the argument count (one or greater), argv is an array
 |> of character pointers to the arguments themselves...
 |
 |whereas the final from 1989 gives:
 |
 |> where argc is the argument count and argv is an array of character
 |> pointers to the arguments themselves.
 |
 |So the "one or greater" note is dropped.  Either way, both then go on to
 |say:
 |
 |> The value in argv[0] should point to a filename that is associated
 |> with the process being started by one of the exec functions.
 |
 |So is this to imply along the way to POSIX they acknowledged that ANSI C
 |does not guarantee argc > 0 and argv != NULL and decided to align?

I would never overestimate it, you surely read too much in that
only.

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)


More information about the TUHS mailing list