Strlcpy and strlcat
The strlcpy()
and strlcat()
functions first appeared in OpenBSD 2.4, and FreeBSD 3.3,
in 1998.
According to their man page, they’re doing
the following:
strlcpy()
andstrlcat()
take the full size of the destination buffer and guaranteeNUL
-termination if there is room. Note that room for theNUL
should be included indstsize
.
strlcpy()
copies up todstsize - 1
characters from the stringsrc
todst
,NUL
-terminating the result ifdstsize
is not0
.
strlcat()
appends stringsrc
to the end ofdst
. It will append at most `dstsize
- strlen(dst) - 1
characters. It will then
NUL-terminate, unless
dstsizeis
0or the original
dststring was longer than
dstsize(in practice this should not happen as it means that either
dstsizeis incorrect or that
dst` is not a proper string).
If the return value is
>= dstsize
, the output string has been truncated. It is the caller’s responsibility to handle this.
Meaning that if a developer miscalculates the size of the destination buffer and makes it too short, the string will be silently truncated. This might prevent some buffer-overflow, but you’ll get corrupted data in exchange.
Moreover, it’s a nice way to introduce infoleaks: strcpy
will copy src
to
dst
, and pad the remaining buffer with \0
, while strlcpy
won’t, leaving
unallocated memory in the buffer. This has been a
constant source of infoleaks on Linux.
strlcpy
is also doing an
equivalent of strlen
on the source, leading to a crash if not NULL-terminated. And even
if it is, it’s still doing the strlen
on the whole source, even if only a
couple of chars are to be copied.
A quick glance
at OpenBSD’s source code shows that the return value of strlcpy
isn’t
systematically checked.
In August 2000, suggestion was made to add them to the glibc, with a hostile reply from its maintainer at the time, Ulric Drepper.
As of 2015, at least OpenBSD, FreeBSD, NetBSD, Solaris, Mac OS X, and QNX provide these functions. Implementations are also present in popular Open Source projects like SDL, GLib, ffmpeg and rsync. The Linux kernel also uses them internally.
The 14 of June 2023, strlcpy
and strlcat
were added
to the glibc, since those two functions are being added to POSIX, under Austin Group
issue 986.