362 lines
11 KiB
Diff
362 lines
11 KiB
Diff
|
Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes)
|
||
|
Date: 2007-10-07
|
||
|
Initial Package Version: 2.6.1
|
||
|
Upstream Status: Rejected Upstream
|
||
|
http://sources.redhat.com/ml/libc-alpha/2000-08/msg00052.html
|
||
|
Origin: OpenBSD, then see the url above, the ported to Owl/Openwall.
|
||
|
http://cvsweb.openwall.com/cgi/cvsweb.cgi/Owl/packages/glibc/\
|
||
|
glibc-2.3.5-openbsd-strlcpy-strlcat.diff
|
||
|
Then I retrieved the latest copies of strlcat.c and strlcpy.c from OpenBSD-cvs,
|
||
|
which had trivial changes.
|
||
|
Description: http://www.courtesan.com/todd/papers/strlcpy.html
|
||
|
|
||
|
diff -Naur glibc-2.6.1.orig/manual/strlcpy.3 glibc-2.6.1/manual/strlcpy.3
|
||
|
--- glibc-2.6.1.orig/manual/strlcpy.3 1970-01-01 00:00:00.000000000 +0000
|
||
|
+++ glibc-2.6.1/manual/strlcpy.3 2007-08-04 06:48:03.000000000 +0000
|
||
|
@@ -0,0 +1,186 @@
|
||
|
+.\" $OpenBSD: strlcpy.3,v 1.18 2005/08/06 03:24:19 jaredy Exp $
|
||
|
+.\"
|
||
|
+.\" Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com>
|
||
|
+.\"
|
||
|
+.\" Permission to use, copy, modify, and distribute this software for any
|
||
|
+.\" purpose with or without fee is hereby granted, provided that the above
|
||
|
+.\" copyright notice and this permission notice appear in all copies.
|
||
|
+.\"
|
||
|
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||
|
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||
|
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||
|
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||
|
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||
|
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||
|
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||
|
+.\"
|
||
|
+.Dd June 22, 1998
|
||
|
+.Dt STRLCPY 3
|
||
|
+.Os
|
||
|
+.Sh NAME
|
||
|
+.Nm strlcpy ,
|
||
|
+.Nm strlcat
|
||
|
+.Nd size-bounded string copying and concatenation
|
||
|
+.Sh SYNOPSIS
|
||
|
+.Fd #include <string.h>
|
||
|
+.Ft size_t
|
||
|
+.Fn strlcpy "char *dst" "const char *src" "size_t size"
|
||
|
+.Ft size_t
|
||
|
+.Fn strlcat "char *dst" "const char *src" "size_t size"
|
||
|
+.Sh DESCRIPTION
|
||
|
+The
|
||
|
+.Fn strlcpy
|
||
|
+and
|
||
|
+.Fn strlcat
|
||
|
+functions copy and concatenate strings respectively.
|
||
|
+They are designed
|
||
|
+to be safer, more consistent, and less error prone replacements for
|
||
|
+.Xr strncpy 3
|
||
|
+and
|
||
|
+.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
|
||
|
+The
|
||
|
+.Fn strlcpy
|
||
|
+function copies up to
|
||
|
+.Fa size
|
||
|
+- 1 characters from the NUL-terminated string
|
||
|
+.Fa src
|
||
|
+to
|
||
|
+.Fa dst ,
|
||
|
+NUL-terminating the result.
|
||
|
+.Pp
|
||
|
+The
|
||
|
+.Fn strlcat
|
||
|
+function appends the NUL-terminated string
|
||
|
+.Fa src
|
||
|
+to the end of
|
||
|
+.Fa dst .
|
||
|
+It will append at most
|
||
|
+.Fa size
|
||
|
+- strlen(dst) - 1 bytes, NUL-terminating the result.
|
||
|
+.Sh RETURN VALUES
|
||
|
+The
|
||
|
+.Fn strlcpy
|
||
|
+and
|
||
|
+.Fn strlcat
|
||
|
+functions return the total length of the string they tried to create.
|
||
|
+For
|
||
|
+.Fn strlcpy
|
||
|
+that means the length of
|
||
|
+.Fa src .
|
||
|
+For
|
||
|
+.Fn strlcat
|
||
|
+that means the initial length of
|
||
|
+.Fa dst
|
||
|
+plus
|
||
|
+the length of
|
||
|
+.Fa src .
|
||
|
+While this may seem somewhat confusing, it was done to make
|
||
|
+truncation detection simple.
|
||
|
+.Pp
|
||
|
+Note, however, that if
|
||
|
+.Fn strlcat
|
||
|
+traverses
|
||
|
+.Fa size
|
||
|
+characters without finding a NUL, the length of the string is considered
|
||
|
+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
|
||
|
+The following code fragment illustrates the simple case:
|
||
|
+.Bd -literal -offset indent
|
||
|
+char *s, *p, buf[BUFSIZ];
|
||
|
+
|
||
|
+\&...
|
||
|
+
|
||
|
+(void)strlcpy(buf, s, sizeof(buf));
|
||
|
+(void)strlcat(buf, p, sizeof(buf));
|
||
|
+.Ed
|
||
|
+.Pp
|
||
|
+To detect truncation, perhaps while building a pathname, something
|
||
|
+like the following might be used:
|
||
|
+.Bd -literal -offset indent
|
||
|
+char *dir, *file, pname[MAXPATHLEN];
|
||
|
+
|
||
|
+\&...
|
||
|
+
|
||
|
+if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
|
||
|
+ goto toolong;
|
||
|
+if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
|
||
|
+ goto toolong;
|
||
|
+.Ed
|
||
|
+.Pp
|
||
|
+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:
|
||
|
+.Bd -literal -offset indent
|
||
|
+char *dir, *file, pname[MAXPATHLEN];
|
||
|
+size_t n;
|
||
|
+
|
||
|
+\&...
|
||
|
+
|
||
|
+n = strlcpy(pname, dir, sizeof(pname));
|
||
|
+if (n >= sizeof(pname))
|
||
|
+ goto toolong;
|
||
|
+if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n)
|
||
|
+ goto toolong;
|
||
|
+.Ed
|
||
|
+.Pp
|
||
|
+However, one may question the validity of such optimizations, as they
|
||
|
+defeat the whole purpose of
|
||
|
+.Fn strlcpy
|
||
|
+and
|
||
|
+.Fn strlcat .
|
||
|
+As a matter of fact, the first version of this manual page got it wrong.
|
||
|
+.Sh SEE ALSO
|
||
|
+.Xr snprintf 3 ,
|
||
|
+.Xr strncat 3 ,
|
||
|
+.Xr strncpy 3
|
||
|
+.Sh HISTORY
|
||
|
+The
|
||
|
+.Fn strlcpy
|
||
|
+and
|
||
|
+.Fn strlcat
|
||
|
+functions first appeared in
|
||
|
+.Ox 2.4 .
|
||
|
diff -Naur glibc-2.6.1.orig/string/Makefile glibc-2.6.1/string/Makefile
|
||
|
--- glibc-2.6.1.orig/string/Makefile 2007-02-01 16:10:11.000000000 +0000
|
||
|
+++ glibc-2.6.1/string/Makefile 2007-08-04 06:48:35.000000000 +0000
|
||
|
@@ -40,7 +40,12 @@
|
||
|
addsep replace) \
|
||
|
envz basename \
|
||
|
strcoll_l strxfrm_l string-inlines memrchr \
|
||
|
- xpg-strerror strerror_l
|
||
|
+ xpg-strerror strerror_l strlcat strlcpy
|
||
|
+
|
||
|
+# These routines will be omitted from the libc shared object.
|
||
|
+# Instead the static object files will be included in a special archive
|
||
|
+# linked against when the shared library will be used.
|
||
|
+static-only-routines = strlcat strlcpy
|
||
|
|
||
|
# Gcc internally generates calls to unbounded memcpy and memset
|
||
|
# for -fbounded-pointer compiles. Glibc uses memchr for explicit checks.
|
||
|
diff -Naur glibc-2.6.1.orig/string/string.h glibc-2.6.1/string/string.h
|
||
|
--- glibc-2.6.1.orig/string/string.h 2007-02-01 16:08:52.000000000 +0000
|
||
|
+++ glibc-2.6.1/string/string.h 2007-08-04 06:48:03.000000000 +0000
|
||
|
@@ -354,6 +354,24 @@
|
||
|
extern char *strsep (char **__restrict __stringp,
|
||
|
__const char *__restrict __delim)
|
||
|
__THROW __nonnull ((1, 2));
|
||
|
+
|
||
|
+/*
|
||
|
+ * Appends __src to string __dst of size __n (unlike strncat, __n is the
|
||
|
+ * full size of __dst, not space left). At most __n-1 characters
|
||
|
+ * will be copied. Always NUL terminates (unless __n <= strlen(__dst)).
|
||
|
+ * Returns strlen(__src) + MIN(__n, strlen(initial __dst)).
|
||
|
+ * If retval >= __n, truncation occurred.
|
||
|
+ */
|
||
|
+extern size_t strlcat (char *__dst, __const char *__src, size_t __n)
|
||
|
+ __THROW __nonnull ((1, 2));
|
||
|
+
|
||
|
+/*
|
||
|
+ * Copy __src to string __dst of size __n. At most __n-1 characters
|
||
|
+ * will be copied. Always NUL terminates (unless __n == 0).
|
||
|
+ * Returns strlen(__src); if retval >= __n, truncation occurred.
|
||
|
+ */
|
||
|
+extern size_t strlcpy (char *__dst, __const char *__src, size_t __n)
|
||
|
+ __THROW __nonnull ((1, 2));
|
||
|
#endif
|
||
|
|
||
|
#ifdef __USE_GNU
|
||
|
diff -Naur glibc-2.6.1.orig/string/strlcat.c glibc-2.6.1/string/strlcat.c
|
||
|
--- glibc-2.6.1.orig/string/strlcat.c 1970-01-01 00:00:00.000000000 +0000
|
||
|
+++ glibc-2.6.1/string/strlcat.c 2007-08-04 06:48:03.000000000 +0000
|
||
|
@@ -0,0 +1,55 @@
|
||
|
+/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
|
||
|
+
|
||
|
+/*
|
||
|
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||
|
+ *
|
||
|
+ * Permission to use, copy, modify, and distribute this software for any
|
||
|
+ * purpose with or without fee is hereby granted, provided that the above
|
||
|
+ * copyright notice and this permission notice appear in all copies.
|
||
|
+ *
|
||
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||
|
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||
|
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||
|
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||
|
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||
|
+ */
|
||
|
+
|
||
|
+#include <sys/types.h>
|
||
|
+#include <string.h>
|
||
|
+
|
||
|
+/*
|
||
|
+ * Appends src to string dst of size siz (unlike strncat, siz is the
|
||
|
+ * full size of dst, not space left). At most siz-1 characters
|
||
|
+ * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
||
|
+ * Returns strlen(src) + MIN(siz, strlen(initial dst)).
|
||
|
+ * If retval >= siz, truncation occurred.
|
||
|
+ */
|
||
|
+size_t
|
||
|
+strlcat(char *dst, const char *src, size_t siz)
|
||
|
+{
|
||
|
+ char *d = dst;
|
||
|
+ const char *s = src;
|
||
|
+ size_t n = siz;
|
||
|
+ size_t dlen;
|
||
|
+
|
||
|
+ /* Find the end of dst and adjust bytes left but don't go past end */
|
||
|
+ while (n-- != 0 && *d != '\0')
|
||
|
+ d++;
|
||
|
+ dlen = d - dst;
|
||
|
+ n = siz - dlen;
|
||
|
+
|
||
|
+ if (n == 0)
|
||
|
+ return(dlen + strlen(s));
|
||
|
+ while (*s != '\0') {
|
||
|
+ if (n != 1) {
|
||
|
+ *d++ = *s;
|
||
|
+ n--;
|
||
|
+ }
|
||
|
+ s++;
|
||
|
+ }
|
||
|
+ *d = '\0';
|
||
|
+
|
||
|
+ return(dlen + (s - src)); /* count does not include NUL */
|
||
|
+}
|
||
|
diff -Naur glibc-2.6.1.orig/string/strlcpy.c glibc-2.6.1/string/strlcpy.c
|
||
|
--- glibc-2.6.1.orig/string/strlcpy.c 1970-01-01 00:00:00.000000000 +0000
|
||
|
+++ glibc-2.6.1/string/strlcpy.c 2007-08-04 06:48:03.000000000 +0000
|
||
|
@@ -0,0 +1,51 @@
|
||
|
+/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */
|
||
|
+
|
||
|
+/*
|
||
|
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||
|
+ *
|
||
|
+ * Permission to use, copy, modify, and distribute this software for any
|
||
|
+ * purpose with or without fee is hereby granted, provided that the above
|
||
|
+ * copyright notice and this permission notice appear in all copies.
|
||
|
+ *
|
||
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||
|
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||
|
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||
|
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||
|
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||
|
+ */
|
||
|
+
|
||
|
+#include <sys/types.h>
|
||
|
+#include <string.h>
|
||
|
+
|
||
|
+/*
|
||
|
+ * Copy src to string dst of size siz. At most siz-1 characters
|
||
|
+ * will be copied. Always NUL terminates (unless siz == 0).
|
||
|
+ * Returns strlen(src); if retval >= siz, truncation occurred.
|
||
|
+ */
|
||
|
+size_t
|
||
|
+strlcpy(char *dst, const char *src, size_t siz)
|
||
|
+{
|
||
|
+ char *d = dst;
|
||
|
+ const char *s = src;
|
||
|
+ size_t n = siz;
|
||
|
+
|
||
|
+ /* Copy as many bytes as will fit */
|
||
|
+ if (n != 0) {
|
||
|
+ while (--n != 0) {
|
||
|
+ if ((*d++ = *s++) == '\0')
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Not enough room in dst, add NUL and traverse rest of src */
|
||
|
+ if (n == 0) {
|
||
|
+ if (siz != 0)
|
||
|
+ *d = '\0'; /* NUL-terminate dst */
|
||
|
+ while (*s++)
|
||
|
+ ;
|
||
|
+ }
|
||
|
+
|
||
|
+ return(s - src - 1); /* count does not include NUL */
|
||
|
+}
|