hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/security/apparmor/domain.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * AppArmor security module
34 *
....@@ -5,11 +6,6 @@
56 *
67 * Copyright (C) 2002-2008 Novell/SUSE
78 * Copyright 2009-2010 Canonical Ltd.
8
- *
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
11
- * published by the Free Software Foundation, version 2 of the
12
- * License.
139 */
1410
1511 #include <linux/errno.h>
....@@ -44,8 +40,8 @@
4440 return;
4541
4642 for (i = 0; i < domain->size; i++)
47
- kzfree(domain->table[i]);
48
- kzfree(domain->table);
43
+ kfree_sensitive(domain->table[i]);
44
+ kfree_sensitive(domain->table);
4945 domain->table = NULL;
5046 }
5147 }
....@@ -324,8 +320,7 @@
324320 might_sleep();
325321
326322 /* transition from exec match to xattr set */
327
- state = aa_dfa_null_transition(profile->xmatch, state);
328
-
323
+ state = aa_dfa_outofband_transition(profile->xmatch, state);
329324 d = bprm->file->f_path.dentry;
330325
331326 for (i = 0; i < profile->xattr_count; i++) {
....@@ -334,7 +329,13 @@
334329 if (size >= 0) {
335330 u32 perm;
336331
337
- /* Check the xattr value, not just presence */
332
+ /*
333
+ * Check the xattr presence before value. This ensure
334
+ * that not present xattr can be distinguished from a 0
335
+ * length value or rule that matches any value
336
+ */
337
+ state = aa_dfa_null_transition(profile->xmatch, state);
338
+ /* Check xattr value */
338339 state = aa_dfa_match_len(profile->xmatch, state, value,
339340 size);
340341 perm = dfa_user_allow(profile->xmatch, state);
....@@ -344,7 +345,7 @@
344345 }
345346 }
346347 /* transition to next element */
347
- state = aa_dfa_null_transition(profile->xmatch, state);
348
+ state = aa_dfa_outofband_transition(profile->xmatch, state);
348349 if (size < 0) {
349350 /*
350351 * No xattr match, so verify if transition to
....@@ -464,7 +465,7 @@
464465 * xattrs, or a longer match
465466 */
466467 candidate = profile;
467
- candidate_len = profile->xmatch_len;
468
+ candidate_len = max(count, profile->xmatch_len);
468469 candidate_xattrs = ret;
469470 conflict = false;
470471 }
....@@ -528,7 +529,7 @@
528529 label = &new_profile->label;
529530 continue;
530531 }
531
- label = aa_label_parse(&profile->label, *name, GFP_ATOMIC,
532
+ label = aa_label_parse(&profile->label, *name, GFP_KERNEL,
532533 true, false);
533534 if (IS_ERR(label))
534535 label = NULL;
....@@ -576,7 +577,7 @@
576577 stack = NULL;
577578 break;
578579 }
579
- /* fall through to X_NAME */
580
+ fallthrough; /* to X_NAME */
580581 case AA_X_NAME:
581582 if (xindex & AA_X_CHILD)
582583 /* released by caller */
....@@ -608,7 +609,7 @@
608609 /* base the stack on post domain transition */
609610 struct aa_label *base = new;
610611
611
- new = aa_label_parse(base, stack, GFP_ATOMIC, true, false);
612
+ new = aa_label_parse(base, stack, GFP_KERNEL, true, false);
612613 if (IS_ERR(new))
613614 new = NULL;
614615 aa_put_label(base);
....@@ -624,8 +625,6 @@
624625 bool *secure_exec)
625626 {
626627 struct aa_label *new = NULL;
627
- struct aa_profile *component;
628
- struct label_it i;
629628 const char *info = NULL, *name = NULL, *target = NULL;
630629 unsigned int state = profile->file.start;
631630 struct aa_perms perms = {};
....@@ -674,39 +673,13 @@
674673 info = "profile transition not found";
675674 /* remove MAY_EXEC to audit as failure */
676675 perms.allow &= ~MAY_EXEC;
677
- } else {
678
- /* verify that each component's xattr requirements are
679
- * met, and fail execution otherwise
680
- */
681
- label_for_each(i, new, component) {
682
- if (aa_xattrs_match(bprm, component, state) <
683
- 0) {
684
- error = -EACCES;
685
- info = "required xattrs not present";
686
- perms.allow &= ~MAY_EXEC;
687
- aa_put_label(new);
688
- new = NULL;
689
- goto audit;
690
- }
691
- }
692676 }
693677 } else if (COMPLAIN_MODE(profile)) {
694678 /* no exec permission - learning mode */
695679 struct aa_profile *new_profile = NULL;
696
- char *n = kstrdup(name, GFP_ATOMIC);
697680
698
- if (n) {
699
- /* name is ptr into buffer */
700
- long pos = name - buffer;
701
- /* break per cpu buffer hold */
702
- put_buffers(buffer);
703
- new_profile = aa_new_null_profile(profile, false, n,
704
- GFP_KERNEL);
705
- get_buffers(buffer);
706
- name = buffer + pos;
707
- strcpy((char *)name, n);
708
- kfree(n);
709
- }
681
+ new_profile = aa_new_null_profile(profile, false, name,
682
+ GFP_KERNEL);
710683 if (!new_profile) {
711684 error = -ENOMEM;
712685 info = "could not create null profile";
....@@ -727,7 +700,7 @@
727700 if (DEBUG_ON) {
728701 dbg_printk("apparmor: scrubbing environment variables"
729702 " for %s profile=", name);
730
- aa_label_printk(new, GFP_ATOMIC);
703
+ aa_label_printk(new, GFP_KERNEL);
731704 dbg_printk("\n");
732705 }
733706 *secure_exec = true;
....@@ -803,7 +776,7 @@
803776 if (DEBUG_ON) {
804777 dbg_printk("apparmor: scrubbing environment "
805778 "variables for %s label=", xname);
806
- aa_label_printk(onexec, GFP_ATOMIC);
779
+ aa_label_printk(onexec, GFP_KERNEL);
807780 dbg_printk("\n");
808781 }
809782 *secure_exec = true;
....@@ -837,7 +810,7 @@
837810 bprm, buffer, cond, unsafe));
838811 if (error)
839812 return ERR_PTR(error);
840
- new = fn_label_build_in_ns(label, profile, GFP_ATOMIC,
813
+ new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
841814 aa_get_newest_label(onexec),
842815 profile_transition(profile, bprm, buffer,
843816 cond, unsafe));
....@@ -849,9 +822,9 @@
849822 buffer, cond, unsafe));
850823 if (error)
851824 return ERR_PTR(error);
852
- new = fn_label_build_in_ns(label, profile, GFP_ATOMIC,
825
+ new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
853826 aa_label_merge(&profile->label, onexec,
854
- GFP_ATOMIC),
827
+ GFP_KERNEL),
855828 profile_transition(profile, bprm, buffer,
856829 cond, unsafe));
857830 }
....@@ -869,14 +842,14 @@
869842 }
870843
871844 /**
872
- * apparmor_bprm_set_creds - set the new creds on the bprm struct
845
+ * apparmor_bprm_creds_for_exec - Update the new creds on the bprm struct
873846 * @bprm: binprm for the exec (NOT NULL)
874847 *
875848 * Returns: %0 or error on failure
876849 *
877850 * TODO: once the other paths are done see if we can't refactor into a fn
878851 */
879
-int apparmor_bprm_set_creds(struct linux_binprm *bprm)
852
+int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm)
880853 {
881854 struct aa_task_ctx *ctx;
882855 struct aa_label *label, *new = NULL;
....@@ -889,9 +862,6 @@
889862 file_inode(bprm->file)->i_uid,
890863 file_inode(bprm->file)->i_mode
891864 };
892
-
893
- if (bprm->called_set_creds)
894
- return 0;
895865
896866 ctx = task_ctx(current);
897867 AA_BUG(!cred_label(bprm->cred));
....@@ -911,13 +881,18 @@
911881 ctx->nnp = aa_get_label(label);
912882
913883 /* buffer freed below, name is pointer into buffer */
914
- get_buffers(buffer);
884
+ buffer = aa_get_buffer(false);
885
+ if (!buffer) {
886
+ error = -ENOMEM;
887
+ goto done;
888
+ }
889
+
915890 /* Test for onexec first as onexec override other x transitions. */
916891 if (ctx->onexec)
917892 new = handle_onexec(label, ctx->onexec, ctx->token,
918893 bprm, buffer, &cond, &unsafe);
919894 else
920
- new = fn_label_build(label, profile, GFP_ATOMIC,
895
+ new = fn_label_build(label, profile, GFP_KERNEL,
921896 profile_transition(profile, bprm, buffer,
922897 &cond, &unsafe));
923898
....@@ -962,7 +937,7 @@
962937 if (DEBUG_ON) {
963938 dbg_printk("scrubbing environment variables for %s "
964939 "label=", bprm->filename);
965
- aa_label_printk(new, GFP_ATOMIC);
940
+ aa_label_printk(new, GFP_KERNEL);
966941 dbg_printk("\n");
967942 }
968943 bprm->secureexec = 1;
....@@ -973,18 +948,18 @@
973948 if (DEBUG_ON) {
974949 dbg_printk("apparmor: clearing unsafe personality "
975950 "bits. %s label=", bprm->filename);
976
- aa_label_printk(new, GFP_ATOMIC);
951
+ aa_label_printk(new, GFP_KERNEL);
977952 dbg_printk("\n");
978953 }
979954 bprm->per_clear |= PER_CLEAR_ON_SETID;
980955 }
981956 aa_put_label(cred_label(bprm->cred));
982957 /* transfer reference, released when cred is freed */
983
- cred_label(bprm->cred) = new;
958
+ set_cred_label(bprm->cred, new);
984959
985960 done:
986961 aa_put_label(label);
987
- put_buffers(buffer);
962
+ aa_put_buffer(buffer);
988963
989964 return error;
990965