mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-01 14:55:10 +00:00
latest revision of change_profile patch, collapse several patches into change_profile-3.diff
This commit is contained in:
320
kernel-patches/for-mainline/change_profile-3.diff
Normal file
320
kernel-patches/for-mainline/change_profile-3.diff
Normal file
@@ -0,0 +1,320 @@
|
|||||||
|
Index: b/security/apparmor/main.c
|
||||||
|
===================================================================
|
||||||
|
--- a/security/apparmor/main.c
|
||||||
|
+++ b/security/apparmor/main.c
|
||||||
|
@@ -934,72 +934,59 @@ repeat:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int do_change_profile(struct task_struct *task, const char *name,
|
||||||
|
- const char *hat, u64 cookie, struct aa_audit *sa)
|
||||||
|
+static int do_change_profile(struct aa_profile *expected, const char *name,
|
||||||
|
+ u64 cookie, 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);
|
||||||
|
+ 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_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
- 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->profile != expected) {
|
||||||
|
+ error = -ESTALE;
|
||||||
|
+ goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cxt->previous_profile) {
|
||||||
|
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, task);
|
||||||
|
+ (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 ((task->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) {
|
||||||
|
+ if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) {
|
||||||
|
error = -EACCES;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
@@ -1015,79 +1002,18 @@ 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 (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);
|
||||||
|
|
||||||
|
- 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);
|
||||||
|
- }
|
||||||
|
- aa_change_task_context(task, new_cxt, profile, 0, NULL);
|
||||||
|
- }
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
@@ -1113,28 +1039,29 @@ int aa_change_profile(const char *name,
|
||||||
|
memset(&sa, 0, sizeof(sa));
|
||||||
|
sa.gfp_mask = GFP_ATOMIC;
|
||||||
|
sa.cookie = cookie;
|
||||||
|
- sa.name = name;
|
||||||
|
sa.operation = "change_profile";
|
||||||
|
|
||||||
|
+repeat:
|
||||||
|
profile = aa_get_profile(current);
|
||||||
|
if (!profile)
|
||||||
|
- /* an unconfined process can not change_profile */
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
if (profile != null_complain_profile &&
|
||||||
|
- !aa_match(profile->file_rules, name) & AA_CHANGE_PROFILE) {
|
||||||
|
+ !(aa_match(profile->file_rules, name) &
|
||||||
|
+ AA_CHANGE_PROFILE)) {
|
||||||
|
/* no permission to transition to profile @name */
|
||||||
|
aa_put_profile(profile);
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- error = do_change_profile(current, name, NULL, cookie, &sa);
|
||||||
|
- } else {
|
||||||
|
- error = do_restore_profile(current, cookie, &sa);
|
||||||
|
- }
|
||||||
|
+ error = do_change_profile(profile, name, cookie, &sa);
|
||||||
|
+ } else
|
||||||
|
+ error = do_change_profile(profile, NULL, cookie, &sa);
|
||||||
|
|
||||||
|
aa_put_profile(profile);
|
||||||
|
+ if (error == -ESTALE)
|
||||||
|
+ goto repeat;
|
||||||
|
+
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1151,22 +1078,55 @@ 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;
|
||||||
|
|
||||||
|
memset(&sa, 0, sizeof(sa));
|
||||||
|
sa.gfp_mask = GFP_ATOMIC;
|
||||||
|
sa.cookie = cookie;
|
||||||
|
- sa.name = hat_name;
|
||||||
|
sa.operation = "change_hat";
|
||||||
|
|
||||||
|
+repeat:
|
||||||
|
+ task_lock(current);
|
||||||
|
+ cxt = aa_task_context(current);
|
||||||
|
+ if (!cxt) {
|
||||||
|
+ 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
|
||||||
|
*/
|
||||||
|
- if (hat_name)
|
||||||
|
- error = do_change_profile(current, NULL, hat_name, cookie, &sa);
|
||||||
|
- else
|
||||||
|
- error = do_restore_profile(current, cookie, &sa);
|
||||||
|
+
|
||||||
|
+ 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 (previous_profile)
|
||||||
|
+ profile_name = previous_profile->name;
|
||||||
|
+ else
|
||||||
|
+ profile_name = profile->name;
|
||||||
|
+
|
||||||
|
+ name = kmalloc(strlen(hat_name) + 3 + strlen(profile_name),
|
||||||
|
+ GFP_KERNEL);
|
||||||
|
+ if (!name) {
|
||||||
|
+ error = -ENOMEM;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ sprintf(name, "%s//%s", profile_name, hat_name);
|
||||||
|
+ error = do_change_profile(profile, name, cookie, &sa);
|
||||||
|
+ kfree(name);
|
||||||
|
+ } else
|
||||||
|
+ error = do_change_profile(profile, NULL, cookie, &sa);
|
||||||
|
+
|
||||||
|
+out:
|
||||||
|
+ aa_put_profile(previous_profile);
|
||||||
|
+ aa_put_profile(profile);
|
||||||
|
+ if (error == -ESTALE)
|
||||||
|
+ goto repeat;
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
Index: b/security/apparmor/procattr.c
|
||||||
|
===================================================================
|
||||||
|
--- 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;
|
||||||
|
@@ -55,10 +54,11 @@ static char *split_token_from_name(const
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
*cookie = simple_strtoull(args, &name, 16);
|
||||||
|
- if (name == args || *name != '^') {
|
||||||
|
+ if ((name == args) || *name != '^') {
|
||||||
|
AA_ERROR("%s: Invalid input '%s'", op, args);
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
name++; /* skip ^ */
|
||||||
|
if (!*name)
|
||||||
|
name = NULL;
|
||||||
|
@@ -151,6 +151,5 @@ repeat:
|
||||||
|
}
|
||||||
|
aa_put_profile(old_profile);
|
||||||
|
aa_put_profile(new_profile);
|
||||||
|
-
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -1,12 +1,8 @@
|
|||||||
Make change_profile one way only, this way it doesn't need to deal
|
|
||||||
with the change_hat logic
|
|
||||||
|
|
||||||
---
|
---
|
||||||
security/apparmor/apparmor.h | 3 -
|
security/apparmor/apparmor.h | 2 -
|
||||||
security/apparmor/lsm.c | 2 -
|
security/apparmor/main.c | 84 +++++++++++++------------------------------
|
||||||
security/apparmor/main.c | 82 ++++++++++++-------------------------------
|
security/apparmor/procattr.c | 20 +++-------
|
||||||
security/apparmor/procattr.c | 27 ++------------
|
3 files changed, 34 insertions(+), 72 deletions(-)
|
||||||
4 files changed, 29 insertions(+), 85 deletions(-)
|
|
||||||
|
|
||||||
--- a/security/apparmor/apparmor.h
|
--- a/security/apparmor/apparmor.h
|
||||||
+++ b/security/apparmor/apparmor.h
|
+++ b/security/apparmor/apparmor.h
|
||||||
@@ -15,72 +11,63 @@ with the change_hat logic
|
|||||||
extern void aa_release(struct task_struct *task);
|
extern void aa_release(struct task_struct *task);
|
||||||
extern int aa_change_hat(const char *id, u64 hat_magic);
|
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, int permanent);
|
||||||
+extern int aa_change_profile(const char *name);
|
+extern int aa_change_profile(const char *name, u64 cookie);
|
||||||
extern struct aa_profile *__aa_find_profile(const char *name,
|
extern struct aa_profile *__aa_find_profile(const char *name,
|
||||||
struct list_head *list);
|
struct list_head *list);
|
||||||
extern struct aa_profile *__aa_find_profile2(const char *name,
|
extern struct aa_profile *__aa_find_profile2(const char *name,
|
||||||
@@ -251,7 +251,6 @@ extern void aa_unconfine_tasks(struct aa
|
|
||||||
extern int aa_getprocattr(struct aa_profile *profile, char **string,
|
|
||||||
unsigned *len);
|
|
||||||
extern int aa_setprocattr_changehat(char *args);
|
|
||||||
-extern int aa_setprocattr_changeprofile(char *args);
|
|
||||||
extern int aa_setprocattr_setprofile(struct task_struct *task, char *args);
|
|
||||||
|
|
||||||
/* apparmorfs.c */
|
|
||||||
--- a/security/apparmor/lsm.c
|
|
||||||
+++ b/security/apparmor/lsm.c
|
|
||||||
@@ -632,7 +632,7 @@ static int apparmor_setprocattr(struct t
|
|
||||||
} else if (strcmp(command, "changeprofile") == 0) {
|
|
||||||
if (current != task)
|
|
||||||
return -EACCES;
|
|
||||||
- error = aa_setprocattr_changeprofile(args);
|
|
||||||
+ error = aa_change_profile(args);
|
|
||||||
} else if (strcmp(command, "setprofile")) {
|
|
||||||
struct aa_profile *profile;
|
|
||||||
|
|
||||||
--- a/security/apparmor/main.c
|
--- a/security/apparmor/main.c
|
||||||
+++ b/security/apparmor/main.c
|
+++ b/security/apparmor/main.c
|
||||||
@@ -932,9 +932,10 @@ repeat:
|
@@ -934,10 +934,8 @@ repeat:
|
||||||
enum { change_profile, permanent_change_profile, restore_profile };
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-enum { change_profile, permanent_change_profile, restore_profile };
|
||||||
|
-
|
||||||
static int do_change_profile(struct aa_profile *expected, const char *name,
|
static int do_change_profile(struct aa_profile *expected, const char *name,
|
||||||
- u64 cookie, int mode, struct aa_audit *sa)
|
- u64 cookie, int mode, struct aa_audit *sa)
|
||||||
+ u64 cookie, struct aa_profile *previous_profile,
|
+ u64 cookie, struct aa_audit *sa)
|
||||||
+ struct aa_audit *sa)
|
|
||||||
{
|
{
|
||||||
- struct aa_profile *profile = NULL, *previous_profile = NULL;
|
struct aa_profile *profile = NULL, *previous_profile = NULL;
|
||||||
+ struct aa_profile *profile = NULL;
|
|
||||||
struct aa_task_context *new_cxt, *cxt;
|
struct aa_task_context *new_cxt, *cxt;
|
||||||
int error = 0;
|
@@ -949,9 +947,11 @@ static int do_change_profile(struct aa_p
|
||||||
|
if (!new_cxt)
|
||||||
@@ -945,7 +946,7 @@ static int do_change_profile(struct aa_p
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
profile = aa_find_profile(name);
|
- profile = aa_find_profile(name);
|
||||||
- if (!profile && mode != restore_profile)
|
- if (!profile && mode != restore_profile)
|
||||||
+ if (!profile)
|
- profile = aa_dup_profile(null_complain_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);
|
cxt = lock_task_and_profiles(current, profile);
|
||||||
@@ -959,27 +960,6 @@ static int do_change_profile(struct aa_p
|
if (!cxt) {
|
||||||
goto out;
|
@@ -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 (cxt->previous_profile) {
|
|
||||||
- if (cxt->cookie != cookie) {
|
|
||||||
- error = -EACCES;
|
|
||||||
- sa->info = "killing process";
|
|
||||||
- aa_audit_reject(profile, sa);
|
|
||||||
- /* terminate process */
|
|
||||||
- (void)send_sig_info(SIGKILL, NULL, current);
|
|
||||||
- goto out;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- previous_profile = cxt->previous_profile;
|
|
||||||
- } else {
|
|
||||||
- previous_profile = cxt->profile;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (mode == permanent_change_profile) {
|
- if (mode == permanent_change_profile) {
|
||||||
- previous_profile = NULL;
|
- previous_profile = NULL;
|
||||||
- cookie = 0;
|
- cookie = 0;
|
||||||
@@ -90,47 +77,41 @@ with the change_hat logic
|
|||||||
if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) {
|
if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) {
|
||||||
error = -EACCES;
|
error = -EACCES;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -996,11 +976,8 @@ static int do_change_profile(struct aa_p
|
@@ -1001,11 +1002,13 @@ static int do_change_profile(struct aa_p
|
||||||
|
|
||||||
if (APPARMOR_AUDIT(cxt))
|
if (APPARMOR_AUDIT(cxt))
|
||||||
aa_audit_message(cxt->profile, sa, AUDIT_APPARMOR_AUDIT);
|
aa_audit_message(cxt->profile, sa, AUDIT_APPARMOR_AUDIT);
|
||||||
- if (mode == restore_profile)
|
- if (mode == restore_profile)
|
||||||
- aa_change_task_context(current, new_cxt, profile, 0, NULL);
|
- aa_change_task_context(current, new_cxt, profile, 0, NULL);
|
||||||
- else
|
- else
|
||||||
- aa_change_task_context(current, new_cxt, profile, cookie,
|
+
|
||||||
- previous_profile);
|
+ if (name && cookie)
|
||||||
+ aa_change_task_context(current, new_cxt, profile, cookie,
|
aa_change_task_context(current, new_cxt, profile, cookie,
|
||||||
+ previous_profile);
|
previous_profile);
|
||||||
|
+ else
|
||||||
|
+ /* either return to previous_profile, or a permanent change */
|
||||||
|
+ aa_change_task_context(current, new_cxt, profile, 0, NULL);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (aa_task_context(current) != new_cxt)
|
if (aa_task_context(current) != new_cxt)
|
||||||
@@ -1014,8 +991,6 @@ out:
|
@@ -1020,7 +1023,6 @@ out:
|
||||||
/**
|
|
||||||
* aa_change_profile - change profile to/from previous stored profile
|
* aa_change_profile - change profile to/from previous stored profile
|
||||||
* @name: name of profile to change to
|
* @name: name of profile to change to
|
||||||
- * @cookie: magic value to validate the profile change
|
* @cookie: magic value to validate the profile change
|
||||||
- * @permanent: whether the profile change is permanent
|
- * @permanent: whether the profile change is permanent
|
||||||
*
|
*
|
||||||
* Change to new profile @name, and store the @cookie in the current task
|
* 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
|
* context. If the new @name is %NULL and the @cookie matches that
|
||||||
@@ -1023,7 +998,7 @@ out:
|
@@ -1028,7 +1030,7 @@ out:
|
||||||
*
|
*
|
||||||
* Returns %0 on success, error otherwise.
|
* 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, int permanent)
|
||||||
+int aa_change_profile(const char *name)
|
+int aa_change_profile(const char *name, u64 cookie)
|
||||||
{
|
{
|
||||||
struct aa_profile *profile;
|
struct aa_profile *profile;
|
||||||
struct aa_audit sa;
|
struct aa_audit sa;
|
||||||
@@ -1031,7 +1006,6 @@ int aa_change_profile(const char *name,
|
@@ -1052,31 +1054,9 @@ repeat:
|
||||||
|
|
||||||
memset(&sa, 0, sizeof(sa));
|
|
||||||
sa.gfp_mask = GFP_ATOMIC;
|
|
||||||
- sa.cookie = cookie;
|
|
||||||
sa.operation = "change_profile";
|
|
||||||
|
|
||||||
repeat:
|
|
||||||
@@ -1047,30 +1021,9 @@ repeat:
|
|
||||||
aa_put_profile(profile);
|
aa_put_profile(profile);
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
}
|
}
|
||||||
@@ -141,8 +122,7 @@ with the change_hat logic
|
|||||||
- else
|
- else
|
||||||
- error = do_change_profile(profile, name, cookie,
|
- error = do_change_profile(profile, name, cookie,
|
||||||
- change_profile, &sa);
|
- change_profile, &sa);
|
||||||
+ error = do_change_profile(profile, name, 0, NULL, &sa);
|
- } else {
|
||||||
} else {
|
|
||||||
- struct aa_profile *previous_profile;
|
- struct aa_profile *previous_profile;
|
||||||
- task_lock(current);
|
- task_lock(current);
|
||||||
- previous_profile =
|
- previous_profile =
|
||||||
@@ -159,49 +139,48 @@ with the change_hat logic
|
|||||||
- * Ignore change_profile to restore_previous profile when
|
- * Ignore change_profile to restore_previous profile when
|
||||||
- * it doesn't exist
|
- * it doesn't exist
|
||||||
- */
|
- */
|
||||||
+ error = -EPERM;
|
- }
|
||||||
}
|
+ error = do_change_profile(profile, name, cookie, &sa);
|
||||||
|
+ } else
|
||||||
|
+ error = do_change_profile(profile, NULL, cookie, &sa);
|
||||||
|
|
||||||
aa_put_profile(profile);
|
aa_put_profile(profile);
|
||||||
@@ -1116,6 +1069,18 @@ repeat:
|
if (error == -ESTALE)
|
||||||
|
@@ -1137,20 +1117,10 @@ repeat:
|
||||||
profile = aa_dup_profile(cxt->profile);
|
goto out;
|
||||||
previous_profile = aa_dup_profile(cxt->previous_profile);
|
|
||||||
+
|
|
||||||
+ if (previous_profile) {
|
|
||||||
+ if (cxt->cookie != cookie) {
|
|
||||||
+ task_unlock(current);
|
|
||||||
+ error = -EACCES;
|
|
||||||
+ sa.info = "killing process";
|
|
||||||
+ aa_audit_reject(profile, &sa);
|
|
||||||
+ /* terminate process */
|
|
||||||
+ (void)send_sig_info(SIGKILL, NULL, current);
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
task_unlock(current);
|
|
||||||
|
|
||||||
if (hat_name) {
|
|
||||||
@@ -1133,14 +1098,13 @@ repeat:
|
|
||||||
}
|
}
|
||||||
sprintf(name, "%s//%s", profile_name, hat_name);
|
sprintf(name, "%s//%s", profile_name, hat_name);
|
||||||
error = do_change_profile(profile, name, cookie,
|
- error = do_change_profile(profile, name, cookie,
|
||||||
- change_profile, &sa);
|
- change_profile, &sa);
|
||||||
+ previous_profile, &sa);
|
+ error = do_change_profile(profile, name, cookie, &sa);
|
||||||
kfree(name);
|
kfree(name);
|
||||||
} else {
|
- } else {
|
||||||
if (previous_profile)
|
- if (previous_profile)
|
||||||
error = do_change_profile(profile,
|
- error = do_change_profile(profile,
|
||||||
previous_profile->name,
|
- previous_profile->name,
|
||||||
- cookie, restore_profile,
|
- cookie, restore_profile,
|
||||||
- &sa);
|
- &sa);
|
||||||
+ 0, NULL, &sa);
|
- /* else
|
||||||
/* else
|
- * Ignore change_hat to restore profile when there is
|
||||||
* Ignore change_hat to restore profile when there is
|
- * no profile to restore
|
||||||
* no profile to restore
|
- */
|
||||||
|
- }
|
||||||
|
+ } else
|
||||||
|
+ error = do_change_profile(profile, NULL, cookie, &sa);
|
||||||
|
|
||||||
|
out:
|
||||||
|
aa_put_profile(previous_profile);
|
||||||
--- a/security/apparmor/procattr.c
|
--- a/security/apparmor/procattr.c
|
||||||
+++ b/security/apparmor/procattr.c
|
+++ b/security/apparmor/procattr.c
|
||||||
@@ -50,20 +50,16 @@ int aa_getprocattr(struct aa_profile *pr
|
@@ -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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,7 +204,7 @@ with the change_hat logic
|
|||||||
name++; /* skip ^ */
|
name++; /* skip ^ */
|
||||||
if (!*name)
|
if (!*name)
|
||||||
name = NULL;
|
name = NULL;
|
||||||
@@ -74,9 +70,8 @@ int aa_setprocattr_changehat(char *args)
|
@@ -74,9 +69,8 @@ int aa_setprocattr_changehat(char *args)
|
||||||
{
|
{
|
||||||
char *hat;
|
char *hat;
|
||||||
u64 cookie;
|
u64 cookie;
|
||||||
@@ -236,24 +215,20 @@ with the change_hat logic
|
|||||||
if (IS_ERR(hat))
|
if (IS_ERR(hat))
|
||||||
return PTR_ERR(hat);
|
return PTR_ERR(hat);
|
||||||
|
|
||||||
@@ -91,20 +86,6 @@ int aa_setprocattr_changehat(char *args)
|
@@ -95,14 +89,12 @@ int aa_setprocattr_changeprofile(char *a
|
||||||
return aa_change_hat(hat, cookie);
|
{
|
||||||
}
|
char *name;
|
||||||
|
u64 cookie;
|
||||||
-int aa_setprocattr_changeprofile(char *args)
|
|
||||||
-{
|
|
||||||
- char *name;
|
|
||||||
- u64 cookie;
|
|
||||||
- int cookie_set = 0;
|
- int cookie_set = 0;
|
||||||
-
|
|
||||||
- name = split_token_from_name("change_profile", &cookie_set, args,
|
- name = split_token_from_name("change_profile", &cookie_set, args,
|
||||||
- &cookie);
|
- &cookie);
|
||||||
- if (IS_ERR(name))
|
+ name = split_token_from_name("change_profile", args, &cookie);
|
||||||
- return PTR_ERR(name);
|
if (IS_ERR(name))
|
||||||
-
|
return PTR_ERR(name);
|
||||||
|
|
||||||
- return aa_change_profile(name, cookie, !cookie_set);
|
- return aa_change_profile(name, cookie, !cookie_set);
|
||||||
-}
|
+ return aa_change_profile(name, cookie);
|
||||||
-
|
}
|
||||||
|
|
||||||
int aa_setprocattr_setprofile(struct task_struct *task, char *args)
|
int aa_setprocattr_setprofile(struct task_struct *task, char *args)
|
||||||
{
|
|
||||||
struct aa_profile *old_profile, *new_profile;
|
|
@@ -49,12 +49,7 @@ change_profile.diff
|
|||||||
change_profile-2.diff
|
change_profile-2.diff
|
||||||
flatten-hats.diff
|
flatten-hats.diff
|
||||||
flatten-hats-2.diff
|
flatten-hats-2.diff
|
||||||
#change_hat-to-change_profile.diff
|
change_profile-3.diff
|
||||||
use-interface_lock.diff
|
|
||||||
change_profile-current.diff
|
|
||||||
change_profile-permenent.diff
|
|
||||||
change_profile-spin-onstale.diff
|
|
||||||
change_profile-no-return.diff
|
|
||||||
unused.diff
|
unused.diff
|
||||||
do_path_lookup-nameidata.diff
|
do_path_lookup-nameidata.diff
|
||||||
sys_fchdir-nameidata.diff
|
sys_fchdir-nameidata.diff
|
||||||
|
Reference in New Issue
Block a user