* Re: [PATCH] Fix race condition when exec'ing setuid files
[not found] <202209131456.76A13BC5E4@keescook>
@ 2022-10-06 20:20 ` Kees Cook
2022-10-07 1:40 ` Theodore Ts'o
0 siblings, 1 reply; 3+ messages in thread
From: Kees Cook @ 2022-10-06 20:20 UTC (permalink / raw)
To: Jorge Merlino
Cc: Christian Brauner, Eric Biederman, Jann Horn, Alexander Viro,
Thomas Gleixner, Andy Lutomirski, Sebastian Andrzej Siewior,
Andrew Morton, linux-mm, linux-fsdevel, John Johansen, Paul Moore,
James Morris, Serge E. Hallyn, Stephen Smalley, Eric Paris,
Richard Haines, Casey Schaufler, Xin Long, David S. Miller,
Todd Kjos, Ondrej Mosnacek, Prashanth Prahlad, Micah Morton,
Fenghua Yu, Andrei Vagin, linux-kernel, apparmor,
linux-security-module, selinux, linux-hardening
On Thu, Sep 13, 2022 at 15:03:38 -0700, Kees Cook wrote:
> It seems quite unusual to have a high-load heavily threaded
> process decide to exec.
In looking at this a bunch more, I actually think everything is working
as intended. If a process is actively launching threads while also trying
to exec, they're going to create races for themselves.
So the question, then, is "why are they trying to exec while actively
spawning new threads?" That appears to be the core problem here, and as
far as I can tell, the kernel has behaved this way for a very long time.
I don't think the kernel should fix this, either, because it leads to a
very weird state for userspace, where the thread spawner may suddenly
die due to the exec happening in another thread. This really looks like
something userspace needs to handle correctly (i.e. don't try to exec
while actively spawning threads).
For example, here's a fix to the original PoC:
--- a.c.original 2022-10-06 13:07:13.279845619 -0700
+++ a.c 2022-10-06 13:10:27.702941645 -0700
@@ -8,8 +8,10 @@
return NULL;
}
+int stop_spawning;
+
void *target(void *p) {
- for (;;) {
+ while (!stop_spawning) {
pthread_t t;
if (pthread_create(&t, NULL, nothing, NULL) == 0)
pthread_join(t, NULL);
@@ -17,18 +19,26 @@
return NULL;
}
+#define MAX_THREADS 10
+
int main(void)
{
+ pthread_t threads[MAX_THREADS];
struct timespec tv;
int i;
- for (i = 0; i < 10; i++) {
- pthread_t t;
- pthread_create(&t, NULL, target, NULL);
+ for (i = 0; i < MAX_THREADS; i++) {
+ pthread_create(&threads[i], NULL, target, NULL);
}
tv.tv_sec = 0;
tv.tv_nsec = 100000;
nanosleep(&tv, NULL);
+
+ /* Signal shut down, and collect spawners. */
+ stop_spawning = 1;
+ for (i = 0; i < MAX_THREADS; i++)
+ pthread_join(threads[i], NULL);
+
if (execl("./b", "./b", NULL) < 0)
perror("execl");
return 0;
--
Kees Cook
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] Fix race condition when exec'ing setuid files
2022-10-06 20:20 ` [PATCH] Fix race condition when exec'ing setuid files Kees Cook
@ 2022-10-07 1:40 ` Theodore Ts'o
2022-10-07 11:58 ` David Laight
0 siblings, 1 reply; 3+ messages in thread
From: Theodore Ts'o @ 2022-10-07 1:40 UTC (permalink / raw)
To: Kees Cook
Cc: Jorge Merlino, Christian Brauner, Eric Biederman, Jann Horn,
Alexander Viro, Thomas Gleixner, Andy Lutomirski,
Sebastian Andrzej Siewior, Andrew Morton, linux-mm, linux-fsdevel,
John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
Stephen Smalley, Eric Paris, Richard Haines, Casey Schaufler,
Xin Long, David S. Miller, Todd Kjos, Ondrej Mosnacek,
Prashanth Prahlad, Micah Morton, Fenghua Yu, Andrei Vagin,
linux-kernel, apparmor, linux-security-module, selinux,
linux-hardening
On Thu, Oct 06, 2022 at 01:20:35PM -0700, Kees Cook wrote:
>
> So the question, then, is "why are they trying to exec while actively
> spawning new threads?" That appears to be the core problem here, and as
> far as I can tell, the kernel has behaved this way for a very long time.
> I don't think the kernel should fix this, either, because it leads to a
> very weird state for userspace, where the thread spawner may suddenly
> die due to the exec happening in another thread. This really looks like
> something userspace needs to handle correctly (i.e. don't try to exec
> while actively spawning threads).
One of the classic failure modes is when a threaded program calls a
library, and that library might try to do a fork/exec (or call
system(3) to run some command. e.g., such as running "lvm create ..."
or to spawn some kind of helper daemon.
There are a number of stack overflow questions about this, and there
are some solutions to _some_ of the problems, such as using
pthread_atfork(), and knowing that you are about to call fork/exec,
and use some out of band mechanism to to make sure no threads get
spawned until the fork/exec is completed --- but if you don't know
that a library is going to do a fork/exec, well, life is tough.
One technique even advocated by a stack overflow article is "avoid
using threads whenver possible". :-/
- Ted
^ permalink raw reply [flat|nested] 3+ messages in thread
* RE: [PATCH] Fix race condition when exec'ing setuid files
2022-10-07 1:40 ` Theodore Ts'o
@ 2022-10-07 11:58 ` David Laight
0 siblings, 0 replies; 3+ messages in thread
From: David Laight @ 2022-10-07 11:58 UTC (permalink / raw)
To: 'Theodore Ts'o', Kees Cook
Cc: Jorge Merlino, Christian Brauner, Eric Biederman, Jann Horn,
Alexander Viro, Thomas Gleixner, Andy Lutomirski,
Sebastian Andrzej Siewior, Andrew Morton, linux-mm@kvack.org,
linux-fsdevel@vger.kernel.org, John Johansen, Paul Moore,
James Morris, Serge E. Hallyn, Stephen Smalley, Eric Paris,
Richard Haines, Casey Schaufler, Xin Long, David S. Miller,
Todd Kjos, Ondrej Mosnacek, Prashanth Prahlad, Micah Morton,
Fenghua Yu, Andrei Vagin, linux-kernel@vger.kernel.org,
apparmor@lists.ubuntu.com, linux-security-module@vger.kernel.org,
selinux@vger.kernel.org, linux-hardening@vger.kernel.org
From: Theodore Ts'o
> Sent: 07 October 2022 02:41
>
> On Thu, Oct 06, 2022 at 01:20:35PM -0700, Kees Cook wrote:
> >
> > So the question, then, is "why are they trying to exec while actively
> > spawning new threads?" That appears to be the core problem here, and as
> > far as I can tell, the kernel has behaved this way for a very long time.
> > I don't think the kernel should fix this, either, because it leads to a
> > very weird state for userspace, where the thread spawner may suddenly
> > die due to the exec happening in another thread. This really looks like
> > something userspace needs to handle correctly (i.e. don't try to exec
> > while actively spawning threads).
>
> One of the classic failure modes is when a threaded program calls a
> library, and that library might try to do a fork/exec (or call
> system(3) to run some command. e.g., such as running "lvm create ..."
> or to spawn some kind of helper daemon.
>
> There are a number of stack overflow questions about this, and there
> are some solutions to _some_ of the problems, such as using
> pthread_atfork(), and knowing that you are about to call fork/exec,
> and use some out of band mechanism to to make sure no threads get
> spawned until the fork/exec is completed --- but if you don't know
> that a library is going to do a fork/exec, well, life is tough.
Or that a library thread is about to create a new thread.
> One technique even advocated by a stack overflow article is "avoid
> using threads whenver possible". :-/
Doesn't fork() only create the current thread in the new process?
So by the time exec() runs there is a nice single threaded process
with an fd table that isn't shared.
For helpers there is always (a properly implemented) posix_spawn() :-)
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-10-07 11:58 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <202209131456.76A13BC5E4@keescook>
2022-10-06 20:20 ` [PATCH] Fix race condition when exec'ing setuid files Kees Cook
2022-10-07 1:40 ` Theodore Ts'o
2022-10-07 11:58 ` David Laight
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).