public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Alejandro Colomar <alx.manpages@gmail.com>
To: linux-man@vger.kernel.org
Cc: Alejandro Colomar <alx@kernel.org>,
	pkg-shadow-devel@alioth-lists.debian.net,
	libc-alpha@sourceware.org
Subject: [PATCH] strcat.3, strncat.3: RIP strncat(3)
Date: Mon,  5 Dec 2022 16:49:05 +0100	[thread overview]
Message-ID: <20221205154904.15321-1-alx@kernel.org> (raw)

Never use this function.  Really.

Cc: <pkg-shadow-devel@alioth-lists.debian.net>
Cc: <libc-alpha@sourceware.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---

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(-)

diff --git a/man3/strcat.3 b/man3/strcat.3
index 61d3e54f1..277e5b1e4 100644
--- a/man3/strcat.3
+++ b/man3/strcat.3
@@ -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)
diff --git a/man3/strncat.3 b/man3/strncat.3
index dc3a1ca1c..fefd68c84 100644
--- a/man3/strncat.3
+++ b/man3/strncat.3
@@ -1 +1,91 @@
-.so man3/strcat.3
+.\" Copyright 2022 Alejandro Colomar <alx@kernel.org>
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.TH strncat 3 (date) "Linux man-pages (unreleased)"
+.SH NAME
+strncat \- concatenate two strings
+.SH LIBRARY
+Standard C library
+.RI ( libc ", " \-lc )
+.SH SYNOPSIS
+.nf
+.B #include <string.h>
+.PP
+.B [[deprecated]]
+.BI "char *strncat(char " dest "[restrict strlen(." dest ") + strnlen(." n ") + 1],"
+.BI "              const char " src "[restrict ." n ],
+.BI "              size_t " n );
+.fi
+.SH DESCRIPTION
+.BI Note: " Never use this function."
+.PP
+For safe string concatenation, see
+.BR strlcat (3bsd).
+For copying or concatenating a string into a fixed-length buffer
+with zeroing of the rest, see
+.BR stpncpy (3).
+.PP
+.BR strncat ()
+appends at most
+.I n
+characters of
+.I src
+to the end of
+.IR dst .
+It always terminates with a null character the string placed in
+.IR dest .
+.PP
+A simple implementation of
+.BR strncat ()
+might be:
+.PP
+.in +4n
+.EX
+char *
+strncat(char *dest, const char *src, size_t n)
+{
+    return memcpy(dest + strlen(dest), src, strnlen(src, n));
+}
+.EE
+.in
+.SH RETURN VALUE
+.BR strncat ()
+returns a pointer to the resulting string
+.IR dest .
+.SH ATTRIBUTES
+For an explanation of the terms used in this section, see
+.BR attributes (7).
+.ad l
+.nh
+.TS
+allbox;
+lbx lb lb
+l l l.
+Interface	Attribute	Value
+T{
+.BR strncat ()
+T}	Thread safety	MT-Safe
+.TE
+.hy
+.ad
+.sp 1
+.SH STANDARDS
+POSIX.1-2001, POSIX.1-2008, C89, C99, SVr4, 4.3BSD.
+.SH BUGS
+All.
+Seriously,
+there's no use case for this function.
+.PP
+It has a
+.I very
+misleading name.
+This function has no relationship with
+.BR strncpy (3).
+.PP
+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.
+.SH SEE ALSO
+.BR strcpy (3),
+.BR string (3)
-- 
2.38.1


             reply	other threads:[~2022-12-05 15:52 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-05 15:49 Alejandro Colomar [this message]
2022-12-05 15:56 ` Alejandro Colomar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221205154904.15321-1-alx@kernel.org \
    --to=alx.manpages@gmail.com \
    --cc=alx@kernel.org \
    --cc=libc-alpha@sourceware.org \
    --cc=linux-man@vger.kernel.org \
    --cc=pkg-shadow-devel@alioth-lists.debian.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).