diff options
author | David Quigley <dpquigl@tycho.nsa.gov> | 2006-06-30 04:55:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-30 14:25:37 -0400 |
commit | a1836a42daf5ddfe9a891973734bd9a7d62eb504 (patch) | |
tree | e8819aec40aff3fa0eecd2ef9d92df8213bce58b | |
parent | 7a01955f99b65622a00ba5c8b39202ddc6fa65f8 (diff) |
[PATCH] SELinux: Add security hook definition for getioprio and insert hooks
Add a new security hook definition for the sys_ioprio_get operation. At
present, the SELinux hook function implementation for this hook is
identical to the getscheduler implementation but a separate hook is
introduced to allow this check to be specialized in the future if
necessary.
This patch also creates a helper function get_task_ioprio which handles the
access check in addition to retrieving the ioprio value for the task.
Signed-off-by: David Quigley <dpquigl@tycho.nsa.gov>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
Cc: Jens Axboe <axboe@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | fs/ioprio.c | 29 | ||||
-rw-r--r-- | include/linux/security.h | 15 | ||||
-rw-r--r-- | security/dummy.c | 6 | ||||
-rw-r--r-- | security/selinux/hooks.c | 6 |
4 files changed, 51 insertions, 5 deletions
diff --git a/fs/ioprio.c b/fs/ioprio.c index 7fa76ed53c10..93aa5715f224 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c | |||
@@ -125,11 +125,24 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio) | |||
125 | return ret; | 125 | return ret; |
126 | } | 126 | } |
127 | 127 | ||
128 | static int get_task_ioprio(struct task_struct *p) | ||
129 | { | ||
130 | int ret; | ||
131 | |||
132 | ret = security_task_getioprio(p); | ||
133 | if (ret) | ||
134 | goto out; | ||
135 | ret = p->ioprio; | ||
136 | out: | ||
137 | return ret; | ||
138 | } | ||
139 | |||
128 | asmlinkage long sys_ioprio_get(int which, int who) | 140 | asmlinkage long sys_ioprio_get(int which, int who) |
129 | { | 141 | { |
130 | struct task_struct *g, *p; | 142 | struct task_struct *g, *p; |
131 | struct user_struct *user; | 143 | struct user_struct *user; |
132 | int ret = -ESRCH; | 144 | int ret = -ESRCH; |
145 | int tmpio; | ||
133 | 146 | ||
134 | read_lock_irq(&tasklist_lock); | 147 | read_lock_irq(&tasklist_lock); |
135 | switch (which) { | 148 | switch (which) { |
@@ -139,16 +152,19 @@ asmlinkage long sys_ioprio_get(int which, int who) | |||
139 | else | 152 | else |
140 | p = find_task_by_pid(who); | 153 | p = find_task_by_pid(who); |
141 | if (p) | 154 | if (p) |
142 | ret = p->ioprio; | 155 | ret = get_task_ioprio(p); |
143 | break; | 156 | break; |
144 | case IOPRIO_WHO_PGRP: | 157 | case IOPRIO_WHO_PGRP: |
145 | if (!who) | 158 | if (!who) |
146 | who = process_group(current); | 159 | who = process_group(current); |
147 | do_each_task_pid(who, PIDTYPE_PGID, p) { | 160 | do_each_task_pid(who, PIDTYPE_PGID, p) { |
161 | tmpio = get_task_ioprio(p); | ||
162 | if (tmpio < 0) | ||
163 | continue; | ||
148 | if (ret == -ESRCH) | 164 | if (ret == -ESRCH) |
149 | ret = p->ioprio; | 165 | ret = tmpio; |
150 | else | 166 | else |
151 | ret = ioprio_best(ret, p->ioprio); | 167 | ret = ioprio_best(ret, tmpio); |
152 | } while_each_task_pid(who, PIDTYPE_PGID, p); | 168 | } while_each_task_pid(who, PIDTYPE_PGID, p); |
153 | break; | 169 | break; |
154 | case IOPRIO_WHO_USER: | 170 | case IOPRIO_WHO_USER: |
@@ -163,10 +179,13 @@ asmlinkage long sys_ioprio_get(int which, int who) | |||
163 | do_each_thread(g, p) { | 179 | do_each_thread(g, p) { |
164 | if (p->uid != user->uid) | 180 | if (p->uid != user->uid) |
165 | continue; | 181 | continue; |
182 | tmpio = get_task_ioprio(p); | ||
183 | if (tmpio < 0) | ||
184 | continue; | ||
166 | if (ret == -ESRCH) | 185 | if (ret == -ESRCH) |
167 | ret = p->ioprio; | 186 | ret = tmpio; |
168 | else | 187 | else |
169 | ret = ioprio_best(ret, p->ioprio); | 188 | ret = ioprio_best(ret, tmpio); |
170 | } while_each_thread(g, p); | 189 | } while_each_thread(g, p); |
171 | 190 | ||
172 | if (who) | 191 | if (who) |
diff --git a/include/linux/security.h b/include/linux/security.h index d4b13d617f63..f75303831d09 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -585,6 +585,10 @@ struct swap_info_struct; | |||
585 | * @p contains the task_struct of process. | 585 | * @p contains the task_struct of process. |
586 | * @ioprio contains the new ioprio value | 586 | * @ioprio contains the new ioprio value |
587 | * Return 0 if permission is granted. | 587 | * Return 0 if permission is granted. |
588 | * @task_getioprio | ||
589 | * Check permission before getting the ioprio value of @p. | ||
590 | * @p contains the task_struct of process. | ||
591 | * Return 0 if permission is granted. | ||
588 | * @task_setrlimit: | 592 | * @task_setrlimit: |
589 | * Check permission before setting the resource limits of the current | 593 | * Check permission before setting the resource limits of the current |
590 | * process for @resource to @new_rlim. The old resource limit values can | 594 | * process for @resource to @new_rlim. The old resource limit values can |
@@ -1227,6 +1231,7 @@ struct security_operations { | |||
1227 | int (*task_setgroups) (struct group_info *group_info); | 1231 | int (*task_setgroups) (struct group_info *group_info); |
1228 | int (*task_setnice) (struct task_struct * p, int nice); | 1232 | int (*task_setnice) (struct task_struct * p, int nice); |
1229 | int (*task_setioprio) (struct task_struct * p, int ioprio); | 1233 | int (*task_setioprio) (struct task_struct * p, int ioprio); |
1234 | int (*task_getioprio) (struct task_struct * p); | ||
1230 | int (*task_setrlimit) (unsigned int resource, struct rlimit * new_rlim); | 1235 | int (*task_setrlimit) (unsigned int resource, struct rlimit * new_rlim); |
1231 | int (*task_setscheduler) (struct task_struct * p, int policy, | 1236 | int (*task_setscheduler) (struct task_struct * p, int policy, |
1232 | struct sched_param * lp); | 1237 | struct sched_param * lp); |
@@ -1864,6 +1869,11 @@ static inline int security_task_setioprio (struct task_struct *p, int ioprio) | |||
1864 | return security_ops->task_setioprio (p, ioprio); | 1869 | return security_ops->task_setioprio (p, ioprio); |
1865 | } | 1870 | } |
1866 | 1871 | ||
1872 | static inline int security_task_getioprio (struct task_struct *p) | ||
1873 | { | ||
1874 | return security_ops->task_getioprio (p); | ||
1875 | } | ||
1876 | |||
1867 | static inline int security_task_setrlimit (unsigned int resource, | 1877 | static inline int security_task_setrlimit (unsigned int resource, |
1868 | struct rlimit *new_rlim) | 1878 | struct rlimit *new_rlim) |
1869 | { | 1879 | { |
@@ -2520,6 +2530,11 @@ static inline int security_task_setioprio (struct task_struct *p, int ioprio) | |||
2520 | return 0; | 2530 | return 0; |
2521 | } | 2531 | } |
2522 | 2532 | ||
2533 | static inline int security_task_getioprio (struct task_struct *p) | ||
2534 | { | ||
2535 | return 0; | ||
2536 | } | ||
2537 | |||
2523 | static inline int security_task_setrlimit (unsigned int resource, | 2538 | static inline int security_task_setrlimit (unsigned int resource, |
2524 | struct rlimit *new_rlim) | 2539 | struct rlimit *new_rlim) |
2525 | { | 2540 | { |
diff --git a/security/dummy.c b/security/dummy.c index de53f6eb0c08..d417936562db 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
@@ -524,6 +524,11 @@ static int dummy_task_setioprio (struct task_struct *p, int ioprio) | |||
524 | return 0; | 524 | return 0; |
525 | } | 525 | } |
526 | 526 | ||
527 | static int dummy_task_getioprio (struct task_struct *p) | ||
528 | { | ||
529 | return 0; | ||
530 | } | ||
531 | |||
527 | static int dummy_task_setrlimit (unsigned int resource, struct rlimit *new_rlim) | 532 | static int dummy_task_setrlimit (unsigned int resource, struct rlimit *new_rlim) |
528 | { | 533 | { |
529 | return 0; | 534 | return 0; |
@@ -988,6 +993,7 @@ void security_fixup_ops (struct security_operations *ops) | |||
988 | set_to_dummy_if_null(ops, task_setgroups); | 993 | set_to_dummy_if_null(ops, task_setgroups); |
989 | set_to_dummy_if_null(ops, task_setnice); | 994 | set_to_dummy_if_null(ops, task_setnice); |
990 | set_to_dummy_if_null(ops, task_setioprio); | 995 | set_to_dummy_if_null(ops, task_setioprio); |
996 | set_to_dummy_if_null(ops, task_getioprio); | ||
991 | set_to_dummy_if_null(ops, task_setrlimit); | 997 | set_to_dummy_if_null(ops, task_setrlimit); |
992 | set_to_dummy_if_null(ops, task_setscheduler); | 998 | set_to_dummy_if_null(ops, task_setscheduler); |
993 | set_to_dummy_if_null(ops, task_getscheduler); | 999 | set_to_dummy_if_null(ops, task_getscheduler); |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index a5189a347354..51bec4c88f19 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -2671,6 +2671,11 @@ static int selinux_task_setioprio(struct task_struct *p, int ioprio) | |||
2671 | return task_has_perm(current, p, PROCESS__SETSCHED); | 2671 | return task_has_perm(current, p, PROCESS__SETSCHED); |
2672 | } | 2672 | } |
2673 | 2673 | ||
2674 | static int selinux_task_getioprio(struct task_struct *p) | ||
2675 | { | ||
2676 | return task_has_perm(current, p, PROCESS__GETSCHED); | ||
2677 | } | ||
2678 | |||
2674 | static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) | 2679 | static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) |
2675 | { | 2680 | { |
2676 | struct rlimit *old_rlim = current->signal->rlim + resource; | 2681 | struct rlimit *old_rlim = current->signal->rlim + resource; |
@@ -4449,6 +4454,7 @@ static struct security_operations selinux_ops = { | |||
4449 | .task_setgroups = selinux_task_setgroups, | 4454 | .task_setgroups = selinux_task_setgroups, |
4450 | .task_setnice = selinux_task_setnice, | 4455 | .task_setnice = selinux_task_setnice, |
4451 | .task_setioprio = selinux_task_setioprio, | 4456 | .task_setioprio = selinux_task_setioprio, |
4457 | .task_getioprio = selinux_task_getioprio, | ||
4452 | .task_setrlimit = selinux_task_setrlimit, | 4458 | .task_setrlimit = selinux_task_setrlimit, |
4453 | .task_setscheduler = selinux_task_setscheduler, | 4459 | .task_setscheduler = selinux_task_setscheduler, |
4454 | .task_getscheduler = selinux_task_getscheduler, | 4460 | .task_getscheduler = selinux_task_getscheduler, |