hc
2024-05-16 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb
kernel/security/apparmor/policy_unpack.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * AppArmor security module
34 *
....@@ -7,11 +8,6 @@
78 * Copyright (C) 1998-2008 Novell/SUSE
89 * Copyright 2009-2010 Canonical Ltd.
910 *
10
- * This program is free software; you can redistribute it and/or
11
- * modify it under the terms of the GNU General Public License as
12
- * published by the Free Software Foundation, version 2 of the
13
- * License.
14
- *
1511 * AppArmor uses a serialized binary format for loading policy. To find
1612 * policy format documentation see Documentation/admin-guide/LSM/apparmor.rst
1713 * All policy is validated before it is used.
....@@ -20,6 +16,7 @@
2016 #include <asm/unaligned.h>
2117 #include <linux/ctype.h>
2218 #include <linux/errno.h>
19
+#include <linux/zlib.h>
2320
2421 #include "include/apparmor.h"
2522 #include "include/audit.h"
....@@ -143,9 +140,11 @@
143140 {
144141 if (l->size != r->size)
145142 return false;
143
+ if (l->compressed_size != r->compressed_size)
144
+ return false;
146145 if (aa_g_hash_policy && memcmp(l->hash, r->hash, aa_hash_size()) != 0)
147146 return false;
148
- return memcmp(l->data, r->data, r->size) == 0;
147
+ return memcmp(l->data, r->data, r->compressed_size ?: r->size) == 0;
149148 }
150149
151150 /*
....@@ -164,10 +163,10 @@
164163 aa_put_ns(ns);
165164 }
166165
167
- kzfree(d->hash);
168
- kzfree(d->name);
166
+ kfree_sensitive(d->hash);
167
+ kfree_sensitive(d->name);
169168 kvfree(d->data);
170
- kzfree(d);
169
+ kfree_sensitive(d);
171170 }
172171
173172 void aa_loaddata_kref(struct kref *kref)
....@@ -244,11 +243,11 @@
244243 static bool unpack_X(struct aa_ext *e, enum aa_code code)
245244 {
246245 if (!inbounds(e, 1))
247
- return 0;
246
+ return false;
248247 if (*(u8 *) e->pos != code)
249
- return 0;
248
+ return false;
250249 e->pos++;
251
- return 1;
250
+ return true;
252251 }
253252
254253 /**
....@@ -262,10 +261,10 @@
262261 * name element in the stream. If @name is NULL any name element will be
263262 * skipped and only the typecode will be tested.
264263 *
265
- * Returns 1 on success (both type code and name tests match) and the read
264
+ * Returns true on success (both type code and name tests match) and the read
266265 * head is advanced past the headers
267266 *
268
- * Returns: 0 if either match fails, the read head does not move
267
+ * Returns: false if either match fails, the read head does not move
269268 */
270269 static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
271270 {
....@@ -290,11 +289,29 @@
290289
291290 /* now check if type code matches */
292291 if (unpack_X(e, code))
293
- return 1;
292
+ return true;
294293
295294 fail:
296295 e->pos = pos;
297
- return 0;
296
+ return false;
297
+}
298
+
299
+static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name)
300
+{
301
+ void *pos = e->pos;
302
+
303
+ if (unpack_nameX(e, AA_U8, name)) {
304
+ if (!inbounds(e, sizeof(u8)))
305
+ goto fail;
306
+ if (data)
307
+ *data = get_unaligned((u8 *)e->pos);
308
+ e->pos += sizeof(u8);
309
+ return true;
310
+ }
311
+
312
+fail:
313
+ e->pos = pos;
314
+ return false;
298315 }
299316
300317 static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
....@@ -307,12 +324,12 @@
307324 if (data)
308325 *data = le32_to_cpu(get_unaligned((__le32 *) e->pos));
309326 e->pos += sizeof(u32);
310
- return 1;
327
+ return true;
311328 }
312329
313330 fail:
314331 e->pos = pos;
315
- return 0;
332
+ return false;
316333 }
317334
318335 static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name)
....@@ -325,12 +342,12 @@
325342 if (data)
326343 *data = le64_to_cpu(get_unaligned((__le64 *) e->pos));
327344 e->pos += sizeof(u64);
328
- return 1;
345
+ return true;
329346 }
330347
331348 fail:
332349 e->pos = pos;
333
- return 0;
350
+ return false;
334351 }
335352
336353 static size_t unpack_array(struct aa_ext *e, const char *name)
....@@ -455,7 +472,7 @@
455472 * @e: serialized data extent information (NOT NULL)
456473 * @profile: profile to add the accept table to (NOT NULL)
457474 *
458
- * Returns: 1 if table successfully unpacked
475
+ * Returns: true if table successfully unpacked
459476 */
460477 static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
461478 {
....@@ -518,12 +535,12 @@
518535 if (!unpack_nameX(e, AA_STRUCTEND, NULL))
519536 goto fail;
520537 }
521
- return 1;
538
+ return true;
522539
523540 fail:
524541 aa_free_domain_entries(&profile->file.trans);
525542 e->pos = saved_pos;
526
- return 0;
543
+ return false;
527544 }
528545
529546 static bool unpack_xattrs(struct aa_ext *e, struct aa_profile *profile)
....@@ -548,11 +565,55 @@
548565 goto fail;
549566 }
550567
551
- return 1;
568
+ return true;
552569
553570 fail:
554571 e->pos = pos;
555
- return 0;
572
+ return false;
573
+}
574
+
575
+static bool unpack_secmark(struct aa_ext *e, struct aa_profile *profile)
576
+{
577
+ void *pos = e->pos;
578
+ int i, size;
579
+
580
+ if (unpack_nameX(e, AA_STRUCT, "secmark")) {
581
+ size = unpack_array(e, NULL);
582
+
583
+ profile->secmark = kcalloc(size, sizeof(struct aa_secmark),
584
+ GFP_KERNEL);
585
+ if (!profile->secmark)
586
+ goto fail;
587
+
588
+ profile->secmark_count = size;
589
+
590
+ for (i = 0; i < size; i++) {
591
+ if (!unpack_u8(e, &profile->secmark[i].audit, NULL))
592
+ goto fail;
593
+ if (!unpack_u8(e, &profile->secmark[i].deny, NULL))
594
+ goto fail;
595
+ if (!unpack_strdup(e, &profile->secmark[i].label, NULL))
596
+ goto fail;
597
+ }
598
+ if (!unpack_nameX(e, AA_ARRAYEND, NULL))
599
+ goto fail;
600
+ if (!unpack_nameX(e, AA_STRUCTEND, NULL))
601
+ goto fail;
602
+ }
603
+
604
+ return true;
605
+
606
+fail:
607
+ if (profile->secmark) {
608
+ for (i = 0; i < size; i++)
609
+ kfree(profile->secmark[i].label);
610
+ kfree(profile->secmark);
611
+ profile->secmark_count = 0;
612
+ profile->secmark = NULL;
613
+ }
614
+
615
+ e->pos = pos;
616
+ return false;
556617 }
557618
558619 static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
....@@ -582,11 +643,11 @@
582643 if (!unpack_nameX(e, AA_STRUCTEND, NULL))
583644 goto fail;
584645 }
585
- return 1;
646
+ return true;
586647
587648 fail:
588649 e->pos = pos;
589
- return 0;
650
+ return false;
590651 }
591652
592653 static u32 strhash(const void *data, u32 len, u32 seed)
....@@ -685,12 +746,18 @@
685746 profile->label.flags |= FLAG_HAT;
686747 if (!unpack_u32(e, &tmp, NULL))
687748 goto fail;
688
- if (tmp == PACKED_MODE_COMPLAIN || (e->version & FORCE_COMPLAIN_FLAG))
749
+ if (tmp == PACKED_MODE_COMPLAIN || (e->version & FORCE_COMPLAIN_FLAG)) {
689750 profile->mode = APPARMOR_COMPLAIN;
690
- else if (tmp == PACKED_MODE_KILL)
751
+ } else if (tmp == PACKED_MODE_ENFORCE) {
752
+ profile->mode = APPARMOR_ENFORCE;
753
+ } else if (tmp == PACKED_MODE_KILL) {
691754 profile->mode = APPARMOR_KILL;
692
- else if (tmp == PACKED_MODE_UNCONFINED)
755
+ } else if (tmp == PACKED_MODE_UNCONFINED) {
693756 profile->mode = APPARMOR_UNCONFINED;
757
+ profile->label.flags |= FLAG_UNCONFINED;
758
+ } else {
759
+ goto fail;
760
+ }
694761 if (!unpack_u32(e, &tmp, NULL))
695762 goto fail;
696763 if (tmp)
....@@ -750,6 +817,11 @@
750817
751818 if (!unpack_rlimits(e, profile)) {
752819 info = "failed to unpack profile rlimits";
820
+ goto fail;
821
+ }
822
+
823
+ if (!unpack_secmark(e, profile)) {
824
+ info = "failed to unpack profile secmark rules";
753825 goto fail;
754826 }
755827
....@@ -824,7 +896,7 @@
824896 while (unpack_strdup(e, &key, NULL)) {
825897 data = kzalloc(sizeof(*data), GFP_KERNEL);
826898 if (!data) {
827
- kzfree(key);
899
+ kfree_sensitive(key);
828900 goto fail;
829901 }
830902
....@@ -832,13 +904,18 @@
832904 data->size = unpack_blob(e, &data->data, NULL);
833905 data->data = kvmemdup(data->data, data->size);
834906 if (data->size && !data->data) {
835
- kzfree(data->key);
836
- kzfree(data);
907
+ kfree_sensitive(data->key);
908
+ kfree_sensitive(data);
837909 goto fail;
838910 }
839911
840
- rhashtable_insert_fast(profile->data, &data->head,
841
- profile->data->p);
912
+ if (rhashtable_insert_fast(profile->data, &data->head,
913
+ profile->data->p)) {
914
+ kfree_sensitive(data->key);
915
+ kfree_sensitive(data);
916
+ info = "failed to insert data to table";
917
+ goto fail;
918
+ }
842919 }
843920
844921 if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
....@@ -892,7 +969,7 @@
892969 * if not specified use previous version
893970 * Mask off everything that is not kernel abi version
894971 */
895
- if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v7)) {
972
+ if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v8)) {
896973 audit_iface(NULL, NULL, NULL, "unsupported interface version",
897974 e, error);
898975 return error;
....@@ -905,11 +982,14 @@
905982 e, error);
906983 return error;
907984 }
908
- if (*ns && strcmp(*ns, name))
985
+ if (*ns && strcmp(*ns, name)) {
909986 audit_iface(NULL, NULL, NULL, "invalid ns change", e,
910987 error);
911
- else if (!*ns)
912
- *ns = name;
988
+ } else if (!*ns) {
989
+ *ns = kstrdup(name, GFP_KERNEL);
990
+ if (!*ns)
991
+ return -ENOMEM;
992
+ }
913993 }
914994
915995 return 0;
....@@ -921,8 +1001,8 @@
9211001 xtype = xindex & AA_X_TYPE_MASK;
9221002 index = xindex & AA_X_INDEX_MASK;
9231003 if (xtype == AA_X_TABLE && index >= table_size)
924
- return 0;
925
- return 1;
1004
+ return false;
1005
+ return true;
9261006 }
9271007
9281008 /* verify dfa xindexes are in range of transition tables */
....@@ -931,11 +1011,11 @@
9311011 int i;
9321012 for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
9331013 if (!verify_xindex(dfa_user_xindex(dfa, i), table_size))
934
- return 0;
1014
+ return false;
9351015 if (!verify_xindex(dfa_other_xindex(dfa, i), table_size))
936
- return 0;
1016
+ return false;
9371017 }
938
- return 1;
1018
+ return true;
9391019 }
9401020
9411021 /**
....@@ -964,7 +1044,7 @@
9641044 aa_put_profile(ent->old);
9651045 aa_put_profile(ent->new);
9661046 kfree(ent->ns_name);
967
- kzfree(ent);
1047
+ kfree_sensitive(ent);
9681048 }
9691049 }
9701050
....@@ -974,6 +1054,105 @@
9741054 if (ent)
9751055 INIT_LIST_HEAD(&ent->list);
9761056 return ent;
1057
+}
1058
+
1059
+static int deflate_compress(const char *src, size_t slen, char **dst,
1060
+ size_t *dlen)
1061
+{
1062
+ int error;
1063
+ struct z_stream_s strm;
1064
+ void *stgbuf, *dstbuf;
1065
+ size_t stglen = deflateBound(slen);
1066
+
1067
+ memset(&strm, 0, sizeof(strm));
1068
+
1069
+ if (stglen < slen)
1070
+ return -EFBIG;
1071
+
1072
+ strm.workspace = kvzalloc(zlib_deflate_workspacesize(MAX_WBITS,
1073
+ MAX_MEM_LEVEL),
1074
+ GFP_KERNEL);
1075
+ if (!strm.workspace)
1076
+ return -ENOMEM;
1077
+
1078
+ error = zlib_deflateInit(&strm, aa_g_rawdata_compression_level);
1079
+ if (error != Z_OK) {
1080
+ error = -ENOMEM;
1081
+ goto fail_deflate_init;
1082
+ }
1083
+
1084
+ stgbuf = kvzalloc(stglen, GFP_KERNEL);
1085
+ if (!stgbuf) {
1086
+ error = -ENOMEM;
1087
+ goto fail_stg_alloc;
1088
+ }
1089
+
1090
+ strm.next_in = src;
1091
+ strm.avail_in = slen;
1092
+ strm.next_out = stgbuf;
1093
+ strm.avail_out = stglen;
1094
+
1095
+ error = zlib_deflate(&strm, Z_FINISH);
1096
+ if (error != Z_STREAM_END) {
1097
+ error = -EINVAL;
1098
+ goto fail_deflate;
1099
+ }
1100
+ error = 0;
1101
+
1102
+ if (is_vmalloc_addr(stgbuf)) {
1103
+ dstbuf = kvzalloc(strm.total_out, GFP_KERNEL);
1104
+ if (dstbuf) {
1105
+ memcpy(dstbuf, stgbuf, strm.total_out);
1106
+ kvfree(stgbuf);
1107
+ }
1108
+ } else
1109
+ /*
1110
+ * If the staging buffer was kmalloc'd, then using krealloc is
1111
+ * probably going to be faster. The destination buffer will
1112
+ * always be smaller, so it's just shrunk, avoiding a memcpy
1113
+ */
1114
+ dstbuf = krealloc(stgbuf, strm.total_out, GFP_KERNEL);
1115
+
1116
+ if (!dstbuf) {
1117
+ error = -ENOMEM;
1118
+ goto fail_deflate;
1119
+ }
1120
+
1121
+ *dst = dstbuf;
1122
+ *dlen = strm.total_out;
1123
+
1124
+fail_stg_alloc:
1125
+ zlib_deflateEnd(&strm);
1126
+fail_deflate_init:
1127
+ kvfree(strm.workspace);
1128
+ return error;
1129
+
1130
+fail_deflate:
1131
+ kvfree(stgbuf);
1132
+ goto fail_stg_alloc;
1133
+}
1134
+
1135
+static int compress_loaddata(struct aa_loaddata *data)
1136
+{
1137
+
1138
+ AA_BUG(data->compressed_size > 0);
1139
+
1140
+ /*
1141
+ * Shortcut the no compression case, else we increase the amount of
1142
+ * storage required by a small amount
1143
+ */
1144
+ if (aa_g_rawdata_compression_level != 0) {
1145
+ void *udata = data->data;
1146
+ int error = deflate_compress(udata, data->size, &data->data,
1147
+ &data->compressed_size);
1148
+ if (error)
1149
+ return error;
1150
+
1151
+ kvfree(udata);
1152
+ } else
1153
+ data->compressed_size = data->size;
1154
+
1155
+ return 0;
9771156 }
9781157
9791158 /**
....@@ -1044,6 +1223,9 @@
10441223 goto fail;
10451224 }
10461225 }
1226
+ error = compress_loaddata(udata);
1227
+ if (error)
1228
+ goto fail;
10471229 return 0;
10481230
10491231 fail_profile:
....@@ -1057,3 +1239,7 @@
10571239
10581240 return error;
10591241 }
1242
+
1243
+#ifdef CONFIG_SECURITY_APPARMOR_KUNIT_TEST
1244
+#include "policy_unpack_test.c"
1245
+#endif /* CONFIG_SECURITY_APPARMOR_KUNIT_TEST */