forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 072de836f53be56a70cecf70b43ae43b7ce17376
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,8 +904,8 @@
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
....@@ -905,11 +977,14 @@
905977 e, error);
906978 return error;
907979 }
908
- if (*ns && strcmp(*ns, name))
980
+ if (*ns && strcmp(*ns, name)) {
909981 audit_iface(NULL, NULL, NULL, "invalid ns change", e,
910982 error);
911
- else if (!*ns)
912
- *ns = name;
983
+ } else if (!*ns) {
984
+ *ns = kstrdup(name, GFP_KERNEL);
985
+ if (!*ns)
986
+ return -ENOMEM;
987
+ }
913988 }
914989
915990 return 0;
....@@ -921,8 +996,8 @@
921996 xtype = xindex & AA_X_TYPE_MASK;
922997 index = xindex & AA_X_INDEX_MASK;
923998 if (xtype == AA_X_TABLE && index >= table_size)
924
- return 0;
925
- return 1;
999
+ return false;
1000
+ return true;
9261001 }
9271002
9281003 /* verify dfa xindexes are in range of transition tables */
....@@ -931,11 +1006,11 @@
9311006 int i;
9321007 for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
9331008 if (!verify_xindex(dfa_user_xindex(dfa, i), table_size))
934
- return 0;
1009
+ return false;
9351010 if (!verify_xindex(dfa_other_xindex(dfa, i), table_size))
936
- return 0;
1011
+ return false;
9371012 }
938
- return 1;
1013
+ return true;
9391014 }
9401015
9411016 /**
....@@ -964,7 +1039,7 @@
9641039 aa_put_profile(ent->old);
9651040 aa_put_profile(ent->new);
9661041 kfree(ent->ns_name);
967
- kzfree(ent);
1042
+ kfree_sensitive(ent);
9681043 }
9691044 }
9701045
....@@ -974,6 +1049,105 @@
9741049 if (ent)
9751050 INIT_LIST_HEAD(&ent->list);
9761051 return ent;
1052
+}
1053
+
1054
+static int deflate_compress(const char *src, size_t slen, char **dst,
1055
+ size_t *dlen)
1056
+{
1057
+ int error;
1058
+ struct z_stream_s strm;
1059
+ void *stgbuf, *dstbuf;
1060
+ size_t stglen = deflateBound(slen);
1061
+
1062
+ memset(&strm, 0, sizeof(strm));
1063
+
1064
+ if (stglen < slen)
1065
+ return -EFBIG;
1066
+
1067
+ strm.workspace = kvzalloc(zlib_deflate_workspacesize(MAX_WBITS,
1068
+ MAX_MEM_LEVEL),
1069
+ GFP_KERNEL);
1070
+ if (!strm.workspace)
1071
+ return -ENOMEM;
1072
+
1073
+ error = zlib_deflateInit(&strm, aa_g_rawdata_compression_level);
1074
+ if (error != Z_OK) {
1075
+ error = -ENOMEM;
1076
+ goto fail_deflate_init;
1077
+ }
1078
+
1079
+ stgbuf = kvzalloc(stglen, GFP_KERNEL);
1080
+ if (!stgbuf) {
1081
+ error = -ENOMEM;
1082
+ goto fail_stg_alloc;
1083
+ }
1084
+
1085
+ strm.next_in = src;
1086
+ strm.avail_in = slen;
1087
+ strm.next_out = stgbuf;
1088
+ strm.avail_out = stglen;
1089
+
1090
+ error = zlib_deflate(&strm, Z_FINISH);
1091
+ if (error != Z_STREAM_END) {
1092
+ error = -EINVAL;
1093
+ goto fail_deflate;
1094
+ }
1095
+ error = 0;
1096
+
1097
+ if (is_vmalloc_addr(stgbuf)) {
1098
+ dstbuf = kvzalloc(strm.total_out, GFP_KERNEL);
1099
+ if (dstbuf) {
1100
+ memcpy(dstbuf, stgbuf, strm.total_out);
1101
+ kvfree(stgbuf);
1102
+ }
1103
+ } else
1104
+ /*
1105
+ * If the staging buffer was kmalloc'd, then using krealloc is
1106
+ * probably going to be faster. The destination buffer will
1107
+ * always be smaller, so it's just shrunk, avoiding a memcpy
1108
+ */
1109
+ dstbuf = krealloc(stgbuf, strm.total_out, GFP_KERNEL);
1110
+
1111
+ if (!dstbuf) {
1112
+ error = -ENOMEM;
1113
+ goto fail_deflate;
1114
+ }
1115
+
1116
+ *dst = dstbuf;
1117
+ *dlen = strm.total_out;
1118
+
1119
+fail_stg_alloc:
1120
+ zlib_deflateEnd(&strm);
1121
+fail_deflate_init:
1122
+ kvfree(strm.workspace);
1123
+ return error;
1124
+
1125
+fail_deflate:
1126
+ kvfree(stgbuf);
1127
+ goto fail_stg_alloc;
1128
+}
1129
+
1130
+static int compress_loaddata(struct aa_loaddata *data)
1131
+{
1132
+
1133
+ AA_BUG(data->compressed_size > 0);
1134
+
1135
+ /*
1136
+ * Shortcut the no compression case, else we increase the amount of
1137
+ * storage required by a small amount
1138
+ */
1139
+ if (aa_g_rawdata_compression_level != 0) {
1140
+ void *udata = data->data;
1141
+ int error = deflate_compress(udata, data->size, &data->data,
1142
+ &data->compressed_size);
1143
+ if (error)
1144
+ return error;
1145
+
1146
+ kvfree(udata);
1147
+ } else
1148
+ data->compressed_size = data->size;
1149
+
1150
+ return 0;
9771151 }
9781152
9791153 /**
....@@ -1044,6 +1218,9 @@
10441218 goto fail;
10451219 }
10461220 }
1221
+ error = compress_loaddata(udata);
1222
+ if (error)
1223
+ goto fail;
10471224 return 0;
10481225
10491226 fail_profile:
....@@ -1057,3 +1234,7 @@
10571234
10581235 return error;
10591236 }
1237
+
1238
+#ifdef CONFIG_SECURITY_APPARMOR_KUNIT_TEST
1239
+#include "policy_unpack_test.c"
1240
+#endif /* CONFIG_SECURITY_APPARMOR_KUNIT_TEST */