3 ms·
argc = 0 is a bad idea? When did we enter into this insane parallel universe? When I first came across (argc, argv) a long long time ago I was befuddled by the
by stefan_ 5y ago
argc = 0 is a bad idea? When did we enter into this insane parallel universe?
When I first came across (argc, argv) a long long time ago I was befuddled by the choice of having argv[0] be something vaguely related to your binary, maybe the path to it. That seemed a very weird choice seeing how most programs have no use for that and now all the arguments you actually care about are shifted.
So now you have a patch to ensure argc is always 1. Only of course if you accept that there are programs that misbehave with argc=0, surely you must also accept there are programs that misbehave if argv[0] is not the program path? This is after all the convention that got you into this misery in the first place!
That's the moment the stupidity fully sets in. So now you write a patch to make sure argv[0] is really the path! Except just as we have discovered with this innocuous patch, you could write a dissertation on the question of "what exactly is meant with the program path" alone. And that really whoever was relying on some specific interpretation on the value of argv[0] would have been much better off with some other syscall to tell him what he was after.
- Someone 5y ago> When I first came across (argc, argv) a long long time ago I was befuddled by the choice of having argv[0] be something vaguely related to your binary, maybe the path to it. I’ve seen a Unix (¿maybe HP-UX?) that seemed to construct the argv strings by taking a copy of the entire command line and writing zero bytes at the end of each argument. I don’t think that’s too weird. Why do multiple allocations to make room for the strings if you know a reasonably tight upper limit to the number of bytes you need to store all of them? (Reasonably tight because the command line _could_ contain consecutive spaces and because of backspaces and quotes around arguments) On that OS, argv* strings also were writable, so programs could even replace those zeroes by spaces to, in many cases (I don’t remember how that worked with quoted arguments), get back the command line used to launch the program: for(i=1; i<argc; ++i) argv[i][-1] = ‘ ‘; printf(“%s\n”, argv[0]); (Yes, on top of, AFAIK, not being guaranteed to work by any standard, that’s undefined behavior in C, but it did work on that OS) So, I guess passing something resembling the executable’s name was something they got for free. It might even originally have been a bug, for all I know.
- garaetjjte 5y ago>but it did work on that OS This will probably work correctly on any POSIX system (well, except that it completely ignores escaping). Also I'm not sure why you would want to reconstruct cmdline in your program (that will lead to Windows-like horror where kernel only passes single string as cmdline and every component along the way interprets it with different escaping rules).
- saagarjha 5y agoargv is defined to be non-const by the standard.
- josefx 5y agoOne could argue that the main problem here was writing from argv into env^1 , so if one wants to break userland APIs to secure this the best start would be to hit the memory region argv resides in with write protection. ^1 We all know that buffer overflows in C are extremely common so fixing argv[0] alone would be insufficient to fix the majority of bugs.