[PATCH 2.6.13-rc7 1/2] New Syscall: get rlimits of any process (reworked)

2005-08-25 Thread Wieland Gmeiner
Hi all!

First I would like to thank everyone who commented on my code.

I understand that this won't go into mainline but nevertheless I would
like to work on it further as it is a great learning experience to me.

I incorporated the changes suggested to me by this list (at least I hope
so), any comments highly appreciated.

Thanks,
Wieland


Rationale: Currently resource usage limits (rlimits) can only be 
set inside a process space, or inherited from the parent process.
It would be useful to allow adjusting resource limits for running 
processes, e.g. tuning the resource usage of daemon processes under 
changing workloads without restarting them.

Implementation: This patch provides a new syscall getprlimit() for
reading a given process resource limits for i386. Its implementation
follows closely the getrlimit syscall. It is given a pid as an
additional argument. If the given pid equals zero the current process
rlimits are read and the behaviour resembles the behaviour of
getrlimit. Otherwise some checking on the validity of the given pid is
done and if the given process is found access is granted if
- the calling process holds the CAP_SYS_PTRACE capability or
- the calling process uid equals the uid, euid, suid of the target
  process and the calling process gid equals the gid, egid, sgid of
  the target process.
(This resembles the behaviour of the ptrace system call.)


See the followup for the writing syscall.

Simple programs for testing the syscalls can be found on
http://stud4.tuwien.ac.at/~e8607062/studies/soc/patches/

Signed-off-by: Wieland Gmeiner <[EMAIL PROTECTED]>




---

 arch/i386/kernel/syscall_table.S |1 
 include/asm-i386/unistd.h|3 -
 include/linux/security.h |   25 +++-
 kernel/sys.c |   81 ++-
 security/dummy.c |5 +-
 security/selinux/hooks.c |   17 +---
 6 files changed, 105 insertions(+), 27 deletions(-)

diff -puN arch/i386/kernel/syscall_table.S~getprlimit 
arch/i386/kernel/syscall_table.S
--- linux-2.6.13-rc7/arch/i386/kernel/syscall_table.S~getprlimit
2005-08-26 05:01:17.0 +0200
+++ linux-2.6.13-rc7-wieland/arch/i386/kernel/syscall_table.S   2005-08-26 
05:01:46.0 +0200
@@ -294,3 +294,4 @@ ENTRY(sys_call_table)
.long sys_inotify_init
.long sys_inotify_add_watch
.long sys_inotify_rm_watch
+   .long sys_getprlimit
diff -puN include/asm-i386/unistd.h~getprlimit include/asm-i386/unistd.h
--- linux-2.6.13-rc7/include/asm-i386/unistd.h~getprlimit   2005-08-26 
05:01:17.0 +0200
+++ linux-2.6.13-rc7-wieland/include/asm-i386/unistd.h  2005-08-26 
05:01:46.0 +0200
@@ -299,8 +299,9 @@
 #define __NR_inotify_init  291
 #define __NR_inotify_add_watch 292
 #define __NR_inotify_rm_watch  293
+#define __NR_getprlimit294
 
-#define NR_syscalls 294
+#define NR_syscalls 295
 
 /*
  * user-visible error numbers are in the range -1 - -128: see
diff -puN include/linux/security.h~getprlimit include/linux/security.h
--- linux-2.6.13-rc7/include/linux/security.h~getprlimit2005-08-26 
05:01:17.0 +0200
+++ linux-2.6.13-rc7-wieland/include/linux/security.h   2005-08-26 
05:01:46.0 +0200
@@ -584,10 +584,12 @@ struct swap_info_struct;
  * @p contains the task_struct of process.
  * @nice contains the new nice value.
  * Return 0 if permission is granted.
- * @task_setrlimit:
- * Check permission before setting the resource limits of the current
- * process for @resource to @new_rlim.  The old resource limit values can
- * be examined by dereferencing (current->signal->rlim + resource).
+ * @task_rlimit:
+ * Check permission before reading the resource limits of the process @p
+ * for @resource or setting the limits to @new_rlim.  The old resource
+ * limit values can be examined by dereferencing
+ * (p->signal->rlim + resource).
+ * @p contains the task_struct for the process.
  * @resource contains the resource whose limit is being set.
  * @new_rlim contains the new limits for @resource.
  * Return 0 if permission is granted.
@@ -1156,7 +1158,8 @@ struct security_operations {
int (*task_getsid) (struct task_struct * p);
int (*task_setgroups) (struct group_info *group_info);
int (*task_setnice) (struct task_struct * p, int nice);
-   int (*task_setrlimit) (unsigned int resource, struct rlimit * new_rlim);
+   int (*task_rlimit) (struct task_struct * p, unsigned int resource,
+   struct rlimit * new_rlim);
int (*task_setscheduler) (struct task_struct * p, int policy,
  struct sched_param * lp);
int (*task_getscheduler) (struct task_struct * p);
@@ -1798,10 +1801,11 @@ static inline int security_task_setnice 
return security_ops->task_setnice (p, nice);
 }
 
-static inline int security_task_setrlimit 

[PATCH 2.6.13-rc7 1/2] New Syscall: get rlimits of any process (reworked)

2005-08-25 Thread Wieland Gmeiner
Hi all!

First I would like to thank everyone who commented on my code.

I understand that this won't go into mainline but nevertheless I would
like to work on it further as it is a great learning experience to me.

I incorporated the changes suggested to me by this list (at least I hope
so), any comments highly appreciated.

Thanks,
Wieland


Rationale: Currently resource usage limits (rlimits) can only be 
set inside a process space, or inherited from the parent process.
It would be useful to allow adjusting resource limits for running 
processes, e.g. tuning the resource usage of daemon processes under 
changing workloads without restarting them.

Implementation: This patch provides a new syscall getprlimit() for
reading a given process resource limits for i386. Its implementation
follows closely the getrlimit syscall. It is given a pid as an
additional argument. If the given pid equals zero the current process
rlimits are read and the behaviour resembles the behaviour of
getrlimit. Otherwise some checking on the validity of the given pid is
done and if the given process is found access is granted if
- the calling process holds the CAP_SYS_PTRACE capability or
- the calling process uid equals the uid, euid, suid of the target
  process and the calling process gid equals the gid, egid, sgid of
  the target process.
(This resembles the behaviour of the ptrace system call.)


See the followup for the writing syscall.

Simple programs for testing the syscalls can be found on
http://stud4.tuwien.ac.at/~e8607062/studies/soc/patches/

Signed-off-by: Wieland Gmeiner [EMAIL PROTECTED]




---

 arch/i386/kernel/syscall_table.S |1 
 include/asm-i386/unistd.h|3 -
 include/linux/security.h |   25 +++-
 kernel/sys.c |   81 ++-
 security/dummy.c |5 +-
 security/selinux/hooks.c |   17 +---
 6 files changed, 105 insertions(+), 27 deletions(-)

diff -puN arch/i386/kernel/syscall_table.S~getprlimit 
arch/i386/kernel/syscall_table.S
--- linux-2.6.13-rc7/arch/i386/kernel/syscall_table.S~getprlimit
2005-08-26 05:01:17.0 +0200
+++ linux-2.6.13-rc7-wieland/arch/i386/kernel/syscall_table.S   2005-08-26 
05:01:46.0 +0200
@@ -294,3 +294,4 @@ ENTRY(sys_call_table)
.long sys_inotify_init
.long sys_inotify_add_watch
.long sys_inotify_rm_watch
+   .long sys_getprlimit
diff -puN include/asm-i386/unistd.h~getprlimit include/asm-i386/unistd.h
--- linux-2.6.13-rc7/include/asm-i386/unistd.h~getprlimit   2005-08-26 
05:01:17.0 +0200
+++ linux-2.6.13-rc7-wieland/include/asm-i386/unistd.h  2005-08-26 
05:01:46.0 +0200
@@ -299,8 +299,9 @@
 #define __NR_inotify_init  291
 #define __NR_inotify_add_watch 292
 #define __NR_inotify_rm_watch  293
+#define __NR_getprlimit294
 
-#define NR_syscalls 294
+#define NR_syscalls 295
 
 /*
  * user-visible error numbers are in the range -1 - -128: see
diff -puN include/linux/security.h~getprlimit include/linux/security.h
--- linux-2.6.13-rc7/include/linux/security.h~getprlimit2005-08-26 
05:01:17.0 +0200
+++ linux-2.6.13-rc7-wieland/include/linux/security.h   2005-08-26 
05:01:46.0 +0200
@@ -584,10 +584,12 @@ struct swap_info_struct;
  * @p contains the task_struct of process.
  * @nice contains the new nice value.
  * Return 0 if permission is granted.
- * @task_setrlimit:
- * Check permission before setting the resource limits of the current
- * process for @resource to @new_rlim.  The old resource limit values can
- * be examined by dereferencing (current-signal-rlim + resource).
+ * @task_rlimit:
+ * Check permission before reading the resource limits of the process @p
+ * for @resource or setting the limits to @new_rlim.  The old resource
+ * limit values can be examined by dereferencing
+ * (p-signal-rlim + resource).
+ * @p contains the task_struct for the process.
  * @resource contains the resource whose limit is being set.
  * @new_rlim contains the new limits for @resource.
  * Return 0 if permission is granted.
@@ -1156,7 +1158,8 @@ struct security_operations {
int (*task_getsid) (struct task_struct * p);
int (*task_setgroups) (struct group_info *group_info);
int (*task_setnice) (struct task_struct * p, int nice);
-   int (*task_setrlimit) (unsigned int resource, struct rlimit * new_rlim);
+   int (*task_rlimit) (struct task_struct * p, unsigned int resource,
+   struct rlimit * new_rlim);
int (*task_setscheduler) (struct task_struct * p, int policy,
  struct sched_param * lp);
int (*task_getscheduler) (struct task_struct * p);
@@ -1798,10 +1801,11 @@ static inline int security_task_setnice 
return security_ops-task_setnice (p, nice);
 }
 
-static inline int security_task_setrlimit (unsigned int