|
|
Log in / Subscribe / Register

Thanks for proving Bernstein right

Thanks for proving Bernstein right

Posted Nov 4, 2007 15:43 UTC (Sun) by jordanb (guest, #45668)
In reply to: Thanks for proving Bernstein right by i3839
Parent article: Daniel Bernstein: ten years of qmail security

History has demonstrated that the weakly-typed pointer system in C *has* been the source of
many, many security bugs.

I can't speak to Java because I don't know much about it but I *can* say that many modern
languages, probably beginning with modula2, have paid a lot of attention to the ways in which
programmers tend to make mistakes and structure the language to either eliminate them or at
least be able to recognize that a bug has been encountered. 

Not allowing pointers/access types to address parts of the memory that haven't been explicitly
allocated as their dereference type is an example of the former. Raising an exception if an
integer overflows rather than just rolling over to zero and continuing like nothing happened
is an example of the latter.

I, personally, am becoming a fan of Ada. It combines strong/safe typing and one of the most
capable regimes of constraints and discriminants that I've seen with an incredible amount of
static analysis, such that a surprising number of mistakes are caught at *compile* time. 

It's certainly true that you can write bad code in any language. But some languages don't do
anything special to try to help you out. And some have some language design decisions that
seem to go out of their way to cause you problems. I can say that C is the only language I use
for which I really need a debugger. That says something I think.

Even though it doesn't have memory pointers, another language that is not designed to help
prevent bugs is PHP. Just the other day I had a bug where a function returned a boolean and I
expected it to return an array. I went off and tried to use the "array" and my program failed
to operate as expected -- but with no warning or error as to what the problem was. As it was
it took my a half hour to track down that rather trivial thing. In any real language, it would
have *told* me that the problem was that I was using a boolean type object improperly, but PHP
shares C's anemic typing regime and thus is ripe for uncaught bugs. 


to post comments

Thanks for proving Bernstein right

Posted Nov 4, 2007 17:54 UTC (Sun) by i3839 (guest, #31386) [Link] (9 responses)

Yes, it certainly has. But more or less all of those can be summarized by "altering the return
address", often in combination with injecting malicious instructions. Compiling programs with
-fstack-protection helps against that, as does random address layout and non-executable
stacks/heaps. So the problem looks worse than it is, because e.g. every buffer overflow is
flagged as a security breach, while in practice it might be near impossible to actually
exploit it.

You might also be interested in the -fmudflap option, but I don't know anything about it. Same
for -ftrapv which causes the program to abort when a signed integer overflows. I tried it, and
it works, but not when optimization is enabled. :-/

And those lowlevel errors distract from the higher level security problems in  applications,
which are more often than not language independent. It's incredible how many unsafe temp file
handling bugs are still found, to name one thing. It's true that many libc functions aren't
very security friendly (e.g. strncat), but by now people should know that and use the safer
alternatives.

The compiler could do much more compiletime checking too, and there are some options to enable
checking a few things, but more could be done. For runtime checking Valgrind is great. The
weak typing of C isn't as big a problem as it could be thanks to compiler warnings.

Only thing I use a debugger for is to get backtraces. And the reason you need a debugger for
that in C and not in some others is because in interpreted languages the backtrace is
generated by the virtual machine.

I really hate PHP, let's not go near there. Any language where mistyping a variable name
causes weird buggy behaviour instead of a (compiletime) error is not worth existing. Weak
typing combined with automatic variable declaration/memory handling is just a nightmare.


Thanks for proving Bernstein right

Posted Nov 4, 2007 18:50 UTC (Sun) by man_ls (guest, #15091) [Link] (8 responses)

That is exactly what we don't want: that your code requires you to use obscure compiler flags (i.e. not enabled by default) or to avoid otherwise perfectly good functions (I assume you mean strcat()). C places the burden of secure programming on developers, where other languages solve many of these issues automatically.

Most security issues that actually have any impact are caused by stupid little things like these. Funny, isn't it?

Thanks for proving Bernstein right

Posted Nov 4, 2007 19:15 UTC (Sun) by i3839 (guest, #31386) [Link] (7 responses)

Well, assuming we're talking about open source here, it's more a distro's choice. But
programmers knowing that their code is security critical and don't trust it enough should
indeed enable a few useful obscure compiler flags.

Oops, I gave the wrong example, I meant strncpy instead of strncat. The latter is indeed safe.

Thanks for proving Bernstein right

Posted Nov 5, 2007 3:59 UTC (Mon) by jordanb (guest, #45668) [Link] (6 responses)

Um, what's wrong with strncpy?

strncpy()

Posted Nov 5, 2007 5:35 UTC (Mon) by Ross (guest, #4065) [Link] (2 responses)

It fails to terminate the string in some cases, so you end up having to either make sure the
buffer is always bigger than the string (in which case you could use strcpy), or manually
terminate the buffer.

It's such a simple function, but it is still a horrible design.

strncpy()

Posted Nov 5, 2007 15:32 UTC (Mon) by nix (subscriber, #2304) [Link] (1 responses)

It's an excellent design for what it was meant for: filling in ancient 
Unix directory entries, which had exactly that format (14 byte max, 
null-terminated if shorter than that).

The mistake was putting it in the C library where people might be tempted 
to use it for other purposes. (See also that horrible pre-stdio function 
gets(), which I see no uses of other than wrapping in things like libssp, 
but which still cna never be removed. At least it's hardly used anymore 
thanks to the warning you get whenever you use it: but strncpy() is used 
too much to warn about, and there's no decent replacement in libc, 
although writing one is a matter of five minutes' work.)

strncpy()

Posted Nov 8, 2007 6:31 UTC (Thu) by ncm (guest, #165) [Link]

snprintf works well enough.

Thanks for proving Bernstein right

Posted Nov 5, 2007 10:47 UTC (Mon) by epa (subscriber, #39769) [Link] (2 responses)

Use strlcpy() instead.

Thanks for proving Bernstein right

Posted Nov 8, 2007 6:35 UTC (Thu) by ncm (guest, #165) [Link] (1 responses)

strlcpy is not in POSIX and never will be.  It doesn't actually do what any sane person would
want, unless you don't really care what ends up in the destination string.  But if you don't
care, why call it at all?

Thanks for proving Bernstein right

Posted Nov 11, 2007 11:30 UTC (Sun) by renox (guest, #23785) [Link]

>strlcpy is not in POSIX and never will be.

So what? There are enough dumb spec in POSIX to show that it's not the ultimate reference in
programming.

> It doesn't actually do what any sane person would
want, unless you don't really care what ends up in the destination string.  But if you don't
care, why call it at all?

That's false: when you don't make a mistake the destination string is correct, when you do
make a mistake, then even if the destination string is incorrect at least this isn't (normaly)
a security issue, which is much better that what those other string copy provides.


Copyright © 2026, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds