Fantastic exchange from DConf
Patrick Schluter via Digitalmars-d
digitalmars-d at puremagic.com
Tue May 9 01:00:14 PDT 2017
On Tuesday, 9 May 2017 at 06:15:12 UTC, H. S. Teoh wrote:
> On Mon, May 08, 2017 at 06:33:08PM +0000, Jerry via
> Digitalmars-d wrote:
>
>
> strncpy(buf, src, sizeof(buf));
>
> Quick, without looking: what's wrong with the above line of
> code?
>
> Not so obvious, huh? The problem is that strncpy is, in spite
> of being the "safe" version of strcpy, badly designed. It does
> not guarantee buf is null-terminated if src was too long to fit
> in buf! Next thing you know -- why, hello, unterminated string
> used to inject shellcode into your "secure" webserver!
>
> The "obvious" fix, of course, is to leave 1 byte for the \0
> terminator:
>
> strncpy(buf, src, sizeof(buf)-1);
>
> Except that this is *still* wrong, because strncpy doesn't
> write a '\0' to the end. You have to manually put one there:
>
> strncpy(buf, src, sizeof(buf)-1);
> buf[sizeof(buf)-1] = '\0';
>
> The second line there has a -1 that lazy/careless C coders
> often forget, so you end up *introducing* a buffer overrun in
> the name of fixing another.
>
> This single problem area (improper use of strncpy) accounts for
> a larger chunk of code I've audited than I dare to admit -- all
> just timebombs waiting for somebody to write an exploit for.
>
Adding to that, strncpy() is also a performance trap. strncpy
will not stop when the input string is finished, it will fill the
buffer up with 0.
so
char buff[4000];
strncpy(buff, "hello", sizeof buff);
will write 4000 bytes on every call.
The thing with strncpy() is that it's a badly named function. It
is named as a string function but isn't a string function. Had it
been named as memncpy() or something like that, it wouldn't
confuse most C programmers. If I get my C lore right, the
function was initially written for writing the file name in the
Unix directory strncpy(dirent, filename, 14); or something like
that.
More information about the Digitalmars-d
mailing list