linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Chris Metcalf <cmetcalf@ezchip.com>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>,
	Fabian Frederick <fabf@skynet.be>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Randy Dunlap <rdunlap@infradead.org>,
	Rickard Strandqvist <rickard_strandqvist@spectrumdigital.se>
Subject: Re: revert "fs/befs/linuxvfs.c: replace strncpy by strlcpy"
Date: Tue, 28 Apr 2015 17:38:49 -0400	[thread overview]
Message-ID: <553FFDE9.9070700@ezchip.com> (raw)
In-Reply-To: <CA+55aFxq5GB1PCH9-en2YMka6EaD8EnAT0iuSoa4yg3KqL_9oA@mail.gmail.com>

On 04/28/2015 04:51 PM, Linus Torvalds wrote:
> On Tue, Apr 28, 2015 at 12:48 PM, Chris Metcalf <cmetcalf@ezchip.com> wrote:
>> FWIW, I wanted to deal with some strncpy/strlcpy API issues last year
>> and just put a "strscpy()" function in arch/tile/gxio/mpipe.c,
> So quite frankly, I don't like that one either.
>
> Some people really *do* want truncation, and your strscpy() makes that
> impossible.

Perhaps the answer is to provide a strscpy() and a separate
strscpy_truncate() that explicitly enables truncation semantics.
I remain skeptical of providing a handy function with an error
return that people are free to ignore.  If one wants truncating
semantics, one should be obliged to say so.

> Also, your strscpy() implementation is actually not thread-safe: it
> can return an non-terminated string if the source string isn't stable.
> That can certainly be a design issue ("don't do that then"), but it
> *can* be a possible source of security issues, so it's a bad idea in
> something that is supposed to be secure.

To do that we'd probably want to provide a generic version that
just copied byte-by-byte, and encourage architecture variants
that were more efficient.  This would leave it less efficient in
general than strncpy/strlcpy (the former typically has efficient
arch versions already, and the latter, although not thread-safe
by your definition, is built on strlen/memcpy, which typically
have efficient arch versions).

I don't see a way to leverage existing efficient implementations,
since only strncpy likely has pre-existing efficient implementations,
and then we'd have to call strlen() on the destination just to
return the total length (after already calling strnlen() on the
source to figure out how long we thought it was).

I suppose if we want to just return a boolean saying "it fit" or
"it didn't fit" we could leverage strncpy, though if the buffer
changed out from under us to be just a single NUL instead of
a long string, we'd still do the silly NUL-fill behavior.  So maybe
it's not worth the contortions.

> And quite frankly, I think that the *only* valid reason to add another
> random string copy function is that you actually get it right. We
> don't need yet another half-arsed routine that can be easily misused.
> We have too many of those.

For sure.  Something like this untested code in lib/string.c, to be 
concrete?

#ifndef __HAVE_ARCH_STRSCPY
/**
  * strscpy_truncate - Copy a C-string into a sized buffer and return whether it fit
  * @dest: Where to copy the string to
  * @src: Where to copy the string from
  * @count: Size of destination buffer
  *
  * Copy the string, or as much of it as fits, into the dest buffer.
  * The routine returns the total number of bytes copied
  * (including the trailing NUL) or zero if the buffer wasn't
  * big enough.  The dest buffer is always NUL-terminated.
  */
static size_t strscpy_truncate(char *dest, const char *src, size_t count)
{
	char *tmp = dest;

	if (count == 0)
		return 0;  /* no NUL-termination possible */

	while ((*tmp++ = *src++) != '\0') {
		if (--count == 0) {
			*--tmp = '\0';
			return 0;
		}
	}

	return tmp - dest;
}
EXPORT_SYMBOL(strscpy_truncate);

/**
  * strscpy - Copy a C-string into a sized buffer, but only if it fits
  * @dest: Where to copy the string to
  * @src: Where to copy the string from
  * @count: Size of destination buffer
  *
  * Use this routine to avoid copying too-long strings.
  * The routine returns the total number of bytes copied
  * (including the trailing NUL) or zero if the buffer wasn't
  * big enough.  To ensure that programmers pay attention
  * to the return code, the destination has a single NUL
  * written at the front (if count is non-zero) when the
  * buffer is not big enough.
  */
static size_t strscpy(char *dest, const char *src, size_t count)
{
	size_t res = strscpy_truncate(dest, src, count);

	if (res == 0 && count != 0)
		dest[0] = '\0';
	return res;
}
EXPORT_SYMBOL(strscpy);
#endif

-- 
Chris Metcalf, EZChip Semiconductor
http://www.ezchip.com


  reply	other threads:[~2015-04-28 21:39 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-28  3:48 revert "fs/befs/linuxvfs.c: replace strncpy by strlcpy" Al Viro
2015-04-28  5:35 ` Fabian Frederick
2015-04-28 16:05   ` Al Viro
2015-04-28 16:42     ` Fabian Frederick
2015-04-28 17:39       ` Al Viro
2015-04-28 20:16         ` Fabian Frederick
2015-04-28 16:42     ` Linus Torvalds
2015-04-28 19:48       ` Chris Metcalf
2015-04-28 20:51         ` Linus Torvalds
2015-04-28 21:38           ` Chris Metcalf [this message]
2015-04-28 21:48             ` Linus Torvalds
2015-04-29  0:35               ` Al Viro
2015-04-29  8:24                 ` Geert Uytterhoeven
2015-04-30 16:01               ` [PATCH 0/3] add new strscpy() API for string copy Chris Metcalf
2015-04-30 16:01                 ` [PATCH 1/3] Make asm/word-at-a-time.h available on all architectures Chris Metcalf
2015-04-30 16:01                 ` [PATCH 2/3] string: provide strscpy() and strscpy_truncate() Chris Metcalf
2015-05-06 15:01                   ` Dan Carpenter
2015-05-06 15:21                     ` Chris Metcalf
2015-05-06 15:59                       ` Dan Carpenter
2015-05-06 16:45                         ` Geert Uytterhoeven
2015-05-07  9:00                           ` Dan Carpenter
2015-05-07 15:10                             ` Chris Metcalf
2015-04-30 16:01                 ` [PATCH 3/3] tile: use global strscpy() rather than private copy Chris Metcalf
2015-05-11 15:37                 ` [PATCH 0/3] add new strscpy() API for string copy Chris Metcalf
2015-05-14 23:10                 ` Michael Ellerman
2015-05-15 15:15                   ` Chris Metcalf
2015-05-18  1:13                     ` Michael Ellerman
2015-05-26 19:33                       ` Chris Metcalf
  -- strict thread matches above, loose matches on Subject: below --
2015-06-30 18:01 [GIT PULL] strscpy string copy function Chris Metcalf
2015-07-01 16:11 ` Linus Torvalds
2015-07-08 20:20   ` [PATCH v2 0/3] add new strscpy() API for string copy Chris Metcalf
2015-07-08 20:20     ` [PATCH v2 1/3] Make asm/word-at-a-time.h available on all architectures Chris Metcalf
2015-07-08 20:20     ` [PATCH v2 2/3] string: provide strscpy() Chris Metcalf
2015-07-08 20:54       ` Geert Uytterhoeven
2015-07-08 20:20     ` [PATCH v2 3/3] tile: use global strscpy() rather than private copy Chris Metcalf

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=553FFDE9.9070700@ezchip.com \
    --to=cmetcalf@ezchip.com \
    --cc=fabf@skynet.be \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rdunlap@infradead.org \
    --cc=rickard_strandqvist@spectrumdigital.se \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@zeniv.linux.org.uk \
    /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 NNTP newsgroup(s).