xref: /netbsd-src/lib/libc/string/strlcpy.3 (revision 0e03e9aa32bfe10a387a6b8519ad3ec2bc3017c5)
1.\"	$NetBSD: strlcpy.3,v 1.22 2024/11/01 16:36:58 nia 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 November 1, 2024
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
50.Tn NUL Ns -terminated
51strings respectively.
52.Pp
53The
54.Fn strlcpy
55function copies up to
56.Fa size Li "- 1"
57bytes from the
58.Tn NUL Ns -terminated
59string
60.Fa src
61to
62.Fa dst ,
63.Tn NUL Ns -terminating
64the result.
65.Pp
66The
67.Fn strlcat
68function appends the
69.Tn NUL Ns -terminated
70string
71.Fa src
72to the end of
73.Fa dst .
74It will append at most
75.Fa size Li "-" Fn strlen dst Li "- 1"
76bytes,
77.Tn NUL Ns -terminating
78the result.
79.Ss Relation to Xr strncpy 3 and Xr strncat 3
80Unlike
81.Xr strncpy 3
82and
83.Xr strncat 3 ,
84.Fn strlcpy
85and
86.Fn strlcat
87are guaranteed to
88.Tn NUL Ns -terminate
89the result (as long as
90.Fa size
91is larger than 0 or, in the case of
92.Fn strlcat ,
93as long as there is at least one byte free in
94.Fa dst ) .
95Note that you should include a byte for the
96.Tn NUL
97in
98.Fa size .
99.Pp
100.Sy WARNING :
101Also unlike
102.Xr strncpy 3
103and
104.Xr strncat 3 ,
105.Fn strlcpy
106and
107.Fn strlcat
108are not guaranteed to initialize all
109.Fa size
110bytes of
111.Fa dst
112\(em bytes past
113.Fa dst Ns Li "[" Fn strlen src Li "+ 1" Ns Li "]"
114are left uninitialized.
115This can lead to security vulnerabilities such as leaking secrets from
116uninitialized stack or heap buffers.
117.Pp
118.Sy WARNING :
119.Fn strlcpy
120and
121.Fn strlcat
122only operate on true
123.Dq C
124strings.
125This means that for
126.Fn strlcpy
127.Fa src
128must be
129.Tn NUL Ns -terminated
130and for
131.Fn strlcat
132both
133.Fa src
134and
135.Fa dst
136must be
137.Tn NUL Ns -terminated .
138Applications handling fixed-width fields with
139.Pq possibly empty
140.Tn NUL
141padding, instead of
142.Tn NUL Ns -terminated
143C strings, MUST use
144.Xr strncpy 3
145and
146.Xr strncat 3
147instead.
148Attempting to use
149.Fn strlcpy
150or
151.Fn strlcat
152for these cases can lead to crashes or security vulnerabilities from
153buffer overruns.
154.Sh RETURN VALUES
155The
156.Fn strlcpy
157and
158.Fn strlcat
159functions return the total length of the string they tried to create.
160For
161.Fn strlcpy
162that means the length of
163.Fa src .
164For
165.Fn strlcat
166that means the initial length of
167.Fa dst
168plus
169the length of
170.Fa src .
171While this may seem somewhat confusing it was done to make
172truncation detection simple.
173.Pp
174Note however, that if
175.Fn strlcat
176traverses
177.Fa size
178bytes without finding a
179.Tn NUL ,
180the length of the string is considered to be
181.Fa size
182and the destination string will not be
183.Tn NUL Ns -terminated
184.Pq since there was no space for the Tn NUL .
185This keeps
186.Fn strlcat
187from running off the end of a string.
188In practice this should not happen (as it means that either
189.Fa size
190is incorrect or that
191.Fa dst
192is not a proper
193.Dq C
194string).
195The check exists to prevent potential security problems in incorrect code.
196.Sh EXAMPLES
197The following code fragment illustrates the simple case:
198.Bd -literal -offset indent
199char *s, *p, buf[BUFSIZ];
200
201\&...
202
203strlcpy(buf, s, sizeof(buf));
204strlcat(buf, p, sizeof(buf));
205.Ed
206.Pp
207To detect truncation, perhaps while building a pathname, something
208like the following might be used:
209.Bd -literal -offset indent
210char *dir, *file, pname[MAXPATHLEN];
211
212\&...
213
214if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
215	goto toolong;
216if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
217	goto toolong;
218.Ed
219.Pp
220Since we know how many bytes we copied the first time, we can
221speed things up a bit by using a copy instead of an append:
222.Bd -literal -offset indent
223char *dir, *file, pname[MAXPATHLEN];
224size_t n;
225
226\&...
227
228n = strlcpy(pname, dir, sizeof(pname));
229if (n >= sizeof(pname))
230	goto toolong;
231if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n)
232	goto toolong;
233.Ed
234.Pp
235However, one may question the validity of such optimizations, as they
236defeat the whole purpose of
237.Fn strlcpy
238and
239.Fn strlcat .
240.Sh SEE ALSO
241.Xr snprintf 3 ,
242.Xr strncat 3 ,
243.Xr strncpy 3
244.Rs
245.%A Todd C. Miller
246.%A Theo de Raadt
247.%T strlcpy and strlcat -- Consistent, Safe, String Copy and Concatenation
248.%I USENIX Association
249.%B Proceedings of the FREENIX Track: 1999 USENIX Annual Technical Conference
250.%D June 6-11, 1999
251.%U http://www.usenix.org/publications/library/proceedings/usenix99/full_papers/millert/millert.pdf
252.Re
253.Sh STANDARDS
254The
255.Fn strlcpy
256and
257.Fn strlcat
258functions conform to
259.St -p1003.1-2024 .
260.Sh HISTORY
261The
262.Fn strlcpy
263and
264.Fn strlcat
265functions first appeared in
266.Ox 2.4 ,
267then in
268.Nx 1.4.3
269and
270.Fx 3.3 .
271