aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2013-02-18 19:03:34 -0500
committerJohn Johansen <john.johansen@canonical.com>2013-04-28 03:35:53 -0400
commit3cfcc19e0b5390c04cb5bfa4e8fde39395410e61 (patch)
tree6ce52c3cc5166390814b9451d58badcfee9a3770
parente573cc30bb36df23fb49a29d96e6c6333d17f59c (diff)
apparmor: add utility function to get an arbitrary tasks profile.
Signed-off-by: John Johansen <john.johansen@canonical.com> Acked-by: Steve Beattie <sbeattie@ubuntu.com>
-rw-r--r--security/apparmor/context.c17
-rw-r--r--security/apparmor/domain.c10
-rw-r--r--security/apparmor/include/context.h41
-rw-r--r--security/apparmor/ipc.c13
4 files changed, 49 insertions, 32 deletions
diff --git a/security/apparmor/context.c b/security/apparmor/context.c
index 8a9b5027c813..611e6ce70b03 100644
--- a/security/apparmor/context.c
+++ b/security/apparmor/context.c
@@ -69,6 +69,23 @@ void aa_dup_task_context(struct aa_task_cxt *new, const struct aa_task_cxt *old)
69} 69}
70 70
71/** 71/**
72 * aa_get_task_profile - Get another task's profile
73 * @task: task to query (NOT NULL)
74 *
75 * Returns: counted reference to @task's profile
76 */
77struct aa_profile *aa_get_task_profile(struct task_struct *task)
78{
79 struct aa_profile *p;
80
81 rcu_read_lock();
82 p = aa_get_profile(__aa_task_profile(task));
83 rcu_read_unlock();
84
85 return p;
86}
87
88/**
72 * aa_replace_current_profile - replace the current tasks profiles 89 * aa_replace_current_profile - replace the current tasks profiles
73 * @profile: new profile (NOT NULL) 90 * @profile: new profile (NOT NULL)
74 * 91 *
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 7a78e814f0d4..fb47d5b71ea6 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -62,17 +62,14 @@ static int may_change_ptraced_domain(struct task_struct *task,
62 struct aa_profile *to_profile) 62 struct aa_profile *to_profile)
63{ 63{
64 struct task_struct *tracer; 64 struct task_struct *tracer;
65 const struct cred *cred = NULL;
66 struct aa_profile *tracerp = NULL; 65 struct aa_profile *tracerp = NULL;
67 int error = 0; 66 int error = 0;
68 67
69 rcu_read_lock(); 68 rcu_read_lock();
70 tracer = ptrace_parent(task); 69 tracer = ptrace_parent(task);
71 if (tracer) { 70 if (tracer)
72 /* released below */ 71 /* released below */
73 cred = get_task_cred(tracer); 72 tracerp = aa_get_task_profile(tracer);
74 tracerp = aa_cred_profile(cred);
75 }
76 73
77 /* not ptraced */ 74 /* not ptraced */
78 if (!tracer || unconfined(tracerp)) 75 if (!tracer || unconfined(tracerp))
@@ -82,8 +79,7 @@ static int may_change_ptraced_domain(struct task_struct *task,
82 79
83out: 80out:
84 rcu_read_unlock(); 81 rcu_read_unlock();
85 if (cred) 82 aa_put_profile(tracerp);
86 put_cred(cred);
87 83
88 return error; 84 return error;
89} 85}
diff --git a/security/apparmor/include/context.h b/security/apparmor/include/context.h
index a9cbee4d9e48..1e9443a58877 100644
--- a/security/apparmor/include/context.h
+++ b/security/apparmor/include/context.h
@@ -80,23 +80,8 @@ int aa_replace_current_profile(struct aa_profile *profile);
80int aa_set_current_onexec(struct aa_profile *profile); 80int aa_set_current_onexec(struct aa_profile *profile);
81int aa_set_current_hat(struct aa_profile *profile, u64 token); 81int aa_set_current_hat(struct aa_profile *profile, u64 token);
82int aa_restore_previous_profile(u64 cookie); 82int aa_restore_previous_profile(u64 cookie);
83struct aa_profile *aa_get_task_profile(struct task_struct *task);
83 84
84/**
85 * __aa_task_is_confined - determine if @task has any confinement
86 * @task: task to check confinement of (NOT NULL)
87 *
88 * If @task != current needs to be called in RCU safe critical section
89 */
90static inline bool __aa_task_is_confined(struct task_struct *task)
91{
92 struct aa_task_cxt *cxt = __task_cred(task)->security;
93
94 BUG_ON(!cxt || !cxt->profile);
95 if (unconfined(aa_newest_version(cxt->profile)))
96 return 0;
97
98 return 1;
99}
100 85
101/** 86/**
102 * aa_cred_profile - obtain cred's profiles 87 * aa_cred_profile - obtain cred's profiles
@@ -114,6 +99,30 @@ static inline struct aa_profile *aa_cred_profile(const struct cred *cred)
114} 99}
115 100
116/** 101/**
102 * __aa_task_profile - retrieve another task's profile
103 * @task: task to query (NOT NULL)
104 *
105 * Returns: @task's profile without incrementing its ref count
106 *
107 * If @task != current needs to be called in RCU safe critical section
108 */
109static inline struct aa_profile *__aa_task_profile(struct task_struct *task)
110{
111 return aa_cred_profile(__task_cred(task));
112}
113
114/**
115 * __aa_task_is_confined - determine if @task has any confinement
116 * @task: task to check confinement of (NOT NULL)
117 *
118 * If @task != current needs to be called in RCU safe critical section
119 */
120static inline bool __aa_task_is_confined(struct task_struct *task)
121{
122 return !unconfined(__aa_task_profile(task));
123}
124
125/**
117 * __aa_current_profile - find the current tasks confining profile 126 * __aa_current_profile - find the current tasks confining profile
118 * 127 *
119 * Returns: up to date confining profile or the ns unconfined profile (NOT NULL) 128 * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
index cf1071b14232..c51d2266587e 100644
--- a/security/apparmor/ipc.c
+++ b/security/apparmor/ipc.c
@@ -95,23 +95,18 @@ int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee,
95 * - tracer profile has CAP_SYS_PTRACE 95 * - tracer profile has CAP_SYS_PTRACE
96 */ 96 */
97 97
98 struct aa_profile *tracer_p; 98 struct aa_profile *tracer_p = aa_get_task_profile(tracer);
99 /* cred released below */
100 const struct cred *cred = get_task_cred(tracer);
101 int error = 0; 99 int error = 0;
102 tracer_p = aa_cred_profile(cred);
103 100
104 if (!unconfined(tracer_p)) { 101 if (!unconfined(tracer_p)) {
105 /* lcred released below */ 102 struct aa_profile *tracee_p = aa_get_task_profile(tracee);
106 const struct cred *lcred = get_task_cred(tracee);
107 struct aa_profile *tracee_p = aa_cred_profile(lcred);
108 103
109 error = aa_may_ptrace(tracer, tracer_p, tracee_p, mode); 104 error = aa_may_ptrace(tracer, tracer_p, tracee_p, mode);
110 error = aa_audit_ptrace(tracer_p, tracee_p, error); 105 error = aa_audit_ptrace(tracer_p, tracee_p, error);
111 106
112 put_cred(lcred); 107 aa_put_profile(tracee_p);
113 } 108 }
114 put_cred(cred); 109 aa_put_profile(tracer_p);
115 110
116 return error; 111 return error;
117} 112}