Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selinux: declare data arrays const

The arrays for the policy capability names, the initial sid identifiers
and the class and permission names are not changed at runtime. Declare
them const to avoid accidental modification.

Do not override the classmap and the initial sid list in the build time
script genheaders.

Check flose(3) is successful in genheaders.c, otherwise the written data
might be corrupted or incomplete.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
[PM: manual merge due to fuzz, minor style tweaks]
Signed-off-by: Paul Moore <paul@paul-moore.com>

authored by

Christian Göttsche and committed by
Paul Moore
ded34574 a9029d97

+71 -58
+45 -30
scripts/selinux/genheaders/genheaders.c
··· 59 59 exit(2); 60 60 } 61 61 62 - for (i = 0; secclass_map[i].name; i++) { 63 - struct security_class_mapping *map = &secclass_map[i]; 64 - map->name = stoupperx(map->name); 65 - for (j = 0; map->perms[j]; j++) 66 - map->perms[j] = stoupperx(map->perms[j]); 67 - } 68 - 69 - isids_len = sizeof(initial_sid_to_string) / sizeof (char *); 70 - for (i = 1; i < isids_len; i++) { 71 - const char *s = initial_sid_to_string[i]; 72 - 73 - if (s) 74 - initial_sid_to_string[i] = stoupperx(s); 75 - } 76 - 77 62 fprintf(fout, "/* This file is automatically generated. Do not edit. */\n"); 78 63 fprintf(fout, "#ifndef _SELINUX_FLASK_H_\n#define _SELINUX_FLASK_H_\n\n"); 79 64 80 65 for (i = 0; secclass_map[i].name; i++) { 81 - struct security_class_mapping *map = &secclass_map[i]; 82 - fprintf(fout, "#define SECCLASS_%-39s %2d\n", map->name, i+1); 66 + char *name = stoupperx(secclass_map[i].name); 67 + 68 + fprintf(fout, "#define SECCLASS_%-39s %2d\n", name, i+1); 69 + free(name); 83 70 } 84 71 85 72 fprintf(fout, "\n"); 86 73 74 + isids_len = sizeof(initial_sid_to_string) / sizeof(char *); 87 75 for (i = 1; i < isids_len; i++) { 88 76 const char *s = initial_sid_to_string[i]; 89 - if (s) 90 - fprintf(fout, "#define SECINITSID_%-39s %2d\n", s, i); 77 + if (s) { 78 + char *sidname = stoupperx(s); 79 + 80 + fprintf(fout, "#define SECINITSID_%-39s %2d\n", sidname, i); 81 + free(sidname); 82 + } 91 83 } 92 84 fprintf(fout, "\n#define SECINITSID_NUM %d\n", i-1); 93 85 fprintf(fout, "\nstatic inline bool security_is_socket_class(u16 kern_tclass)\n"); ··· 88 96 fprintf(fout, "\tswitch (kern_tclass) {\n"); 89 97 for (i = 0; secclass_map[i].name; i++) { 90 98 static char s[] = "SOCKET"; 91 - struct security_class_mapping *map = &secclass_map[i]; 92 - int len = strlen(map->name), l = sizeof(s) - 1; 93 - if (len >= l && memcmp(map->name + len - l, s, l) == 0) 94 - fprintf(fout, "\tcase SECCLASS_%s:\n", map->name); 99 + int len, l; 100 + char *name = stoupperx(secclass_map[i].name); 101 + 102 + len = strlen(name); 103 + l = sizeof(s) - 1; 104 + if (len >= l && memcmp(name + len - l, s, l) == 0) 105 + fprintf(fout, "\tcase SECCLASS_%s:\n", name); 106 + free(name); 95 107 } 96 108 fprintf(fout, "\t\tsock = true;\n"); 97 109 fprintf(fout, "\t\tbreak;\n"); ··· 106 110 fprintf(fout, "}\n"); 107 111 108 112 fprintf(fout, "\n#endif\n"); 109 - fclose(fout); 113 + 114 + if (fclose(fout) != 0) { 115 + fprintf(stderr, "Could not successfully close %s: %s\n", 116 + argv[1], strerror(errno)); 117 + exit(4); 118 + } 110 119 111 120 fout = fopen(argv[2], "w"); 112 121 if (!fout) { 113 122 fprintf(stderr, "Could not open %s for writing: %s\n", 114 123 argv[2], strerror(errno)); 115 - exit(4); 124 + exit(5); 116 125 } 117 126 118 127 fprintf(fout, "/* This file is automatically generated. Do not edit. */\n"); 119 128 fprintf(fout, "#ifndef _SELINUX_AV_PERMISSIONS_H_\n#define _SELINUX_AV_PERMISSIONS_H_\n\n"); 120 129 121 130 for (i = 0; secclass_map[i].name; i++) { 122 - struct security_class_mapping *map = &secclass_map[i]; 123 - int len = strlen(map->name); 131 + const struct security_class_mapping *map = &secclass_map[i]; 132 + int len; 133 + char *name = stoupperx(map->name); 134 + 135 + len = strlen(name); 124 136 for (j = 0; map->perms[j]; j++) { 137 + char *permname; 138 + 125 139 if (j >= 32) { 126 140 fprintf(stderr, "Too many permissions to fit into an access vector at (%s, %s).\n", 127 141 map->name, map->perms[j]); 128 142 exit(5); 129 143 } 130 - fprintf(fout, "#define %s__%-*s 0x%08xU\n", map->name, 131 - 39-len, map->perms[j], 1U<<j); 144 + permname = stoupperx(map->perms[j]); 145 + fprintf(fout, "#define %s__%-*s 0x%08xU\n", name, 146 + 39-len, permname, 1U<<j); 147 + free(permname); 132 148 } 149 + free(name); 133 150 } 134 151 135 152 fprintf(fout, "\n#endif\n"); 136 - fclose(fout); 153 + 154 + if (fclose(fout) != 0) { 155 + fprintf(stderr, "Could not successfully close %s: %s\n", 156 + argv[2], strerror(errno)); 157 + exit(6); 158 + } 159 + 137 160 exit(0); 138 161 }
+2 -2
scripts/selinux/mdp/mdp.c
··· 82 82 83 83 /* print out the class permissions */ 84 84 for (i = 0; secclass_map[i].name; i++) { 85 - struct security_class_mapping *map = &secclass_map[i]; 85 + const struct security_class_mapping *map = &secclass_map[i]; 86 86 fprintf(fout, "class %s\n", map->name); 87 87 fprintf(fout, "{\n"); 88 88 for (j = 0; map->perms[j]; j++) ··· 103 103 #define SYSTEMLOW "s0" 104 104 #define SYSTEMHIGH "s1:c0.c1" 105 105 for (i = 0; secclass_map[i].name; i++) { 106 - struct security_class_mapping *map = &secclass_map[i]; 106 + const struct security_class_mapping *map = &secclass_map[i]; 107 107 108 108 fprintf(fout, "mlsconstrain %s {\n", map->name); 109 109 for (j = 0; map->perms[j]; j++)
+1 -1
security/selinux/avc.c
··· 668 668 struct common_audit_data *ad = a; 669 669 struct selinux_audit_data *sad = ad->selinux_audit_data; 670 670 u32 av = sad->audited; 671 - const char **perms; 671 + const char *const *perms; 672 672 int i, perm; 673 673 674 674 audit_log_format(ab, "avc: %s ", sad->denied ? "denied" : "granted");
+1 -1
security/selinux/include/avc_ss.h
··· 18 18 const char *perms[sizeof(u32) * 8 + 1]; 19 19 }; 20 20 21 - extern struct security_class_mapping secclass_map[]; 21 + extern const struct security_class_mapping secclass_map[]; 22 22 23 23 #endif /* _SELINUX_AVC_SS_H_ */ 24 24
+1 -1
security/selinux/include/classmap.h
··· 38 38 * Note: The name for any socket class should be suffixed by "socket", 39 39 * and doesn't contain more than one substr of "socket". 40 40 */ 41 - struct security_class_mapping secclass_map[] = { 41 + const struct security_class_mapping secclass_map[] = { 42 42 { "security", 43 43 { "compute_av", "compute_create", "compute_member", 44 44 "check_context", "load_policy", "compute_relabel",
+1 -1
security/selinux/include/initial_sid_to_string.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 - static const char *initial_sid_to_string[] = { 2 + static const char *const initial_sid_to_string[] = { 3 3 NULL, 4 4 "kernel", 5 5 "security",
+1 -1
security/selinux/include/policycap.h
··· 16 16 }; 17 17 #define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1) 18 18 19 - extern const char *selinux_policycap_names[__POLICYDB_CAP_MAX]; 19 + extern const char *const selinux_policycap_names[__POLICYDB_CAP_MAX]; 20 20 21 21 #endif /* _SELINUX_POLICYCAP_H_ */
+1 -1
security/selinux/include/policycap_names.h
··· 5 5 #include "policycap.h" 6 6 7 7 /* Policy capability names */ 8 - const char *selinux_policycap_names[__POLICYDB_CAP_MAX] = { 8 + const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = { 9 9 "network_peer_controls", 10 10 "open_perms", 11 11 "extended_socket_class",
+1 -1
security/selinux/ss/avtab.c
··· 385 385 chain2_len_sum); 386 386 } 387 387 388 - static uint16_t spec_order[] = { 388 + static const uint16_t spec_order[] = { 389 389 AVTAB_ALLOWED, 390 390 AVTAB_AUDITDENY, 391 391 AVTAB_AUDITALLOW,
+15 -17
security/selinux/ss/policydb.c
··· 61 61 }; 62 62 63 63 /* These need to be updated if SYM_NUM or OCON_NUM changes */ 64 - static struct policydb_compat_info policydb_compat[] = { 64 + static const struct policydb_compat_info policydb_compat[] = { 65 65 { 66 66 .version = POLICYDB_VERSION_BASE, 67 67 .sym_num = SYM_NUM - 3, ··· 159 159 }, 160 160 }; 161 161 162 - static struct policydb_compat_info *policydb_lookup_compat(int version) 162 + static const struct policydb_compat_info *policydb_lookup_compat(int version) 163 163 { 164 164 int i; 165 - struct policydb_compat_info *info = NULL; 166 165 167 166 for (i = 0; i < ARRAY_SIZE(policydb_compat); i++) { 168 - if (policydb_compat[i].version == version) { 169 - info = &policydb_compat[i]; 170 - break; 171 - } 167 + if (policydb_compat[i].version == version) 168 + return &policydb_compat[i]; 172 169 } 173 - return info; 170 + 171 + return NULL; 174 172 } 175 173 176 174 /* ··· 312 314 return 0; 313 315 } 314 316 315 - static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) = { 317 + static int (*const destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) = { 316 318 common_destroy, 317 319 cls_destroy, 318 320 role_destroy, ··· 667 669 return 0; 668 670 } 669 671 670 - static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) = { 672 + static int (*const index_f[SYM_NUM]) (void *key, void *datum, void *datap) = { 671 673 common_index, 672 674 class_index, 673 675 role_index, ··· 1635 1637 return rc; 1636 1638 } 1637 1639 1638 - static int (*read_f[SYM_NUM]) (struct policydb *p, struct symtab *s, void *fp) = { 1640 + static int (*const read_f[SYM_NUM]) (struct policydb *p, 1641 + struct symtab *s, void *fp) = { 1639 1642 common_read, 1640 1643 class_read, 1641 1644 role_read, ··· 2207 2208 return rc; 2208 2209 } 2209 2210 2210 - static int ocontext_read(struct policydb *p, struct policydb_compat_info *info, 2211 + static int ocontext_read(struct policydb *p, const struct policydb_compat_info *info, 2211 2212 void *fp) 2212 2213 { 2213 2214 int i, j, rc; ··· 2403 2404 u32 len, nprim, nel, perm; 2404 2405 2405 2406 char *policydb_str; 2406 - struct policydb_compat_info *info; 2407 + const struct policydb_compat_info *info; 2407 2408 2408 2409 policydb_init(p); 2409 2410 ··· 3237 3238 return 0; 3238 3239 } 3239 3240 3240 - static int (*write_f[SYM_NUM]) (void *key, void *datum, 3241 - void *datap) = { 3241 + static int (*const write_f[SYM_NUM]) (void *key, void *datum, void *datap) = { 3242 3242 common_write, 3243 3243 class_write, 3244 3244 role_write, ··· 3248 3250 cat_write, 3249 3251 }; 3250 3252 3251 - static int ocontext_write(struct policydb *p, struct policydb_compat_info *info, 3253 + static int ocontext_write(struct policydb *p, const struct policydb_compat_info *info, 3252 3254 void *fp) 3253 3255 { 3254 3256 unsigned int i, j, rc; ··· 3605 3607 __le32 buf[4]; 3606 3608 u32 config; 3607 3609 size_t len; 3608 - struct policydb_compat_info *info; 3610 + const struct policydb_compat_info *info; 3609 3611 3610 3612 /* 3611 3613 * refuse to write policy older than compressed avtab
+2 -2
security/selinux/ss/services.c
··· 99 99 struct extended_perms *xperms); 100 100 101 101 static int selinux_set_mapping(struct policydb *pol, 102 - struct security_class_mapping *map, 102 + const struct security_class_mapping *map, 103 103 struct selinux_map *out_map) 104 104 { 105 105 u16 i, j; ··· 121 121 /* Store the raw class and permission values */ 122 122 j = 0; 123 123 while (map[j].name) { 124 - struct security_class_mapping *p_in = map + (j++); 124 + const struct security_class_mapping *p_in = map + (j++); 125 125 struct selinux_mapping *p_out = out_map->mapping + j; 126 126 127 127 /* An empty class string skips ahead */