From: Corey Minyard * POSIX timers have no limit on creation. This means that a normal user can create an arbitrary number of POSIX timers and run the system out of kernel memory. This patch adds a limit on the number of POSIX timers. I'm not sure if this is the best way to handle the problem, but allowing a user to use up all kernel memory is bad. Actually, in 2.6, the queued signals allocated by the timer will limit it to max_queued_signals, but that means the user can use up all the queued signals by allocating a bunch of timers. Bad, too. Note that I would like to make the default value of the maximum number of posix timers relative to the queued signal's default, but it is a magic number and I couldn't find a good place to put the value. --- 25-akpm/include/asm-alpha/resource.h | 6 +++++- 25-akpm/include/asm-arm/resource.h | 6 +++++- 25-akpm/include/asm-arm26/resource.h | 6 +++++- 25-akpm/include/asm-cris/resource.h | 8 ++++++-- 25-akpm/include/asm-h8300/resource.h | 8 ++++++-- 25-akpm/include/asm-i386/resource.h | 8 ++++++-- 25-akpm/include/asm-ia64/resource.h | 6 +++++- 25-akpm/include/asm-m68k/resource.h | 8 ++++++-- 25-akpm/include/asm-mips/resource.h | 6 +++++- 25-akpm/include/asm-parisc/resource.h | 6 +++++- 25-akpm/include/asm-ppc/resource.h | 6 +++++- 25-akpm/include/asm-ppc64/resource.h | 6 +++++- 25-akpm/include/asm-s390/resource.h | 8 ++++++-- 25-akpm/include/asm-sh/resource.h | 6 +++++- 25-akpm/include/asm-sparc/resource.h | 8 ++++++-- 25-akpm/include/asm-sparc64/resource.h | 8 ++++++-- 25-akpm/include/asm-v850/resource.h | 8 ++++++-- 25-akpm/include/asm-x86_64/resource.h | 8 ++++++-- 25-akpm/include/linux/sched.h | 10 ++++++++++ 25-akpm/include/linux/signal.h | 1 + 25-akpm/kernel/posix-timers.c | 9 ++++++++- 25-akpm/kernel/signal.c | 20 ++++++++++++-------- 25-akpm/kernel/sysctl.c | 18 ------------------ 23 files changed, 130 insertions(+), 54 deletions(-) diff -puN include/asm-alpha/resource.h~timers-signals-rlimits include/asm-alpha/resource.h --- 25/include/asm-alpha/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.729487504 -0700 +++ 25-akpm/include/asm-alpha/resource.h 2004-05-08 22:20:57.762482488 -0700 @@ -16,8 +16,10 @@ #define RLIMIT_NPROC 8 /* max number of processes */ #define RLIMIT_MEMLOCK 9 /* max locked-in-memory address space */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 /* * SuS says limits have to be unsigned. Fine, it's unsigned, but @@ -41,6 +43,8 @@ {LONG_MAX, LONG_MAX}, /* RLIMIT_NPROC */ \ {LONG_MAX, LONG_MAX}, /* RLIMIT_MEMLOCK */ \ {LONG_MAX, LONG_MAX}, /* RLIMIT_LOCKS */ \ + {INR_PT, INR_PT }, /* RLIMIT_POSIX_TIMERS */ \ + {INR_QS, INR_QS }, /* RLIMIT_QUEUED_SIGNALS */ \ } #endif /* __KERNEL__ */ diff -puN include/asm-arm26/resource.h~timers-signals-rlimits include/asm-arm26/resource.h --- 25/include/asm-arm26/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.730487352 -0700 +++ 25-akpm/include/asm-arm26/resource.h 2004-05-08 22:20:57.763482336 -0700 @@ -16,8 +16,10 @@ #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #define RLIMIT_AS 9 /* address space limit */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 #ifdef __KERNEL__ @@ -40,6 +42,8 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ + {INR_PT, INR_PT }, \ + {INR_QS, INR_QS }, \ } #endif /* __KERNEL__ */ diff -puN include/asm-arm/resource.h~timers-signals-rlimits include/asm-arm/resource.h --- 25/include/asm-arm/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.732487048 -0700 +++ 25-akpm/include/asm-arm/resource.h 2004-05-08 22:20:57.763482336 -0700 @@ -16,8 +16,10 @@ #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #define RLIMIT_AS 9 /* address space limit */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 #ifdef __KERNEL__ @@ -40,6 +42,8 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ + { INR_PT, INR_PT }, \ + { INR_QS, INR_QS }, \ } #endif /* __KERNEL__ */ diff -puN include/asm-cris/resource.h~timers-signals-rlimits include/asm-cris/resource.h --- 25/include/asm-cris/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.733486896 -0700 +++ 25-akpm/include/asm-cris/resource.h 2004-05-08 22:20:57.763482336 -0700 @@ -16,8 +16,10 @@ #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #define RLIMIT_AS 9 /* address space limit */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 /* * SuS says limits have to be unsigned. @@ -38,8 +40,10 @@ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { INR_PT, INR_PT }, \ + { INR_QS, INR_QS }, \ } #endif /* __KERNEL__ */ diff -puN include/asm-h8300/resource.h~timers-signals-rlimits include/asm-h8300/resource.h --- 25/include/asm-h8300/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.735486592 -0700 +++ 25-akpm/include/asm-h8300/resource.h 2004-05-08 22:20:57.764482184 -0700 @@ -16,8 +16,10 @@ #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #define RLIMIT_AS 9 /* address space limit */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 /* * SuS says limits have to be unsigned. @@ -39,7 +41,9 @@ { INR_OPEN, INR_OPEN }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { INR_PT, INR_PT }, \ + { INR_QS, INR_QS }, \ } #endif /* __KERNEL__ */ diff -puN include/asm-i386/resource.h~timers-signals-rlimits include/asm-i386/resource.h --- 25/include/asm-i386/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.736486440 -0700 +++ 25-akpm/include/asm-i386/resource.h 2004-05-08 22:20:57.764482184 -0700 @@ -16,8 +16,10 @@ #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #define RLIMIT_AS 9 /* address space limit */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 /* * SuS says limits have to be unsigned. @@ -39,7 +41,9 @@ { INR_OPEN, INR_OPEN }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { INR_PT, INR_PT }, \ + { INR_QS, INR_QS }, \ } #endif /* __KERNEL__ */ diff -puN include/asm-ia64/resource.h~timers-signals-rlimits include/asm-ia64/resource.h --- 25/include/asm-ia64/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.737486288 -0700 +++ 25-akpm/include/asm-ia64/resource.h 2004-05-08 22:20:57.765482032 -0700 @@ -23,8 +23,10 @@ #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #define RLIMIT_AS 9 /* address space limit */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 /* * SuS says limits have to be unsigned. @@ -47,6 +49,8 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ + { INR_PT, INR_PT }, \ + { INR_QS, INR_QS }, \ } # endif /* __KERNEL__ */ diff -puN include/asm-m68k/resource.h~timers-signals-rlimits include/asm-m68k/resource.h --- 25/include/asm-m68k/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.738486136 -0700 +++ 25-akpm/include/asm-m68k/resource.h 2004-05-08 22:20:57.765482032 -0700 @@ -16,8 +16,10 @@ #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #define RLIMIT_AS 9 /* address space limit */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 /* * SuS says limits have to be unsigned. @@ -39,7 +41,9 @@ { INR_OPEN, INR_OPEN }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { INR_PT, INR_PT }, \ + { INR_QS, INR_QS }, \ } #endif /* __KERNEL__ */ diff -puN include/asm-mips/resource.h~timers-signals-rlimits include/asm-mips/resource.h --- 25/include/asm-mips/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.740485832 -0700 +++ 25-akpm/include/asm-mips/resource.h 2004-05-08 22:20:57.766481880 -0700 @@ -23,8 +23,10 @@ #define RLIMIT_NPROC 8 /* max number of processes */ #define RLIMIT_MEMLOCK 9 /* max locked-in-memory address space */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 /* Number of limit flavors. */ +#define RLIM_NLIMITS 13 /* Number of limit flavors. */ #ifdef __KERNEL__ @@ -54,6 +56,8 @@ { 0, 0 }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ + { INR_PT, INR_PT }, \ + { INR_QS, INR_QS }, \ } #endif /* __KERNEL__ */ diff -puN include/asm-parisc/resource.h~timers-signals-rlimits include/asm-parisc/resource.h --- 25/include/asm-parisc/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.741485680 -0700 +++ 25-akpm/include/asm-parisc/resource.h 2004-05-08 22:20:57.766481880 -0700 @@ -16,8 +16,10 @@ #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #define RLIMIT_AS 9 /* address space limit */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 /* * SuS says limits have to be unsigned. @@ -40,6 +42,8 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ + { INR_PT, INR_PT }, \ + { INR_QS, INR_QS }, \ } #endif /* __KERNEL__ */ diff -puN include/asm-ppc64/resource.h~timers-signals-rlimits include/asm-ppc64/resource.h --- 25/include/asm-ppc64/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.742485528 -0700 +++ 25-akpm/include/asm-ppc64/resource.h 2004-05-08 22:20:57.767481728 -0700 @@ -21,8 +21,10 @@ #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #define RLIMIT_AS 9 /* address space limit(?) */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 #ifdef __KERNEL__ @@ -46,6 +48,8 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ + { INR_PT, INR_PT }, \ + { INR_QS, INR_QS }, \ } #endif /* __KERNEL__ */ diff -puN include/asm-ppc/resource.h~timers-signals-rlimits include/asm-ppc/resource.h --- 25/include/asm-ppc/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.744485224 -0700 +++ 25-akpm/include/asm-ppc/resource.h 2004-05-08 22:20:57.767481728 -0700 @@ -12,8 +12,10 @@ #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #define RLIMIT_AS 9 /* address space limit(?) */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 #ifdef __KERNEL__ @@ -37,6 +39,8 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ + { INR_PT, INR_PT }, \ + { INR_QS, INR_QS }, \ } #endif /* __KERNEL__ */ diff -puN include/asm-s390/resource.h~timers-signals-rlimits include/asm-s390/resource.h --- 25/include/asm-s390/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.745485072 -0700 +++ 25-akpm/include/asm-s390/resource.h 2004-05-08 22:20:57.767481728 -0700 @@ -24,8 +24,10 @@ #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #define RLIMIT_AS 9 /* address space limit */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 /* * SuS says limits have to be unsigned. @@ -44,10 +46,12 @@ { 0, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ - { INR_OPEN, INR_OPEN }, \ + { INR_OPEN, INR_OPEN }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ + { INR_PT, INR_PT }, \ + { INR_QS, INR_QS }, \ } #endif /* __KERNEL__ */ diff -puN include/asm-sh/resource.h~timers-signals-rlimits include/asm-sh/resource.h --- 25/include/asm-sh/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.746484920 -0700 +++ 25-akpm/include/asm-sh/resource.h 2004-05-08 22:20:57.768481576 -0700 @@ -16,8 +16,10 @@ #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #define RLIMIT_AS 9 /* address space limit */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 #ifdef __KERNEL__ @@ -40,6 +42,8 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ + { INR_PT, INR_PT }, \ + { INR_QS, INR_QS }, \ } #endif /* __KERNEL__ */ diff -puN include/asm-sparc64/resource.h~timers-signals-rlimits include/asm-sparc64/resource.h --- 25/include/asm-sparc64/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.747484768 -0700 +++ 25-akpm/include/asm-sparc64/resource.h 2004-05-08 22:20:57.768481576 -0700 @@ -22,8 +22,10 @@ #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #define RLIMIT_AS 9 /* address space limit */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 /* * SuS says limits have to be unsigned. @@ -43,7 +45,9 @@ {INR_OPEN, INR_OPEN}, {0, 0}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ - {RLIM_INFINITY, RLIM_INFINITY} \ + {RLIM_INFINITY, RLIM_INFINITY}, \ + {INR_PT, INR_PT }, \ + {INR_QS, INR_QS }, \ } #endif /* __KERNEL__ */ diff -puN include/asm-sparc/resource.h~timers-signals-rlimits include/asm-sparc/resource.h --- 25/include/asm-sparc/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.749484464 -0700 +++ 25-akpm/include/asm-sparc/resource.h 2004-05-08 22:20:57.769481424 -0700 @@ -22,8 +22,10 @@ #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #define RLIMIT_AS 9 /* address space limit */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 /* * SuS says limits have to be unsigned. @@ -44,7 +46,9 @@ {INR_OPEN, INR_OPEN}, {0, 0}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ - {RLIM_INFINITY, RLIM_INFINITY} \ + {RLIM_INFINITY, RLIM_INFINITY}, \ + {INR_PT, INR_PT }, \ + {INR_QS, INR_QS }, \ } #endif /* __KERNEL__ */ diff -puN include/asm-v850/resource.h~timers-signals-rlimits include/asm-v850/resource.h --- 25/include/asm-v850/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.750484312 -0700 +++ 25-akpm/include/asm-v850/resource.h 2004-05-08 22:20:57.770481272 -0700 @@ -16,8 +16,10 @@ #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #define RLIMIT_AS 9 /* address space limit */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 /* * SuS says limits have to be unsigned. @@ -39,7 +41,9 @@ { INR_OPEN, INR_OPEN }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { INR_PT, INR_PT }, \ + { INR_QS, INR_QS }, \ } #endif /* __KERNEL__ */ diff -puN include/asm-x86_64/resource.h~timers-signals-rlimits include/asm-x86_64/resource.h --- 25/include/asm-x86_64/resource.h~timers-signals-rlimits 2004-05-08 22:20:57.751484160 -0700 +++ 25-akpm/include/asm-x86_64/resource.h 2004-05-08 22:20:57.770481272 -0700 @@ -16,8 +16,10 @@ #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ #define RLIMIT_AS 9 /* address space limit */ #define RLIMIT_LOCKS 10 /* maximum file locks held */ +#define RLIMIT_POSIX_TIMERS 11 /* max number of POSIX timers */ +#define RLIMIT_QUEUED_SIGNALS 12 /* max number of queued signals */ -#define RLIM_NLIMITS 11 +#define RLIM_NLIMITS 13 /* * SuS says limits have to be unsigned. @@ -39,7 +41,9 @@ { INR_OPEN, INR_OPEN }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { INR_PT, INR_PT }, \ + { INR_QS, INR_QS }, \ } #endif /* __KERNEL__ */ diff -puN include/linux/sched.h~timers-signals-rlimits include/linux/sched.h --- 25/include/linux/sched.h~timers-signals-rlimits 2004-05-08 22:20:57.753483856 -0700 +++ 25-akpm/include/linux/sched.h 2004-05-08 22:20:57.772480968 -0700 @@ -323,12 +323,18 @@ struct user_struct { atomic_t __count; /* reference count */ atomic_t processes; /* How many processes does this user have? */ atomic_t files; /* How many open files does this user have? */ + atomic_t posix_timers; /* How many POSIX timers does this user have? */ + atomic_t queued_sigs; /* How many queued sigs does this user have? */ /* Hash table maintenance information */ struct list_head uidhash_list; uid_t uid; }; +/* Some defaults for the above. */ +#define INR_PT 128 /* Default limit on POSIX timers per user */ +#define INR_QS 128 /* Default rlimit on queued signals per user. */ + extern struct user_struct *find_user(uid_t); extern struct user_struct root_user; @@ -756,6 +762,10 @@ extern void __set_special_pids(pid_t ses /* per-UID process charging. */ extern struct user_struct * alloc_uid(uid_t); +static inline void get_uid(struct user_struct *up) +{ + atomic_inc(&up->__count); +} extern void free_uid(struct user_struct *); extern void switch_uid(struct user_struct *); diff -puN include/linux/signal.h~timers-signals-rlimits include/linux/signal.h --- 25/include/linux/signal.h~timers-signals-rlimits 2004-05-08 22:20:57.754483704 -0700 +++ 25-akpm/include/linux/signal.h 2004-05-08 22:20:57.772480968 -0700 @@ -16,6 +16,7 @@ struct sigqueue { spinlock_t *lock; int flags; siginfo_t info; + struct user_struct *user; }; /* flags values. */ diff -puN kernel/posix-timers.c~timers-signals-rlimits kernel/posix-timers.c --- 25/kernel/posix-timers.c~timers-signals-rlimits 2004-05-08 22:20:57.756483400 -0700 +++ 25-akpm/kernel/posix-timers.c 2004-05-08 22:22:15.006739576 -0700 @@ -390,14 +390,20 @@ void register_posix_clock(int clock_id, posix_clocks[clock_id] = *new_clock; } -static struct k_itimer * alloc_posix_timer(void) +static struct k_itimer *alloc_posix_timer(void) { struct k_itimer *tmr; + + if (atomic_read(¤t->user->posix_timers) >= + current->rlim[RLIMIT_POSIX_TIMERS].rlim_cur) + return NULL; tmr = kmem_cache_alloc(posix_timers_cache, GFP_KERNEL); if (!tmr) return tmr; + atomic_inc(¤t->user->posix_timers); memset(tmr, 0, sizeof (struct k_itimer)); if (unlikely(!(tmr->sigq = sigqueue_alloc()))) { + atomic_dec(¤t->user->posix_timers); kmem_cache_free(posix_timers_cache, tmr); tmr = 0; } @@ -418,6 +424,7 @@ static void release_posix_timer(struct k if (unlikely(tmr->it_process) && tmr->it_sigev_notify == (SIGEV_SIGNAL|SIGEV_THREAD_ID)) put_task_struct(tmr->it_process); + atomic_dec(¤t->user->posix_timers); kmem_cache_free(posix_timers_cache, tmr); } diff -puN kernel/signal.c~timers-signals-rlimits kernel/signal.c --- 25/kernel/signal.c~timers-signals-rlimits 2004-05-08 22:20:57.757483248 -0700 +++ 25-akpm/kernel/signal.c 2004-05-08 22:20:57.777480208 -0700 @@ -31,9 +31,6 @@ static kmem_cache_t *sigqueue_cachep; -atomic_t nr_queued_signals; -int max_queued_signals = 1024; - /* * In POSIX a signal is sent either to a specific thread (Linux task) * or to the process as a whole (Linux thread group). How the signal @@ -268,13 +265,16 @@ struct sigqueue *__sigqueue_alloc(void) { struct sigqueue *q = 0; - if (atomic_read(&nr_queued_signals) < max_queued_signals) + if (atomic_read(¤t->user->queued_sigs) < + current->rlim[RLIMIT_QUEUED_SIGNALS].rlim_cur) q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC); if (q) { - atomic_inc(&nr_queued_signals); INIT_LIST_HEAD(&q->list); q->flags = 0; q->lock = 0; + q->user = current->user; + get_uid(q->user); + atomic_inc(&q->user->queued_sigs); } return(q); } @@ -283,8 +283,9 @@ static inline void __sigqueue_free(struc { if (q->flags & SIGQUEUE_PREALLOC) return; + atomic_dec(&q->user->queued_sigs); + free_uid(q->user); kmem_cache_free(sigqueue_cachep, q); - atomic_dec(&nr_queued_signals); } static void flush_sigqueue(struct sigpending *queue) @@ -718,12 +719,15 @@ static int send_signal(int sig, struct s make sure at least one signal gets delivered and don't pass on the info struct. */ - if (atomic_read(&nr_queued_signals) < max_queued_signals) + if (atomic_read(¤t->user->queued_sigs) < + current->rlim[RLIMIT_QUEUED_SIGNALS].rlim_cur) q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC); if (q) { - atomic_inc(&nr_queued_signals); q->flags = 0; + q->user = current->user; + get_uid(q->user); + atomic_inc(&q->user->queued_sigs); list_add_tail(&q->list, &signals->list); switch ((unsigned long) info) { case 0: diff -puN kernel/sysctl.c~timers-signals-rlimits kernel/sysctl.c --- 25/kernel/sysctl.c~timers-signals-rlimits 2004-05-08 22:20:57.759482944 -0700 +++ 25-akpm/kernel/sysctl.c 2004-05-08 22:20:57.779479904 -0700 @@ -53,8 +53,6 @@ extern int C_A_D; extern int sysctl_overcommit_memory; extern int sysctl_overcommit_ratio; extern int max_threads; -extern atomic_t nr_queued_signals; -extern int max_queued_signals; extern int sysrq_enabled; extern int core_uses_pid; extern char core_pattern[]; @@ -429,22 +427,6 @@ static ctl_table kern_table[] = { .proc_handler = &proc_dointvec, }, #endif - { - .ctl_name = KERN_RTSIGNR, - .procname = "rtsig-nr", - .data = &nr_queued_signals, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec, - }, - { - .ctl_name = KERN_RTSIGMAX, - .procname = "rtsig-max", - .data = &max_queued_signals, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, #ifdef CONFIG_SYSVIPC { .ctl_name = KERN_SHMMAX, _