Hi all, when process wants set limit of open files to RLIM_INFINITY it gets EPERM even if it has CAP_SYS_RESOURCE capability. Attached patch should fix the problem. Please add me to CC of your responses because I'm not member of list. Regards, Adam -- Adam Tkac
On Tue, 9 Sep 2008 09:14:07 +0200 The kernel has had this behaviour for a long time. 2.6.13 had: if ((new_rlim.rlim_max > old_rlim->rlim_max) && !capable(CAP_SYS_RESOURCE)) return -EPERM; if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > NR_OPEN) return -EPERM; I don't immediately see a problem with your change, but what makes you believe that it is needed? Is there some standard which we're violating? Is there some operational situation in which the current behaviour is causing a problem? Thanks. --
Well, this change is not _absolutely_ needed because everyone who wants
unlimited file descriptors he could set it to NR_OPEN. Look on
example (from BIND):
...
#elif defined(NR_OPEN) && defined(__linux__)
/*
* Some Linux kernels don't accept RLIM_INFINIT; the maximum
* possible value is the NR_OPEN defined in linux/fs.h.
*/
if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
rl.rlim_cur = rl.rlim_max = NR_OPEN;
unixresult = setrlimit(unixresource, &rl);
if (unixresult == 0)
return (ISC_R_SUCCESS);
}
#elif ...
I think that when you allow set RLIMIT_NOFILE to RLIM_INFINITY you
increase portability - you don't have to check if OS is linux and then
use different schema for limits.
Regards, Adam
--
Adam Tkac
--
On Thu, 11 Sep 2008 09:54:38 +0200
OK.
I updated the changelog as below.
Please send a Signed-off-by: for thsi change, as per section 12 of
Documentation/SubmittingPatches.
Thanks.
From: Adam Tkac <vonsch@gmail.com>
When a process wants to set the limit of open files to RLIM_INFINITY it
gets EPERM even if it has CAP_SYS_RESOURCE capability.
For example, BIND does:
...
#elif defined(NR_OPEN) && defined(__linux__)
/*
* Some Linux kernels don't accept RLIM_INFINIT; the maximum
* possible value is the NR_OPEN defined in linux/fs.h.
*/
if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
rl.rlim_cur = rl.rlim_max = NR_OPEN;
unixresult = setrlimit(unixresource, &rl);
if (unixresult == 0)
return (ISC_R_SUCCESS);
}
#elif ...
If we allow setting RLIMIT_NOFILE to RLIM_INFINITY we increase portability
- you don't have to check if OS is linux and then use different schema for
limits.
The spec says "Specifying RLIM_INFINITY as any resource limit value on a
successful call to setrlimit() shall inhibit enforcement of that resource
limit." and we're presently not doing that.
Cc: Michael Kerrisk <mtk.manpages@googlemail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
kernel/sys.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff -puN kernel/sys.c~rlimit-permit-setting-rlimit_nofile-to-rlim_infinity kernel/sys.c
--- a/kernel/sys.c~rlimit-permit-setting-rlimit_nofile-to-rlim_infinity
+++ a/kernel/sys.c
@@ -1532,8 +1532,14 @@ asmlinkage long sys_setrlimit(unsigned i
if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
!capable(CAP_SYS_RESOURCE))
return -EPERM;
- if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open)
- return -EPERM;
+ if (resource == RLIMIT_NOFILE) {
+ if (new_rlim.rlim_max == RLIM_INFINITY)
+ new_rlim.rlim_max = sysctl_nr_open;
+ if ...When a process wants to set the limit of open files to RLIM_INFINITY it
gets EPERM even if it has CAP_SYS_RESOURCE capability.
For example, BIND does:
...
#elif defined(NR_OPEN) && defined(__linux__)
/*
* Some Linux kernels don't accept RLIM_INFINIT; the maximum
* possible value is the NR_OPEN defined in linux/fs.h.
*/
if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) {
rl.rlim_cur = rl.rlim_max = NR_OPEN;
unixresult = setrlimit(unixresource, &rl);
if (unixresult == 0)
return (ISC_R_SUCCESS);
}
#elif ...
If we allow setting RLIMIT_NOFILE to RLIM_INFINITY we increase portability
- you don't have to check if OS is linux and then use different schema for
limits.
The spec says "Specifying RLIM_INFINITY as any resource limit value on a
successful call to setrlimit() shall inhibit enforcement of that resource
limit." and we're presently not doing that.
Cc: Michael Kerrisk <mtk.manpages@googlemail.com>
Signed-off-by: Adam Tkac <vonsch@gmail.com>
Tested-by: Adam Tkac <vonsch@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
kernel/sys.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff -puN kernel/sys.c~rlimit-permit-setting-rlimit_nofile-to-rlim_infinity kernel/sys.c
--- a/kernel/sys.c~rlimit-permit-setting-rlimit_nofile-to-rlim_infinity
+++ a/kernel/sys.c
@@ -1532,8 +1532,14 @@ asmlinkage long sys_setrlimit(unsigned i
if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
!capable(CAP_SYS_RESOURCE))
return -EPERM;
- if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open)
- return -EPERM;
+ if (resource == RLIMIT_NOFILE) {
+ if (new_rlim.rlim_max == RLIM_INFINITY)
+ new_rlim.rlim_max = sysctl_nr_open;
+ if (new_rlim.rlim_cur == RLIM_INFINITY)
+ new_rlim.rlim_cur = sysctl_nr_open;
+ if (new_rlim.rlim_max > sysctl_nr_open)
+ return -EPERM;
+ }
...This makes it possible to set cur > nr_open (when max = INF but nr_open < cur < INF). You need to check that cur <= max after adjustment. Andreas. -- Andreas Schwab, SuSE Labs, schwab@suse.de SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." --
Right you are. Improved patch is attached, when cur > max && cur != INF after adjustment EINVAL is returned. (cur can be also set to max but it seems like bad solution for me) -- Adam Tkac
