xref: /netbsd-src/lib/libc/string/strlcpy.3 (revision 8dbf56fefd8def5a9c6d4b334a659cf03c6799c2)
1.\"	$NetBSD: strlcpy.3,v 1.15 2023/08/11 08:15:30 riastradh Exp $
2.\" from OpenBSD: strlcpy.3,v 1.11 2000/11/16 23:27:41 angelos Exp
3.\"
4.\" Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com>
5.\" All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\"    notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\"    notice, this list of conditions and the following disclaimer in the
14.\"    documentation and/or other materials provided with the distribution.
15.\" 3. The name of the author may not be used to endorse or promote products
16.\"    derived from this software without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
21.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28.\"
29.Dd August 11, 2023
30.Dt STRLCPY 3
31.Os
32.Sh NAME
33.Nm strlcpy ,
34.Nm strlcat
35.Nd size-bounded string copying and concatenation
36.Sh LIBRARY
37.Lb libc
38.Sh SYNOPSIS
39.In string.h
40.Ft size_t
41.Fn strlcpy "char *dst" "const char *src" "size_t size"
42.Ft size_t
43.Fn strlcat "char *dst" "const char *src" "size_t size"
44.Sh DESCRIPTION
45The
46.Fn strlcpy
47and
48.Fn strlcat
49functions copy and concatenate NUL-terminated strings respectively.
50.Pp
51The
52.Fn strlcpy
53function copies up to
54.Fa size
55- 1 characters from the NUL-terminated string
56.Fa src
57to
58.Fa dst ,
59NUL-terminating the result.
60.Pp
61The
62.Fn strlcat
63function appends the NUL-terminated string
64.Fa src
65to the end of
66.Fa dst .
67It will append at most
68.Fa size
69- strlen(dst) - 1 bytes, NUL-terminating the result.
70.Ss Relation to Xr strncpy 3 and Xr strncat 3
71Unlike
72.Xr strncpy 3
73and
74.Xr strncat 3 ,
75.Fn strlcpy
76and
77.Fn strlcat
78are guaranteed to
79NUL-terminate the result (as long as
80.Fa size
81is larger than 0 or, in the case of
82.Fn strlcat ,
83as long as there is at least one byte free in
84.Fa dst ) .
85Note that you should include a byte for the NUL in
86.Fa size .
87.Pp
88.Sy WARNING :
89Also unlike
90.Xr strncpy 3
91and
92.Xr strncat 3 ,
93.Fn strlcpy
94and
95.Fn strlcat
96are not guaranteed to initialize all
97.Fa size
98bytes of
99.Fa dst
100\(em bytes past
101.Fa dst Ns Li "[" Fn strlen src Li "+ 1" Ns Li "]"
102are left uninitialized.
103This can lead to security vulnerabilities such as leaking secrets from
104uninitialized stack or heap buffers.
105.Pp
106.Sy WARNING :
107.Fn strlcpy
108and
109.Fn strlcat
110only operate on true
111.Dq C
112strings.
113This means that for
114.Fn strlcpy
115.Fa src
116must be NUL-terminated and for
117.Fn strlcat
118both
119.Fa src
120and
121.Fa dst
122must be NUL-terminated.
123Applications handling fixed-width fields with
124.Pq possibly empty
125NUL padding, instead of NUL-terminated C strings, MUST use
126.Xr strncpy 3
127and
128.Xr strncat 3
129instead.
130Attempting to use
131.Fn strlcpy
132or
133.Fn strlcat
134for these cases can lead to crashes or security vulnerabilities from
135buffer overruns.
136.Sh RETURN VALUES
137The
138.Fn strlcpy
139and
140.Fn strlcat
141functions return the total length of the string they tried to create.
142For
143.Fn strlcpy
144that means the length of
145.Fa src .
146For
147.Fn strlcat
148that means the initial length of
149.Fa dst
150plus
151the length of
152.Fa src .
153While this may seem somewhat confusing it was done to make
154truncation detection simple.
155.Pp
156Note however, that if
157.Fn strlcat
158traverses
159.Fa size
160characters without finding a NUL, the length of the string is considered
161to be
162.Fa size
163and the destination string will not be NUL-terminated (since there was
164no space for the NUL).
165This keeps
166.Fn strlcat
167from running off the end of a string.
168In practice this should not happen (as it means that either
169.Fa size
170is incorrect or that
171.Fa dst
172is not a proper
173.Dq C
174string).
175The check exists to prevent potential security problems in incorrect code.
176.Sh EXAMPLES
177The following code fragment illustrates the simple case:
178.Bd -literal -offset indent
179char *s, *p, buf[BUFSIZ];
180
181\&...
182
183(void)strlcpy(buf, s, sizeof(buf));
184(void)strlcat(buf, p, sizeof(buf));
185.Ed
186.Pp
187To detect truncation, perhaps while building a pathname, something
188like the following might be used:
189.Bd -literal -offset indent
190char *dir, *file, pname[MAXPATHLEN];
191
192\&...
193
194if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
195	goto toolong;
196if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
197	goto toolong;
198.Ed
199.Pp
200Since we know how many characters we copied the first time, we can
201speed things up a bit by using a copy instead of an append:
202.Bd -literal -offset indent
203char *dir, *file, pname[MAXPATHLEN];
204size_t n;
205
206\&...
207
208n = strlcpy(pname, dir, sizeof(pname));
209if (n \*[Ge] sizeof(pname))
210	goto toolong;
211if (strlcpy(pname + n, file, sizeof(pname) - n) \*[Ge] sizeof(pname) - n)
212	goto toolong;
213.Ed
214.Pp
215However, one may question the validity of such optimizations, as they
216defeat the whole purpose of
217.Fn strlcpy
218and
219.Fn strlcat .
220.Sh SEE ALSO
221.Xr snprintf 3 ,
222.Xr strncat 3 ,
223.Xr strncpy 3
224.Rs
225.%A Todd C. Miller
226.%A Theo de Raadt
227.%T strlcpy and strlcat -- Consistent, Safe, String Copy and Concatenation
228.%I USENIX Association
229.%B Proceedings of the FREENIX Track: 1999 USENIX Annual Technical Conference
230.%D June 6-11, 1999
231.%U http://www.usenix.org/publications/library/proceedings/usenix99/full_papers/millert/millert.pdf
232.Re
233.Sh HISTORY
234The
235.Fn strlcpy
236and
237.Fn strlcat
238functions first appeared in
239.Ox 2.4 ,
240then in
241.Nx 1.4.3
242and
243.Fx 3.3 .
244