From 3cfcc19e0b5390c04cb5bfa4e8fde39395410e61 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Mon, 18 Feb 2013 16:03:34 -0800 Subject: apparmor: add utility function to get an arbitrary tasks profile. Signed-off-by: John Johansen Acked-by: Steve Beattie --- security/apparmor/context.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'security/apparmor/context.c') diff --git a/security/apparmor/context.c b/security/apparmor/context.c index 8a9b5027c81..611e6ce70b0 100644 --- a/security/apparmor/context.c +++ b/security/apparmor/context.c @@ -68,6 +68,23 @@ void aa_dup_task_context(struct aa_task_cxt *new, const struct aa_task_cxt *old) aa_get_profile(new->onexec); } +/** + * 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) -- cgit v1.2.3-70-g09d2 From 7a2871b566f34d980556072943295efd107eb53c Mon Sep 17 00:00:00 2001 From: John Johansen Date: Mon, 18 Feb 2013 16:05:34 -0800 Subject: apparmor: use common fn to clear task_context for domain transitions Signed-off-by: John Johansen Acked-by: Steve Beattie --- security/apparmor/context.c | 17 ++++++----------- security/apparmor/domain.c | 6 +----- security/apparmor/include/context.h | 13 +++++++++++++ 3 files changed, 20 insertions(+), 16 deletions(-) (limited to 'security/apparmor/context.c') diff --git a/security/apparmor/context.c b/security/apparmor/context.c index 611e6ce70b0..3f911afa2bb 100644 --- a/security/apparmor/context.c +++ b/security/apparmor/context.c @@ -105,16 +105,12 @@ int aa_replace_current_profile(struct aa_profile *profile) return -ENOMEM; cxt = new->security; - if (unconfined(profile) || (cxt->profile->ns != profile->ns)) { + if (unconfined(profile) || (cxt->profile->ns != profile->ns)) /* if switching to unconfined or a different profile namespace * clear out context state */ - aa_put_profile(cxt->previous); - aa_put_profile(cxt->onexec); - cxt->previous = NULL; - cxt->onexec = NULL; - cxt->token = 0; - } + aa_clear_task_cxt_trans(cxt); + /* be careful switching cxt->profile, when racing replacement it * is possible that cxt->profile->replacedby is the reference keeping * @profile valid, so make sure to get its reference before dropping @@ -222,11 +218,10 @@ int aa_restore_previous_profile(u64 token) aa_get_profile(cxt->profile); aa_put_profile(cxt->previous); } - /* clear exec && prev information when restoring to previous context */ + /* ref has been transfered so avoid putting ref in clear_task_cxt */ cxt->previous = NULL; - cxt->token = 0; - aa_put_profile(cxt->onexec); - cxt->onexec = NULL; + /* clear exec && prev information when restoring to previous context */ + aa_clear_task_cxt_trans(cxt); commit_creds(new); return 0; diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index fb47d5b71ea..07fcb09b990 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -512,11 +512,7 @@ x_clear: cxt->profile = new_profile; /* clear out all temporary/transitional state from the context */ - aa_put_profile(cxt->previous); - aa_put_profile(cxt->onexec); - cxt->previous = NULL; - cxt->onexec = NULL; - cxt->token = 0; + aa_clear_task_cxt_trans(cxt); audit: error = aa_audit_file(profile, &perms, GFP_KERNEL, OP_EXEC, MAY_EXEC, diff --git a/security/apparmor/include/context.h b/security/apparmor/include/context.h index 1e9443a5887..4cecad31322 100644 --- a/security/apparmor/include/context.h +++ b/security/apparmor/include/context.h @@ -160,4 +160,17 @@ static inline struct aa_profile *aa_current_profile(void) return profile; } +/** + * aa_clear_task_cxt_trans - clear transition tracking info from the cxt + * @cxt: task context to clear (NOT NULL) + */ +static inline void aa_clear_task_cxt_trans(struct aa_task_cxt *cxt) +{ + aa_put_profile(cxt->previous); + aa_put_profile(cxt->onexec); + cxt->previous = NULL; + cxt->onexec = NULL; + cxt->token = 0; +} + #endif /* __AA_CONTEXT_H */ -- cgit v1.2.3-70-g09d2 From 214beacaa7b669473bc963af719fa359a8312ea4 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Wed, 27 Feb 2013 03:43:40 -0800 Subject: apparmor: localize getting the security context to a few macros Signed-off-by: John Johansen Acked-by: Seth Arnold --- security/apparmor/context.c | 10 +++++----- security/apparmor/domain.c | 6 +++--- security/apparmor/include/context.h | 7 +++++-- security/apparmor/lsm.c | 22 +++++++++++----------- 4 files changed, 24 insertions(+), 21 deletions(-) (limited to 'security/apparmor/context.c') diff --git a/security/apparmor/context.c b/security/apparmor/context.c index 3f911afa2bb..d5af1d15f26 100644 --- a/security/apparmor/context.c +++ b/security/apparmor/context.c @@ -93,7 +93,7 @@ struct aa_profile *aa_get_task_profile(struct task_struct *task) */ int aa_replace_current_profile(struct aa_profile *profile) { - struct aa_task_cxt *cxt = current_cred()->security; + struct aa_task_cxt *cxt = current_cxt(); struct cred *new; BUG_ON(!profile); @@ -104,7 +104,7 @@ int aa_replace_current_profile(struct aa_profile *profile) if (!new) return -ENOMEM; - cxt = new->security; + cxt = cred_cxt(new); if (unconfined(profile) || (cxt->profile->ns != profile->ns)) /* if switching to unconfined or a different profile namespace * clear out context state @@ -136,7 +136,7 @@ int aa_set_current_onexec(struct aa_profile *profile) if (!new) return -ENOMEM; - cxt = new->security; + cxt = cred_cxt(new); aa_get_profile(profile); aa_put_profile(cxt->onexec); cxt->onexec = profile; @@ -163,7 +163,7 @@ int aa_set_current_hat(struct aa_profile *profile, u64 token) return -ENOMEM; BUG_ON(!profile); - cxt = new->security; + cxt = cred_cxt(new); if (!cxt->previous) { /* transfer refcount */ cxt->previous = cxt->profile; @@ -200,7 +200,7 @@ int aa_restore_previous_profile(u64 token) if (!new) return -ENOMEM; - cxt = new->security; + cxt = cred_cxt(new); if (cxt->token != token) { abort_creds(new); return -EACCES; diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index 07fcb09b990..01b7bd669a8 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -356,7 +356,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) if (bprm->cred_prepared) return 0; - cxt = bprm->cred->security; + cxt = cred_cxt(bprm->cred); BUG_ON(!cxt); profile = aa_get_profile(aa_newest_version(cxt->profile)); @@ -551,7 +551,7 @@ int apparmor_bprm_secureexec(struct linux_binprm *bprm) void apparmor_bprm_committing_creds(struct linux_binprm *bprm) { struct aa_profile *profile = __aa_current_profile(); - struct aa_task_cxt *new_cxt = bprm->cred->security; + struct aa_task_cxt *new_cxt = cred_cxt(bprm->cred); /* bail out if unconfined or not changing profile */ if ((new_cxt->profile == profile) || @@ -628,7 +628,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) /* released below */ cred = get_current_cred(); - cxt = cred->security; + cxt = cred_cxt(cred); profile = aa_cred_profile(cred); previous_profile = cxt->previous; diff --git a/security/apparmor/include/context.h b/security/apparmor/include/context.h index 4cecad31322..d44ba5802e3 100644 --- a/security/apparmor/include/context.h +++ b/security/apparmor/include/context.h @@ -21,6 +21,9 @@ #include "policy.h" +#define cred_cxt(X) (X)->security +#define current_cxt() cred_cxt(current_cred()) + /* struct aa_file_cxt - the AppArmor context the file was opened in * @perms: the permission the file was opened with * @@ -93,7 +96,7 @@ struct aa_profile *aa_get_task_profile(struct task_struct *task); */ static inline struct aa_profile *aa_cred_profile(const struct cred *cred) { - struct aa_task_cxt *cxt = cred->security; + struct aa_task_cxt *cxt = cred_cxt(cred); BUG_ON(!cxt || !cxt->profile); return aa_newest_version(cxt->profile); } @@ -145,7 +148,7 @@ static inline struct aa_profile *__aa_current_profile(void) */ static inline struct aa_profile *aa_current_profile(void) { - const struct aa_task_cxt *cxt = current_cred()->security; + const struct aa_task_cxt *cxt = current_cxt(); struct aa_profile *profile; BUG_ON(!cxt || !cxt->profile); diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 10843aa5a36..2027fdf2060 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -48,8 +48,8 @@ int apparmor_initialized __initdata; */ static void apparmor_cred_free(struct cred *cred) { - aa_free_task_context(cred->security); - cred->security = NULL; + aa_free_task_context(cred_cxt(cred)); + cred_cxt(cred) = NULL; } /* @@ -62,7 +62,7 @@ static int apparmor_cred_alloc_blank(struct cred *cred, gfp_t gfp) if (!cxt) return -ENOMEM; - cred->security = cxt; + cred_cxt(cred) = cxt; return 0; } @@ -77,8 +77,8 @@ static int apparmor_cred_prepare(struct cred *new, const struct cred *old, if (!cxt) return -ENOMEM; - aa_dup_task_context(cxt, old->security); - new->security = cxt; + aa_dup_task_context(cxt, cred_cxt(old)); + cred_cxt(new) = cxt; return 0; } @@ -87,8 +87,8 @@ static int apparmor_cred_prepare(struct cred *new, const struct cred *old, */ static void apparmor_cred_transfer(struct cred *new, const struct cred *old) { - const struct aa_task_cxt *old_cxt = old->security; - struct aa_task_cxt *new_cxt = new->security; + const struct aa_task_cxt *old_cxt = cred_cxt(old); + struct aa_task_cxt *new_cxt = cred_cxt(new); aa_dup_task_context(new_cxt, old_cxt); } @@ -507,7 +507,7 @@ static int apparmor_getprocattr(struct task_struct *task, char *name, int error = -ENOENT; /* released below */ const struct cred *cred = get_task_cred(task); - struct aa_task_cxt *cxt = cred->security; + struct aa_task_cxt *cxt = cred_cxt(cred); if (strcmp(name, "current") == 0) error = aa_getprocattr(aa_newest_version(cxt->profile), @@ -880,7 +880,7 @@ static int __init set_init_cxt(void) return -ENOMEM; cxt->profile = aa_get_profile(root_ns->unconfined); - cred->security = cxt; + cred_cxt(cred) = cxt; return 0; } @@ -910,8 +910,8 @@ static int __init apparmor_init(void) error = register_security(&apparmor_ops); if (error) { struct cred *cred = (struct cred *)current->real_cred; - aa_free_task_context(cred->security); - cred->security = NULL; + aa_free_task_context(cred_cxt(cred)); + cred_cxt(cred) = NULL; AA_ERROR("Unable to register AppArmor\n"); goto register_security_out; } -- cgit v1.2.3-70-g09d2