lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CADBMgpz7k=LhktfcJhSDBDWN0oLeQxPqhOVws3fq0LNpnfOSYg@mail.gmail.com>
Date: Mon, 22 Jan 2024 18:53:19 -0800
From: Dylan Hatch <dylanbhatch@...gle.com>
To: Oleg Nesterov <oleg@...hat.com>
Cc: Andrew Morton <akpm@...ux-foundation.org>, Kees Cook <keescook@...omium.org>, 
	Frederic Weisbecker <frederic@...nel.org>, "Joel Fernandes (Google)" <joel@...lfernandes.org>, 
	Ard Biesheuvel <ardb@...nel.org>, "Matthew Wilcox (Oracle)" <willy@...radead.org>, 
	Thomas Gleixner <tglx@...utronix.de>, Sebastian Andrzej Siewior <bigeasy@...utronix.de>, 
	"Eric W. Biederman" <ebiederm@...ssion.com>, Vincent Whitchurch <vincent.whitchurch@...s.com>, 
	Dmitry Vyukov <dvyukov@...gle.com>, Luis Chamberlain <mcgrof@...nel.org>, 
	Mike Christie <michael.christie@...cle.com>, David Hildenbrand <david@...hat.com>, 
	Catalin Marinas <catalin.marinas@....com>, Stefan Roesch <shr@...kernel.io>, 
	Joey Gouly <joey.gouly@....com>, Josh Triplett <josh@...htriplett.org>, Helge Deller <deller@....de>, 
	Ondrej Mosnacek <omosnace@...hat.com>, Florent Revest <revest@...omium.org>, 
	Miguel Ojeda <ojeda@...nel.org>, linux-kernel@...r.kernel.org
Subject: Re: [PATCH 2/2] getrusage: use sig->stats_lock

On Sun, Jan 21, 2024 at 4:09 AM Oleg Nesterov <oleg@...hat.com> wrote:
>
> Dylan, do you have a better description? Can you share your repro?

That description seems accurate to me.

> although I think that something simple like
>
>         #define NT BIG_NUMBER
>
>         pthread_barrier_t barr;
>
>         void *thread(void *arg)
>         {
>                 struct rusage ru;
>
>                 pthread_barrier_wait(&barr);
>                 for (;;)
>                         getrusage(RUSAGE_SELF, &ru);
>                 return NULL;
>         }
>
>         int main(void)
>         {
>                 pthread_barrier_init(&barr, NULL, NT);
>
>                 for (int n = 0; n < NT-1; ++n) {
>                         pthread_t pt;
>                         pthread_create(&pt, NULL, thread, NULL);
>                 }
>                 thread(NULL);
>
>                 return 0;
>         }
>
> should work if you have a machine with a lot of memory/cpus.
>
> Oleg.
>

Here's my repro, very similar to what you've sent:

#define _GNU_SOURCE
#include <sys/resource.h>
#include <sched.h>
#include <sys/wait.h>
#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>

int thrd_func(void *data) {
       struct rusage usage;
       int *complete = (void *)data;

       while (!*complete);
       while (1) {
              getrusage(RUSAGE_SELF, &usage);
       }
}

#define STACK_SIZE (1024)

int main(int argc, char **argv) {
       if (argc != 2) {
              printf("Usage: %s <thread count>\n", argv[0]);
              exit(EXIT_SUCCESS);
       }
       const int cnt = atoi(argv[1]);
       int pids[cnt];
       int complete = 0;
       printf("Starting test with %d threads...\n", cnt);
       for (int i = 0; i < cnt; i++) {
              char *stack = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE,
                                               MAP_PRIVATE |
MAP_ANONYMOUS | MAP_STACK, -1, 0);
              if (stack == MAP_FAILED) {
                     perror("mmap() failed\n");
                    return -1;
              }

              pids[i] = clone(thrd_func, stack + STACK_SIZE, CLONE_THREAD
                               | CLONE_SIGHAND | CLONE_FS | CLONE_VM |
CLONE_FILES, (void *) &complete);

              if (pids[i] == -1) {
                     perror("clone() failed\n");
                     return pids[i];
              }
       }
       complete = 1;
       printf("waiting on threads...\n");
       sleep(100);
       complete = 0;
       printf("test finished.\n");
       exit(EXIT_SUCCESS);
}

I can't remember exactly why I chose to call mmap and clone directly instead
of using pthreads... but I do know what mmap'ing in a smaller stack size
makes the repro more reliable since you can create more threads. It
seemed like around 250K threads was about enough to reliably produce
the lockup, but your mileage may vary.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ