Messages in this thread Patch in this message | | | Date | Thu, 15 Apr 2004 21:10:28 -0300 | From | Marcelo Tosatti <> | Subject | Re: message queue limits |
| |
Hi Andrew!
On Thu, Apr 15, 2004 at 03:54:08PM -0700, Andrew Morton wrote: > Marcelo Tosatti <marcelo.tosatti@cyclades.com> wrote: > > > > This adds a new "RLIMIT_SIGPENDING" limit, which is used to limit > > per-uid pending signals. Currently an unpriviledged user can queue > > more than maximum of allowed signals and cause overall system > > malfunction. > > So now it takes two users to gang up and do the same thing.
Decrease rlim_cur then. Usually people dont have several accounts on the same box.
> We should either exempt root from the global check or simply remove the global > limit > altogether.
Then allow for unlimited pending signals? Are you sure?
> Is it possible for a process to do setuid() with outstanding signals? If > so, they may end up with a negative current->user->signal_pending?
Nice catch, root can do that and I think current->user->signal_pending can get negative. Not completly sure though.
> You need to initialise ->signal_pending in alloc_uid().
--- signal.c.orig 2004-04-15 20:44:17.458438104 -0300 +++ signal.c 2004-04-15 20:45:36.850368696 -0300 @@ -288,7 +288,8 @@ return; kmem_cache_free(sigqueue_cachep, q); atomic_dec(&nr_queued_signals); - atomic_dec(¤t->user->signal_pending); + if (atomic_read(¤t->user->signal_pending) > 0) + atomic_dec(¤t->user->signal_pending); } static void flush_sigqueue(struct sigpending *queue) --- user.c.orig 2004-04-15 20:44:20.395991528 -0300 +++ user.c 2004-04-15 20:44:37.069456776 -0300 @@ -98,6 +98,7 @@ atomic_set(&new->__count, 1); atomic_set(&new->processes, 0); atomic_set(&new->files, 0); + atomic_set(&new->signal_pending, 0); /* * Before adding this, check whether we raced > What are you doing for testing of this?
Simple app posted by Nikita (attached) together with MySQL and sql-bench for creating mysql threads. The setuid() was added by me now.
#include <signal.h> #include <unistd.h> #include <stdlib.h>
int main() { sigset_t set; int i; pid_t pid; sigemptyset(&set); sigaddset(&set, 40); sigprocmask(SIG_BLOCK, &set, 0); pid = getpid(); for (i = 0; i < 1024; i++) kill(pid, 40);
setuid(500);
while (1) sleep(1); }
| |