aboutsummaryrefslogtreecommitdiffstats
path: root/security/apparmor
diff options
context:
space:
mode:
Diffstat (limited to 'security/apparmor')
-rw-r--r--security/apparmor/audit.c11
-rw-r--r--security/apparmor/capability.c4
-rw-r--r--security/apparmor/domain.c35
-rw-r--r--security/apparmor/file.c2
-rw-r--r--security/apparmor/include/audit.h1
-rw-r--r--security/apparmor/ipc.c2
-rw-r--r--security/apparmor/lib.c2
-rw-r--r--security/apparmor/lsm.c6
-rw-r--r--security/apparmor/path.c2
-rw-r--r--security/apparmor/policy.c6
-rw-r--r--security/apparmor/policy_unpack.c2
-rw-r--r--security/apparmor/resource.c2
12 files changed, 62 insertions, 13 deletions
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index cc3520d39a78..3ae28db5a64f 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -111,7 +111,7 @@ static const char *const aa_audit_type[] = {
111static void audit_pre(struct audit_buffer *ab, void *ca) 111static 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->tsk ? sa->tsk : current; 114 struct task_struct *tsk = sa->aad->tsk ? sa->aad->tsk : current;
115 115
116 if (aa_g_audit_header) { 116 if (aa_g_audit_header) {
117 audit_log_format(ab, "apparmor="); 117 audit_log_format(ab, "apparmor=");
@@ -149,6 +149,12 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
149 audit_log_format(ab, " name="); 149 audit_log_format(ab, " name=");
150 audit_log_untrustedstring(ab, sa->aad->name); 150 audit_log_untrustedstring(ab, sa->aad->name);
151 } 151 }
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
152} 158}
153 159
154/** 160/**
@@ -205,7 +211,8 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
205 aa_audit_msg(type, sa, cb); 211 aa_audit_msg(type, sa, cb);
206 212
207 if (sa->aad->type == AUDIT_APPARMOR_KILL) 213 if (sa->aad->type == AUDIT_APPARMOR_KILL)
208 (void)send_sig_info(SIGKILL, NULL, sa->tsk ? sa->tsk : current); 214 (void)send_sig_info(SIGKILL, NULL,
215 sa->aad->tsk ? sa->aad->tsk : current);
209 216
210 if (sa->aad->type == AUDIT_APPARMOR_ALLOWED) 217 if (sa->aad->type == AUDIT_APPARMOR_ALLOWED)
211 return complain_error(sa->aad->error); 218 return complain_error(sa->aad->error);
diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c
index 088dba3bf7dc..887a5e948945 100644
--- a/security/apparmor/capability.c
+++ b/security/apparmor/capability.c
@@ -65,10 +65,10 @@ static int audit_caps(struct aa_profile *profile, struct task_struct *task,
65 int type = AUDIT_APPARMOR_AUTO; 65 int type = AUDIT_APPARMOR_AUTO;
66 struct common_audit_data sa; 66 struct common_audit_data sa;
67 struct apparmor_audit_data aad = {0,}; 67 struct apparmor_audit_data aad = {0,};
68 COMMON_AUDIT_DATA_INIT(&sa, CAP); 68 sa.type = LSM_AUDIT_DATA_CAP;
69 sa.aad = &aad; 69 sa.aad = &aad;
70 sa.tsk = task;
71 sa.u.cap = cap; 70 sa.u.cap = cap;
71 sa.aad->tsk = task;
72 sa.aad->op = OP_CAPABLE; 72 sa.aad->op = OP_CAPABLE;
73 sa.aad->error = error; 73 sa.aad->error = error;
74 74
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 6327685c101e..b81ea10a17a3 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -394,6 +394,11 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
394 new_profile = find_attach(ns, &ns->base.profiles, name); 394 new_profile = find_attach(ns, &ns->base.profiles, name);
395 if (!new_profile) 395 if (!new_profile)
396 goto cleanup; 396 goto cleanup;
397 /*
398 * NOTE: Domain transitions from unconfined are allowed
399 * even when no_new_privs is set because this aways results
400 * in a further reduction of permissions.
401 */
397 goto apply; 402 goto apply;
398 } 403 }
399 404
@@ -455,6 +460,16 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
455 /* fail exec */ 460 /* fail exec */
456 error = -EACCES; 461 error = -EACCES;
457 462
463 /*
464 * Policy has specified a domain transition, if no_new_privs then
465 * fail the exec.
466 */
467 if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) {
468 aa_put_profile(new_profile);
469 error = -EPERM;
470 goto cleanup;
471 }
472
458 if (!new_profile) 473 if (!new_profile)
459 goto audit; 474 goto audit;
460 475
@@ -609,6 +624,14 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
609 const char *target = NULL, *info = NULL; 624 const char *target = NULL, *info = NULL;
610 int error = 0; 625 int error = 0;
611 626
627 /*
628 * Fail explicitly requested domain transitions if no_new_privs.
629 * There is no exception for unconfined as change_hat is not
630 * available.
631 */
632 if (current->no_new_privs)
633 return -EPERM;
634
612 /* released below */ 635 /* released below */
613 cred = get_current_cred(); 636 cred = get_current_cred();
614 cxt = cred->security; 637 cxt = cred->security;
@@ -750,6 +773,18 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
750 cxt = cred->security; 773 cxt = cred->security;
751 profile = aa_cred_profile(cred); 774 profile = aa_cred_profile(cred);
752 775
776 /*
777 * Fail explicitly requested domain transitions if no_new_privs
778 * and not unconfined.
779 * Domain transitions from unconfined are allowed even when
780 * no_new_privs is set because this aways results in a reduction
781 * of permissions.
782 */
783 if (current->no_new_privs && !unconfined(profile)) {
784 put_cred(cred);
785 return -EPERM;
786 }
787
753 if (ns_name) { 788 if (ns_name) {
754 /* released below */ 789 /* released below */
755 ns = aa_find_namespace(profile->ns, ns_name); 790 ns = aa_find_namespace(profile->ns, ns_name);
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index 2f8fcba9ce4b..cf19d4093ca4 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -108,7 +108,7 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
108 int type = AUDIT_APPARMOR_AUTO; 108 int type = AUDIT_APPARMOR_AUTO;
109 struct common_audit_data sa; 109 struct common_audit_data sa;
110 struct apparmor_audit_data aad = {0,}; 110 struct apparmor_audit_data aad = {0,};
111 COMMON_AUDIT_DATA_INIT(&sa, NONE); 111 sa.type = LSM_AUDIT_DATA_NONE;
112 sa.aad = &aad; 112 sa.aad = &aad;
113 aad.op = op, 113 aad.op = op,
114 aad.fs.request = request; 114 aad.fs.request = request;
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
index 3868b1e5d5ba..4b7e18951aea 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -110,6 +110,7 @@ struct apparmor_audit_data {
110 void *profile; 110 void *profile;
111 const char *name; 111 const char *name;
112 const char *info; 112 const char *info;
113 struct task_struct *tsk;
113 union { 114 union {
114 void *target; 115 void *target;
115 struct { 116 struct {
diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
index c3da93a5150d..cf1071b14232 100644
--- a/security/apparmor/ipc.c
+++ b/security/apparmor/ipc.c
@@ -42,7 +42,7 @@ static int aa_audit_ptrace(struct aa_profile *profile,
42{ 42{
43 struct common_audit_data sa; 43 struct common_audit_data sa;
44 struct apparmor_audit_data aad = {0,}; 44 struct apparmor_audit_data aad = {0,};
45 COMMON_AUDIT_DATA_INIT(&sa, NONE); 45 sa.type = LSM_AUDIT_DATA_NONE;
46 sa.aad = &aad; 46 sa.aad = &aad;
47 aad.op = OP_PTRACE; 47 aad.op = OP_PTRACE;
48 aad.target = target; 48 aad.target = target;
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
index e75829ba0ff9..7430298116d6 100644
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -66,7 +66,7 @@ void aa_info_message(const char *str)
66 if (audit_enabled) { 66 if (audit_enabled) {
67 struct common_audit_data sa; 67 struct common_audit_data sa;
68 struct apparmor_audit_data aad = {0,}; 68 struct apparmor_audit_data aad = {0,};
69 COMMON_AUDIT_DATA_INIT(&sa, NONE); 69 sa.type = LSM_AUDIT_DATA_NONE;
70 sa.aad = &aad; 70 sa.aad = &aad;
71 aad.info = str; 71 aad.info = str;
72 aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL); 72 aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL);
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index ad05d391974d..032daab449b0 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -373,7 +373,7 @@ static int apparmor_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
373 AA_MAY_META_READ); 373 AA_MAY_META_READ);
374} 374}
375 375
376static int apparmor_dentry_open(struct file *file, const struct cred *cred) 376static int apparmor_file_open(struct file *file, const struct cred *cred)
377{ 377{
378 struct aa_file_cxt *fcxt = file->f_security; 378 struct aa_file_cxt *fcxt = file->f_security;
379 struct aa_profile *profile; 379 struct aa_profile *profile;
@@ -589,7 +589,7 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
589 } else { 589 } else {
590 struct common_audit_data sa; 590 struct common_audit_data sa;
591 struct apparmor_audit_data aad = {0,}; 591 struct apparmor_audit_data aad = {0,};
592 COMMON_AUDIT_DATA_INIT(&sa, NONE); 592 sa.type = LSM_AUDIT_DATA_NONE;
593 sa.aad = &aad; 593 sa.aad = &aad;
594 aad.op = OP_SETPROCATTR; 594 aad.op = OP_SETPROCATTR;
595 aad.info = name; 595 aad.info = name;
@@ -640,9 +640,9 @@ static struct security_operations apparmor_ops = {
640 .path_chmod = apparmor_path_chmod, 640 .path_chmod = apparmor_path_chmod,
641 .path_chown = apparmor_path_chown, 641 .path_chown = apparmor_path_chown,
642 .path_truncate = apparmor_path_truncate, 642 .path_truncate = apparmor_path_truncate,
643 .dentry_open = apparmor_dentry_open,
644 .inode_getattr = apparmor_inode_getattr, 643 .inode_getattr = apparmor_inode_getattr,
645 644
645 .file_open = apparmor_file_open,
646 .file_permission = apparmor_file_permission, 646 .file_permission = apparmor_file_permission,
647 .file_alloc_security = apparmor_file_alloc_security, 647 .file_alloc_security = apparmor_file_alloc_security,
648 .file_free_security = apparmor_file_free_security, 648 .file_free_security = apparmor_file_free_security,
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index 2daeea4f9266..e91ffee80162 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -94,6 +94,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
94 * be returned. 94 * be returned.
95 */ 95 */
96 if (!res || IS_ERR(res)) { 96 if (!res || IS_ERR(res)) {
97 if (PTR_ERR(res) == -ENAMETOOLONG)
98 return -ENAMETOOLONG;
97 connected = 0; 99 connected = 0;
98 res = dentry_path_raw(path->dentry, buf, buflen); 100 res = dentry_path_raw(path->dentry, buf, buflen);
99 if (IS_ERR(res)) { 101 if (IS_ERR(res)) {
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index f1f7506a464d..cf5fd220309b 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -903,6 +903,10 @@ struct aa_profile *aa_lookup_profile(struct aa_namespace *ns, const char *hname)
903 profile = aa_get_profile(__lookup_profile(&ns->base, hname)); 903 profile = aa_get_profile(__lookup_profile(&ns->base, hname));
904 read_unlock(&ns->lock); 904 read_unlock(&ns->lock);
905 905
906 /* the unconfined profile is not in the regular profile list */
907 if (!profile && strcmp(hname, "unconfined") == 0)
908 profile = aa_get_profile(ns->unconfined);
909
906 /* refcount released by caller */ 910 /* refcount released by caller */
907 return profile; 911 return profile;
908} 912}
@@ -965,7 +969,7 @@ static int audit_policy(int op, gfp_t gfp, const char *name, const char *info,
965{ 969{
966 struct common_audit_data sa; 970 struct common_audit_data sa;
967 struct apparmor_audit_data aad = {0,}; 971 struct apparmor_audit_data aad = {0,};
968 COMMON_AUDIT_DATA_INIT(&sa, NONE); 972 sa.type = LSM_AUDIT_DATA_NONE;
969 sa.aad = &aad; 973 sa.aad = &aad;
970 aad.op = op; 974 aad.op = op;
971 aad.name = name; 975 aad.name = name;
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index deab7c7e8dc0..329b1fd30749 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -95,7 +95,7 @@ static int audit_iface(struct aa_profile *new, const char *name,
95 struct aa_profile *profile = __aa_current_profile(); 95 struct aa_profile *profile = __aa_current_profile();
96 struct common_audit_data sa; 96 struct common_audit_data sa;
97 struct apparmor_audit_data aad = {0,}; 97 struct apparmor_audit_data aad = {0,};
98 COMMON_AUDIT_DATA_INIT(&sa, NONE); 98 sa.type = LSM_AUDIT_DATA_NONE;
99 sa.aad = &aad; 99 sa.aad = &aad;
100 if (e) 100 if (e)
101 aad.iface.pos = e->pos - e->start; 101 aad.iface.pos = e->pos - e->start;
diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
index 2fe8613efe33..e1f3d7ef2c54 100644
--- a/security/apparmor/resource.c
+++ b/security/apparmor/resource.c
@@ -52,7 +52,7 @@ static int audit_resource(struct aa_profile *profile, unsigned int resource,
52 struct common_audit_data sa; 52 struct common_audit_data sa;
53 struct apparmor_audit_data aad = {0,}; 53 struct apparmor_audit_data aad = {0,};
54 54
55 COMMON_AUDIT_DATA_INIT(&sa, NONE); 55 sa.type = LSM_AUDIT_DATA_NONE;
56 sa.aad = &aad; 56 sa.aad = &aad;
57 aad.op = OP_SETRLIMIT, 57 aad.op = OP_SETRLIMIT,
58 aad.rlim.rlim = resource; 58 aad.rlim.rlim = resource;