linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
To: Stephen Kitt <steve@sk2.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Joe Perches <joe@perches.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	linux-kernel@vger.kernel.org, Jonathan Corbet <corbet@lwn.net>,
	Kees Cook <keescook@chromium.org>,
	Nitin Gote <nitin.r.gote@intel.com>,
	jannh@google.com, kernel-hardening@lists.openwall.com,
	Takashi Iwai <tiwai@suse.com>,
	Clemens Ladisch <clemens@ladisch.de>,
	alsa-devel@alsa-project.org
Subject: Re: [PATCH V2 1/2] string: Add stracpy and stracpy_pad mechanisms
Date: Thu, 26 Sep 2019 10:51:09 +0200	[thread overview]
Message-ID: <f257526e-7d6e-6665-b539-da113b0f83ba@rasmusvillemoes.dk> (raw)
In-Reply-To: <24bb53c57767c1c2a8f266c305a670f7@sk2.org>

On 26/09/2019 10.25, Stephen Kitt wrote:
> Le 26/09/2019 09:29, Rasmus Villemoes a écrit :
>> On 26/09/2019 02.01, Stephen Kitt wrote:
>>> Le 25/09/2019 23:50, Andrew Morton a écrit :
>>>> On Tue, 23 Jul 2019 06:51:36 -0700 Joe Perches <joe@perches.com> wrote:
>>>>
>>
>> Please don't. At least not for the cases where the source is a string
>> literal - that just gives worse code generation (because gcc doesn't
>> know anything about strscpy or strlcpy), and while a run-time (silent)
>> truncation is better than a run-time buffer overflow, wouldn't it be
>> even better with a build time error?
> 
> Yes, that was the plan once Joe's patch gets merged (if it does), and my
> patch was only an example of using stracpy, as a step on the road. I was
> intending to follow up with a patch converting stracpy to something like
> https://www.openwall.com/lists/kernel-hardening/2019/07/06/14
> 
> __FORTIFY_INLINE ssize_t strscpy(char *dest, const char *src, size_t count)
> {
>     size_t dest_size = __builtin_object_size(dest, 0);
>     size_t src_size = __builtin_object_size(src, 0);
>     if (__builtin_constant_p(count) &&
>         __builtin_constant_p(src_size) &&
>         __builtin_constant_p(dest_size) &&

Eh? Isn't the output of __builtin_object_size() by definition a
compile-time constant - whatever the compiler happens to know about the
object size (or a sentinel 0 or -1 depending on the type argument)?

> 
> #define stracpy(dest, src)                        \
> ({                                    \
>     size_t count = ARRAY_SIZE(dest);                \
>     size_t dest_size = __builtin_object_size(dest, 0);        \
>     size_t src_size = __builtin_object_size(src, 0);        \
>     BUILD_BUG_ON(!(__same_type(dest, char[]) ||            \
>                __same_type(dest, unsigned char[]) ||        \
>                __same_type(dest, signed char[])));        \
>                                     \
>     (__builtin_constant_p(count) &&                    \
>      __builtin_constant_p(src_size) &&                \
>      __builtin_constant_p(dest_size) &&                \
>      src_size <= count &&                        \
>      src_size <= dest_size &&                    \
>      src[src_size - 1] == '\0') ?                    \
>         (((size_t) strcpy(dest, src)) & 0) + src_size - 1    \
>     :                                \
>         strscpy(dest, src, count);                \
> })
> 
> and both of these get optimised to movs when copying a constant string
> which fits in the target.

But does it catch the case of overflowing a char[] member in a struct
passed by reference at build time? I'm surprised that
__builtin_object_size(dest, 0) seems to be (size_t)-1, when dest is
s->name (with struct s { char name[4]; };). So I'm not very confident
that any of the fancy fortify logic actually works here - we _really_
should have some Kbuild infrastructure for saying "this .c file should
not compile" so we can test that the fortifications actually work in the
simple and common cases.

> I was going at this from the angle of improving the existing APIs and
> their resulting code.

I'm not against stracpy() as a wrapper for strscpy(), but we should make
sure that whenever we can fail at build time (i.e., both source and dst
lengths known), we do - and in that case also let the compiler optimize
the copy (not only to do the immediate movs, but that also gives it
wider opportunity to remove it completely as dead stores if the
surrounding code ends up dead - with a call to some strscpy(), gcc
cannot eliminate that). If stracpy() can be made sufficiently magic that
it fails at build time for the string literal cases, fine, let's not add
yet another API. Otherwise, I think the static_strcpy() is a much more
readable and reliable API for those cases.

If I'm reading your stracpy() macro correctly, you're explicitly
requesting a run-time truncation (the src_size <= dest_size check
causing as to fall back to strscpy) rather than failing at build time.

Rasmus

  reply	other threads:[~2019-09-26  8:51 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-23 13:51 [PATCH V2 0/2] string: Add stracpy and stracpy_pad Joe Perches
2019-07-23 13:51 ` [PATCH V2 1/2] string: Add stracpy and stracpy_pad mechanisms Joe Perches
2019-07-23 14:37   ` Rasmus Villemoes
2019-07-23 15:39     ` Joe Perches
2019-07-24  6:53       ` Rasmus Villemoes
2019-07-24  7:10         ` Joe Perches
2019-09-25 21:50   ` Andrew Morton
2019-09-26  0:01     ` Stephen Kitt
2019-09-26  7:29       ` Rasmus Villemoes
2019-09-26  8:25         ` Stephen Kitt
2019-09-26  8:51           ` Rasmus Villemoes [this message]
2019-09-26  8:34     ` Joe Perches
2019-09-26 15:45       ` Kees Cook
2019-09-27 12:57       ` Julia Lawall
2019-09-27 13:22       ` Julia Lawall
2019-07-23 13:51 ` [PATCH V2 2/2] kernel-doc: core-api: Include string.h into core-api Joe Perches

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=f257526e-7d6e-6665-b539-da113b0f83ba@rasmusvillemoes.dk \
    --to=linux@rasmusvillemoes.dk \
    --cc=akpm@linux-foundation.org \
    --cc=alsa-devel@alsa-project.org \
    --cc=clemens@ladisch.de \
    --cc=corbet@lwn.net \
    --cc=jannh@google.com \
    --cc=joe@perches.com \
    --cc=keescook@chromium.org \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nitin.r.gote@intel.com \
    --cc=steve@sk2.org \
    --cc=tiwai@suse.com \
    --cc=torvalds@linux-foundation.org \
    /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).