Skip to contentSkip to conversation

strcat.3, strncat.3: RIP strncat(3)

PATCH In review Alejandro Colomar 1 participant 2 messages Dec 5, 2022 Man-pages: manual pages for Linux -- Sections 2, 3, 4, 5, and 7

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 strcat.3, strncat.3: RIP strncat(3)

Never use this function. Really.

---

Hi!

To shadow-utils readers, I've seen there are a few uses of strncat(3) in shadow-utils. I'll review my current PR about string handling to also address this issue.

To glibc readers, please bury this function deep down as if it were radioactive waste.

Cheers,

Alex

 man3/strcat.3  | 75 +++-------------------------------------
 man3/strncat.3 | 92 +++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 95 insertions(+), 72 deletions(-)
man3/strcat.3 +4 -71
index 61d3e54f1..277e5b1e4 100644
@@ -11,7 +11,7 @@
 .\"     Improve discussion of strncat().
 .TH strcat 3 (date) "Linux man-pages (unreleased)"
 .SH NAME
-strcat, strncat \- concatenate two strings
+strcat \- concatenate two strings
 .SH LIBRARY
 Standard C library
 .RI ( libc ", " \-lc )
@@ -20,8 +20,6 @@ .SH SYNOPSIS
 .B #include <string.h>
 .PP
 .BI "char *strcat(char *restrict " dest ", const char *restrict " src );
-.BI "char *strncat(char " dest "[restrict strlen(." dest ") + strnlen(." n ") + 1],"
-.BI "              const char " src "[restrict ." n "], size_t " n );
 .fi
 .SH DESCRIPTION
 The
@@ -42,73 +40,10 @@ .SH DESCRIPTION
 .I dest
 is not large enough, program behavior is unpredictable;
 .IR "buffer overruns are a favorite avenue for attacking secure programs" .
-.PP
-The
-.BR strncat ()
-function is similar, except that
-.IP \(bu 3
-it will use at most
-.I n
-bytes from
-.IR src ;
-and
-.IP \(bu
-.I src
-does not need to be null-terminated if it contains
-.I n
-or more bytes.
-.PP
-As with
-.BR strcat (),
-the resulting string in
-.I dest
-is always null-terminated.
-.PP
-If
-.I src
-contains
-.I n
-or more bytes,
-.BR strncat ()
-writes
-.I n+1
-bytes to
-.I dest
-.RI ( n
-from
-.I src
-plus the terminating null byte).
-Therefore, the size of
-.I dest
-must be at least
-.IR "strlen(dest)+n+1" .
-.PP
-A simple implementation of
-.BR strncat ()
-might be:
-.PP
-.in +4n
-.EX
-char *
-strncat(char *dest, const char *src, size_t n)
-{
-    size_t dest_len = strlen(dest);
-    size_t i;
-
-    for (i = 0 ; i < n && src[i] != \(aq\e0\(aq ; i++)
-        dest[dest_len + i] = src[i];
-    dest[dest_len + i] = \(aq\e0\(aq;
-
-    return dest;
-}
-.EE
-.in
 .SH RETURN VALUE
 The
 .BR strcat ()
-and
-.BR strncat ()
-functions return a pointer to the resulting string
+function returns a pointer to the resulting string
 .IR dest .
 .SH ATTRIBUTES
 For an explanation of the terms used in this section, see
@@ -175,12 +110,10 @@ .SH NOTES
 .SH EXAMPLES
 Because
 .BR strcat ()
-and
-.BR strncat ()
 must find the null byte that terminates the string
 .I dest
 using a search that starts at the beginning of the string,
-the execution time of these functions
+the execution time of this function
 scales according to the length of the string
 .IR dest .
 This can be demonstrated by running the program below.
@@ -222,6 +155,6 @@ .SH SEE ALSO
 .BR memcpy (3),
 .BR strcpy (3),
 .BR string (3),
-.BR strncpy (3),
+.BR strlcat (3bsd),
 .BR wcscat (3),
 .BR wcsncat (3)
man3/strncat.3 +91 -1

92 lines not on this page · raw message

Signature · 1 line
2.38.1
#1 lore raw
Quoted 13 lines · Alejandro Colomar

Never use this function. Really.

---

Hi!

To shadow-utils readers, I've seen there are a few uses of strncat(3) in shadow-utils. I'll review my current PR about string handling to also address this issue.

Quoted 7 lines

To glibc readers, please bury this function deep down as if it were radioactive waste.

Cheers,

Alex

The rendered version of the new manual page for strncpy(3) is:

strncat(3) Library Functions Manual strncat(3)

NAME
strncat - concatenate two strings

LIBRARY
Standard C library (libc, -lc)

SYNOPSIS

       #include <string.h>

       [[deprecated]]
       char *strncat(char dest[restrict strlen(.dest) + strnlen(.n) + 1],
                     const char src[restrict .n],
                     size_t n);

DESCRIPTION
Note: Never use this function.

For safe string concatenation, see strlcat(3bsd). For copying or concatenating a string into a fixed‐length buffer with zero‐ ing of the rest, see stpncpy(3).

strncat() appends at most n characters of src to the end of dst. It always terminates with a null character the string placed in dest.

A simple implementation of strncat() might be:

char *
strncat(char *dest, const char *src, size_t n)
{
return memcpy(dest + strlen(dest), src, strnlen(src, n));
}

RETURN VALUE
strncat() returns a pointer to the resulting string dest.

ATTRIBUTES
For an explanation of the terms used in this section, see at‐ tributes(7). ┌─────────────────────────────────────┬───────────────┬─────────┐
│Interface │ Attribute │ Value │
├─────────────────────────────────────┼───────────────┼─────────┤
│strncat() │ Thread safety │ MT‐Safe │
└─────────────────────────────────────┴───────────────┴─────────┘

STANDARDS

       POSIX.1‐2001, POSIX.1‐2008, C89, C99, SVr4, 4.3BSD.

BUGS
All. Seriously, there’s no use case for this function.

It has a very misleading name. This function has no relation‐ ship with strncpy(3).

Since it doesn’t know the size of the destination buffer, this function can easily write past the end of the array, being an open door to all kinds of crackers.

SEE ALSO

       strcpy(3), string(3)

Linux man‐pages (unreleased) (date) strncat(3)

Signature · 1 line
<http://www.alejandro-colomar.es/>