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>
This commit is contained in:
Christian Göttsche 2022-05-02 16:43:38 +02:00 committed by Paul Moore
parent a9029d9704
commit ded34574d4
11 changed files with 71 additions and 58 deletions

View File

@ -59,35 +59,27 @@ int main(int argc, char *argv[])
exit(2);
}
for (i = 0; secclass_map[i].name; i++) {
struct security_class_mapping *map = &secclass_map[i];
map->name = stoupperx(map->name);
for (j = 0; map->perms[j]; j++)
map->perms[j] = stoupperx(map->perms[j]);
}
isids_len = sizeof(initial_sid_to_string) / sizeof (char *);
for (i = 1; i < isids_len; i++) {
const char *s = initial_sid_to_string[i];
if (s)
initial_sid_to_string[i] = stoupperx(s);
}
fprintf(fout, "/* This file is automatically generated. Do not edit. */\n");
fprintf(fout, "#ifndef _SELINUX_FLASK_H_\n#define _SELINUX_FLASK_H_\n\n");
for (i = 0; secclass_map[i].name; i++) {
struct security_class_mapping *map = &secclass_map[i];
fprintf(fout, "#define SECCLASS_%-39s %2d\n", map->name, i+1);
char *name = stoupperx(secclass_map[i].name);
fprintf(fout, "#define SECCLASS_%-39s %2d\n", name, i+1);
free(name);
}
fprintf(fout, "\n");
isids_len = sizeof(initial_sid_to_string) / sizeof(char *);
for (i = 1; i < isids_len; i++) {
const char *s = initial_sid_to_string[i];
if (s)
fprintf(fout, "#define SECINITSID_%-39s %2d\n", s, i);
if (s) {
char *sidname = stoupperx(s);
fprintf(fout, "#define SECINITSID_%-39s %2d\n", sidname, i);
free(sidname);
}
}
fprintf(fout, "\n#define SECINITSID_NUM %d\n", i-1);
fprintf(fout, "\nstatic inline bool security_is_socket_class(u16 kern_tclass)\n");
@ -96,10 +88,14 @@ int main(int argc, char *argv[])
fprintf(fout, "\tswitch (kern_tclass) {\n");
for (i = 0; secclass_map[i].name; i++) {
static char s[] = "SOCKET";
struct security_class_mapping *map = &secclass_map[i];
int len = strlen(map->name), l = sizeof(s) - 1;
if (len >= l && memcmp(map->name + len - l, s, l) == 0)
fprintf(fout, "\tcase SECCLASS_%s:\n", map->name);
int len, l;
char *name = stoupperx(secclass_map[i].name);
len = strlen(name);
l = sizeof(s) - 1;
if (len >= l && memcmp(name + len - l, s, l) == 0)
fprintf(fout, "\tcase SECCLASS_%s:\n", name);
free(name);
}
fprintf(fout, "\t\tsock = true;\n");
fprintf(fout, "\t\tbreak;\n");
@ -110,33 +106,52 @@ int main(int argc, char *argv[])
fprintf(fout, "}\n");
fprintf(fout, "\n#endif\n");
fclose(fout);
if (fclose(fout) != 0) {
fprintf(stderr, "Could not successfully close %s: %s\n",
argv[1], strerror(errno));
exit(4);
}
fout = fopen(argv[2], "w");
if (!fout) {
fprintf(stderr, "Could not open %s for writing: %s\n",
argv[2], strerror(errno));
exit(4);
exit(5);
}
fprintf(fout, "/* This file is automatically generated. Do not edit. */\n");
fprintf(fout, "#ifndef _SELINUX_AV_PERMISSIONS_H_\n#define _SELINUX_AV_PERMISSIONS_H_\n\n");
for (i = 0; secclass_map[i].name; i++) {
struct security_class_mapping *map = &secclass_map[i];
int len = strlen(map->name);
const struct security_class_mapping *map = &secclass_map[i];
int len;
char *name = stoupperx(map->name);
len = strlen(name);
for (j = 0; map->perms[j]; j++) {
char *permname;
if (j >= 32) {
fprintf(stderr, "Too many permissions to fit into an access vector at (%s, %s).\n",
map->name, map->perms[j]);
exit(5);
}
fprintf(fout, "#define %s__%-*s 0x%08xU\n", map->name,
39-len, map->perms[j], 1U<<j);
permname = stoupperx(map->perms[j]);
fprintf(fout, "#define %s__%-*s 0x%08xU\n", name,
39-len, permname, 1U<<j);
free(permname);
}
free(name);
}
fprintf(fout, "\n#endif\n");
fclose(fout);
if (fclose(fout) != 0) {
fprintf(stderr, "Could not successfully close %s: %s\n",
argv[2], strerror(errno));
exit(6);
}
exit(0);
}

View File

@ -82,7 +82,7 @@ int main(int argc, char *argv[])
/* print out the class permissions */
for (i = 0; secclass_map[i].name; i++) {
struct security_class_mapping *map = &secclass_map[i];
const struct security_class_mapping *map = &secclass_map[i];
fprintf(fout, "class %s\n", map->name);
fprintf(fout, "{\n");
for (j = 0; map->perms[j]; j++)
@ -103,7 +103,7 @@ int main(int argc, char *argv[])
#define SYSTEMLOW "s0"
#define SYSTEMHIGH "s1:c0.c1"
for (i = 0; secclass_map[i].name; i++) {
struct security_class_mapping *map = &secclass_map[i];
const struct security_class_mapping *map = &secclass_map[i];
fprintf(fout, "mlsconstrain %s {\n", map->name);
for (j = 0; map->perms[j]; j++)

View File

@ -668,7 +668,7 @@ static void avc_audit_pre_callback(struct audit_buffer *ab, void *a)
struct common_audit_data *ad = a;
struct selinux_audit_data *sad = ad->selinux_audit_data;
u32 av = sad->audited;
const char **perms;
const char *const *perms;
int i, perm;
audit_log_format(ab, "avc: %s ", sad->denied ? "denied" : "granted");

View File

@ -18,7 +18,7 @@ struct security_class_mapping {
const char *perms[sizeof(u32) * 8 + 1];
};
extern struct security_class_mapping secclass_map[];
extern const struct security_class_mapping secclass_map[];
#endif /* _SELINUX_AVC_SS_H_ */

View File

@ -38,7 +38,7 @@
* Note: The name for any socket class should be suffixed by "socket",
* and doesn't contain more than one substr of "socket".
*/
struct security_class_mapping secclass_map[] = {
const struct security_class_mapping secclass_map[] = {
{ "security",
{ "compute_av", "compute_create", "compute_member",
"check_context", "load_policy", "compute_relabel",

View File

@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
static const char *initial_sid_to_string[] = {
static const char *const initial_sid_to_string[] = {
NULL,
"kernel",
"security",

View File

@ -16,6 +16,6 @@ enum {
};
#define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1)
extern const char *selinux_policycap_names[__POLICYDB_CAP_MAX];
extern const char *const selinux_policycap_names[__POLICYDB_CAP_MAX];
#endif /* _SELINUX_POLICYCAP_H_ */

View File

@ -5,7 +5,7 @@
#include "policycap.h"
/* Policy capability names */
const char *selinux_policycap_names[__POLICYDB_CAP_MAX] = {
const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = {
"network_peer_controls",
"open_perms",
"extended_socket_class",

View File

@ -385,7 +385,7 @@ void avtab_hash_eval(struct avtab *h, char *tag)
chain2_len_sum);
}
static uint16_t spec_order[] = {
static const uint16_t spec_order[] = {
AVTAB_ALLOWED,
AVTAB_AUDITDENY,
AVTAB_AUDITALLOW,

View File

@ -61,7 +61,7 @@ struct policydb_compat_info {
};
/* These need to be updated if SYM_NUM or OCON_NUM changes */
static struct policydb_compat_info policydb_compat[] = {
static const struct policydb_compat_info policydb_compat[] = {
{
.version = POLICYDB_VERSION_BASE,
.sym_num = SYM_NUM - 3,
@ -159,18 +159,16 @@ static struct policydb_compat_info policydb_compat[] = {
},
};
static struct policydb_compat_info *policydb_lookup_compat(int version)
static const struct policydb_compat_info *policydb_lookup_compat(int version)
{
int i;
struct policydb_compat_info *info = NULL;
for (i = 0; i < ARRAY_SIZE(policydb_compat); i++) {
if (policydb_compat[i].version == version) {
info = &policydb_compat[i];
break;
}
if (policydb_compat[i].version == version)
return &policydb_compat[i];
}
return info;
return NULL;
}
/*
@ -314,7 +312,7 @@ static int cat_destroy(void *key, void *datum, void *p)
return 0;
}
static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) = {
static int (*const destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) = {
common_destroy,
cls_destroy,
role_destroy,
@ -669,7 +667,7 @@ static int cat_index(void *key, void *datum, void *datap)
return 0;
}
static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) = {
static int (*const index_f[SYM_NUM]) (void *key, void *datum, void *datap) = {
common_index,
class_index,
role_index,
@ -1637,7 +1635,8 @@ bad:
return rc;
}
static int (*read_f[SYM_NUM]) (struct policydb *p, struct symtab *s, void *fp) = {
static int (*const read_f[SYM_NUM]) (struct policydb *p,
struct symtab *s, void *fp) = {
common_read,
class_read,
role_read,
@ -2208,7 +2207,7 @@ out:
return rc;
}
static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
static int ocontext_read(struct policydb *p, const struct policydb_compat_info *info,
void *fp)
{
int i, j, rc;
@ -2404,7 +2403,7 @@ int policydb_read(struct policydb *p, void *fp)
u32 len, nprim, nel, perm;
char *policydb_str;
struct policydb_compat_info *info;
const struct policydb_compat_info *info;
policydb_init(p);
@ -3238,8 +3237,7 @@ static int user_write(void *vkey, void *datum, void *ptr)
return 0;
}
static int (*write_f[SYM_NUM]) (void *key, void *datum,
void *datap) = {
static int (*const write_f[SYM_NUM]) (void *key, void *datum, void *datap) = {
common_write,
class_write,
role_write,
@ -3250,7 +3248,7 @@ static int (*write_f[SYM_NUM]) (void *key, void *datum,
cat_write,
};
static int ocontext_write(struct policydb *p, struct policydb_compat_info *info,
static int ocontext_write(struct policydb *p, const struct policydb_compat_info *info,
void *fp)
{
unsigned int i, j, rc;
@ -3607,7 +3605,7 @@ int policydb_write(struct policydb *p, void *fp)
__le32 buf[4];
u32 config;
size_t len;
struct policydb_compat_info *info;
const struct policydb_compat_info *info;
/*
* refuse to write policy older than compressed avtab

View File

@ -99,7 +99,7 @@ static void context_struct_compute_av(struct policydb *policydb,
struct extended_perms *xperms);
static int selinux_set_mapping(struct policydb *pol,
struct security_class_mapping *map,
const struct security_class_mapping *map,
struct selinux_map *out_map)
{
u16 i, j;
@ -121,7 +121,7 @@ static int selinux_set_mapping(struct policydb *pol,
/* Store the raw class and permission values */
j = 0;
while (map[j].name) {
struct security_class_mapping *p_in = map + (j++);
const struct security_class_mapping *p_in = map + (j++);
struct selinux_mapping *p_out = out_map->mapping + j;
/* An empty class string skips ahead */