Live data from Hacker News

Let's Destroy C

gist.github.com

181–190 of 192 posts

Re: Let's Destroy C

#181

Earlier quoted context omitted.

puts and printf aren't keywords, they're regular functions.

Well, sort of. Specifically, printf is an oddball function because it uses the varargs mechanism, and the whole format strings mechanism is inherently risky because it effectively bypasses the type system and says "trust me." Back when I was learning C, on a Mac with THINK C, misusing printf was a sure-fire way to crash the computer very quickly, especially since misaligned accesses of 16-bit or 32-bit words caused c…

Nope, printf is a regular function - regular functions can use varargs just fine.

And it's C; everything bypasses the type system and says "trust me". Memory allocation bypasses the type system and says "trust me".

  struct foo* foo = malloc(sizeof foo);
  // yep, this is definitely the right number of bytes
If you want strong typing (!= static typing), C is not the language you should be using, printf or no printf.

Re: Let's Destroy C

#182
post #180

Earlier quoted context omitted.

No, they’re equivalent in terms of security. The article’s author (posting here on HN) is grossly mistaken.

They are nearly equivalent in terms of functional security. Function isn't everything though. One example shows an awareness of the security issue and good habit being used despite the low impact. I'd argue that there is a security benefit to using one over the other. Additionally, it's not as simple as saying "if you can change memory, then you can change memory". Memory exploits are quite often chains of small issu…

> One example shows [...]

Yes,

  printf("Hello, World!\n");
shows an awareness of the security issue and good habit being used.

  printf("%s\n", "Hello, World!");
shows that you think "%s\n\0Hello, World!" (or however the compiler decides to lay out those strings) can't be overwritten with "%p%nHello, World!" (or something to that effect), but "Hello, World!\n" somehow can.

Re: Let's Destroy C

#183

Earlier quoted context omitted.

So an attacker able to write to memory would be able to elevate into the ability to... write to memory. That doesn't sound particularly worrisome.

In a lot of cases the attacker can only write to a limited range of memory addresses. If that string happens to fall in that range, they can use it to write to other addresses and/or find out where in memory certain things are stored. So their ability to write to a limited range of addresses can be extended to a larger range.

If the attacker can write to string memory, they can overwrite "%s\n\0Hello World" just as easily as "Hello World\n".

Re: Let's Destroy C

#184
post #71
post #70

Earlier quoted context omitted.

That's not UB, that's implementation dependent, AFAIK the C standard says nothing about read-only memory. Attempting to modify a string literal is indeed UB but that would only happen if an attacker managed to attempt to modify the string, not when the program is used normally.

> That's not UB, that's implementation dependent, AFAIK the C standard says nothing about read-only memory. If we're being pedantic, it's _unspecified behaviour_. The implementation isn't required to document how it would behave.

Is it really not UB to attempt to modify RO things? Typically (on major implementations, e.g. GNU/Linux or MSVC/Windows) it will crash, and I don't think it is allowed to crash on non-UB things?

Re: Let's Destroy C

#185

Those defines remind me of how Bourne shell was originally written using such a system to make the source look more like Algol 68. It might even still be maintained that way in BSD to this day [0]. [0] https://books.google.ca/books?id=9f9uAQAAQBAJ&pg=PA9&lpg=PA9...

"to this day" in 1994 is very much not "to this day" in 2020.

The various BSDs use the Almquist and Korn shells for /bin/sh nowadays. Indeed, M. Van der Linden was out of date even back in 1994. At that time, BSD had already been largely freed of AT&T code, such as the Bourne shell, for 3 years. It's now approaching 3 decades.

Re: Let's Destroy C

#186
post #59

My friend served as a military officer and told me a story. Every evening before lights out, he had to count soldiers via a roll call, a 10-minute routine. If someone coughed during that (no matter what intent), then suddenly many soldiers began to cough, and that ruined everything. The only solution he figured out to remain legal/moral was to pause and start it all over if someone coughs.

Wouldn't it make sense to roll-call different sub-groups independently?

Re: Let's Destroy C

#188

Earlier quoted context omitted.

puts and printf aren't keywords, they're regular functions.

Well, sort of. Specifically, printf is an oddball function because it uses the varargs mechanism, and the whole format strings mechanism is inherently risky because it effectively bypasses the type system and says "trust me." Back when I was learning C, on a Mac with THINK C, misusing printf was a sure-fire way to crash the computer very quickly, especially since misaligned accesses of 16-bit or 32-bit words caused c…

No.

The popular C compilers have a feature where they will do some additional type checking on the arguments passed to "format" functions. You can mark your own functions with this attribute.

See the format attribute https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attribute....

printf is not an oddball function. Also, typechecking format strings in general does not have to be that complicated. They are still used in golang.

Of all the security pitfalls of C, the format string design of printf is way down the list. As others have noted, printf is not what makes the C type system weak.

Re: Let's Destroy C

#189
post #180

Earlier quoted context omitted.

They are nearly equivalent in terms of functional security. Function isn't everything though. One example shows an awareness of the security issue and good habit being used despite the low impact. I'd argue that there is a security benefit to using one over the other. Additionally, it's not as simple as saying "if you can change memory, then you can change memory". Memory exploits are quite often chains of small issu…

> One example shows [...] Yes, printf("Hello, World!\n"); shows an awareness of the security issue and good habit being used. printf("%s\n", "Hello, World!"); shows that you think "%s\n\0Hello, World!" (or however the compiler decides to lay out those strings) can't be overwritten with "%p%nHello, World!" (or something to that effect), but "Hello, World!\n" somehow can .

You know that reinforcing habit is not about this trivial example. You are arguing in bad faith.

We've spent the last 20 years cleaning up after the shoddy work of this exact attitude.

Re: Let's Destroy C

#190
post #189

Earlier quoted context omitted.

> One example shows [...] Yes, printf("Hello, World!\n"); shows an awareness of the security issue and good habit being used. printf("%s\n", "Hello, World!"); shows that you think "%s\n\0Hello, World!" (or however the compiler decides to lay out those strings) can't be overwritten with "%p%nHello, World!" (or something to that effect), but "Hello, World!\n" somehow can .

You know that reinforcing habit is not about this trivial example. You are arguing in bad faith. We've spent the last 20 years cleaning up after the shoddy work of this exact attitude.

We've spent the last 20 years cleaning up after the shoddy work of people (like you) who think avoiding the deficiencies of a thin wrapper over assembly is just a matter of good habits, rather than actually understanding what the hell they're doing.

And breaking up constants into misordered, mishmashed fragments isn't even a good habit in the first place.

Edit: Come to think of it, given that the original complaint was:

> > printf("Hello, World!\n");

> [...] All this requires is a modification to one string in memory and you have an injection vulnerability.

There's also the fact that it's you who is arguing in bad faith, since a: habit wasn't part of it to begin with, and b: you haven't given any example of a case where a habit of writing `printf("%s\n","");` rather than `printf("\n");` is useful for anything whatsoever, security or otherwise.

Post reply on HN