8 ms·
Now you C me, now you don't
- MaxBarraclough 6y ago> In a nutshell, format string bugs are a class of bugs in which an attacker provides their own format string data into a formatting function, e.g. printf(attacker_controlled) It might be an odd thing to have a strong opinion about, but I consider it poor form to use printf in a C hello world, for this reason. Stick with puts unless you need to use format-specifiers in the string.
- jacquesm 6y agoThat is actually a very good point.
- kjeetgill 6y agoI'd agree with you in most anything but a hello world. Showcasing a few basic powertools as a starting point is probably better than introducing "subtle copies" of the same functionality.
- microtherion 6y agoIn that case, you could use printf("%s", "Hello, world!").
- tptacek 6y agoYou think the idiomatic C hello-world is poor form because of format string attacks?
- MaxBarraclough 6y agoYes. Only use the more dangerous function when you have cause to do so.
- jacinabox 6y agoBut be careful because stdout might be too short to receive the output.
- IncRnd 6y agoPrintf is perfectly acceptable when a string is being printed without format-specifiers. You are abstracting your limited experience to be true for all situations. For a simple example, how will puts print a string without a line termination?
- orwin 6y agoHence, use write()! Not completely joking here, I think everytime I've had to use strings to make two C programs communicate over a network, write() was as easy to use as printf(). Obviously it's not true when communicating with a user.
- saagarjha 6y agowrite requires a length, it’s not specifically designed for working with strings like printf is.
- IncRnd 6y agoThat's not a bad point for many cases. I was pointing out that the coding rule in the upper comment to always use puts, and never printf, is bad advice. I am glad to hear you mention network coding. More people should do that, so fewer people make statements like, "always use puts for writing strings, never printf."
- MaxBarraclough 6y ago> You are abstracting your limited experience to be true for all situations. You aren't qualified to comment on my experience. > For a simple example, how will puts print a string without a line termination? Use fputs. If we're still just writing a simple string, there's no need to reach for a function with format-specifier interpretation.
- IncRnd 6y ago> You aren't qualified to comment on my experience. I think the language barrier made you believe I was personally attacking you. You literally constructed a general argument from a specific statement. That is a logical fallacy called fallacy of composition. If you find yourself printing a string with printf and getting a different result from fputs, it has nothing to do with a newline but with not having checked the string's contents. Ignoring that doesn't fix code with unvalidated input.
- saagarjha 6y agoprintf is only problematic when you have attacked controlled data in the format string. Using a literal is perfectly safe and the intended usage.
- MaxBarraclough 6y agoRight, in this instance the behaviour is identical, but that wasn't my point. In the interests of defensive programming, it makes sense to stick with the simpler and safer function unless there's a good reason to use the more complex and more dangerous function. printf should be used only when necessary. In a hello world, it's not necessary. > Using a literal is perfectly safe and the intended usage. It's not strictly true that it's perfectly safe. The literal could accidentally contain %n which would cause undefined behaviour. A little contrived, but consider Something has gone really #$@&%n£ wrong! It's roughly the intended usage of printf, but it's precisely the intended usage of puts / fputs. Using them closes the door completely on format-specifier bugs.
- wglb 6y agoAnd do you recommend checking the return value on printf and puts?
- Kranar 6y agoWhat for? Say printf returns an error, what would you do in that case?
- MaxBarraclough 6y agoIt's bad to just ignore errors. You could immediately terminate, perhaps after printing an error-message to stderr. Depending on the program, this might be better than continuing on with a broken output stream. In C++ you can have iostream throw on error, avoiding the problem of missing manual checks.
- rurban 6y agoIt's still a minefield, and nobody is doing anything against it. printf %n is known to be dangerous for ages, and the secure variant printf_s which forbids it is nowhere implemented because politics. Almost nobody uses the -Wformat attributes in its declarations, and the wide variants of __attribute__(format(wprintf)) and wscanf are waiting to be implemented since 2008. Patches do exist for ages.
- colejohnson66 6y ago> [...]and the secure variant printf_s which forbids it is nowhere implemented because politics. I’m curious. What’s the reason behind not implementing a safer version of a function?
- masklinn 6y agoThat the _s functions are part of Annex K, which is optional, often not very good[0], and whose reliance on runtime checking is often considered problematic given we're talking about C developers. The politics referred to are because the annex is basically a bunch of Microsoft extensions pasted in the standard. Take printf_s for instance, its main job is to forbid %n, at runtime[1]. It's much safer and more reliable to perform static analysis to mandate literal format strings and forbid %n. [0] aka not very well designed, and not really good at leading developers away from mistakes, they also deviated from some "unsafe" functions in ways which could be quite critical e.g. strncpy_s infamously does not zero the destination buffer like strncpy, which might not be expected by people catering to codebases knowingly taking advantage of this property [1] it will also check for %s null pointer which is somewhat more helpful, but again we're talking about C people here
- colejohnson66 6y ago> The politics referred to are because the annex is basically a bunch of Microsoft extensions pasted in the standard. So... M$FT bad, therefore anything they do is bad? That makes no sense.
- 6y ago
- deleted 6y ago[deleted]