5 ms·
I'm surprised that the Linux kernel doesn't prevent execve with argc == 0. I know a lot of programs that would break on that too.
by Jasper_ 5y ago
I'm surprised that the Linux kernel doesn't prevent execve with argc == 0. I know a lot of programs that would break on that too.
- Retr0id 5y agoChanging that now would break the core tenet of "never break userspace".
- mmis1000 5y agoI actually wonder what it could actually break. argv[0] always exists in normal means, it is either physical path of the executable or soft link position. Without accidents like run a program from code and forget about passing argv. That couldn't happen at all. And in fact, most cross platform program or shell even just assume argv[0] is the same as executable path (and don't give you a option to change it, because it is not possible on all platforms).
- Retr0id 5y agoI have personally written (lazy) code that calls execve with argv=NULL. So it'd break that.
- westurner 5y agoSo, all C/C++ code on {Linux,} but not {OpenBSD,} that handles argc/argv needs to at least just exit() on the conditions added by the like 8 lines in main() in the patch for this issue?: https://gitlab.freedesktop.org/polkit/polkit/-/commit/a2bf5c9c83b6ae46cbd5c779d3055bff81ded683 https://gitlab.freedesktop.org/polkit/polkit/-/commit/a2bf5c... if (argc < 1) { exit(126); } if (argv[n] == NULL) { exit(128) } // But this could never ever happen? if (argv == NULL)
- mmis1000 5y agoI did that once, but the target is a shell. Shells relies on argv[0] to determine what it is running as (login shell have prefix on argv[0]). So it end up blew up in a funny way. After a bit google I realize I need to repeat the file path by myself on *nix. In windows, the spawn equivalent take a long string, anything after file path is argument. So it can't be a bug since day 1.
- mananaysiempre 5y ago> In windows, the spawn equivalent take a long string, anything after file path is argument. The tradeoff being that even reliably getting a Windows program in C to receive a given value in argv[] is awful[1], and the full rules for what happens if you’re unfortunate enough to need to pass through the shell are truly horrendous[2] (as well as, of course, nearly undocumented). Oh, and there is literally no way to pass arguments through in a batch file[3] (i.e. no reliable equivalent to "$@"). The reason is that command lines being dumb strings (as they are in DOS and consequently Windows) means that there are at least two places where command-line parsing needs to happen: in the shell, to detect shell syntax, including simply knowing where the command ends; and in the program (C runtime library startup or equivalent), to separate, unquote, and unescape the string into an arguments array. Thus there are at least two sets of escaping rules in play at the same time, which will inevitably diverge. (In Windows there are something like three and a half, given that executing from a batch file adds an additional layer of textual preprocessing and delayed expansion uses slightly different rules, but that is not inherent in the design choice, it’s just braindamage.) I actually find this an interesting design problem (and have commented on it before[4]), because while the depths of insanity in the Unix approach (the shell tokenizes and globs) aren’t quite as unfathomable, the touch ./-rf; rm * problem that it implies still feels like something that shouldn’t happen, and I just can’t see an interesting intermediate point between those that wouldn’t substantially complicate the shell-to-entry-point interface. [1] https://daviddeley.com/autohotkey/parameters/parameters.htm#WIN https://daviddeley.com/autohotkey/parameters/parameters.htm#... [2] https://stackoverflow.com/a/4095133 https://stackoverflow.com/a/4095133 [3] https://stackoverflow.com/a/51794454 https://stackoverflow.com/a/51794454 [4] https://news.ycombinator.com/item?id=29161630 https://news.ycombinator.com/item?id=29161630
- GoblinSlayer 5y agoWhere it's not possible? It's possible at least on all unixes and windows.
- tptacek 5y agoWhere is it not possible to execve(..., NULL, ...)? On every other Unix besides Linux, apparently.
- GoblinSlayer 5y agoI mean the claim about impossibility to replace argv[0], which is certainly required on unixes by the login shell.
- mmis1000 5y agoUmmm. On windows, it seems you can make it something else, but not null it. Windows literally specify there will be at least one parameter in argv (argc is always big or equal to 1) https://docs.microsoft.com/en-us/cpp/cpp/main-function-command-line-args?view=msvc-170 https://docs.microsoft.com/en-us/cpp/cpp/main-function-comma...
- eternityforest 5y agoIs there a legitimate use for argc=0? Could they just change it behind the scenes to have a single name of the program argument if it's 0? Seems like a good use case for Android style API levels, but only if used very sparingly and with old ones not removed.
- tptacek 5y agoThere is not.
- terom 5y agoThis was one of the interesting details in the analysis: > however, we note that OpenBSD is not exploitable, because its kernel refuses to execve() a program if argc is 0.
- captn3m0 5y agoThere's a patch submitted for this: https://lore.kernel.org/lkml/20220126043947.10058-1-ariadne@dereferenced.org/T/ https://lore.kernel.org/lkml/20220126043947.10058-1-ariadne@...
- fulafel 5y agonitpick: execve/execvpe don't get passed argc, it's probably synthesized by libc init code. But the env/args data could indeed be sanity checked.