LWN: Comments on "Format string vulnerability in sudo" https://lwn.net/Articles/478139/ This is a special feed containing comments posted to the individual LWN article titled "Format string vulnerability in sudo". en-us Sat, 01 Nov 2025 09:38:12 +0000 Sat, 01 Nov 2025 09:38:12 +0000 https://www.rssboard.org/rss-specification lwn@lwn.net Format string vulnerability in sudo https://lwn.net/Articles/479352/ https://lwn.net/Articles/479352/ cmccabe <div class="FormattedComment"> <font class="QuotedText">&gt; You *definitely* don't want to look in dirname(argv[0])</font><br> <font class="QuotedText">&gt; for configuration files, for several reasons: argv[0]</font><br> <font class="QuotedText">&gt; need not contain a path at all, it might contain a</font><br> <font class="QuotedText">&gt; user-controlled path that you don't trust, and on most</font><br> <font class="QuotedText">&gt; systems the path containing the binary will never contain</font><br> <font class="QuotedText">&gt; configuration files.</font><br> <p> Well, I would definitely never suggest doing this for setuid binaries, like sudo. I did it once for with scripts that I wrote and it worked out fine.<br> </div> Fri, 03 Feb 2012 19:07:03 +0000 Format string vulnerability in sudo https://lwn.net/Articles/479243/ https://lwn.net/Articles/479243/ josh <div class="FormattedComment"> I don't consider hardcoding the name an arbitrary limitation; the program *does* know its own name, it just doesn't change that name based on its filename. :)<br> <p> Libraries ought to accept the program name as a parameter; the program could choose to pass them argv[0] if it wants to, but might want to pass something else (a subcommand name for instance), or just pass the compile-time name of the program.<br> <p> You *definitely* don't want to look in dirname(argv[0]) for configuration files, for several reasons: argv[0] need not contain a path at all, it might contain a user-controlled path that you don't trust, and on most systems the path containing the binary will never contain configuration files. Most programs get their configuration path at compile-time; programs using autotools get it from the ./configure command line.<br> <p> As for making behavior conditional on the program name, that makes sense for something like busybox that needs to save space at all costs, but most programs don't do that anymore due to various logistical complications, preferring instead to have the same behavior no matter how they get invoked. For example, these days gunzip refers to a shell script rather than a hardlink to gzip.<br> <p> I don't necessarily consider argv[0] a universally bad thing to rely on, but I don't think it should get used and relied on as often as it does.<br> </div> Fri, 03 Feb 2012 08:54:09 +0000 Format string vulnerability in sudo https://lwn.net/Articles/479237/ https://lwn.net/Articles/479237/ cmccabe <div class="FormattedComment"> Sorry for the perhaps overly adversarial tone of the above comment. I'm just annoyed that people could genuinely think argv[0] was a bad thing. Meh.<br> </div> Fri, 03 Feb 2012 06:44:02 +0000 Format string vulnerability in sudo https://lwn.net/Articles/479236/ https://lwn.net/Articles/479236/ cmccabe <div class="FormattedComment"> I don't see the point of arbitrarily limiting the ability of sysadmins to rename programs. Why hardcode the name when you don't have to? Do you enjoy adding arbitrary limitations just because you can?<br> <p> Even if we ignore the rename issue, there are plenty of reasons why a program might want to know its own name.<br> <p> One of them is if you are writing an argument parsing library intended to be used by many different programs. You won't know the program name ahead of time, and you want to print it out in the usage message.<br> <p> Another is if you want the same program to have different behaviors based on the name it was invoked with. Busybox has used this trick for more than a decade to avoid the space overhead of having a different binary for each command.<br> <p> If you're searching for configuration files, one place you might want to look is in dirname(argv[0]).<br> <p> Just because you don't have the imagination to think of good uses for argv[0], doesn't mean that they don't exist.<br> </div> Fri, 03 Feb 2012 06:36:03 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478761/ https://lwn.net/Articles/478761/ rqosa (And then have the log messages from that development build show up under the chosen name.) Wed, 01 Feb 2012 20:02:47 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478758/ https://lwn.net/Articles/478758/ rqosa Note, though, that it says that the sudo_debug() logging facility is intended for use by developers of sudo itself (and its plugins). I suppose they might want to name their development/debugging builds of sudo differently from the main systemwide installation of sudo. Wed, 01 Feb 2012 20:01:41 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478739/ https://lwn.net/Articles/478739/ wahern <div class="FormattedComment"> Nevermind me. I originally read your post to argue that programs shouldn't prepend their name at all.<br> <p> Although, calling themselves something other than how they were invoked would be quite confusing, IMO.<br> <p> </div> Wed, 01 Feb 2012 19:22:32 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478731/ https://lwn.net/Articles/478731/ wahern <div class="FormattedComment"> Well behaved programs are always supposed to prepend their name to stderr messages. Otherwise in a pipeline of commands (or a tree, if they call each other), you can't tell where a particular error is coming from.<br> <p> It's usually far easier to just use warn(3) and warnx(3) from &lt;err.h&gt;, which prepend the program name. Or getprogname() (*BSD) or program_invocation_short_name (glibc) if you're rolling your own formatter. But sudo probably needs to be much more portable than than those allow.<br> <p> <p> </div> Wed, 01 Feb 2012 19:17:14 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478574/ https://lwn.net/Articles/478574/ ekj <div class="FormattedComment"> Agreed. There's absolutely nothing wrong with this. If I rename my Firefox-executable to ArthyMcChicken, the help menu is still gonna say "About Firefox", not magically "About ArthyMcChicken", the program *is* still Firefox regardless of what I named my executable file.<br> <p> Similarily, the program is still the sudo-program, even if I rename the executable to carbonated_kryptonite<br> <p> <p> <p> </div> Wed, 01 Feb 2012 08:39:12 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478571/ https://lwn.net/Articles/478571/ josh <div class="FormattedComment"> I certainly agree that all of the methods you mentioned seem worse than using argv[0].<br> <p> I don't, however, see the point of trying to adapt to sysadmins blindly renaming executables. The program is called "sudo", and it should refer to itself as such. I see nothing wrong with this:<br> <p> ~$ strangename foo<br> sudo: foo: command not found<br> <p> Sysadmins should not blindly rename executables without informing those executables at compile time. Autoconf makes renaming executables fairly straightforward; just look at --program-transform-name and similar, which exists for crazy sites that install GNU programs with a 'g' prefix, such as gsed. And if you use a packaging system, you shouldn't bypass the packaging system by renaming any files it installed.<br> </div> Wed, 01 Feb 2012 08:10:57 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478570/ https://lwn.net/Articles/478570/ cmccabe <div class="FormattedComment"> A compile-time define is not going to help if a sysadmin renames the program.<br> <p> And there isn't any other way to get the name of a running process without resorting to horrible platform-specific hacks.<br> <p> Before you comment: yes, I'm aware of prctl, which allows you to get the initial 15 bytes of the name, and reading /proc/cmdline, and even running ps and grepping for the process name. They are all much worse than just using argv[0].<br> </div> Wed, 01 Feb 2012 08:00:47 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478364/ https://lwn.net/Articles/478364/ iabervon <p>The problem is that they've got a:</p> <code> sudo_debug(level, fmt, ...) </code> <p>function which wants to do a single write() and get the executable name at the beginning, following printf() rules for the fmt.</p> <p>They probably should have done it by using the preprocessor to paste "%s" into the beginning of the format string and the call to get the executable name into the beginning of the arguments (which limits callers to string literals for the format, but that shouldn't be a problem).</p> Tue, 31 Jan 2012 19:31:09 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478282/ https://lwn.net/Articles/478282/ jengelh <div class="FormattedComment"> sudo suffers from many other problems (also leading to a crash or whacky behavior) bugs.debian.org/648066, I wish they'd get as much attention as a simple format string-induced crash.<br> </div> Tue, 31 Jan 2012 16:43:59 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478246/ https://lwn.net/Articles/478246/ gowen <div class="FormattedComment"> Fair enough, but I don't think you make that case in a very compelling way. This format string vulnerability is very little to do with argv[0] - its the attack vector in this case, but the bug is to do with the passing an unsanitised user_string (regardless of where it came from) as the first argument of printf(user_string,....).<br> <p> And I like that /bin/sh gets me a more POSIXy shell that /bin/bash, without needing two executables.<br> </div> Tue, 31 Jan 2012 13:50:12 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478244/ https://lwn.net/Articles/478244/ gowen <div class="FormattedComment"> It's only better if you want the newline. And if you're using it to print argv[0] before an error message, you probably don't want the newline...<br> </div> Tue, 31 Jan 2012 13:46:51 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478245/ https://lwn.net/Articles/478245/ josh <div class="FormattedComment"> I agree; I just also wanted to point out that argv[0] seems like a notable thing to avoid using.<br> </div> Tue, 31 Jan 2012 13:46:32 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478243/ https://lwn.net/Articles/478243/ josh <div class="FormattedComment"> GCC will actually turn calls to printf into calls to puts automatically when possible.<br> </div> Tue, 31 Jan 2012 13:45:56 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478242/ https://lwn.net/Articles/478242/ josh <div class="FormattedComment"> Use a compile-time #define then; autotools even provides you with one automatically.<br> </div> Tue, 31 Jan 2012 13:44:06 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478228/ https://lwn.net/Articles/478228/ epa <div class="FormattedComment"> or better just puts(user_string);<br> </div> Tue, 31 Jan 2012 11:59:38 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478221/ https://lwn.net/Articles/478221/ gowen <div class="FormattedComment"> That's not really the point though. The point is its always a bug to do:<br> <p> foo(const char* user_string)<br> {<br> printf(user_string);<br> }<br> <p> when what you mean is:<br> <p> foo(const char* user_string)<br> {<br> printf("%s",user_string);<br> }<br> </div> Tue, 31 Jan 2012 10:25:36 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478217/ https://lwn.net/Articles/478217/ alonz But then you run into trouble if somebody renames the program &ndash; e.g. because of a name clash with some other program, or in order to install two versions of the same tool concurrently. <p> <tt>argv[0]</tt> is more robust. Tue, 31 Jan 2012 09:59:57 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478211/ https://lwn.net/Articles/478211/ josh <div class="FormattedComment"> I do understand what programs typically use argv[0] for, but I don't see the point. If you don't change the behavior of your program based on argv[0], then why bother printing argv[0] in your usage or your messages? Just print the name of your program, which you already know at compile time.<br> </div> Tue, 31 Jan 2012 09:00:39 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478210/ https://lwn.net/Articles/478210/ zuki <div class="FormattedComment"> <font class="QuotedText">&gt; One thing argv[0] is often used for is to allow a program to print its own </font><br> <font class="QuotedText">&gt; name, such as in the "usage" message that's printed in response to the </font><br> <font class="QuotedText">&gt; "-?" switch, or in "trace" messages used for debugging.</font><br> This doesn't make much sense. What is the gain? Saving 5 bytes on the name string? Of course there are some exceptions, like programs which vary their behaviour based on argv[0], or which can legitimately be installed under different names, but 99% of programs are better of printing their real name, even if called differently. E.g. if the user specifies the full path ../../usr/bin/sudo, it's inelegant to say<br> <p> usage: ../../usr/bin/sudo [options]<br> <p> (Besides the user probably knows how he or she called the program.)<br> </div> Tue, 31 Jan 2012 08:59:18 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478201/ https://lwn.net/Articles/478201/ Adrien <div class="FormattedComment"> GCC should also be able to pick up the vulnerability with -Wformat family of warnings.<br> <p> Code:<br> | % cat a.c<br> | #include &lt;stdio.h&gt;<br> |<br> | void f(char *fmt) {<br> | printf(fmt, 1);<br> | }<br> <p> Compilation:<br> | % gcc -c -Wformat -Wformat-nonliteral a.c<br> | a.c: In function ‘f’:<br> | a.c:4:3: warning: format not a string literal, argument types not checked<br> <p> <p> -Wformat is enabled by -Wall but -Wformat-nonliteral is not (not by -Wextra either). Still, it's really something that should not be skipped (along with a number of other warnings; C developers: USE THE WARNINGS!).<br> <p> For reference, from gcc's manpage:<br> | -Wformat-nonliteral<br> | If -Wformat is specified, also warn if the format string is not a<br> | string literal and so cannot be checked, unless the format function<br> | takes its format arguments as a "va_list".<br> <p> </div> Tue, 31 Jan 2012 07:44:26 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478195/ https://lwn.net/Articles/478195/ rqosa <p><font class="QuotedText">&gt; Honestly, programs need to stop looking at argv[0] at all.</font></p> <p>Using argv[0] doesn't necessarily cause a vulnerability — it's no more of a hazard than the other elements of argv. It just needs to be treated like any other untrusted data source (which in this case probably means it should have been used as one of the values to which the format string was bound, rather than part of the format string itself).</p> <p><font class="QuotedText">&gt; I don't know why any program looks at argv[0] at all</font></p> <p>One thing argv[0] is often used for is to allow a program to print its own name, such as in the "usage" message that's printed in response to the "-?" switch, or in "trace" messages used for debugging. I'm guessing that the latter usage is what sudo uses argv[0] for — the vulnerability report says that it's in a function called sudo_debug() which is intended for use "<font class="QuotedText">when developing policy or I/O logging plugins</font>". So, probably sudo_debug() is a function that plugins call in order to print trace messages, and it uses argv[0] to prepend something like "sudo: " to the messages before printing them.</p> Tue, 31 Jan 2012 07:10:50 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478185/ https://lwn.net/Articles/478185/ josh <div class="FormattedComment"> Honestly, programs need to stop looking at argv[0] at all. Most programs have stopped changing their behavior based on argv[0] these days, preferring instead to use tiny wrappers, shared libraries, or two compilations of the same code with different preprocessor definitions. Given that, I don't know why any program looks at argv[0] at all, certainly not sudo.<br> </div> Tue, 31 Jan 2012 05:01:10 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478159/ https://lwn.net/Articles/478159/ mgedmin The linked article says _FORTIFY_SOURCE helps here: <blockquote> "On systems that support FORTIFY_SOURCE (most Linux and NetBSD), adding -D_FORTIFY_SOURCE=2 to the OSDEFS line in src/Makfile and then rebuilding sudo will prevent the bug from being exploited." </blockquote> Mon, 30 Jan 2012 23:37:48 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478156/ https://lwn.net/Articles/478156/ mathstuf <div class="FormattedComment"> It's 2. Build logs here[1].<br> <p> [1]<a href="http://kojipkgs.fedoraproject.org/packages/sudo/1.8.3p1/2.fc16/data/logs/x86_64/build.log">http://kojipkgs.fedoraproject.org/packages/sudo/1.8.3p1/2...</a><br> </div> Mon, 30 Jan 2012 23:31:14 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478152/ https://lwn.net/Articles/478152/ SEJeff <div class="FormattedComment"> What is the Fedora/RHEL default? I know that they both do enable FORTIFY_SOURCE by default, just not sure what level.<br> </div> Mon, 30 Jan 2012 23:11:43 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478149/ https://lwn.net/Articles/478149/ pr1268 <p><tt>$ sudo -V<br/>Sudo version 1.7.4p6</tt></p> <p>Thank goodness Slackware is a few versions behind bleeding edge! <tt>:-D</tt></p> <p>Yes, I <i>did</i> read the part about <font class="QuotedText">&quot;...that does not mean that such exploits do not exist.&quot;</font></p> Mon, 30 Jan 2012 23:00:53 +0000 Format string vulnerability in sudo https://lwn.net/Articles/478142/ https://lwn.net/Articles/478142/ arjan <div class="FormattedComment"> one note on format string issues...<br> <p> if you compile with -D_FORTIFY_SOURCE=2, glibc's printf and co do some extra checks that will block most format string sploits.<br> Not sure if this one gets blocked (since it's only in printf and co)<br> <p> </div> Mon, 30 Jan 2012 22:33:14 +0000