remove old patches that got folded into change_profile-3.diff

This commit is contained in:
John Johansen 2007-06-23 08:08:12 +00:00
parent b69788e3f8
commit d740aec8e8
5 changed files with 0 additions and 1017 deletions

View file

@ -1,95 +0,0 @@
make change_hat, change_profile explicit to current instead of a generic
task.
---
security/apparmor/main.c | 27 ++++++++++++---------------
1 file changed, 12 insertions(+), 15 deletions(-)
--- a/security/apparmor/main.c
+++ b/security/apparmor/main.c
@@ -929,8 +929,7 @@ repeat:
}
}
-static int do_change_profile(struct task_struct *task, const char *name,
- u64 cookie, int restore_profile,
+static int do_change_profile(const char *name, u64 cookie, int restore_profile,
struct aa_audit *sa)
{
struct aa_profile *profile = NULL, *previous_profile = NULL;
@@ -947,7 +946,7 @@ static int do_change_profile(struct task
if (!profile && !restore_profile)
profile = aa_dup_profile(null_complain_profile);
- cxt = lock_task_and_profiles(task, profile);
+ cxt = lock_task_and_profiles(current, profile);
if (!cxt) {
error = -EPERM;
goto out;
@@ -959,7 +958,7 @@ static int do_change_profile(struct task
sa->info = "killing process";
aa_audit_reject(profile, sa);
/* terminate process */
- (void)send_sig_info(SIGKILL, NULL, task);
+ (void)send_sig_info(SIGKILL, NULL, current);
goto out;
}
@@ -968,7 +967,7 @@ static int do_change_profile(struct task
previous_profile = cxt->profile;
}
- if ((task->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) {
+ if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) {
error = -EACCES;
goto out;
}
@@ -985,15 +984,15 @@ static int do_change_profile(struct task
if (APPARMOR_AUDIT(cxt))
aa_audit_message(cxt->profile, sa, AUDIT_APPARMOR_AUDIT);
if (restore_profile)
- aa_change_task_context(task, new_cxt, profile, 0, NULL);
+ aa_change_task_context(current, new_cxt, profile, 0, NULL);
else
- aa_change_task_context(task, new_cxt, profile, cookie,
+ aa_change_task_context(current, new_cxt, profile, cookie,
previous_profile);
out:
- if (aa_task_context(task) != new_cxt)
+ if (aa_task_context(current) != new_cxt)
aa_free_task_context(new_cxt);
- unlock_task_and_profiles(task, cxt, profile);
+ unlock_task_and_profiles(current, cxt, profile);
aa_put_profile(profile);
return error;
}
@@ -1037,11 +1036,10 @@ int aa_change_profile(const char *name,
mutex_unlock(&aa_interface_lock);
return -EACCES;
}
- error = do_change_profile(current, name, cookie, 0, &sa);
+ error = do_change_profile(name, cookie, 0, &sa);
} else {
if (cxt->previous_profile)
- error = do_change_profile(current,
- cxt->previous_profile->name,
+ error = do_change_profile(cxt->previous_profile->name,
cookie, 1, &sa);
/* else
* Ignore change_profile to restore_previous profile when
@@ -1099,12 +1097,11 @@ int aa_change_hat(const char *hat_name,
return -ENOMEM;
}
sprintf(name, "%s//%s", profile_name, hat_name);
- error = do_change_profile(current, name, cookie, 0, &sa);
+ error = do_change_profile(name, cookie, 0, &sa);
kfree(name);
} else {
if (cxt->previous_profile)
- error = do_change_profile(current,
- cxt->previous_profile->name,
+ error = do_change_profile(cxt->previous_profile->name,
cookie, 1, &sa);
/* else
* Ignore change_hat to restore profile when there is

View file

@ -1,169 +0,0 @@
Give change_profile the ability to do a permanent transition
---
security/apparmor/apparmor.h | 2 +-
security/apparmor/main.c | 33 +++++++++++++++++++++++++--------
security/apparmor/procattr.c | 18 +++++++++++++-----
3 files changed, 39 insertions(+), 14 deletions(-)
--- a/security/apparmor/apparmor.h
+++ b/security/apparmor/apparmor.h
@@ -215,7 +215,7 @@ extern int aa_clone(struct task_struct *
extern int aa_register(struct linux_binprm *bprm);
extern void aa_release(struct task_struct *task);
extern int aa_change_hat(const char *id, u64 hat_magic);
-extern int aa_change_profile(const char *name, u64 cookie);
+extern int aa_change_profile(const char *name, u64 cookie, int permanent);
extern struct aa_profile *__aa_find_profile(const char *name,
struct list_head *list);
extern struct aa_profile *__aa_find_profile2(const char *name,
--- a/security/apparmor/main.c
+++ b/security/apparmor/main.c
@@ -929,7 +929,9 @@ repeat:
}
}
-static int do_change_profile(const char *name, u64 cookie, int restore_profile,
+enum { change_profile, permanent_change_profile, restore_profile };
+
+static int do_change_profile(const char *name, u64 cookie, int mode,
struct aa_audit *sa)
{
struct aa_profile *profile = NULL, *previous_profile = NULL;
@@ -943,7 +945,7 @@ static int do_change_profile(const char
return -ENOMEM;
profile = aa_find_profile(name);
- if (!profile && !restore_profile)
+ if (!profile && mode != restore_profile)
profile = aa_dup_profile(null_complain_profile);
cxt = lock_task_and_profiles(current, profile);
@@ -967,6 +969,12 @@ static int do_change_profile(const char
previous_profile = cxt->profile;
}
+ if (mode == permanent_change_profile) {
+ previous_profile = NULL;
+ cookie = 0;
+ sa->info = "permanent";
+ }
+
if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) {
error = -EACCES;
goto out;
@@ -983,7 +991,7 @@ static int do_change_profile(const char
if (APPARMOR_AUDIT(cxt))
aa_audit_message(cxt->profile, sa, AUDIT_APPARMOR_AUDIT);
- if (restore_profile)
+ if (mode == restore_profile)
aa_change_task_context(current, new_cxt, profile, 0, NULL);
else
aa_change_task_context(current, new_cxt, profile, cookie,
@@ -1002,6 +1010,7 @@ out:
* aa_change_profile - change profile to/from previous stored profile
* @name: name of profile to change to
* @cookie: magic value to validate the profile change
+ * @permanent: whether the profile change is permanent
*
* Change to new profile @name, and store the @cookie in the current task
* context. If the new @name is %NULL and the @cookie matches that
@@ -1009,7 +1018,7 @@ out:
*
* Returns %0 on success, error otherwise.
*/
-int aa_change_profile(const char *name, u64 cookie)
+int aa_change_profile(const char *name, u64 cookie, int permanent)
{
struct aa_task_context *cxt;
struct aa_audit sa;
@@ -1036,11 +1045,18 @@ int aa_change_profile(const char *name,
mutex_unlock(&aa_interface_lock);
return -EACCES;
}
- error = do_change_profile(name, cookie, 0, &sa);
+ if (permanent)
+ error = do_change_profile(name, cookie,
+ permanent_change_profile,
+ &sa);
+ else
+ error = do_change_profile(name, cookie, change_profile,
+ &sa);
} else {
if (cxt->previous_profile)
error = do_change_profile(cxt->previous_profile->name,
- cookie, 1, &sa);
+ cookie, restore_profile,
+ &sa);
/* else
* Ignore change_profile to restore_previous profile when
* it doesn't exist
@@ -1097,12 +1113,13 @@ int aa_change_hat(const char *hat_name,
return -ENOMEM;
}
sprintf(name, "%s//%s", profile_name, hat_name);
- error = do_change_profile(name, cookie, 0, &sa);
+ error = do_change_profile(name, cookie, change_profile, &sa);
kfree(name);
} else {
if (cxt->previous_profile)
error = do_change_profile(cxt->previous_profile->name,
- cookie, 1, &sa);
+ cookie, restore_profile,
+ &sa);
/* else
* Ignore change_hat to restore profile when there is
* no profile to restore
--- a/security/apparmor/procattr.c
+++ b/security/apparmor/procattr.c
@@ -50,14 +50,19 @@ int aa_getprocattr(struct aa_profile *pr
return 0;
}
-static char *split_token_from_name(const char *op, char *args, u64 *cookie)
+static char *split_token_from_name(const char *op, int *cookie_set,
+ char *args, u64 *cookie)
{
char *name;
*cookie = simple_strtoull(args, &name, 16);
- if (name == args || *name != '^') {
+ if ((name == args && *cookie_set) || *name != '^') {
AA_ERROR("%s: Invalid input '%s'", op, args);
return ERR_PTR(-EINVAL);
+ } else if (name == args) {
+ *cookie_set = 0;
+ } else {
+ *cookie_set = 1;
}
name++; /* skip ^ */
if (!*name)
@@ -69,8 +74,9 @@ int aa_setprocattr_changehat(char *args)
{
char *hat;
u64 cookie;
+ int cookie_set = 1;
- hat = split_token_from_name("change_hat", args, &cookie);
+ hat = split_token_from_name("change_hat", &cookie_set, args, &cookie);
if (IS_ERR(hat))
return PTR_ERR(hat);
@@ -89,12 +95,14 @@ int aa_setprocattr_changeprofile(char *a
{
char *name;
u64 cookie;
+ int cookie_set = 0;
- name = split_token_from_name("change_profile", args, &cookie);
+ name = split_token_from_name("change_profile", &cookie_set, args,
+ &cookie);
if (IS_ERR(name))
return PTR_ERR(name);
- return aa_change_profile(name, cookie);
+ return aa_change_profile(name, cookie, !cookie_set);
}
int aa_setprocattr_setprofile(struct task_struct *task, char *args)

View file

@ -1,234 +0,0 @@
---
security/apparmor/apparmor.h | 2 -
security/apparmor/main.c | 84 +++++++++++++------------------------------
security/apparmor/procattr.c | 20 +++-------
3 files changed, 34 insertions(+), 72 deletions(-)
--- a/security/apparmor/apparmor.h
+++ b/security/apparmor/apparmor.h
@@ -215,7 +215,7 @@ extern int aa_clone(struct task_struct *
extern int aa_register(struct linux_binprm *bprm);
extern void aa_release(struct task_struct *task);
extern int aa_change_hat(const char *id, u64 hat_magic);
-extern int aa_change_profile(const char *name, u64 cookie, int permanent);
+extern int aa_change_profile(const char *name, u64 cookie);
extern struct aa_profile *__aa_find_profile(const char *name,
struct list_head *list);
extern struct aa_profile *__aa_find_profile2(const char *name,
--- a/security/apparmor/main.c
+++ b/security/apparmor/main.c
@@ -934,10 +934,8 @@ repeat:
}
}
-enum { change_profile, permanent_change_profile, restore_profile };
-
static int do_change_profile(struct aa_profile *expected, const char *name,
- u64 cookie, int mode, struct aa_audit *sa)
+ u64 cookie, struct aa_audit *sa)
{
struct aa_profile *profile = NULL, *previous_profile = NULL;
struct aa_task_context *new_cxt, *cxt;
@@ -949,9 +947,11 @@ static int do_change_profile(struct aa_p
if (!new_cxt)
return -ENOMEM;
- profile = aa_find_profile(name);
- if (!profile && mode != restore_profile)
- profile = aa_dup_profile(null_complain_profile);
+ if (name) {
+ profile = aa_find_profile(name);
+ if (!profile)
+ profile = aa_dup_profile(null_complain_profile);
+ }
cxt = lock_task_and_profiles(current, profile);
if (!cxt) {
@@ -968,23 +968,24 @@ static int do_change_profile(struct aa_p
if (cxt->cookie != cookie) {
error = -EACCES;
sa->info = "killing process";
- aa_audit_reject(profile, sa);
+ aa_audit_reject(cxt->profile, sa);
/* terminate process */
(void)send_sig_info(SIGKILL, NULL, current);
goto out;
}
- previous_profile = cxt->previous_profile;
+ if (name)
+ previous_profile = cxt->previous_profile;
+ else
+ /* profile is null - returning to previous_profile */
+ profile = aa_dup_profile(cxt->previous_profile);
+ } else if (!name) {
+ /* ignore return when their is no previous_profile */
+ goto out;
} else {
previous_profile = cxt->profile;
}
- if (mode == permanent_change_profile) {
- previous_profile = NULL;
- cookie = 0;
- sa->info = "permanent";
- }
-
if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) {
error = -EACCES;
goto out;
@@ -1001,11 +1002,13 @@ static int do_change_profile(struct aa_p
if (APPARMOR_AUDIT(cxt))
aa_audit_message(cxt->profile, sa, AUDIT_APPARMOR_AUDIT);
- if (mode == restore_profile)
- aa_change_task_context(current, new_cxt, profile, 0, NULL);
- else
+
+ if (name && cookie)
aa_change_task_context(current, new_cxt, profile, cookie,
previous_profile);
+ else
+ /* either return to previous_profile, or a permanent change */
+ aa_change_task_context(current, new_cxt, profile, 0, NULL);
out:
if (aa_task_context(current) != new_cxt)
@@ -1020,7 +1023,6 @@ out:
* aa_change_profile - change profile to/from previous stored profile
* @name: name of profile to change to
* @cookie: magic value to validate the profile change
- * @permanent: whether the profile change is permanent
*
* Change to new profile @name, and store the @cookie in the current task
* context. If the new @name is %NULL and the @cookie matches that
@@ -1028,7 +1030,7 @@ out:
*
* Returns %0 on success, error otherwise.
*/
-int aa_change_profile(const char *name, u64 cookie, int permanent)
+int aa_change_profile(const char *name, u64 cookie)
{
struct aa_profile *profile;
struct aa_audit sa;
@@ -1052,31 +1054,9 @@ repeat:
aa_put_profile(profile);
return -EACCES;
}
- if (permanent)
- error = do_change_profile(profile, name, cookie,
- permanent_change_profile,
- &sa);
- else
- error = do_change_profile(profile, name, cookie,
- change_profile, &sa);
- } else {
- struct aa_profile *previous_profile;
- task_lock(current);
- previous_profile =
- aa_dup_profile(aa_task_context(current)->previous_profile);
- task_unlock(current);
-
- if (previous_profile)
- error = do_change_profile(profile,
- previous_profile->name,
- cookie, restore_profile,
- &sa);
- aa_put_profile(previous_profile);
- /* else
- * Ignore change_profile to restore_previous profile when
- * it doesn't exist
- */
- }
+ error = do_change_profile(profile, name, cookie, &sa);
+ } else
+ error = do_change_profile(profile, NULL, cookie, &sa);
aa_put_profile(profile);
if (error == -ESTALE)
@@ -1137,20 +1117,10 @@ repeat:
goto out;
}
sprintf(name, "%s//%s", profile_name, hat_name);
- error = do_change_profile(profile, name, cookie,
- change_profile, &sa);
+ error = do_change_profile(profile, name, cookie, &sa);
kfree(name);
- } else {
- if (previous_profile)
- error = do_change_profile(profile,
- previous_profile->name,
- cookie, restore_profile,
- &sa);
- /* else
- * Ignore change_hat to restore profile when there is
- * no profile to restore
- */
- }
+ } else
+ error = do_change_profile(profile, NULL, cookie, &sa);
out:
aa_put_profile(previous_profile);
--- a/security/apparmor/procattr.c
+++ b/security/apparmor/procattr.c
@@ -27,7 +27,6 @@ int aa_getprocattr(struct aa_profile *pr
str = kmalloc(*len, GFP_ATOMIC);
if (!str)
return -ENOMEM;
- /* FIXME: do we want to report ^ instead of // for hatnames */
memcpy(str, profile->name, name_len);
str += name_len;
@@ -50,20 +49,16 @@ int aa_getprocattr(struct aa_profile *pr
return 0;
}
-static char *split_token_from_name(const char *op, int *cookie_set,
- char *args, u64 *cookie)
+static char *split_token_from_name(const char *op, char *args, u64 *cookie)
{
char *name;
*cookie = simple_strtoull(args, &name, 16);
- if ((name == args && *cookie_set) || *name != '^') {
+ if ((name == args) || *name != '^') {
AA_ERROR("%s: Invalid input '%s'", op, args);
return ERR_PTR(-EINVAL);
- } else if (name == args) {
- *cookie_set = 0;
- } else {
- *cookie_set = 1;
}
+
name++; /* skip ^ */
if (!*name)
name = NULL;
@@ -74,9 +69,8 @@ int aa_setprocattr_changehat(char *args)
{
char *hat;
u64 cookie;
- int cookie_set = 1;
- hat = split_token_from_name("change_hat", &cookie_set, args, &cookie);
+ hat = split_token_from_name("change_hat", args, &cookie);
if (IS_ERR(hat))
return PTR_ERR(hat);
@@ -95,14 +89,12 @@ int aa_setprocattr_changeprofile(char *a
{
char *name;
u64 cookie;
- int cookie_set = 0;
- name = split_token_from_name("change_profile", &cookie_set, args,
- &cookie);
+ name = split_token_from_name("change_profile", args, &cookie);
if (IS_ERR(name))
return PTR_ERR(name);
- return aa_change_profile(name, cookie, !cookie_set);
+ return aa_change_profile(name, cookie);
}
int aa_setprocattr_setprofile(struct task_struct *task, char *args)

View file

@ -1,216 +0,0 @@
change the way change_profile/change_hat work so that they spin on stale
instead of taking the interface lock
---
security/apparmor/main.c | 85 ++++++++++++++++++++++++++++---------------
security/apparmor/procattr.c | 4 --
2 files changed, 56 insertions(+), 33 deletions(-)
--- a/security/apparmor/main.c
+++ b/security/apparmor/main.c
@@ -931,8 +931,8 @@ repeat:
enum { change_profile, permanent_change_profile, restore_profile };
-static int do_change_profile(const char *name, u64 cookie, int mode,
- struct aa_audit *sa)
+static int do_change_profile(struct aa_profile *expected, const char *name,
+ u64 cookie, int mode, struct aa_audit *sa)
{
struct aa_profile *profile = NULL, *previous_profile = NULL;
struct aa_task_context *new_cxt, *cxt;
@@ -954,6 +954,11 @@ static int do_change_profile(const char
goto out;
}
+ if (cxt->profile != expected) {
+ error = -ESTALE;
+ goto out;
+ }
+
if (cxt->previous_profile) {
if (cxt->cookie != cookie) {
error = -EACCES;
@@ -1020,7 +1025,7 @@ out:
*/
int aa_change_profile(const char *name, u64 cookie, int permanent)
{
- struct aa_task_context *cxt;
+ struct aa_profile *profile;
struct aa_audit sa;
int error = 0;
@@ -1029,41 +1034,49 @@ int aa_change_profile(const char *name,
sa.cookie = cookie;
sa.operation = "change_profile";
- mutex_lock(&aa_interface_lock);
-
- cxt = aa_task_context(current);
- if (!cxt) {
- mutex_unlock(&aa_interface_lock);
+repeat:
+ profile = aa_get_profile(current);
+ if (!profile)
return -EPERM;
- }
if (name) {
- if (cxt->profile != null_complain_profile &&
- !(aa_match(cxt->profile->file_rules, name) &
+ if (profile != null_complain_profile &&
+ !(aa_match(profile->file_rules, name) &
AA_CHANGE_PROFILE)) {
/* no permission to transition to profile @name */
- mutex_unlock(&aa_interface_lock);
+ aa_put_profile(profile);
return -EACCES;
}
if (permanent)
- error = do_change_profile(name, cookie,
+ error = do_change_profile(profile, name, cookie,
permanent_change_profile,
&sa);
else
- error = do_change_profile(name, cookie, change_profile,
- &sa);
+ error = do_change_profile(profile, name, cookie,
+ change_profile, &sa);
} else {
- if (cxt->previous_profile)
- error = do_change_profile(cxt->previous_profile->name,
+ struct aa_profile *previous_profile;
+ task_lock(current);
+ previous_profile =
+ aa_dup_profile(aa_task_context(current)->previous_profile);
+ task_unlock(current);
+
+ if (previous_profile)
+ error = do_change_profile(profile,
+ previous_profile->name,
cookie, restore_profile,
&sa);
+ aa_put_profile(previous_profile);
/* else
* Ignore change_profile to restore_previous profile when
* it doesn't exist
*/
}
- mutex_unlock(&aa_interface_lock);
+ aa_put_profile(profile);
+ if (error == -ESTALE)
+ goto repeat;
+
return error;
}
@@ -1081,6 +1094,7 @@ int aa_change_profile(const char *name,
int aa_change_hat(const char *hat_name, u64 cookie)
{
struct aa_task_context *cxt;
+ struct aa_profile *profile, *previous_profile;
struct aa_audit sa;
int error = 0;
@@ -1089,35 +1103,42 @@ int aa_change_hat(const char *hat_name,
sa.cookie = cookie;
sa.operation = "change_hat";
- mutex_lock(&aa_interface_lock);
+repeat:
+ task_lock(current);
cxt = aa_task_context(current);
if (!cxt) {
- mutex_unlock(&aa_interface_lock);
+ task_unlock(current);
return -EPERM;
}
/* FIXME: there is currently no way to tell if a profile doesn't have
* hats so that we can return -ECHILD
*/
+ profile = aa_dup_profile(cxt->profile);
+ previous_profile = aa_dup_profile(cxt->previous_profile);
+ task_unlock(current);
+
if (hat_name) {
char *name, *profile_name;
- if (cxt->previous_profile)
- profile_name = cxt->previous_profile->name;
+ if (previous_profile)
+ profile_name = previous_profile->name;
else
- profile_name = cxt->profile->name;
+ profile_name = profile->name;
name = kmalloc(strlen(hat_name) + 3 + strlen(profile_name),
GFP_KERNEL);
if (!name) {
- mutex_unlock(&aa_interface_lock);
- return -ENOMEM;
+ error = -ENOMEM;
+ goto out;
}
sprintf(name, "%s//%s", profile_name, hat_name);
- error = do_change_profile(name, cookie, change_profile, &sa);
+ error = do_change_profile(profile, name, cookie,
+ change_profile, &sa);
kfree(name);
} else {
- if (cxt->previous_profile)
- error = do_change_profile(cxt->previous_profile->name,
+ if (previous_profile)
+ error = do_change_profile(profile,
+ previous_profile->name,
cookie, restore_profile,
&sa);
/* else
@@ -1125,7 +1146,13 @@ int aa_change_hat(const char *hat_name,
* no profile to restore
*/
}
- mutex_unlock(&aa_interface_lock);
+
+out:
+ aa_put_profile(previous_profile);
+ aa_put_profile(profile);
+ if (error == -ESTALE)
+ goto repeat;
+
return error;
}
--- a/security/apparmor/procattr.c
+++ b/security/apparmor/procattr.c
@@ -118,7 +118,6 @@ int aa_setprocattr_setprofile(struct tas
AA_DEBUG("%s: current %d\n",
__FUNCTION__, current->pid);
- mutex_lock(&aa_interface_lock);
repeat:
if (strcmp(args, "unconfined") == 0)
new_profile = NULL;
@@ -128,7 +127,6 @@ repeat:
sa.name = args;
sa.info = "unknown profile";
aa_audit_reject(NULL, &sa);
- mutex_unlock(&aa_interface_lock);
return -EINVAL;
}
}
@@ -141,7 +139,6 @@ repeat:
error = PTR_ERR(old_profile);
if (error == -ESTALE)
goto repeat;
- mutex_unlock(&aa_interface_lock);
return error;
}
@@ -162,6 +159,5 @@ repeat:
}
aa_put_profile(old_profile);
aa_put_profile(new_profile);
- mutex_unlock(&aa_interface_lock);
return 0;
}

View file

@ -1,303 +0,0 @@
---
security/apparmor/main.c | 191 +++++++++++++++----------------------------
security/apparmor/procattr.c | 5 -
2 files changed, 74 insertions(+), 122 deletions(-)
--- a/security/apparmor/main.c
+++ b/security/apparmor/main.c
@@ -915,55 +915,29 @@ repeat:
}
static int do_change_profile(struct task_struct *task, const char *name,
- const char *hat, u64 cookie, struct aa_audit *sa)
+ u64 cookie, int restore_profile,
+ struct aa_audit *sa)
{
- struct aa_profile *profile = NULL, *previous_profile = NULL,
- *name_profile = NULL;
- struct aa_task_context *new_cxt, *cxt, *old_cxt = NULL;
+ struct aa_profile *profile = NULL, *previous_profile = NULL;
+ struct aa_task_context *new_cxt, *cxt;
int error = 0;
+ sa->name = name;
+
new_cxt = aa_alloc_task_context(GFP_KERNEL);
if (!new_cxt)
return -ENOMEM;
-repeat:
- if (name) {
- if (hat)
- profile = aa_find_profile2(name, hat);
- else
- profile = aa_find_profile(name);
- if (!profile)
- /* if we name_profile is set then returning
- * and return profile has been removed, so go
- * unconfined.
- */
- profile = aa_dup_profile(null_complain_profile);
- }
+ profile = aa_find_profile(name);
+ if (!profile && !restore_profile)
+ profile = aa_dup_profile(null_complain_profile);
+
cxt = lock_task_and_profiles(task, profile);
if (!cxt) {
error = -EPERM;
goto out;
}
- if (!name || (hat && old_cxt && old_cxt != cxt)) {
- /* need to find the change_hat name */
- aa_put_profile(name_profile);
- if (cxt->previous_profile)
- name_profile = aa_dup_profile(cxt->previous_profile);
- else
- name_profile = aa_dup_profile(cxt->profile);
- name = name_profile->name;
- unlock_task_and_profiles(task, cxt, profile);
- aa_put_profile(profile);
- goto repeat;
- }
-
- if (unlikely(profile && profile->isstale)) {
- unlock_task_and_profiles(task, cxt, profile);
- aa_put_profile(profile);
- goto repeat;
- }
-
if (cxt->previous_profile) {
if (cxt->cookie != cookie) {
error = -EACCES;
@@ -995,75 +969,12 @@ repeat:
if (APPARMOR_AUDIT(cxt))
aa_audit_message(cxt->profile, sa, AUDIT_APPARMOR_AUDIT);
- aa_change_task_context(task, new_cxt, profile, cookie,
- previous_profile);
-
-out:
- if (aa_task_context(task) != new_cxt)
- aa_free_task_context(new_cxt);
- unlock_task_and_profiles(task, cxt, profile);
- aa_put_profile(profile);
- aa_put_profile(name_profile);
- return error;
-}
-
-static int do_restore_profile(struct task_struct *task, u64 cookie,
- struct aa_audit *sa)
-{
- struct aa_profile *profile = NULL;
- struct aa_task_context *cxt, *new_cxt, *old_cxt = NULL;
- int error = 0;
-
- new_cxt = aa_alloc_task_context(GFP_KERNEL);
- if (!new_cxt)
- return -ENOMEM;
-
-repeat:
- cxt = lock_task_and_profiles(task, profile);
- if (!cxt) {
- error = -EPERM;
- goto out;
- }
-
- /* ignore returning to stored profile when there isn't one */
- if (!cxt->previous_profile)
- goto out;
-
- if (!profile)
- /* setting profile with previous_profile is locking safe */
- profile = aa_dup_profile(cxt->previous_profile);
-
- if (profile->isstale || (old_cxt && old_cxt != cxt)) {
- struct aa_profile *previous_profile;
-
- previous_profile = aa_dup_profile(cxt->previous_profile);
- old_cxt = cxt;
- unlock_task_and_profiles(task, cxt, profile);
- aa_put_profile(profile);
- profile = aa_find_profile(previous_profile->name);
- aa_put_profile(previous_profile);
- goto repeat;
- }
-
- if (cxt->cookie != cookie) {
- error = -EACCES;
- sa->info = "killing process";
- aa_audit_reject(profile, sa);
- /* terminate process */
- (void)send_sig_info(SIGKILL, NULL, task);
- goto out;
- }
-
- if ((task->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile))
- error = -EACCES;
- else {
- if (APPARMOR_AUDIT(cxt)) {
- sa->name = profile->name;
- aa_audit_message(cxt->profile, sa,
- AUDIT_APPARMOR_AUDIT);
- }
+ if (restore_profile)
aa_change_task_context(task, new_cxt, profile, 0, NULL);
- }
+ else
+ aa_change_task_context(task, new_cxt, profile, cookie,
+ previous_profile);
+
out:
if (aa_task_context(task) != new_cxt)
aa_free_task_context(new_cxt);
@@ -1086,35 +997,44 @@ out:
*/
int aa_change_profile(const char *name, u64 cookie)
{
- struct aa_profile *profile;
+ struct aa_task_context *cxt;
struct aa_audit sa;
int error = 0;
memset(&sa, 0, sizeof(sa));
sa.gfp_mask = GFP_ATOMIC;
sa.cookie = cookie;
- sa.name = name;
sa.operation = "change_profile";
- profile = aa_get_profile(current);
- if (!profile)
- /* an unconfined process can not change_profile */
+ mutex_lock(&aa_interface_lock);
+
+ cxt = aa_task_context(current);
+ if (!cxt) {
+ mutex_unlock(&aa_interface_lock);
return -EPERM;
+ }
if (name) {
- if (profile != null_complain_profile &&
- !aa_match(profile->file_rules, name) & AA_CHANGE_PROFILE) {
+ if (cxt->profile != null_complain_profile &&
+ !(aa_match(cxt->profile->file_rules, name) &
+ AA_CHANGE_PROFILE)) {
/* no permission to transition to profile @name */
- aa_put_profile(profile);
+ mutex_unlock(&aa_interface_lock);
return -EACCES;
}
-
- error = do_change_profile(current, name, NULL, cookie, &sa);
+ error = do_change_profile(current, name, cookie, 0, &sa);
} else {
- error = do_restore_profile(current, cookie, &sa);
+ if (cxt->previous_profile)
+ error = do_change_profile(current,
+ cxt->previous_profile->name,
+ cookie, 1, &sa);
+ /* else
+ * Ignore change_profile to restore_previous profile when
+ * it doesn't exist
+ */
}
- aa_put_profile(profile);
+ mutex_unlock(&aa_interface_lock);
return error;
}
@@ -1131,23 +1051,52 @@ int aa_change_profile(const char *name,
*/
int aa_change_hat(const char *hat_name, u64 cookie)
{
+ struct aa_task_context *cxt;
struct aa_audit sa;
int error = 0;
memset(&sa, 0, sizeof(sa));
sa.gfp_mask = GFP_ATOMIC;
sa.cookie = cookie;
- sa.name = hat_name;
sa.operation = "change_hat";
+ mutex_lock(&aa_interface_lock);
+ cxt = aa_task_context(current);
+ if (!cxt) {
+ mutex_unlock(&aa_interface_lock);
+ return -EPERM;
+ }
/* FIXME: there is currently no way to tell if a profile doesn't have
* hats so that we can return -ECHILD
*/
- if (hat_name)
- error = do_change_profile(current, NULL, hat_name, cookie, &sa);
- else
- error = do_restore_profile(current, cookie, &sa);
+ if (hat_name) {
+ char *name, *profile_name;
+ if (cxt->previous_profile)
+ profile_name = cxt->previous_profile->name;
+ else
+ profile_name = cxt->profile->name;
+
+ name = kmalloc(strlen(hat_name) + 3 + strlen(profile_name),
+ GFP_KERNEL);
+ if (!name) {
+ mutex_unlock(&aa_interface_lock);
+ return -ENOMEM;
+ }
+ sprintf(name, "%s//%s", profile_name, hat_name);
+ error = do_change_profile(current, name, cookie, 0, &sa);
+ kfree(name);
+ } else {
+ if (cxt->previous_profile)
+ error = do_change_profile(current,
+ cxt->previous_profile->name,
+ cookie, 1, &sa);
+ /* else
+ * Ignore change_hat to restore profile when there is
+ * no profile to restore
+ */
+ }
+ mutex_unlock(&aa_interface_lock);
return error;
}
--- a/security/apparmor/procattr.c
+++ b/security/apparmor/procattr.c
@@ -110,6 +110,7 @@ int aa_setprocattr_setprofile(struct tas
AA_DEBUG("%s: current %d\n",
__FUNCTION__, current->pid);
+ mutex_lock(&aa_interface_lock);
repeat:
if (strcmp(args, "unconfined") == 0)
new_profile = NULL;
@@ -119,6 +120,7 @@ repeat:
sa.name = args;
sa.info = "unknown profile";
aa_audit_reject(NULL, &sa);
+ mutex_unlock(&aa_interface_lock);
return -EINVAL;
}
}
@@ -131,6 +133,7 @@ repeat:
error = PTR_ERR(old_profile);
if (error == -ESTALE)
goto repeat;
+ mutex_unlock(&aa_interface_lock);
return error;
}
@@ -151,6 +154,6 @@ repeat:
}
aa_put_profile(old_profile);
aa_put_profile(new_profile);
-
+ mutex_unlock(&aa_interface_lock);
return 0;
}