From: Kees Cook <kees@kernel.org>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: "Eric Biederman" <ebiederm@xmission.com>,
"Alexander Viro" <viro@zeniv.linux.org.uk>,
"Christian Brauner" <brauner@kernel.org>,
"Jan Kara" <jack@suse.cz>,
linux-mm@kvack.org, linux-fsdevel@vger.kernel.org,
"Ingo Molnar" <mingo@redhat.com>,
"Peter Zijlstra" <peterz@infradead.org>,
"Juri Lelli" <juri.lelli@redhat.com>,
"Vincent Guittot" <vincent.guittot@linaro.org>,
"Dietmar Eggemann" <dietmar.eggemann@arm.com>,
"Steven Rostedt" <rostedt@goodmis.org>,
"Ben Segall" <bsegall@google.com>, "Mel Gorman" <mgorman@suse.de>,
"Valentin Schneider" <vschneid@redhat.com>,
"Jens Axboe" <axboe@kernel.dk>,
"Pavel Begunkov" <asml.silence@gmail.com>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Chen Yu" <yu.c.chen@intel.com>,
"Shuah Khan" <skhan@linuxfoundation.org>,
"Mickaël Salaün" <mic@digikod.net>,
linux-kernel@vger.kernel.org, io-uring@vger.kernel.org,
linux-hardening@vger.kernel.org
Subject: Re: [PATCH] exec: Make sure task->comm is always NUL-terminated
Date: Sat, 30 Nov 2024 13:05:18 -0800 [thread overview]
Message-ID: <202411301244.381F2B8D17@keescook> (raw)
In-Reply-To: <CAHk-=wjAmu9OBS--RwB+HQn4nhUku=7ECOnSRP8JG0oRU97-kA@mail.gmail.com>
On Fri, Nov 29, 2024 at 11:15:44PM -0800, Linus Torvalds wrote:
> Edited down to just the end result:
>
> On Fri, 29 Nov 2024 at 20:49, Kees Cook <kees@kernel.org> wrote:
> >
> > void __set_task_comm(struct task_struct *tsk, const char *buf, bool exec)
> > {
> > size_t len = min(strlen(buf), sizeof(tsk->comm) - 1);
> >
> > trace_task_rename(tsk, buf);
> > memcpy(tsk->comm, buf, len);
> > memset(&tsk->comm[len], 0, sizeof(tsk->comm) - len);
> > perf_event_comm(tsk, exec);
> > }
>
> I actually don't think that's super-safe either. Yeah, it works in
> practice, and the last byte is certainly always going to be 0, but it
> might not be reliably padded.
Right, my concern over comm is strictly about unterminated reads (i.e.
exposing memory contents stored after "comm" in the task_struct). I've not
been worried about "uninitialized content" exposure because the starting
contents have always been wiped and will (now) always end with a NUL,
so the worst exposure is seeing prior or racing bytes of whatever is
being written into comm concurrently.
> Why? It walks over the source twice. First at strlen() time, then at
> memcpy. So if the source isn't stable, the end result might have odd
> results with NUL characters in the middle.
Yeah, this just means it has greater potential to be garbled.
> And strscpy() really was *supposed* to be safe even in this case, and
> I thought it was until I looked closer.
>
> But I think strscpy() can be saved.
Yeah, fixing the final NUL byte write is needed.
> Something (UNTESTED!) like the attached I think does the right thing.
> I added a couple of "READ_ONCE()" things to make it really super-clear
> that strscpy() reads the source exactly once, and to not allow any
> compiler re-materialization of the reads (although I think that when I
> asked people, it turns out neither gcc nor clang rematerialize memory
> accesses, so that READ_ONCE is likely more a documentation ad
> theoretical thing than a real thing).
This is fine, but it doesn't solve either an unstable source nor
concurrent writers to dest. If source changes out from under strscpy,
we can still copy a "torn" write. If destination changes out from under
strscpy, we just get a potentially interleaved output (but with the
NUL-write change, we never have a dest that _lacks_ a NUL terminator).
So yeah, let's change the loop as you have it. I'm fine with the
READ_ONCE() additions, but I'm not clear on what benefit it has.
> Hmm? I don't think your version is wrong, but I also think we'd be
> better off making our 'strscpy()' infrastructure explicitly safe wrt
> unstable source strings.
Agreed. I'll get this tested against our string handling selftests...
--
Kees Cook
next prev parent reply other threads:[~2024-11-30 21:05 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-30 4:49 [PATCH] exec: Make sure task->comm is always NUL-terminated Kees Cook
2024-11-30 7:15 ` Linus Torvalds
2024-11-30 21:05 ` Kees Cook [this message]
2024-11-30 21:33 ` Linus Torvalds
2024-12-01 20:23 ` Linus Torvalds
2024-11-30 21:40 ` David Laight
2024-12-01 21:49 ` Jens Axboe
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=202411301244.381F2B8D17@keescook \
--to=kees@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=asml.silence@gmail.com \
--cc=axboe@kernel.dk \
--cc=brauner@kernel.org \
--cc=bsegall@google.com \
--cc=dietmar.eggemann@arm.com \
--cc=ebiederm@xmission.com \
--cc=io-uring@vger.kernel.org \
--cc=jack@suse.cz \
--cc=juri.lelli@redhat.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mgorman@suse.de \
--cc=mic@digikod.net \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=skhan@linuxfoundation.org \
--cc=torvalds@linux-foundation.org \
--cc=vincent.guittot@linaro.org \
--cc=viro@zeniv.linux.org.uk \
--cc=vschneid@redhat.com \
--cc=yu.c.chen@intel.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.