From patchwork Thu Aug 11 05:02:42 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [08/13] AppArmor: add utility function to get an arbitrary tasks profile. Date: Wed, 10 Aug 2011 19:02:42 -0000 From: John Johansen X-Patchwork-Id: 109527 Message-Id: <1313038967-19941-9-git-send-email-john.johansen@canonical.com> To: kernel-team@lists.ubuntu.com Signed-off-by: John Johansen --- security/apparmor/context.c | 17 +++++++++++++ security/apparmor/domain.c | 10 ++----- security/apparmor/include/context.h | 44 ++++++++++++++++++++++------------ security/apparmor/ipc.c | 13 +++------- 4 files changed, 52 insertions(+), 32 deletions(-) diff --git a/security/apparmor/context.c b/security/apparmor/context.c index 8a9b502..611e6ce 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) } /** + * aa_get_task_profile - Get another task's profile + * @task: task to query (NOT NULL) + * + * Returns: counted reference to @task's profile + */ +struct aa_profile *aa_get_task_profile(struct task_struct *task) +{ + struct aa_profile *p; + + rcu_read_lock(); + p = aa_get_profile(__aa_task_profile(task)); + rcu_read_unlock(); + + return p; +} + +/** * aa_replace_current_profile - replace the current tasks profiles * @profile: new profile (NOT NULL) * diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index 78adc43..e3d2b4f 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, struct aa_profile *to_profile) { struct task_struct *tracer; - const struct cred *cred = NULL; struct aa_profile *tracerp = NULL; int error = 0; rcu_read_lock(); tracer = tracehook_tracer_task(task); - if (tracer) { + if (tracer) /* released below */ - cred = get_task_cred(tracer); - tracerp = aa_cred_profile(cred); - } + tracerp = aa_get_profile(__aa_task_profile(tracer)); /* not ptraced */ if (!tracer || unconfined(tracerp)) @@ -82,8 +79,7 @@ static int may_change_ptraced_domain(struct task_struct *task, out: rcu_read_unlock(); - if (cred) - put_cred(cred); + aa_put_profile(tracerp); return error; } diff --git a/security/apparmor/include/context.h b/security/apparmor/include/context.h index a9cbee4..520e06f 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); int aa_set_current_onexec(struct aa_profile *profile); int aa_set_current_hat(struct aa_profile *profile, u64 token); int aa_restore_previous_profile(u64 cookie); +struct aa_profile *aa_get_task_profile(struct task_struct *task); -/** - * __aa_task_is_confined - determine if @task has any confinement - * @task: task to check confinement of (NOT NULL) - * - * If @task != current needs to be called in RCU safe critical section - */ -static inline bool __aa_task_is_confined(struct task_struct *task) -{ - struct aa_task_cxt *cxt = __task_cred(task)->security; - - BUG_ON(!cxt || !cxt->profile); - if (unconfined(aa_newest_version(cxt->profile))) - return 0; - - return 1; -} /** * aa_cred_profile - obtain cred's profiles @@ -114,6 +99,33 @@ static inline struct aa_profile *aa_cred_profile(const struct cred *cred) } /** + * __aa_task_profile - retrieve another task's profile + * @task: task to query (NOT NULL) + * + * Returns: @task's profile without incrementing its ref count + * + * If @task != current needs to be called in RCU safe critical section + */ +static struct aa_profile *__aa_task_profile(struct task_struct *task) +{ + return aa_cred_profile(__task_cred(task)); +} + +/** + * __aa_task_is_confined - determine if @task has any confinement + * @task: task to check confinement of (NOT NULL) + * + * If @task != current needs to be called in RCU safe critical section + */ +static inline bool __aa_task_is_confined(struct task_struct *task) +{ + if (unconfined(__aa_task_profile(task))) + return 0; + + return 1; +} + +/** * __aa_current_profile - find the current tasks confining profile * * 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 649fad8..fcc3978 100644 --- a/security/apparmor/ipc.c +++ b/security/apparmor/ipc.c @@ -92,23 +92,18 @@ int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee, * - tracer profile has CAP_SYS_PTRACE */ - struct aa_profile *tracer_p; - /* cred released below */ - const struct cred *cred = get_task_cred(tracer); + struct aa_profile *tracer_p = aa_get_task_profile(tracer); int error = 0; - tracer_p = aa_cred_profile(cred); if (!unconfined(tracer_p)) { - /* lcred released below */ - const struct cred *lcred = get_task_cred(tracee); - struct aa_profile *tracee_p = aa_cred_profile(lcred); + struct aa_profile *tracee_p = aa_get_task_profile(tracee); error = aa_may_ptrace(tracer, tracer_p, tracee_p, mode); error = aa_audit_ptrace(tracer_p, tracee_p, error); - put_cred(lcred); + aa_put_profile(tracee_p); } - put_cred(cred); + aa_put_profile(tracer_p); return error; }