Re: strcpy versus strncpy

Victor Lavrenko (lavrenko@CS.MSU.SU)
Tue, 03 Mar 1998 16:50:12 +0300

On Tue, 3 Mar 1998, Morten Welinder wrote:

> 1. Different parts of a program can assign different meanings as
> a file name to the same string because they truncate at different
> lengths. (Since a program might pass on a file name to a sub-
> process, such different lengths need not be in the same program.)
>
> 2. Certain operations, such as prepending "./" or $PWD to a file
> name, can change the semantics of the name. Since prepending
> $PWD would typically be done to make a file name robust, this
> might come as a nasty surprise to some programs.
>
> 3. What you think is plenty, others may call insufficient.
> Automatically generated file/function/variable/whatever names
> tend to be long. Why should a program fail to work with those.
> Not convinced? What does the following program do on Solaris?
>
> int main () { return printf ("aaa...10000...aaa\n"); }
>
> With gcc, it dumps core due to stack overflow deep down in printf.
> With Sun's cc, it prints a few thousand a's because the compiler
> silently truncates the string.

On Tue, 3 Mar 1998, Dean Gaudet wrote:

> 4. strncpy is required to zero-fill the entire destination, which can be
> quite a performance pig if the destination is big and the strncpy is
> executed frequently.

5. Destination of strncpy will be not null-terminated string, if the
length of the source string is n or more. Just imagine what security
holes will have your program, if it will have not null-terminated
strings!

I think, that strncpy is not the way to fix security problems that
happened with strcpy. Secure version of strcpy should raise an
exception rather than writing a part (and not null-terminated!) of the
string. Who needs these 'features' of strncpy?

E.g. secure strcpy may check the length of the source string, and if
it's more than n, don't copy (or clear the destination) and/or return
NULL.

More secureness we will obtain using strnlen (that was discussed here)
for previous checking with new fourth parameter to limit the size of
the source string.

Here is what I suggest (you may write 'strnlen' by yourself ;-) - it
returns negative value if it fails to find the end of the string):

char *strscpy(char *dst, const char *src, size_t nd, size_t ns) {
int l=strnlen(src, ns);
if (l < 0 || l > nd) return NULL;
return strcpy(dst, src);
}

Also, if you think that always nd==ns, you may implement secure strcpy
with only three parameters.

So, I hope, after these messages, a great discussion about improving
secureness of string.h can be started here...

Regards,

Victor Lavrenko

Homepage: http://ultra.cs.msu.su/~lavrenko
E-mail: lavrenko@mcst.ru
lavrenko@cs.msu.su
Fingerprint: 03 72 59 3F A7 CE 05 EE FE DD 66 9F A6 D9 EB 1B

Public PGP-key:
http://pgp.ai.mit.edu:11371/pks/lookup?op=get&search=0xE049D3D1