Use OpenBSD's revamped description of strlcpy and strlcat.

This explanation is supposed to be simpler and better.  In particular
"comparing it to the snprintf API provides lots of value, since it raises the
bar on understanding, so that programmers/auditors will a better job calling
all 3 of these functions."

Requested by:	deraadt@cvs.openbsd.org
Obtained From:	OpenBSD
Reviewed by:	cperciva
This commit is contained in:
Eitan Adler 2013-11-04 19:05:31 +00:00
parent 023fc3804d
commit fc81a90261

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: strlcpy.3,v 1.19 2007/05/31 19:19:32 jmc Exp $ .\" $OpenBSD: strlcpy.3,v 1.26 2013/09/30 12:02:35 millert Exp $
.\" .\"
.\" Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com> .\" Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com>
.\" .\"
@ -27,7 +27,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd June 22, 1998 .Dd November 10, 2013
.Dt STRLCPY 3 .Dt STRLCPY 3
.Os .Os
.Sh NAME .Sh NAME
@ -47,69 +47,81 @@ The
.Fn strlcpy .Fn strlcpy
and and
.Fn strlcat .Fn strlcat
functions copy and concatenate strings respectively. functions copy and concatenate strings with the
They are designed same input parameters and output result as
to be safer, more consistent, and less error prone replacements for .Xr snprintf 3 .
They are designed to be safer, more consistent, and less error
prone replacements for the easily misused functions
.Xr strncpy 3 .Xr strncpy 3
and and
.Xr strncat 3 . .Xr strncat 3 .
Unlike those functions,
.Fn strlcpy
and
.Fn strlcat
take the full size of the buffer (not just the length) and guarantee to
NUL-terminate the result (as long as
.Fa size
is larger than 0 or, in the case of
.Fn strlcat ,
as long as there is at least one byte free in
.Fa dst ) .
Note that a byte for the NUL should be included in
.Fa size .
Also note that
.Fn strlcpy
and
.Fn strlcat
only operate on true
.Dq C
strings.
This means that for
.Fn strlcpy
.Fa src
must be NUL-terminated and for
.Fn strlcat
both
.Fa src
and
.Fa dst
must be NUL-terminated.
.Pp .Pp
The
.Fn strlcpy .Fn strlcpy
function copies up to and
.Fa size .Fn strlcat
- 1 characters from the NUL-terminated string take the full size of the destination buffer and guarantee
NUL-termination if there is room.
Note that room for the NUL should be included in
.Fa dstsize .
.Pp
.Fn strlcpy
copies up to
.Fa dstsize
\- 1 characters from the string
.Fa src .Fa src
to to
.Fa dst , .Fa dst ,
NUL-terminating the result. NUL-terminating the result if
.Fa dstsize
is not 0.
.Pp .Pp
The
.Fn strlcat .Fn strlcat
function appends the NUL-terminated string appends string
.Fa src .Fa src
to the end of to the end of
.Fa dst . .Fa dst .
It will append at most It will append at most
.Fa size .Fa dstsize
- strlen(dst) - 1 bytes, NUL-terminating the result. \- strlen(dst) \- 1 characters.
It will then NUL-terminate, unless
.Fa dstsize
is 0 or the original
.Fa dst
string was longer than
.Fa dstsize
(in practice this should not happen
as it means that either
.Fa dstsize
is incorrect or that
.Fa dst
is not a proper string).
.Pp
If the
.Fa src
and
.Fa dst
strings overlap, the behavior is undefined.
.Sh RETURN VALUES .Sh RETURN VALUES
The Besides quibbles over the return type
.Pf ( Va size_t
versus
.Va int )
and signal handler safety
.Pf ( Xr snprintf 3
is not entirely safe on some systems), the
following two are equivalent:
.Bd -literal -offset indent
n = strlcpy(dst, src, len);
n = snprintf(dst, len, "%s", src);
.Ed
.Pp
Like
.Xr snprintf 3 ,
the
.Fn strlcpy .Fn strlcpy
and and
.Fn strlcat .Fn strlcat
functions return the total length of the string they tried to functions return the total length of the string they tried to create.
create.
For For
.Fn strlcpy .Fn strlcpy
that means the length of that means the length of
@ -121,29 +133,12 @@ that means the initial length of
plus plus
the length of the length of
.Fa src . .Fa src .
While this may seem somewhat confusing, it was done to make
truncation detection simple.
.Pp .Pp
Note however, that if If the return value is
.Fn strlcat .Cm >=
traverses .Va dstsize ,
.Fa size the output string has been truncated.
characters without finding a NUL, the length of the string is considered It is the caller's responsibility to handle this.
to be
.Fa size
and the destination string will not be NUL-terminated (since there was
no space for the NUL).
This keeps
.Fn strlcat
from running off the end of a string.
In practice this should not happen (as it means that either
.Fa size
is incorrect or that
.Fa dst
is not a proper
.Dq C
string).
The check exists to prevent potential security problems in incorrect code.
.Sh EXAMPLES .Sh EXAMPLES
The following code fragment illustrates the simple case: The following code fragment illustrates the simple case:
.Bd -literal -offset indent .Bd -literal -offset indent
@ -169,7 +164,7 @@ if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
.Ed .Ed
.Pp .Pp
Since it is known how many characters were copied the first time, things Since it is known how many characters were copied the first time, things
can be sped up a bit by using a copy instead of an append. can be sped up a bit by using a copy instead of an append:
.Bd -literal -offset indent .Bd -literal -offset indent
char *dir, *file, pname[MAXPATHLEN]; char *dir, *file, pname[MAXPATHLEN];
size_t n; size_t n;
@ -201,5 +196,5 @@ and
.Fn strlcat .Fn strlcat
functions first appeared in functions first appeared in
.Ox 2.4 , .Ox 2.4 ,
and made their appearance in and
.Fx 3.3 . .Fx 3.3 .