Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git

This commit is contained in:
Stephen Rothwell 2025-01-13 13:11:14 +11:00
commit 1a6c1734d2
22 changed files with 170 additions and 165 deletions

View File

@ -77,6 +77,7 @@ struct common_audit_data {
#define LSM_AUDIT_DATA_LOCKDOWN 15 #define LSM_AUDIT_DATA_LOCKDOWN 15
#define LSM_AUDIT_DATA_NOTIFICATION 16 #define LSM_AUDIT_DATA_NOTIFICATION 16
#define LSM_AUDIT_DATA_ANONINODE 17 #define LSM_AUDIT_DATA_ANONINODE 17
#define LSM_AUDIT_DATA_NLMSGTYPE 18
union { union {
struct path path; struct path path;
struct dentry *dentry; struct dentry *dentry;
@ -98,6 +99,7 @@ struct common_audit_data {
struct lsm_ibendport_audit *ibendport; struct lsm_ibendport_audit *ibendport;
int reason; int reason;
const char *anonclass; const char *anonclass;
u16 nlmsg_type;
} u; } u;
/* this union contains LSM specific data */ /* this union contains LSM specific data */
union { union {

View File

@ -425,6 +425,9 @@ static void dump_common_audit_data(struct audit_buffer *ab,
case LSM_AUDIT_DATA_ANONINODE: case LSM_AUDIT_DATA_ANONINODE:
audit_log_format(ab, " anonclass=%s", a->u.anonclass); audit_log_format(ab, " anonclass=%s", a->u.anonclass);
break; break;
case LSM_AUDIT_DATA_NLMSGTYPE:
audit_log_format(ab, " nl-msgtype=%hu", a->u.nlmsg_type);
break;
} /* switch (a->type) */ } /* switch (a->type) */
} }

View File

@ -33,11 +33,10 @@ $(addprefix $(obj)/,$(selinux-y)): $(obj)/flask.h
quiet_cmd_genhdrs = GEN $(addprefix $(obj)/,$(genhdrs)) quiet_cmd_genhdrs = GEN $(addprefix $(obj)/,$(genhdrs))
cmd_genhdrs = $< $(addprefix $(obj)/,$(genhdrs)) cmd_genhdrs = $< $(addprefix $(obj)/,$(genhdrs))
# see the note above, replace the $targets and 'flask.h' rule with the lines targets += $(genhdrs)
# below:
# targets += $(genhdrs) # see the note above, replace the 'flask.h' rule with the line below:
# $(addprefix $(obj)/,$(genhdrs)) &: $(obj)/genheaders FORCE # $(addprefix $(obj)/,$(genhdrs)) &: $(obj)/genheaders FORCE
targets += flask.h
$(obj)/flask.h: $(obj)/genheaders FORCE $(obj)/flask.h: $(obj)/genheaders FORCE
$(call if_changed,genhdrs) $(call if_changed,genhdrs)

View File

@ -407,7 +407,7 @@ static const struct {
static int match_opt_prefix(char *s, int l, char **arg) static int match_opt_prefix(char *s, int l, char **arg)
{ {
int i; unsigned int i;
for (i = 0; i < ARRAY_SIZE(tokens); i++) { for (i = 0; i < ARRAY_SIZE(tokens); i++) {
size_t len = tokens[i].len; size_t len = tokens[i].len;
@ -3135,7 +3135,7 @@ static int selinux_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
const struct cred *cred = current_cred(); const struct cred *cred = current_cred();
struct inode *inode = d_backing_inode(dentry); struct inode *inode = d_backing_inode(dentry);
unsigned int ia_valid = iattr->ia_valid; unsigned int ia_valid = iattr->ia_valid;
__u32 av = FILE__WRITE; u32 av = FILE__WRITE;
/* ATTR_FORCE is just used for ATTR_KILL_S[UG]ID. */ /* ATTR_FORCE is just used for ATTR_KILL_S[UG]ID. */
if (ia_valid & ATTR_FORCE) { if (ia_valid & ATTR_FORCE) {
@ -4836,7 +4836,7 @@ out:
return err; return err;
err_af: err_af:
/* Note that SCTP services expect -EINVAL, others -EAFNOSUPPORT. */ /* Note that SCTP services expect -EINVAL, others -EAFNOSUPPORT. */
if (sksec->sclass == SECCLASS_SCTP_SOCKET) if (sk->sk_protocol == IPPROTO_SCTP)
return -EINVAL; return -EINVAL;
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
} }
@ -5940,14 +5940,14 @@ static int nlmsg_sock_has_extended_perms(struct sock *sk, u32 perms, u16 nlmsg_t
{ {
struct sk_security_struct *sksec = sk->sk_security; struct sk_security_struct *sksec = sk->sk_security;
struct common_audit_data ad; struct common_audit_data ad;
struct lsm_network_audit net;
u8 driver; u8 driver;
u8 xperm; u8 xperm;
if (sock_skip_has_perm(sksec->sid)) if (sock_skip_has_perm(sksec->sid))
return 0; return 0;
ad_net_init_from_sk(&ad, &net, sk); ad.type = LSM_AUDIT_DATA_NLMSGTYPE;
ad.u.nlmsg_type = nlmsg_type;
driver = nlmsg_type >> 8; driver = nlmsg_type >> 8;
xperm = nlmsg_type & 0xff; xperm = nlmsg_type & 0xff;

View File

@ -179,7 +179,7 @@ const struct security_class_mapping secclass_map[] = {
{ "anon_inode", { COMMON_FILE_PERMS, NULL } }, { "anon_inode", { COMMON_FILE_PERMS, NULL } },
{ "io_uring", { "override_creds", "sqpoll", "cmd", NULL } }, { "io_uring", { "override_creds", "sqpoll", "cmd", NULL } },
{ "user_namespace", { "create", NULL } }, { "user_namespace", { "create", NULL } },
{ NULL } /* last one */ { NULL, {} }
}; };
#ifdef __KERNEL__ /* avoid this check when building host programs */ #ifdef __KERNEL__ /* avoid this check when building host programs */

View File

@ -16,7 +16,7 @@
int security_get_bools(struct selinux_policy *policy, u32 *len, char ***names, int security_get_bools(struct selinux_policy *policy, u32 *len, char ***names,
int **values); int **values);
int security_set_bools(u32 len, int *values); int security_set_bools(u32 len, const int *values);
int security_get_bool_value(u32 index); int security_get_bool_value(u32 index);

View File

@ -46,10 +46,11 @@
#define POLICYDB_VERSION_INFINIBAND 31 #define POLICYDB_VERSION_INFINIBAND 31
#define POLICYDB_VERSION_GLBLUB 32 #define POLICYDB_VERSION_GLBLUB 32
#define POLICYDB_VERSION_COMP_FTRANS 33 /* compressed filename transitions */ #define POLICYDB_VERSION_COMP_FTRANS 33 /* compressed filename transitions */
#define POLICYDB_VERSION_COND_XPERMS 34 /* extended permissions in conditional policies */
/* Range of policy versions we understand*/ /* Range of policy versions we understand*/
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_COMP_FTRANS #define POLICYDB_VERSION_MAX POLICYDB_VERSION_COND_XPERMS
/* Mask for just the mount related flags */ /* Mask for just the mount related flags */
#define SE_MNTMASK 0x0f #define SE_MNTMASK 0x0f
@ -292,7 +293,7 @@ int security_context_to_sid_default(const char *scontext, u32 scontext_len,
int security_context_to_sid_force(const char *scontext, u32 scontext_len, int security_context_to_sid_force(const char *scontext, u32 scontext_len,
u32 *sid); u32 *sid);
int security_get_user_sids(u32 callsid, char *username, u32 **sids, u32 *nel); int security_get_user_sids(u32 fromsid, const char *username, u32 **sids, u32 *nel);
int security_port_sid(u8 protocol, u16 port, u32 *out_sid); int security_port_sid(u8 protocol, u16 port, u32 *out_sid);
@ -310,7 +311,7 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
int security_validate_transition_user(u32 oldsid, u32 newsid, u32 tasksid, int security_validate_transition_user(u32 oldsid, u32 newsid, u32 tasksid,
u16 tclass); u16 tclass);
int security_bounded_transition(u32 oldsid, u32 newsid); int security_bounded_transition(u32 old_sid, u32 new_sid);
int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid); int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);

View File

@ -1515,7 +1515,7 @@ static const struct file_operations sel_avc_hash_stats_ops = {
#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
static struct avc_cache_stats *sel_avc_get_stat_idx(loff_t *idx) static struct avc_cache_stats *sel_avc_get_stat_idx(loff_t *idx)
{ {
int cpu; loff_t cpu;
for (cpu = *idx; cpu < nr_cpu_ids; ++cpu) { for (cpu = *idx; cpu < nr_cpu_ids; ++cpu) {
if (!cpu_possible(cpu)) if (!cpu_possible(cpu))
@ -2001,7 +2001,7 @@ static int sel_fill_super(struct super_block *sb, struct fs_context *fc)
[SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUGO}, [SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUGO},
[SEL_VALIDATE_TRANS] = {"validatetrans", &sel_transition_ops, [SEL_VALIDATE_TRANS] = {"validatetrans", &sel_transition_ops,
S_IWUGO}, S_IWUGO},
/* last one */ {""} /* last one */ {"", NULL, 0}
}; };
ret = selinux_fs_info_create(sb); ret = selinux_fs_info_create(sb);

View File

@ -336,10 +336,10 @@ static const uint16_t spec_order[] = {
}; };
/* clang-format on */ /* clang-format on */
int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, int avtab_read_item(struct avtab *a, struct policy_file *fp, struct policydb *pol,
int (*insertf)(struct avtab *a, const struct avtab_key *k, int (*insertf)(struct avtab *a, const struct avtab_key *k,
const struct avtab_datum *d, void *p), const struct avtab_datum *d, void *p),
void *p) void *p, bool conditional)
{ {
__le16 buf16[4]; __le16 buf16[4];
u16 enabled; u16 enabled;
@ -457,6 +457,13 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
"was specified\n", "was specified\n",
vers); vers);
return -EINVAL; return -EINVAL;
} else if ((vers < POLICYDB_VERSION_COND_XPERMS) &&
(key.specified & AVTAB_XPERMS) && conditional) {
pr_err("SELinux: avtab: policy version %u does not "
"support extended permissions rules in conditional "
"policies and one was specified\n",
vers);
return -EINVAL;
} else if (key.specified & AVTAB_XPERMS) { } else if (key.specified & AVTAB_XPERMS) {
memset(&xperms, 0, sizeof(struct avtab_extended_perms)); memset(&xperms, 0, sizeof(struct avtab_extended_perms));
rc = next_entry(&xperms.specified, fp, sizeof(u8)); rc = next_entry(&xperms.specified, fp, sizeof(u8));
@ -500,7 +507,7 @@ static int avtab_insertf(struct avtab *a, const struct avtab_key *k,
return avtab_insert(a, k, d); return avtab_insert(a, k, d);
} }
int avtab_read(struct avtab *a, void *fp, struct policydb *pol) int avtab_read(struct avtab *a, struct policy_file *fp, struct policydb *pol)
{ {
int rc; int rc;
__le32 buf[1]; __le32 buf[1];
@ -523,7 +530,7 @@ int avtab_read(struct avtab *a, void *fp, struct policydb *pol)
goto bad; goto bad;
for (i = 0; i < nel; i++) { for (i = 0; i < nel; i++) {
rc = avtab_read_item(a, fp, pol, avtab_insertf, NULL); rc = avtab_read_item(a, fp, pol, avtab_insertf, NULL, false);
if (rc) { if (rc) {
if (rc == -ENOMEM) if (rc == -ENOMEM)
pr_err("SELinux: avtab: out of memory\n"); pr_err("SELinux: avtab: out of memory\n");
@ -543,7 +550,7 @@ bad:
goto out; goto out;
} }
int avtab_write_item(struct policydb *p, const struct avtab_node *cur, void *fp) int avtab_write_item(struct policydb *p, const struct avtab_node *cur, struct policy_file *fp)
{ {
__le16 buf16[4]; __le16 buf16[4];
__le32 buf32[ARRAY_SIZE(cur->datum.u.xperms->perms.p)]; __le32 buf32[ARRAY_SIZE(cur->datum.u.xperms->perms.p)];
@ -579,7 +586,7 @@ int avtab_write_item(struct policydb *p, const struct avtab_node *cur, void *fp)
return 0; return 0;
} }
int avtab_write(struct policydb *p, struct avtab *a, void *fp) int avtab_write(struct policydb *p, struct avtab *a, struct policy_file *fp)
{ {
u32 i; u32 i;
int rc = 0; int rc = 0;

View File

@ -89,7 +89,7 @@ struct avtab {
}; };
void avtab_init(struct avtab *h); void avtab_init(struct avtab *h);
int avtab_alloc(struct avtab *, u32); int avtab_alloc(struct avtab *h, u32 nrules);
int avtab_alloc_dup(struct avtab *new, const struct avtab *orig); int avtab_alloc_dup(struct avtab *new, const struct avtab *orig);
void avtab_destroy(struct avtab *h); void avtab_destroy(struct avtab *h);
@ -105,15 +105,16 @@ static inline void avtab_hash_eval(struct avtab *h, const char *tag)
#endif #endif
struct policydb; struct policydb;
int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, struct policy_file;
int avtab_read_item(struct avtab *a, struct policy_file *fp, struct policydb *pol,
int (*insert)(struct avtab *a, const struct avtab_key *k, int (*insert)(struct avtab *a, const struct avtab_key *k,
const struct avtab_datum *d, void *p), const struct avtab_datum *d, void *p),
void *p); void *p, bool conditional);
int avtab_read(struct avtab *a, void *fp, struct policydb *pol); int avtab_read(struct avtab *a, struct policy_file *fp, struct policydb *pol);
int avtab_write_item(struct policydb *p, const struct avtab_node *cur, int avtab_write_item(struct policydb *p, const struct avtab_node *cur,
void *fp); struct policy_file *fp);
int avtab_write(struct policydb *p, struct avtab *a, void *fp); int avtab_write(struct policydb *p, struct avtab *a, struct policy_file *fp);
struct avtab_node *avtab_insert_nonunique(struct avtab *h, struct avtab_node *avtab_insert_nonunique(struct avtab *h,
const struct avtab_key *key, const struct avtab_key *key,

View File

@ -206,7 +206,7 @@ static int bool_isvalid(struct cond_bool_datum *b)
return 1; return 1;
} }
int cond_read_bool(struct policydb *p, struct symtab *s, void *fp) int cond_read_bool(struct policydb *p, struct symtab *s, struct policy_file *fp)
{ {
char *key = NULL; char *key = NULL;
struct cond_bool_datum *booldatum; struct cond_bool_datum *booldatum;
@ -230,17 +230,11 @@ int cond_read_bool(struct policydb *p, struct symtab *s, void *fp)
goto err; goto err;
len = le32_to_cpu(buf[2]); len = le32_to_cpu(buf[2]);
if (((len == 0) || (len == (u32)-1)))
goto err;
rc = -ENOMEM; rc = str_read(&key, GFP_KERNEL, fp, len);
key = kmalloc(len + 1, GFP_KERNEL);
if (!key)
goto err;
rc = next_entry(key, fp, len);
if (rc) if (rc)
goto err; goto err;
key[len] = '\0';
rc = symtab_insert(s, key, booldatum); rc = symtab_insert(s, key, booldatum);
if (rc) if (rc)
goto err; goto err;
@ -323,7 +317,7 @@ static int cond_insertf(struct avtab *a, const struct avtab_key *k,
return 0; return 0;
} }
static int cond_read_av_list(struct policydb *p, void *fp, static int cond_read_av_list(struct policydb *p, struct policy_file *fp,
struct cond_av_list *list, struct cond_av_list *list,
struct cond_av_list *other) struct cond_av_list *other)
{ {
@ -349,7 +343,7 @@ static int cond_read_av_list(struct policydb *p, void *fp,
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
data.dst = &list->nodes[i]; data.dst = &list->nodes[i];
rc = avtab_read_item(&p->te_cond_avtab, fp, p, cond_insertf, rc = avtab_read_item(&p->te_cond_avtab, fp, p, cond_insertf,
&data); &data, true);
if (rc) { if (rc) {
kfree(list->nodes); kfree(list->nodes);
list->nodes = NULL; list->nodes = NULL;
@ -375,7 +369,7 @@ static int expr_node_isvalid(struct policydb *p, struct cond_expr_node *expr)
return 1; return 1;
} }
static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp) static int cond_read_node(struct policydb *p, struct cond_node *node, struct policy_file *fp)
{ {
__le32 buf[2]; __le32 buf[2];
u32 i, len; u32 i, len;
@ -415,7 +409,7 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
return cond_read_av_list(p, fp, &node->false_list, &node->true_list); return cond_read_av_list(p, fp, &node->false_list, &node->true_list);
} }
int cond_read_list(struct policydb *p, void *fp) int cond_read_list(struct policydb *p, struct policy_file *fp)
{ {
__le32 buf[1]; __le32 buf[1];
u32 i, len; u32 i, len;
@ -453,7 +447,7 @@ int cond_write_bool(void *vkey, void *datum, void *ptr)
char *key = vkey; char *key = vkey;
struct cond_bool_datum *booldatum = datum; struct cond_bool_datum *booldatum = datum;
struct policy_data *pd = ptr; struct policy_data *pd = ptr;
void *fp = pd->fp; struct policy_file *fp = pd->fp;
__le32 buf[3]; __le32 buf[3];
u32 len; u32 len;
int rc; int rc;
@ -536,7 +530,7 @@ static int cond_write_node(struct policydb *p, struct cond_node *node,
return 0; return 0;
} }
int cond_write_list(struct policydb *p, void *fp) int cond_write_list(struct policydb *p, struct policy_file *fp)
{ {
u32 i; u32 i;
__le32 buf[1]; __le32 buf[1];

View File

@ -68,10 +68,10 @@ int cond_destroy_bool(void *key, void *datum, void *p);
int cond_index_bool(void *key, void *datum, void *datap); int cond_index_bool(void *key, void *datum, void *datap);
int cond_read_bool(struct policydb *p, struct symtab *s, void *fp); int cond_read_bool(struct policydb *p, struct symtab *s, struct policy_file *fp);
int cond_read_list(struct policydb *p, void *fp); int cond_read_list(struct policydb *p, struct policy_file *fp);
int cond_write_bool(void *key, void *datum, void *ptr); int cond_write_bool(void *key, void *datum, void *ptr);
int cond_write_list(struct policydb *p, void *fp); int cond_write_list(struct policydb *p, struct policy_file *fp);
void cond_compute_av(struct avtab *ctab, struct avtab_key *key, void cond_compute_av(struct avtab *ctab, struct avtab_key *key,
struct av_decision *avd, struct extended_perms *xperms); struct av_decision *avd, struct extended_perms *xperms);

View File

@ -20,7 +20,7 @@ u32 context_compute_hash(const struct context *c)
* context struct with only the len & str set (and vice versa) * context struct with only the len & str set (and vice versa)
* under a given policy. Since context structs from different * under a given policy. Since context structs from different
* policies should never meet, it is safe to hash valid and * policies should never meet, it is safe to hash valid and
* invalid contexts differently. The context_cmp() function * invalid contexts differently. The context_equal() function
* already operates under the same assumption. * already operates under the same assumption.
*/ */
if (c->len) if (c->len)

View File

@ -132,13 +132,13 @@ out:
return rc; return rc;
} }
static inline int mls_context_cmp(const struct context *c1, static inline bool mls_context_equal(const struct context *c1,
const struct context *c2) const struct context *c2)
{ {
return ((c1->range.level[0].sens == c2->range.level[0].sens) && return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) && ebitmap_equal(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
(c1->range.level[1].sens == c2->range.level[1].sens) && (c1->range.level[1].sens == c2->range.level[1].sens) &&
ebitmap_cmp(&c1->range.level[1].cat, &c2->range.level[1].cat)); ebitmap_equal(&c1->range.level[1].cat, &c2->range.level[1].cat));
} }
static inline void mls_context_destroy(struct context *c) static inline void mls_context_destroy(struct context *c)
@ -188,15 +188,15 @@ static inline void context_destroy(struct context *c)
mls_context_destroy(c); mls_context_destroy(c);
} }
static inline int context_cmp(const struct context *c1, static inline bool context_equal(const struct context *c1,
const struct context *c2) const struct context *c2)
{ {
if (c1->len && c2->len) if (c1->len && c2->len)
return (c1->len == c2->len && !strcmp(c1->str, c2->str)); return (c1->len == c2->len && !strcmp(c1->str, c2->str));
if (c1->len || c2->len) if (c1->len || c2->len)
return 0; return 0;
return ((c1->user == c2->user) && (c1->role == c2->role) && return ((c1->user == c2->user) && (c1->role == c2->role) &&
(c1->type == c2->type) && mls_context_cmp(c1, c2)); (c1->type == c2->type) && mls_context_equal(c1, c2));
} }
u32 context_compute_hash(const struct context *c); u32 context_compute_hash(const struct context *c);

View File

@ -25,12 +25,12 @@
static struct kmem_cache *ebitmap_node_cachep __ro_after_init; static struct kmem_cache *ebitmap_node_cachep __ro_after_init;
int ebitmap_cmp(const struct ebitmap *e1, const struct ebitmap *e2) bool ebitmap_equal(const struct ebitmap *e1, const struct ebitmap *e2)
{ {
const struct ebitmap_node *n1, *n2; const struct ebitmap_node *n1, *n2;
if (e1->highbit != e2->highbit) if (e1->highbit != e2->highbit)
return 0; return false;
n1 = e1->node; n1 = e1->node;
n2 = e2->node; n2 = e2->node;
@ -41,9 +41,9 @@ int ebitmap_cmp(const struct ebitmap *e1, const struct ebitmap *e2)
} }
if (n1 || n2) if (n1 || n2)
return 0; return false;
return 1; return true;
} }
int ebitmap_cpy(struct ebitmap *dst, const struct ebitmap *src) int ebitmap_cpy(struct ebitmap *dst, const struct ebitmap *src)
@ -360,7 +360,7 @@ void ebitmap_destroy(struct ebitmap *e)
e->node = NULL; e->node = NULL;
} }
int ebitmap_read(struct ebitmap *e, void *fp) int ebitmap_read(struct ebitmap *e, struct policy_file *fp)
{ {
struct ebitmap_node *n = NULL; struct ebitmap_node *n = NULL;
u32 mapunit, count, startbit, index, i; u32 mapunit, count, startbit, index, i;
@ -478,7 +478,7 @@ bad:
goto out; goto out;
} }
int ebitmap_write(const struct ebitmap *e, void *fp) int ebitmap_write(const struct ebitmap *e, struct policy_file *fp)
{ {
struct ebitmap_node *n; struct ebitmap_node *n;
u32 bit, count, last_bit, last_startbit; u32 bit, count, last_bit, last_startbit;

View File

@ -120,7 +120,7 @@ static inline void ebitmap_node_clr_bit(struct ebitmap_node *n, u32 bit)
(bit) < ebitmap_length(e); \ (bit) < ebitmap_length(e); \
(bit) = ebitmap_next_positive(e, &(n), bit)) (bit) = ebitmap_next_positive(e, &(n), bit))
int ebitmap_cmp(const struct ebitmap *e1, const struct ebitmap *e2); bool ebitmap_equal(const struct ebitmap *e1, const struct ebitmap *e2);
int ebitmap_cpy(struct ebitmap *dst, const struct ebitmap *src); int ebitmap_cpy(struct ebitmap *dst, const struct ebitmap *src);
int ebitmap_and(struct ebitmap *dst, const struct ebitmap *e1, int ebitmap_and(struct ebitmap *dst, const struct ebitmap *e1,
const struct ebitmap *e2); const struct ebitmap *e2);
@ -129,8 +129,9 @@ int ebitmap_contains(const struct ebitmap *e1, const struct ebitmap *e2,
int ebitmap_get_bit(const struct ebitmap *e, u32 bit); int ebitmap_get_bit(const struct ebitmap *e, u32 bit);
int ebitmap_set_bit(struct ebitmap *e, u32 bit, int value); int ebitmap_set_bit(struct ebitmap *e, u32 bit, int value);
void ebitmap_destroy(struct ebitmap *e); void ebitmap_destroy(struct ebitmap *e);
int ebitmap_read(struct ebitmap *e, void *fp); struct policy_file;
int ebitmap_write(const struct ebitmap *e, void *fp); int ebitmap_read(struct ebitmap *e, struct policy_file *fp);
int ebitmap_write(const struct ebitmap *e, struct policy_file *fp);
u32 ebitmap_hash(const struct ebitmap *e, u32 hash); u32 ebitmap_hash(const struct ebitmap *e, u32 hash);
#ifdef CONFIG_NETLABEL #ifdef CONFIG_NETLABEL

View File

@ -171,7 +171,7 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l)
* levdatum->level->cat and no bit in l->cat is larger than * levdatum->level->cat and no bit in l->cat is larger than
* p->p_cats.nprim. * p->p_cats.nprim.
*/ */
return ebitmap_contains(&levdatum->level->cat, &l->cat, return ebitmap_contains(&levdatum->level.cat, &l->cat,
p->p_cats.nprim); p->p_cats.nprim);
} }
@ -289,7 +289,7 @@ int mls_context_to_sid(struct policydb *pol, char oldc, char *scontext,
levdatum = symtab_search(&pol->p_levels, sensitivity); levdatum = symtab_search(&pol->p_levels, sensitivity);
if (!levdatum) if (!levdatum)
return -EINVAL; return -EINVAL;
context->range.level[l].sens = levdatum->level->sens; context->range.level[l].sens = levdatum->level.sens;
/* Extract category set. */ /* Extract category set. */
while (next_cat != NULL) { while (next_cat != NULL) {
@ -456,7 +456,7 @@ int mls_convert_context(struct policydb *oldp, struct policydb *newp,
if (!levdatum) if (!levdatum)
return -EINVAL; return -EINVAL;
newc->range.level[l].sens = levdatum->level->sens; newc->range.level[l].sens = levdatum->level.sens;
ebitmap_for_each_positive_bit(&oldc->range.level[l].cat, node, ebitmap_for_each_positive_bit(&oldc->range.level[l].cat, node,
i) i)

View File

@ -29,7 +29,7 @@ struct mls_range {
static inline int mls_level_eq(const struct mls_level *l1, static inline int mls_level_eq(const struct mls_level *l1,
const struct mls_level *l2) const struct mls_level *l2)
{ {
return ((l1->sens == l2->sens) && ebitmap_cmp(&l1->cat, &l2->cat)); return ((l1->sens == l2->sens) && ebitmap_equal(&l1->cat, &l2->cat));
} }
static inline int mls_level_dom(const struct mls_level *l1, static inline int mls_level_dom(const struct mls_level *l1,

View File

@ -155,6 +155,11 @@ static const struct policydb_compat_info policydb_compat[] = {
.sym_num = SYM_NUM, .sym_num = SYM_NUM,
.ocon_num = OCON_NUM, .ocon_num = OCON_NUM,
}, },
{
.version = POLICYDB_VERSION_COND_XPERMS,
.sym_num = SYM_NUM,
.ocon_num = OCON_NUM,
},
}; };
static const struct policydb_compat_info * static const struct policydb_compat_info *
@ -296,9 +301,7 @@ static int sens_destroy(void *key, void *datum, void *p)
kfree(key); kfree(key);
if (datum) { if (datum) {
levdatum = datum; levdatum = datum;
if (levdatum->level) ebitmap_destroy(&levdatum->level.cat);
ebitmap_destroy(&levdatum->level->cat);
kfree(levdatum->level);
} }
kfree(datum); kfree(datum);
return 0; return 0;
@ -630,11 +633,11 @@ static int sens_index(void *key, void *datum, void *datap)
p = datap; p = datap;
if (!levdatum->isalias) { if (!levdatum->isalias) {
if (!levdatum->level->sens || if (!levdatum->level.sens ||
levdatum->level->sens > p->p_levels.nprim) levdatum->level.sens > p->p_levels.nprim)
return -EINVAL; return -EINVAL;
p->sym_val_to_name[SYM_LEVELS][levdatum->level->sens - 1] = key; p->sym_val_to_name[SYM_LEVELS][levdatum->level.sens - 1] = key;
} }
return 0; return 0;
@ -992,7 +995,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
* Read a MLS range structure from a policydb binary * Read a MLS range structure from a policydb binary
* representation file. * representation file.
*/ */
static int mls_read_range_helper(struct mls_range *r, void *fp) static int mls_read_range_helper(struct mls_range *r, struct policy_file *fp)
{ {
__le32 buf[2]; __le32 buf[2];
u32 items; u32 items;
@ -1052,7 +1055,7 @@ out:
* from a policydb binary representation file. * from a policydb binary representation file.
*/ */
static int context_read_and_validate(struct context *c, struct policydb *p, static int context_read_and_validate(struct context *c, struct policydb *p,
void *fp) struct policy_file *fp)
{ {
__le32 buf[3]; __le32 buf[3];
int rc; int rc;
@ -1090,7 +1093,7 @@ out:
* binary representation file. * binary representation file.
*/ */
static int str_read(char **strp, gfp_t flags, void *fp, u32 len) int str_read(char **strp, gfp_t flags, struct policy_file *fp, u32 len)
{ {
int rc; int rc;
char *str; char *str;
@ -1113,7 +1116,7 @@ static int str_read(char **strp, gfp_t flags, void *fp, u32 len)
return 0; return 0;
} }
static int perm_read(struct policydb *p, struct symtab *s, void *fp) static int perm_read(struct policydb *p, struct symtab *s, struct policy_file *fp)
{ {
char *key = NULL; char *key = NULL;
struct perm_datum *perdatum; struct perm_datum *perdatum;
@ -1146,7 +1149,7 @@ bad:
return rc; return rc;
} }
static int common_read(struct policydb *p, struct symtab *s, void *fp) static int common_read(struct policydb *p, struct symtab *s, struct policy_file *fp)
{ {
char *key = NULL; char *key = NULL;
struct common_datum *comdatum; struct common_datum *comdatum;
@ -1198,7 +1201,7 @@ static void type_set_init(struct type_set *t)
ebitmap_init(&t->negset); ebitmap_init(&t->negset);
} }
static int type_set_read(struct type_set *t, void *fp) static int type_set_read(struct type_set *t, struct policy_file *fp)
{ {
__le32 buf[1]; __le32 buf[1];
int rc; int rc;
@ -1217,7 +1220,7 @@ static int type_set_read(struct type_set *t, void *fp)
} }
static int read_cons_helper(struct policydb *p, struct constraint_node **nodep, static int read_cons_helper(struct policydb *p, struct constraint_node **nodep,
u32 ncons, int allowxtarget, void *fp) u32 ncons, int allowxtarget, struct policy_file *fp)
{ {
struct constraint_node *c, *lc; struct constraint_node *c, *lc;
struct constraint_expr *e, *le; struct constraint_expr *e, *le;
@ -1311,7 +1314,7 @@ static int read_cons_helper(struct policydb *p, struct constraint_node **nodep,
return 0; return 0;
} }
static int class_read(struct policydb *p, struct symtab *s, void *fp) static int class_read(struct policydb *p, struct symtab *s, struct policy_file *fp)
{ {
char *key = NULL; char *key = NULL;
struct class_datum *cladatum; struct class_datum *cladatum;
@ -1408,7 +1411,7 @@ bad:
return rc; return rc;
} }
static int role_read(struct policydb *p, struct symtab *s, void *fp) static int role_read(struct policydb *p, struct symtab *s, struct policy_file *fp)
{ {
char *key = NULL; char *key = NULL;
struct role_datum *role; struct role_datum *role;
@ -1465,7 +1468,7 @@ bad:
return rc; return rc;
} }
static int type_read(struct policydb *p, struct symtab *s, void *fp) static int type_read(struct policydb *p, struct symtab *s, struct policy_file *fp)
{ {
char *key = NULL; char *key = NULL;
struct type_datum *typdatum; struct type_datum *typdatum;
@ -1517,7 +1520,7 @@ bad:
* Read a MLS level structure from a policydb binary * Read a MLS level structure from a policydb binary
* representation file. * representation file.
*/ */
static int mls_read_level(struct mls_level *lp, void *fp) static int mls_read_level(struct mls_level *lp, struct policy_file *fp)
{ {
__le32 buf[1]; __le32 buf[1];
int rc; int rc;
@ -1539,7 +1542,7 @@ static int mls_read_level(struct mls_level *lp, void *fp)
return 0; return 0;
} }
static int user_read(struct policydb *p, struct symtab *s, void *fp) static int user_read(struct policydb *p, struct symtab *s, struct policy_file *fp)
{ {
char *key = NULL; char *key = NULL;
struct user_datum *usrdatum; struct user_datum *usrdatum;
@ -1590,7 +1593,7 @@ bad:
return rc; return rc;
} }
static int sens_read(struct policydb *p, struct symtab *s, void *fp) static int sens_read(struct policydb *p, struct symtab *s, struct policy_file *fp)
{ {
char *key = NULL; char *key = NULL;
struct level_datum *levdatum; struct level_datum *levdatum;
@ -1613,12 +1616,7 @@ static int sens_read(struct policydb *p, struct symtab *s, void *fp)
if (rc) if (rc)
goto bad; goto bad;
rc = -ENOMEM; rc = mls_read_level(&levdatum->level, fp);
levdatum->level = kmalloc(sizeof(*levdatum->level), GFP_KERNEL);
if (!levdatum->level)
goto bad;
rc = mls_read_level(levdatum->level, fp);
if (rc) if (rc)
goto bad; goto bad;
@ -1631,7 +1629,7 @@ bad:
return rc; return rc;
} }
static int cat_read(struct policydb *p, struct symtab *s, void *fp) static int cat_read(struct policydb *p, struct symtab *s, struct policy_file *fp)
{ {
char *key = NULL; char *key = NULL;
struct cat_datum *catdatum; struct cat_datum *catdatum;
@ -1666,7 +1664,7 @@ bad:
/* clang-format off */ /* clang-format off */
static int (*const read_f[SYM_NUM])(struct policydb *p, struct symtab *s, static int (*const read_f[SYM_NUM])(struct policydb *p, struct symtab *s,
void *fp) = { struct policy_file *fp) = {
common_read, common_read,
class_read, class_read,
role_read, role_read,
@ -1836,7 +1834,7 @@ u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name)
return 1U << (perdatum->value - 1); return 1U << (perdatum->value - 1);
} }
static int range_read(struct policydb *p, void *fp) static int range_read(struct policydb *p, struct policy_file *fp)
{ {
struct range_trans *rt = NULL; struct range_trans *rt = NULL;
struct mls_range *r = NULL; struct mls_range *r = NULL;
@ -1913,7 +1911,7 @@ out:
return rc; return rc;
} }
static int filename_trans_read_helper_compat(struct policydb *p, void *fp) static int filename_trans_read_helper_compat(struct policydb *p, struct policy_file *fp)
{ {
struct filename_trans_key key, *ft = NULL; struct filename_trans_key key, *ft = NULL;
struct filename_trans_datum *last, *datum = NULL; struct filename_trans_datum *last, *datum = NULL;
@ -1998,7 +1996,7 @@ out:
return rc; return rc;
} }
static int filename_trans_read_helper(struct policydb *p, void *fp) static int filename_trans_read_helper(struct policydb *p, struct policy_file *fp)
{ {
struct filename_trans_key *ft = NULL; struct filename_trans_key *ft = NULL;
struct filename_trans_datum **dst, *datum, *first = NULL; struct filename_trans_datum **dst, *datum, *first = NULL;
@ -2087,7 +2085,7 @@ out:
return rc; return rc;
} }
static int filename_trans_read(struct policydb *p, void *fp) static int filename_trans_read(struct policydb *p, struct policy_file *fp)
{ {
u32 nel, i; u32 nel, i;
__le32 buf[1]; __le32 buf[1];
@ -2128,7 +2126,7 @@ static int filename_trans_read(struct policydb *p, void *fp)
return 0; return 0;
} }
static int genfs_read(struct policydb *p, void *fp) static int genfs_read(struct policydb *p, struct policy_file *fp)
{ {
int rc; int rc;
u32 i, j, nel, nel2, len, len2; u32 i, j, nel, nel2, len, len2;
@ -2242,7 +2240,7 @@ out:
} }
static int ocontext_read(struct policydb *p, static int ocontext_read(struct policydb *p,
const struct policydb_compat_info *info, void *fp) const struct policydb_compat_info *info, struct policy_file *fp)
{ {
int rc; int rc;
unsigned int i; unsigned int i;
@ -2439,7 +2437,7 @@ out:
* Read the configuration data from a policy database binary * Read the configuration data from a policy database binary
* representation file into a policy database structure. * representation file into a policy database structure.
*/ */
int policydb_read(struct policydb *p, void *fp) int policydb_read(struct policydb *p, struct policy_file *fp)
{ {
struct role_allow *ra, *lra; struct role_allow *ra, *lra;
struct role_trans_key *rtk = NULL; struct role_trans_key *rtk = NULL;
@ -2475,24 +2473,18 @@ int policydb_read(struct policydb *p, void *fp)
goto bad; goto bad;
} }
rc = -ENOMEM; rc = str_read(&policydb_str, GFP_KERNEL, fp, len);
policydb_str = kmalloc(len + 1, GFP_KERNEL);
if (!policydb_str) {
pr_err("SELinux: unable to allocate memory for policydb "
"string of length %d\n",
len);
goto bad;
}
rc = next_entry(policydb_str, fp, len);
if (rc) { if (rc) {
pr_err("SELinux: truncated policydb string identifier\n"); if (rc == -ENOMEM) {
kfree(policydb_str); pr_err("SELinux: unable to allocate memory for policydb string of length %d\n",
len);
} else {
pr_err("SELinux: truncated policydb string identifier\n");
}
goto bad; goto bad;
} }
rc = -EINVAL; rc = -EINVAL;
policydb_str[len] = '\0';
if (strcmp(policydb_str, POLICYDB_STRING)) { if (strcmp(policydb_str, POLICYDB_STRING)) {
pr_err("SELinux: policydb string %s does not match " pr_err("SELinux: policydb string %s does not match "
"my string %s\n", "my string %s\n",
@ -2762,7 +2754,7 @@ bad:
* Write a MLS level structure to a policydb binary * Write a MLS level structure to a policydb binary
* representation file. * representation file.
*/ */
static int mls_write_level(struct mls_level *l, void *fp) static int mls_write_level(struct mls_level *l, struct policy_file *fp)
{ {
__le32 buf[1]; __le32 buf[1];
int rc; int rc;
@ -2783,7 +2775,7 @@ static int mls_write_level(struct mls_level *l, void *fp)
* Write a MLS range structure to a policydb binary * Write a MLS range structure to a policydb binary
* representation file. * representation file.
*/ */
static int mls_write_range_helper(struct mls_range *r, void *fp) static int mls_write_range_helper(struct mls_range *r, struct policy_file *fp)
{ {
__le32 buf[3]; __le32 buf[3];
size_t items; size_t items;
@ -2823,7 +2815,7 @@ static int sens_write(void *vkey, void *datum, void *ptr)
char *key = vkey; char *key = vkey;
struct level_datum *levdatum = datum; struct level_datum *levdatum = datum;
struct policy_data *pd = ptr; struct policy_data *pd = ptr;
void *fp = pd->fp; struct policy_file *fp = pd->fp;
__le32 buf[2]; __le32 buf[2];
size_t len; size_t len;
int rc; int rc;
@ -2839,7 +2831,7 @@ static int sens_write(void *vkey, void *datum, void *ptr)
if (rc) if (rc)
return rc; return rc;
rc = mls_write_level(levdatum->level, fp); rc = mls_write_level(&levdatum->level, fp);
if (rc) if (rc)
return rc; return rc;
@ -2851,7 +2843,7 @@ static int cat_write(void *vkey, void *datum, void *ptr)
char *key = vkey; char *key = vkey;
struct cat_datum *catdatum = datum; struct cat_datum *catdatum = datum;
struct policy_data *pd = ptr; struct policy_data *pd = ptr;
void *fp = pd->fp; struct policy_file *fp = pd->fp;
__le32 buf[3]; __le32 buf[3];
size_t len; size_t len;
int rc; int rc;
@ -2876,7 +2868,7 @@ static int role_trans_write_one(void *key, void *datum, void *ptr)
struct role_trans_key *rtk = key; struct role_trans_key *rtk = key;
struct role_trans_datum *rtd = datum; struct role_trans_datum *rtd = datum;
struct policy_data *pd = ptr; struct policy_data *pd = ptr;
void *fp = pd->fp; struct policy_file *fp = pd->fp;
struct policydb *p = pd->p; struct policydb *p = pd->p;
__le32 buf[3]; __le32 buf[3];
int rc; int rc;
@ -2896,7 +2888,7 @@ static int role_trans_write_one(void *key, void *datum, void *ptr)
return 0; return 0;
} }
static int role_trans_write(struct policydb *p, void *fp) static int role_trans_write(struct policydb *p, struct policy_file *fp)
{ {
struct policy_data pd = { .p = p, .fp = fp }; struct policy_data pd = { .p = p, .fp = fp };
__le32 buf[1]; __le32 buf[1];
@ -2910,7 +2902,7 @@ static int role_trans_write(struct policydb *p, void *fp)
return hashtab_map(&p->role_tr, role_trans_write_one, &pd); return hashtab_map(&p->role_tr, role_trans_write_one, &pd);
} }
static int role_allow_write(struct role_allow *r, void *fp) static int role_allow_write(struct role_allow *r, struct policy_file *fp)
{ {
struct role_allow *ra; struct role_allow *ra;
__le32 buf[2]; __le32 buf[2];
@ -2938,7 +2930,7 @@ static int role_allow_write(struct role_allow *r, void *fp)
* Write a security context structure * Write a security context structure
* to a policydb binary representation file. * to a policydb binary representation file.
*/ */
static int context_write(struct policydb *p, struct context *c, void *fp) static int context_write(struct policydb *p, struct context *c, struct policy_file *fp)
{ {
int rc; int rc;
__le32 buf[3]; __le32 buf[3];
@ -2991,7 +2983,7 @@ static int common_write(void *vkey, void *datum, void *ptr)
char *key = vkey; char *key = vkey;
struct common_datum *comdatum = datum; struct common_datum *comdatum = datum;
struct policy_data *pd = ptr; struct policy_data *pd = ptr;
void *fp = pd->fp; struct policy_file *fp = pd->fp;
__le32 buf[4]; __le32 buf[4];
size_t len; size_t len;
int rc; int rc;
@ -3016,7 +3008,7 @@ static int common_write(void *vkey, void *datum, void *ptr)
return 0; return 0;
} }
static int type_set_write(struct type_set *t, void *fp) static int type_set_write(struct type_set *t, struct policy_file *fp)
{ {
int rc; int rc;
__le32 buf[1]; __le32 buf[1];
@ -3035,7 +3027,7 @@ static int type_set_write(struct type_set *t, void *fp)
} }
static int write_cons_helper(struct policydb *p, struct constraint_node *node, static int write_cons_helper(struct policydb *p, struct constraint_node *node,
void *fp) struct policy_file *fp)
{ {
struct constraint_node *c; struct constraint_node *c;
struct constraint_expr *e; struct constraint_expr *e;
@ -3086,7 +3078,7 @@ static int class_write(void *vkey, void *datum, void *ptr)
char *key = vkey; char *key = vkey;
struct class_datum *cladatum = datum; struct class_datum *cladatum = datum;
struct policy_data *pd = ptr; struct policy_data *pd = ptr;
void *fp = pd->fp; struct policy_file *fp = pd->fp;
struct policydb *p = pd->p; struct policydb *p = pd->p;
struct constraint_node *c; struct constraint_node *c;
__le32 buf[6]; __le32 buf[6];
@ -3171,7 +3163,7 @@ static int role_write(void *vkey, void *datum, void *ptr)
char *key = vkey; char *key = vkey;
struct role_datum *role = datum; struct role_datum *role = datum;
struct policy_data *pd = ptr; struct policy_data *pd = ptr;
void *fp = pd->fp; struct policy_file *fp = pd->fp;
struct policydb *p = pd->p; struct policydb *p = pd->p;
__le32 buf[3]; __le32 buf[3];
size_t items, len; size_t items, len;
@ -3211,7 +3203,7 @@ static int type_write(void *vkey, void *datum, void *ptr)
struct type_datum *typdatum = datum; struct type_datum *typdatum = datum;
struct policy_data *pd = ptr; struct policy_data *pd = ptr;
struct policydb *p = pd->p; struct policydb *p = pd->p;
void *fp = pd->fp; struct policy_file *fp = pd->fp;
__le32 buf[4]; __le32 buf[4];
int rc; int rc;
size_t items, len; size_t items, len;
@ -3252,7 +3244,7 @@ static int user_write(void *vkey, void *datum, void *ptr)
struct user_datum *usrdatum = datum; struct user_datum *usrdatum = datum;
struct policy_data *pd = ptr; struct policy_data *pd = ptr;
struct policydb *p = pd->p; struct policydb *p = pd->p;
void *fp = pd->fp; struct policy_file *fp = pd->fp;
__le32 buf[3]; __le32 buf[3];
size_t items, len; size_t items, len;
int rc; int rc;
@ -3301,7 +3293,8 @@ static int (*const write_f[SYM_NUM])(void *key, void *datum, void *datap) = {
/* clang-format on */ /* clang-format on */
static int ocontext_write(struct policydb *p, static int ocontext_write(struct policydb *p,
const struct policydb_compat_info *info, void *fp) const struct policydb_compat_info *info,
struct policy_file *fp)
{ {
unsigned int i, j; unsigned int i, j;
int rc; int rc;
@ -3437,7 +3430,7 @@ static int ocontext_write(struct policydb *p,
return 0; return 0;
} }
static int genfs_write(struct policydb *p, void *fp) static int genfs_write(struct policydb *p, struct policy_file *fp)
{ {
struct genfs *genfs; struct genfs *genfs;
struct ocontext *c; struct ocontext *c;
@ -3495,7 +3488,7 @@ static int range_write_helper(void *key, void *data, void *ptr)
struct range_trans *rt = key; struct range_trans *rt = key;
struct mls_range *r = data; struct mls_range *r = data;
struct policy_data *pd = ptr; struct policy_data *pd = ptr;
void *fp = pd->fp; struct policy_file *fp = pd->fp;
struct policydb *p = pd->p; struct policydb *p = pd->p;
int rc; int rc;
@ -3517,7 +3510,7 @@ static int range_write_helper(void *key, void *data, void *ptr)
return 0; return 0;
} }
static int range_write(struct policydb *p, void *fp) static int range_write(struct policydb *p, struct policy_file *fp)
{ {
__le32 buf[1]; __le32 buf[1];
int rc; int rc;
@ -3544,7 +3537,7 @@ static int filename_write_helper_compat(void *key, void *data, void *ptr)
struct filename_trans_key *ft = key; struct filename_trans_key *ft = key;
struct filename_trans_datum *datum = data; struct filename_trans_datum *datum = data;
struct ebitmap_node *node; struct ebitmap_node *node;
void *fp = ptr; struct policy_file *fp = ptr;
__le32 buf[4]; __le32 buf[4];
int rc; int rc;
u32 bit, len = strlen(ft->name); u32 bit, len = strlen(ft->name);
@ -3581,7 +3574,7 @@ static int filename_write_helper(void *key, void *data, void *ptr)
{ {
struct filename_trans_key *ft = key; struct filename_trans_key *ft = key;
struct filename_trans_datum *datum; struct filename_trans_datum *datum;
void *fp = ptr; struct policy_file *fp = ptr;
__le32 buf[3]; __le32 buf[3];
int rc; int rc;
u32 ndatum, len = strlen(ft->name); u32 ndatum, len = strlen(ft->name);
@ -3626,7 +3619,7 @@ static int filename_write_helper(void *key, void *data, void *ptr)
return 0; return 0;
} }
static int filename_trans_write(struct policydb *p, void *fp) static int filename_trans_write(struct policydb *p, struct policy_file *fp)
{ {
__le32 buf[1]; __le32 buf[1];
int rc; int rc;
@ -3658,7 +3651,7 @@ static int filename_trans_write(struct policydb *p, void *fp)
* structure to a policy database binary representation * structure to a policy database binary representation
* file. * file.
*/ */
int policydb_write(struct policydb *p, void *fp) int policydb_write(struct policydb *p, struct policy_file *fp)
{ {
unsigned int num_syms; unsigned int num_syms;
int rc; int rc;

View File

@ -126,7 +126,7 @@ struct user_datum {
/* Sensitivity attributes */ /* Sensitivity attributes */
struct level_datum { struct level_datum {
struct mls_level *level; /* sensitivity and associated categories */ struct mls_level level; /* sensitivity and associated categories */
unsigned char isalias; /* is this sensitivity an alias for another? */ unsigned char isalias; /* is this sensitivity an alias for another? */
}; };
@ -144,7 +144,7 @@ struct range_trans {
/* Boolean data type */ /* Boolean data type */
struct cond_bool_datum { struct cond_bool_datum {
__u32 value; /* internal type value */ u32 value; /* internal type value */
int state; int state;
}; };
@ -312,14 +312,19 @@ struct policydb {
u32 process_trans_perms; u32 process_trans_perms;
} __randomize_layout; } __randomize_layout;
struct policy_file {
char *data;
size_t len;
};
extern void policydb_destroy(struct policydb *p); extern void policydb_destroy(struct policydb *p);
extern int policydb_load_isids(struct policydb *p, struct sidtab *s); extern int policydb_load_isids(struct policydb *p, struct sidtab *s);
extern int policydb_context_isvalid(struct policydb *p, struct context *c); extern int policydb_context_isvalid(struct policydb *p, struct context *c);
extern int policydb_class_isvalid(struct policydb *p, unsigned int class); extern int policydb_class_isvalid(struct policydb *p, unsigned int class);
extern int policydb_type_isvalid(struct policydb *p, unsigned int type); extern int policydb_type_isvalid(struct policydb *p, unsigned int type);
extern int policydb_role_isvalid(struct policydb *p, unsigned int role); extern int policydb_role_isvalid(struct policydb *p, unsigned int role);
extern int policydb_read(struct policydb *p, void *fp); extern int policydb_read(struct policydb *p, struct policy_file *fp);
extern int policydb_write(struct policydb *p, void *fp); extern int policydb_write(struct policydb *p, struct policy_file *fp);
extern struct filename_trans_datum * extern struct filename_trans_datum *
policydb_filenametr_search(struct policydb *p, struct filename_trans_key *key); policydb_filenametr_search(struct policydb *p, struct filename_trans_key *key);
@ -342,14 +347,9 @@ policydb_roletr_search(struct policydb *p, struct role_trans_key *key);
#define POLICYDB_MAGIC SELINUX_MAGIC #define POLICYDB_MAGIC SELINUX_MAGIC
#define POLICYDB_STRING "SE Linux" #define POLICYDB_STRING "SE Linux"
struct policy_file {
char *data;
size_t len;
};
struct policy_data { struct policy_data {
struct policydb *p; struct policydb *p;
void *fp; struct policy_file *fp;
}; };
static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes) static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes)
@ -386,6 +386,8 @@ static inline char *sym_name(struct policydb *p, unsigned int sym_num,
return p->sym_val_to_name[sym_num][element_nr]; return p->sym_val_to_name[sym_num][element_nr];
} }
extern int str_read(char **strp, gfp_t flags, struct policy_file *fp, u32 len);
extern u16 string_to_security_class(struct policydb *p, const char *name); extern u16 string_to_security_class(struct policydb *p, const char *name);
extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name); extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name);

View File

@ -952,7 +952,7 @@ static void avd_init(struct selinux_policy *policy, struct av_decision *avd)
} }
static void update_xperms_extended_data(u8 specified, static void update_xperms_extended_data(u8 specified,
struct extended_perms_data *from, const struct extended_perms_data *from,
struct extended_perms_data *xp_data) struct extended_perms_data *xp_data)
{ {
unsigned int i; unsigned int i;
@ -973,6 +973,8 @@ static void update_xperms_extended_data(u8 specified,
void services_compute_xperms_decision(struct extended_perms_decision *xpermd, void services_compute_xperms_decision(struct extended_perms_decision *xpermd,
struct avtab_node *node) struct avtab_node *node)
{ {
u16 specified;
switch (node->datum.u.xperms->specified) { switch (node->datum.u.xperms->specified) {
case AVTAB_XPERMS_IOCTLFUNCTION: case AVTAB_XPERMS_IOCTLFUNCTION:
if (xpermd->base_perm != AVC_EXT_IOCTL || if (xpermd->base_perm != AVC_EXT_IOCTL ||
@ -997,17 +999,19 @@ void services_compute_xperms_decision(struct extended_perms_decision *xpermd,
return; return;
} }
if (node->key.specified == AVTAB_XPERMS_ALLOWED) { specified = node->key.specified & ~(AVTAB_ENABLED | AVTAB_ENABLED_OLD);
if (specified == AVTAB_XPERMS_ALLOWED) {
xpermd->used |= XPERMS_ALLOWED; xpermd->used |= XPERMS_ALLOWED;
update_xperms_extended_data(node->datum.u.xperms->specified, update_xperms_extended_data(node->datum.u.xperms->specified,
&node->datum.u.xperms->perms, &node->datum.u.xperms->perms,
xpermd->allowed); xpermd->allowed);
} else if (node->key.specified == AVTAB_XPERMS_AUDITALLOW) { } else if (specified == AVTAB_XPERMS_AUDITALLOW) {
xpermd->used |= XPERMS_AUDITALLOW; xpermd->used |= XPERMS_AUDITALLOW;
update_xperms_extended_data(node->datum.u.xperms->specified, update_xperms_extended_data(node->datum.u.xperms->specified,
&node->datum.u.xperms->perms, &node->datum.u.xperms->perms,
xpermd->auditallow); xpermd->auditallow);
} else if (node->key.specified == AVTAB_XPERMS_DONTAUDIT) { } else if (specified == AVTAB_XPERMS_DONTAUDIT) {
xpermd->used |= XPERMS_DONTAUDIT; xpermd->used |= XPERMS_DONTAUDIT;
update_xperms_extended_data(node->datum.u.xperms->specified, update_xperms_extended_data(node->datum.u.xperms->specified,
&node->datum.u.xperms->perms, &node->datum.u.xperms->perms,
@ -2611,17 +2615,15 @@ out:
return rc; return rc;
} }
static int match_ipv6_addrmask(u32 *input, u32 *addr, u32 *mask) static bool match_ipv6_addrmask(const u32 input[4], const u32 addr[4], const u32 mask[4])
{ {
int i, fail = 0; int i;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
if (addr[i] != (input[i] & mask[i])) { if (addr[i] != (input[i] & mask[i]))
fail = 1; return false;
break;
}
return !fail; return true;
} }
/** /**
@ -2726,7 +2728,7 @@ out:
*/ */
int security_get_user_sids(u32 fromsid, int security_get_user_sids(u32 fromsid,
char *username, const char *username,
u32 **sids, u32 **sids,
u32 *nel) u32 *nel)
{ {
@ -3048,7 +3050,7 @@ err:
} }
int security_set_bools(u32 len, int *values) int security_set_bools(u32 len, const int *values)
{ {
struct selinux_state *state = &selinux_state; struct selinux_state *state = &selinux_state;
struct selinux_policy *newpolicy, *oldpolicy; struct selinux_policy *newpolicy, *oldpolicy;
@ -3347,7 +3349,7 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
__func__, xfrm_sid); __func__, xfrm_sid);
goto out; goto out;
} }
rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES); rc = (mls_context_equal(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES);
if (rc) if (rc)
goto out; goto out;

View File

@ -66,7 +66,7 @@ static u32 context_to_sid(struct sidtab *s, struct context *context, u32 hash)
hash_for_each_possible_rcu(s->context_to_sid, entry, list, hash) { hash_for_each_possible_rcu(s->context_to_sid, entry, list, hash) {
if (entry->hash != hash) if (entry->hash != hash)
continue; continue;
if (context_cmp(&entry->context, context)) { if (context_equal(&entry->context, context)) {
sid = entry->sid; sid = entry->sid;
break; break;
} }
@ -114,12 +114,12 @@ int sidtab_set_initial(struct sidtab *s, u32 sid, struct context *context)
int sidtab_hash_stats(struct sidtab *sidtab, char *page) int sidtab_hash_stats(struct sidtab *sidtab, char *page)
{ {
int i; unsigned int i;
int chain_len = 0; int chain_len = 0;
int slots_used = 0; int slots_used = 0;
int entries = 0; int entries = 0;
int max_chain_len = 0; int max_chain_len = 0;
int cur_bucket = 0; unsigned int cur_bucket = 0;
struct sidtab_entry *entry; struct sidtab_entry *entry;
rcu_read_lock(); rcu_read_lock();