diff options
| author | Ingo Molnar <mingo@kernel.org> | 2013-12-17 09:27:08 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2013-12-17 09:27:08 -0500 |
| commit | bb799d3b980eb803ca2da4a4eefbd9308f8d988a (patch) | |
| tree | 69fbe0cd6d47b23a50f5e1d87bf7489532fae149 /security/apparmor | |
| parent | 919fc6e34831d1c2b58bfb5ae261dc3facc9b269 (diff) | |
| parent | 319e2e3f63c348a9b66db4667efa73178e18b17d (diff) | |
Merge tag 'v3.13-rc4' into core/locking
Merge Linux 3.13-rc4, to refresh this rather old tree with the latest fixes.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'security/apparmor')
| -rw-r--r-- | security/apparmor/audit.c | 14 | ||||
| -rw-r--r-- | security/apparmor/capability.c | 15 | ||||
| -rw-r--r-- | security/apparmor/domain.c | 16 | ||||
| -rw-r--r-- | security/apparmor/include/audit.h | 1 | ||||
| -rw-r--r-- | security/apparmor/include/capability.h | 5 | ||||
| -rw-r--r-- | security/apparmor/include/ipc.h | 4 | ||||
| -rw-r--r-- | security/apparmor/ipc.c | 9 | ||||
| -rw-r--r-- | security/apparmor/lsm.c | 2 |
8 files changed, 22 insertions, 44 deletions
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c index 031d2d9dd695..89c78658031f 100644 --- a/security/apparmor/audit.c +++ b/security/apparmor/audit.c | |||
| @@ -111,7 +111,6 @@ static const char *const aa_audit_type[] = { | |||
| 111 | static void audit_pre(struct audit_buffer *ab, void *ca) | 111 | static void audit_pre(struct audit_buffer *ab, void *ca) |
| 112 | { | 112 | { |
| 113 | struct common_audit_data *sa = ca; | 113 | struct common_audit_data *sa = ca; |
| 114 | struct task_struct *tsk = sa->aad->tsk ? sa->aad->tsk : current; | ||
| 115 | 114 | ||
| 116 | if (aa_g_audit_header) { | 115 | if (aa_g_audit_header) { |
| 117 | audit_log_format(ab, "apparmor="); | 116 | audit_log_format(ab, "apparmor="); |
| @@ -132,11 +131,6 @@ static void audit_pre(struct audit_buffer *ab, void *ca) | |||
| 132 | 131 | ||
| 133 | if (sa->aad->profile) { | 132 | if (sa->aad->profile) { |
| 134 | struct aa_profile *profile = sa->aad->profile; | 133 | struct aa_profile *profile = sa->aad->profile; |
| 135 | pid_t pid; | ||
| 136 | rcu_read_lock(); | ||
| 137 | pid = rcu_dereference(tsk->real_parent)->pid; | ||
| 138 | rcu_read_unlock(); | ||
| 139 | audit_log_format(ab, " parent=%d", pid); | ||
| 140 | if (profile->ns != root_ns) { | 134 | if (profile->ns != root_ns) { |
| 141 | audit_log_format(ab, " namespace="); | 135 | audit_log_format(ab, " namespace="); |
| 142 | audit_log_untrustedstring(ab, profile->ns->base.hname); | 136 | audit_log_untrustedstring(ab, profile->ns->base.hname); |
| @@ -149,12 +143,6 @@ static void audit_pre(struct audit_buffer *ab, void *ca) | |||
| 149 | audit_log_format(ab, " name="); | 143 | audit_log_format(ab, " name="); |
| 150 | audit_log_untrustedstring(ab, sa->aad->name); | 144 | audit_log_untrustedstring(ab, sa->aad->name); |
| 151 | } | 145 | } |
| 152 | |||
| 153 | if (sa->aad->tsk) { | ||
| 154 | audit_log_format(ab, " pid=%d comm=", tsk->pid); | ||
| 155 | audit_log_untrustedstring(ab, tsk->comm); | ||
| 156 | } | ||
| 157 | |||
| 158 | } | 146 | } |
| 159 | 147 | ||
| 160 | /** | 148 | /** |
| @@ -212,7 +200,7 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp, | |||
| 212 | 200 | ||
| 213 | if (sa->aad->type == AUDIT_APPARMOR_KILL) | 201 | if (sa->aad->type == AUDIT_APPARMOR_KILL) |
| 214 | (void)send_sig_info(SIGKILL, NULL, | 202 | (void)send_sig_info(SIGKILL, NULL, |
| 215 | sa->aad->tsk ? sa->aad->tsk : current); | 203 | sa->u.tsk ? sa->u.tsk : current); |
| 216 | 204 | ||
| 217 | if (sa->aad->type == AUDIT_APPARMOR_ALLOWED) | 205 | if (sa->aad->type == AUDIT_APPARMOR_ALLOWED) |
| 218 | return complain_error(sa->aad->error); | 206 | return complain_error(sa->aad->error); |
diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c index 84d1f5f53877..1101c6f64bb7 100644 --- a/security/apparmor/capability.c +++ b/security/apparmor/capability.c | |||
| @@ -53,8 +53,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) | |||
| 53 | 53 | ||
| 54 | /** | 54 | /** |
| 55 | * audit_caps - audit a capability | 55 | * audit_caps - audit a capability |
| 56 | * @profile: profile confining task (NOT NULL) | 56 | * @profile: profile being tested for confinement (NOT NULL) |
| 57 | * @task: task capability test was performed against (NOT NULL) | ||
| 58 | * @cap: capability tested | 57 | * @cap: capability tested |
| 59 | * @error: error code returned by test | 58 | * @error: error code returned by test |
| 60 | * | 59 | * |
| @@ -63,8 +62,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) | |||
| 63 | * | 62 | * |
| 64 | * Returns: 0 or sa->error on success, error code on failure | 63 | * Returns: 0 or sa->error on success, error code on failure |
| 65 | */ | 64 | */ |
| 66 | static int audit_caps(struct aa_profile *profile, struct task_struct *task, | 65 | static int audit_caps(struct aa_profile *profile, int cap, int error) |
| 67 | int cap, int error) | ||
| 68 | { | 66 | { |
| 69 | struct audit_cache *ent; | 67 | struct audit_cache *ent; |
| 70 | int type = AUDIT_APPARMOR_AUTO; | 68 | int type = AUDIT_APPARMOR_AUTO; |
| @@ -73,7 +71,6 @@ static int audit_caps(struct aa_profile *profile, struct task_struct *task, | |||
| 73 | sa.type = LSM_AUDIT_DATA_CAP; | 71 | sa.type = LSM_AUDIT_DATA_CAP; |
| 74 | sa.aad = &aad; | 72 | sa.aad = &aad; |
| 75 | sa.u.cap = cap; | 73 | sa.u.cap = cap; |
| 76 | sa.aad->tsk = task; | ||
| 77 | sa.aad->op = OP_CAPABLE; | 74 | sa.aad->op = OP_CAPABLE; |
| 78 | sa.aad->error = error; | 75 | sa.aad->error = error; |
| 79 | 76 | ||
| @@ -124,8 +121,7 @@ static int profile_capable(struct aa_profile *profile, int cap) | |||
| 124 | 121 | ||
| 125 | /** | 122 | /** |
| 126 | * aa_capable - test permission to use capability | 123 | * aa_capable - test permission to use capability |
| 127 | * @task: task doing capability test against (NOT NULL) | 124 | * @profile: profile being tested against (NOT NULL) |
| 128 | * @profile: profile confining @task (NOT NULL) | ||
| 129 | * @cap: capability to be tested | 125 | * @cap: capability to be tested |
| 130 | * @audit: whether an audit record should be generated | 126 | * @audit: whether an audit record should be generated |
| 131 | * | 127 | * |
| @@ -133,8 +129,7 @@ static int profile_capable(struct aa_profile *profile, int cap) | |||
| 133 | * | 129 | * |
| 134 | * Returns: 0 on success, or else an error code. | 130 | * Returns: 0 on success, or else an error code. |
| 135 | */ | 131 | */ |
| 136 | int aa_capable(struct task_struct *task, struct aa_profile *profile, int cap, | 132 | int aa_capable(struct aa_profile *profile, int cap, int audit) |
| 137 | int audit) | ||
| 138 | { | 133 | { |
| 139 | int error = profile_capable(profile, cap); | 134 | int error = profile_capable(profile, cap); |
| 140 | 135 | ||
| @@ -144,5 +139,5 @@ int aa_capable(struct task_struct *task, struct aa_profile *profile, int cap, | |||
| 144 | return error; | 139 | return error; |
| 145 | } | 140 | } |
| 146 | 141 | ||
| 147 | return audit_caps(profile, task, cap, error); | 142 | return audit_caps(profile, cap, error); |
| 148 | } | 143 | } |
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index 26c607c971f5..452567d3a08e 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c | |||
| @@ -50,23 +50,21 @@ void aa_free_domain_entries(struct aa_domain *domain) | |||
| 50 | 50 | ||
| 51 | /** | 51 | /** |
| 52 | * may_change_ptraced_domain - check if can change profile on ptraced task | 52 | * may_change_ptraced_domain - check if can change profile on ptraced task |
| 53 | * @task: task we want to change profile of (NOT NULL) | ||
| 54 | * @to_profile: profile to change to (NOT NULL) | 53 | * @to_profile: profile to change to (NOT NULL) |
| 55 | * | 54 | * |
| 56 | * Check if the task is ptraced and if so if the tracing task is allowed | 55 | * Check if current is ptraced and if so if the tracing task is allowed |
| 57 | * to trace the new domain | 56 | * to trace the new domain |
| 58 | * | 57 | * |
| 59 | * Returns: %0 or error if change not allowed | 58 | * Returns: %0 or error if change not allowed |
| 60 | */ | 59 | */ |
| 61 | static int may_change_ptraced_domain(struct task_struct *task, | 60 | static int may_change_ptraced_domain(struct aa_profile *to_profile) |
| 62 | struct aa_profile *to_profile) | ||
| 63 | { | 61 | { |
| 64 | struct task_struct *tracer; | 62 | struct task_struct *tracer; |
| 65 | struct aa_profile *tracerp = NULL; | 63 | struct aa_profile *tracerp = NULL; |
| 66 | int error = 0; | 64 | int error = 0; |
| 67 | 65 | ||
| 68 | rcu_read_lock(); | 66 | rcu_read_lock(); |
| 69 | tracer = ptrace_parent(task); | 67 | tracer = ptrace_parent(current); |
| 70 | if (tracer) | 68 | if (tracer) |
| 71 | /* released below */ | 69 | /* released below */ |
| 72 | tracerp = aa_get_task_profile(tracer); | 70 | tracerp = aa_get_task_profile(tracer); |
| @@ -75,7 +73,7 @@ static int may_change_ptraced_domain(struct task_struct *task, | |||
| 75 | if (!tracer || unconfined(tracerp)) | 73 | if (!tracer || unconfined(tracerp)) |
| 76 | goto out; | 74 | goto out; |
| 77 | 75 | ||
| 78 | error = aa_may_ptrace(tracer, tracerp, to_profile, PTRACE_MODE_ATTACH); | 76 | error = aa_may_ptrace(tracerp, to_profile, PTRACE_MODE_ATTACH); |
| 79 | 77 | ||
| 80 | out: | 78 | out: |
| 81 | rcu_read_unlock(); | 79 | rcu_read_unlock(); |
| @@ -477,7 +475,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) | |||
| 477 | } | 475 | } |
| 478 | 476 | ||
| 479 | if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) { | 477 | if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) { |
| 480 | error = may_change_ptraced_domain(current, new_profile); | 478 | error = may_change_ptraced_domain(new_profile); |
| 481 | if (error) { | 479 | if (error) { |
| 482 | aa_put_profile(new_profile); | 480 | aa_put_profile(new_profile); |
| 483 | goto audit; | 481 | goto audit; |
| @@ -690,7 +688,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) | |||
| 690 | } | 688 | } |
| 691 | } | 689 | } |
| 692 | 690 | ||
| 693 | error = may_change_ptraced_domain(current, hat); | 691 | error = may_change_ptraced_domain(hat); |
| 694 | if (error) { | 692 | if (error) { |
| 695 | info = "ptraced"; | 693 | info = "ptraced"; |
| 696 | error = -EPERM; | 694 | error = -EPERM; |
| @@ -829,7 +827,7 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec, | |||
| 829 | } | 827 | } |
| 830 | 828 | ||
| 831 | /* check if tracing task is allowed to trace target domain */ | 829 | /* check if tracing task is allowed to trace target domain */ |
| 832 | error = may_change_ptraced_domain(current, target); | 830 | error = may_change_ptraced_domain(target); |
| 833 | if (error) { | 831 | if (error) { |
| 834 | info = "ptrace prevents transition"; | 832 | info = "ptrace prevents transition"; |
| 835 | goto audit; | 833 | goto audit; |
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h index 30e8d7687259..ba3dfd17f23f 100644 --- a/security/apparmor/include/audit.h +++ b/security/apparmor/include/audit.h | |||
| @@ -109,7 +109,6 @@ struct apparmor_audit_data { | |||
| 109 | void *profile; | 109 | void *profile; |
| 110 | const char *name; | 110 | const char *name; |
| 111 | const char *info; | 111 | const char *info; |
| 112 | struct task_struct *tsk; | ||
| 113 | union { | 112 | union { |
| 114 | void *target; | 113 | void *target; |
| 115 | struct { | 114 | struct { |
diff --git a/security/apparmor/include/capability.h b/security/apparmor/include/capability.h index 2e7c9d6a2f3b..fc3fa381d850 100644 --- a/security/apparmor/include/capability.h +++ b/security/apparmor/include/capability.h | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * This file contains AppArmor capability mediation definitions. | 4 | * This file contains AppArmor capability mediation definitions. |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 1998-2008 Novell/SUSE | 6 | * Copyright (C) 1998-2008 Novell/SUSE |
| 7 | * Copyright 2009-2010 Canonical Ltd. | 7 | * Copyright 2009-2013 Canonical Ltd. |
| 8 | * | 8 | * |
| 9 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
| 10 | * modify it under the terms of the GNU General Public License as | 10 | * modify it under the terms of the GNU General Public License as |
| @@ -38,8 +38,7 @@ struct aa_caps { | |||
| 38 | 38 | ||
| 39 | extern struct aa_fs_entry aa_fs_entry_caps[]; | 39 | extern struct aa_fs_entry aa_fs_entry_caps[]; |
| 40 | 40 | ||
| 41 | int aa_capable(struct task_struct *task, struct aa_profile *profile, int cap, | 41 | int aa_capable(struct aa_profile *profile, int cap, int audit); |
| 42 | int audit); | ||
| 43 | 42 | ||
| 44 | static inline void aa_free_cap_rules(struct aa_caps *caps) | 43 | static inline void aa_free_cap_rules(struct aa_caps *caps) |
| 45 | { | 44 | { |
diff --git a/security/apparmor/include/ipc.h b/security/apparmor/include/ipc.h index aeda0fbc8b2f..288ca76e2fb1 100644 --- a/security/apparmor/include/ipc.h +++ b/security/apparmor/include/ipc.h | |||
| @@ -19,8 +19,8 @@ | |||
| 19 | 19 | ||
| 20 | struct aa_profile; | 20 | struct aa_profile; |
| 21 | 21 | ||
| 22 | int aa_may_ptrace(struct task_struct *tracer_task, struct aa_profile *tracer, | 22 | int aa_may_ptrace(struct aa_profile *tracer, struct aa_profile *tracee, |
| 23 | struct aa_profile *tracee, unsigned int mode); | 23 | unsigned int mode); |
| 24 | 24 | ||
| 25 | int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee, | 25 | int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee, |
| 26 | unsigned int mode); | 26 | unsigned int mode); |
diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c index c51d2266587e..777ac1c47253 100644 --- a/security/apparmor/ipc.c +++ b/security/apparmor/ipc.c | |||
| @@ -54,15 +54,14 @@ static int aa_audit_ptrace(struct aa_profile *profile, | |||
| 54 | 54 | ||
| 55 | /** | 55 | /** |
| 56 | * aa_may_ptrace - test if tracer task can trace the tracee | 56 | * aa_may_ptrace - test if tracer task can trace the tracee |
| 57 | * @tracer_task: task who will do the tracing (NOT NULL) | ||
| 58 | * @tracer: profile of the task doing the tracing (NOT NULL) | 57 | * @tracer: profile of the task doing the tracing (NOT NULL) |
| 59 | * @tracee: task to be traced | 58 | * @tracee: task to be traced |
| 60 | * @mode: whether PTRACE_MODE_READ || PTRACE_MODE_ATTACH | 59 | * @mode: whether PTRACE_MODE_READ || PTRACE_MODE_ATTACH |
| 61 | * | 60 | * |
| 62 | * Returns: %0 else error code if permission denied or error | 61 | * Returns: %0 else error code if permission denied or error |
| 63 | */ | 62 | */ |
| 64 | int aa_may_ptrace(struct task_struct *tracer_task, struct aa_profile *tracer, | 63 | int aa_may_ptrace(struct aa_profile *tracer, struct aa_profile *tracee, |
| 65 | struct aa_profile *tracee, unsigned int mode) | 64 | unsigned int mode) |
| 66 | { | 65 | { |
| 67 | /* TODO: currently only based on capability, not extended ptrace | 66 | /* TODO: currently only based on capability, not extended ptrace |
| 68 | * rules, | 67 | * rules, |
| @@ -72,7 +71,7 @@ int aa_may_ptrace(struct task_struct *tracer_task, struct aa_profile *tracer, | |||
| 72 | if (unconfined(tracer) || tracer == tracee) | 71 | if (unconfined(tracer) || tracer == tracee) |
| 73 | return 0; | 72 | return 0; |
| 74 | /* log this capability request */ | 73 | /* log this capability request */ |
| 75 | return aa_capable(tracer_task, tracer, CAP_SYS_PTRACE, 1); | 74 | return aa_capable(tracer, CAP_SYS_PTRACE, 1); |
| 76 | } | 75 | } |
| 77 | 76 | ||
| 78 | /** | 77 | /** |
| @@ -101,7 +100,7 @@ int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee, | |||
| 101 | if (!unconfined(tracer_p)) { | 100 | if (!unconfined(tracer_p)) { |
| 102 | struct aa_profile *tracee_p = aa_get_task_profile(tracee); | 101 | struct aa_profile *tracee_p = aa_get_task_profile(tracee); |
| 103 | 102 | ||
| 104 | error = aa_may_ptrace(tracer, tracer_p, tracee_p, mode); | 103 | error = aa_may_ptrace(tracer_p, tracee_p, mode); |
| 105 | error = aa_audit_ptrace(tracer_p, tracee_p, error); | 104 | error = aa_audit_ptrace(tracer_p, tracee_p, error); |
| 106 | 105 | ||
| 107 | aa_put_profile(tracee_p); | 106 | aa_put_profile(tracee_p); |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index fb99e18123b4..4257b7e2796b 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
| @@ -145,7 +145,7 @@ static int apparmor_capable(const struct cred *cred, struct user_namespace *ns, | |||
| 145 | if (!error) { | 145 | if (!error) { |
| 146 | profile = aa_cred_profile(cred); | 146 | profile = aa_cred_profile(cred); |
| 147 | if (!unconfined(profile)) | 147 | if (!unconfined(profile)) |
| 148 | error = aa_capable(current, profile, cap, audit); | 148 | error = aa_capable(profile, cap, audit); |
| 149 | } | 149 | } |
| 150 | return error; | 150 | return error; |
| 151 | } | 151 | } |
