diff options
author | David Quigley <dpquigl@tycho.nsa.gov> | 2006-06-30 04:55:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-30 14:25:36 -0400 |
commit | f9008e4c5c525941967b67777945aa6266ab6326 (patch) | |
tree | a0c9436485b80d548ef74d5f1aec0f6d0309af6e | |
parent | ed11d9eb2228acc483c819ab353e3c41bcb158fa (diff) |
[PATCH] SELinux: extend task_kill hook to handle signals sent by AIO completion
This patch extends the security_task_kill hook to handle signals sent by AIO
completion. In this case, the secid of the task responsible for the signal
needs to be obtained and saved earlier, so a security_task_getsecid() hook is
added, and then this saved value is passed subsequently to the extended
task_kill hook for use in checking.
Signed-off-by: David Quigley <dpquigl@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: Chris Wright <chrisw@sous-sol.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | include/linux/security.h | 23 | ||||
-rw-r--r-- | security/dummy.c | 6 | ||||
-rw-r--r-- | security/selinux/hooks.c | 20 |
3 files changed, 40 insertions, 9 deletions
diff --git a/include/linux/security.h b/include/linux/security.h index c7ea15716dce..d4b13d617f63 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -567,6 +567,9 @@ struct swap_info_struct; | |||
567 | * @p. | 567 | * @p. |
568 | * @p contains the task_struct for the process. | 568 | * @p contains the task_struct for the process. |
569 | * Return 0 if permission is granted. | 569 | * Return 0 if permission is granted. |
570 | * @task_getsecid: | ||
571 | * Retrieve the security identifier of the process @p. | ||
572 | * @p contains the task_struct for the process and place is into @secid. | ||
570 | * @task_setgroups: | 573 | * @task_setgroups: |
571 | * Check permission before setting the supplementary group set of the | 574 | * Check permission before setting the supplementary group set of the |
572 | * current process. | 575 | * current process. |
@@ -615,6 +618,7 @@ struct swap_info_struct; | |||
615 | * @p contains the task_struct for process. | 618 | * @p contains the task_struct for process. |
616 | * @info contains the signal information. | 619 | * @info contains the signal information. |
617 | * @sig contains the signal value. | 620 | * @sig contains the signal value. |
621 | * @secid contains the sid of the process where the signal originated | ||
618 | * Return 0 if permission is granted. | 622 | * Return 0 if permission is granted. |
619 | * @task_wait: | 623 | * @task_wait: |
620 | * Check permission before allowing a process to reap a child process @p | 624 | * Check permission before allowing a process to reap a child process @p |
@@ -1219,6 +1223,7 @@ struct security_operations { | |||
1219 | int (*task_setpgid) (struct task_struct * p, pid_t pgid); | 1223 | int (*task_setpgid) (struct task_struct * p, pid_t pgid); |
1220 | int (*task_getpgid) (struct task_struct * p); | 1224 | int (*task_getpgid) (struct task_struct * p); |
1221 | int (*task_getsid) (struct task_struct * p); | 1225 | int (*task_getsid) (struct task_struct * p); |
1226 | void (*task_getsecid) (struct task_struct * p, u32 * secid); | ||
1222 | int (*task_setgroups) (struct group_info *group_info); | 1227 | int (*task_setgroups) (struct group_info *group_info); |
1223 | int (*task_setnice) (struct task_struct * p, int nice); | 1228 | int (*task_setnice) (struct task_struct * p, int nice); |
1224 | int (*task_setioprio) (struct task_struct * p, int ioprio); | 1229 | int (*task_setioprio) (struct task_struct * p, int ioprio); |
@@ -1228,7 +1233,7 @@ struct security_operations { | |||
1228 | int (*task_getscheduler) (struct task_struct * p); | 1233 | int (*task_getscheduler) (struct task_struct * p); |
1229 | int (*task_movememory) (struct task_struct * p); | 1234 | int (*task_movememory) (struct task_struct * p); |
1230 | int (*task_kill) (struct task_struct * p, | 1235 | int (*task_kill) (struct task_struct * p, |
1231 | struct siginfo * info, int sig); | 1236 | struct siginfo * info, int sig, u32 secid); |
1232 | int (*task_wait) (struct task_struct * p); | 1237 | int (*task_wait) (struct task_struct * p); |
1233 | int (*task_prctl) (int option, unsigned long arg2, | 1238 | int (*task_prctl) (int option, unsigned long arg2, |
1234 | unsigned long arg3, unsigned long arg4, | 1239 | unsigned long arg3, unsigned long arg4, |
@@ -1839,6 +1844,11 @@ static inline int security_task_getsid (struct task_struct *p) | |||
1839 | return security_ops->task_getsid (p); | 1844 | return security_ops->task_getsid (p); |
1840 | } | 1845 | } |
1841 | 1846 | ||
1847 | static inline void security_task_getsecid (struct task_struct *p, u32 *secid) | ||
1848 | { | ||
1849 | security_ops->task_getsecid (p, secid); | ||
1850 | } | ||
1851 | |||
1842 | static inline int security_task_setgroups (struct group_info *group_info) | 1852 | static inline int security_task_setgroups (struct group_info *group_info) |
1843 | { | 1853 | { |
1844 | return security_ops->task_setgroups (group_info); | 1854 | return security_ops->task_setgroups (group_info); |
@@ -1878,9 +1888,10 @@ static inline int security_task_movememory (struct task_struct *p) | |||
1878 | } | 1888 | } |
1879 | 1889 | ||
1880 | static inline int security_task_kill (struct task_struct *p, | 1890 | static inline int security_task_kill (struct task_struct *p, |
1881 | struct siginfo *info, int sig) | 1891 | struct siginfo *info, int sig, |
1892 | u32 secid) | ||
1882 | { | 1893 | { |
1883 | return security_ops->task_kill (p, info, sig); | 1894 | return security_ops->task_kill (p, info, sig, secid); |
1884 | } | 1895 | } |
1885 | 1896 | ||
1886 | static inline int security_task_wait (struct task_struct *p) | 1897 | static inline int security_task_wait (struct task_struct *p) |
@@ -2491,6 +2502,9 @@ static inline int security_task_getsid (struct task_struct *p) | |||
2491 | return 0; | 2502 | return 0; |
2492 | } | 2503 | } |
2493 | 2504 | ||
2505 | static inline void security_task_getsecid (struct task_struct *p, u32 *secid) | ||
2506 | { } | ||
2507 | |||
2494 | static inline int security_task_setgroups (struct group_info *group_info) | 2508 | static inline int security_task_setgroups (struct group_info *group_info) |
2495 | { | 2509 | { |
2496 | return 0; | 2510 | return 0; |
@@ -2530,7 +2544,8 @@ static inline int security_task_movememory (struct task_struct *p) | |||
2530 | } | 2544 | } |
2531 | 2545 | ||
2532 | static inline int security_task_kill (struct task_struct *p, | 2546 | static inline int security_task_kill (struct task_struct *p, |
2533 | struct siginfo *info, int sig) | 2547 | struct siginfo *info, int sig, |
2548 | u32 secid) | ||
2534 | { | 2549 | { |
2535 | return 0; | 2550 | return 0; |
2536 | } | 2551 | } |
diff --git a/security/dummy.c b/security/dummy.c index 913540808577..de53f6eb0c08 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
@@ -506,6 +506,9 @@ static int dummy_task_getsid (struct task_struct *p) | |||
506 | return 0; | 506 | return 0; |
507 | } | 507 | } |
508 | 508 | ||
509 | static void dummy_task_getsecid (struct task_struct *p, u32 *secid) | ||
510 | { } | ||
511 | |||
509 | static int dummy_task_setgroups (struct group_info *group_info) | 512 | static int dummy_task_setgroups (struct group_info *group_info) |
510 | { | 513 | { |
511 | return 0; | 514 | return 0; |
@@ -548,7 +551,7 @@ static int dummy_task_wait (struct task_struct *p) | |||
548 | } | 551 | } |
549 | 552 | ||
550 | static int dummy_task_kill (struct task_struct *p, struct siginfo *info, | 553 | static int dummy_task_kill (struct task_struct *p, struct siginfo *info, |
551 | int sig) | 554 | int sig, u32 secid) |
552 | { | 555 | { |
553 | return 0; | 556 | return 0; |
554 | } | 557 | } |
@@ -981,6 +984,7 @@ void security_fixup_ops (struct security_operations *ops) | |||
981 | set_to_dummy_if_null(ops, task_setpgid); | 984 | set_to_dummy_if_null(ops, task_setpgid); |
982 | set_to_dummy_if_null(ops, task_getpgid); | 985 | set_to_dummy_if_null(ops, task_getpgid); |
983 | set_to_dummy_if_null(ops, task_getsid); | 986 | set_to_dummy_if_null(ops, task_getsid); |
987 | set_to_dummy_if_null(ops, task_getsecid); | ||
984 | set_to_dummy_if_null(ops, task_setgroups); | 988 | set_to_dummy_if_null(ops, task_setgroups); |
985 | set_to_dummy_if_null(ops, task_setnice); | 989 | set_to_dummy_if_null(ops, task_setnice); |
986 | set_to_dummy_if_null(ops, task_setioprio); | 990 | set_to_dummy_if_null(ops, task_setioprio); |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b85afcf38527..a5189a347354 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -2644,6 +2644,11 @@ static int selinux_task_getsid(struct task_struct *p) | |||
2644 | return task_has_perm(current, p, PROCESS__GETSESSION); | 2644 | return task_has_perm(current, p, PROCESS__GETSESSION); |
2645 | } | 2645 | } |
2646 | 2646 | ||
2647 | static void selinux_task_getsecid(struct task_struct *p, u32 *secid) | ||
2648 | { | ||
2649 | selinux_get_task_sid(p, secid); | ||
2650 | } | ||
2651 | |||
2647 | static int selinux_task_setgroups(struct group_info *group_info) | 2652 | static int selinux_task_setgroups(struct group_info *group_info) |
2648 | { | 2653 | { |
2649 | /* See the comment for setuid above. */ | 2654 | /* See the comment for setuid above. */ |
@@ -2700,12 +2705,14 @@ static int selinux_task_movememory(struct task_struct *p) | |||
2700 | return task_has_perm(current, p, PROCESS__SETSCHED); | 2705 | return task_has_perm(current, p, PROCESS__SETSCHED); |
2701 | } | 2706 | } |
2702 | 2707 | ||
2703 | static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int sig) | 2708 | static int selinux_task_kill(struct task_struct *p, struct siginfo *info, |
2709 | int sig, u32 secid) | ||
2704 | { | 2710 | { |
2705 | u32 perm; | 2711 | u32 perm; |
2706 | int rc; | 2712 | int rc; |
2713 | struct task_security_struct *tsec; | ||
2707 | 2714 | ||
2708 | rc = secondary_ops->task_kill(p, info, sig); | 2715 | rc = secondary_ops->task_kill(p, info, sig, secid); |
2709 | if (rc) | 2716 | if (rc) |
2710 | return rc; | 2717 | return rc; |
2711 | 2718 | ||
@@ -2716,8 +2723,12 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int si | |||
2716 | perm = PROCESS__SIGNULL; /* null signal; existence test */ | 2723 | perm = PROCESS__SIGNULL; /* null signal; existence test */ |
2717 | else | 2724 | else |
2718 | perm = signal_to_av(sig); | 2725 | perm = signal_to_av(sig); |
2719 | 2726 | tsec = p->security; | |
2720 | return task_has_perm(current, p, perm); | 2727 | if (secid) |
2728 | rc = avc_has_perm(secid, tsec->sid, SECCLASS_PROCESS, perm, NULL); | ||
2729 | else | ||
2730 | rc = task_has_perm(current, p, perm); | ||
2731 | return rc; | ||
2721 | } | 2732 | } |
2722 | 2733 | ||
2723 | static int selinux_task_prctl(int option, | 2734 | static int selinux_task_prctl(int option, |
@@ -4434,6 +4445,7 @@ static struct security_operations selinux_ops = { | |||
4434 | .task_setpgid = selinux_task_setpgid, | 4445 | .task_setpgid = selinux_task_setpgid, |
4435 | .task_getpgid = selinux_task_getpgid, | 4446 | .task_getpgid = selinux_task_getpgid, |
4436 | .task_getsid = selinux_task_getsid, | 4447 | .task_getsid = selinux_task_getsid, |
4448 | .task_getsecid = selinux_task_getsecid, | ||
4437 | .task_setgroups = selinux_task_setgroups, | 4449 | .task_setgroups = selinux_task_setgroups, |
4438 | .task_setnice = selinux_task_setnice, | 4450 | .task_setnice = selinux_task_setnice, |
4439 | .task_setioprio = selinux_task_setioprio, | 4451 | .task_setioprio = selinux_task_setioprio, |