Automated merge of 'dev' into 'next'

* dev:
  selinux: add netlink nlmsg_type audit message
  selinux: add support for xperms in conditional policies
  selinux: Fix SCTP error inconsistency in selinux_socket_bind()
  selinux: use native iterator types
  selinux: add generated av_permissions.h to targets
This commit is contained in:
Paul Moore 2024-12-15 22:00:17 -05:00
commit f453a5d339
12 changed files with 41 additions and 20 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;
@ -4835,7 +4835,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
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;
} }
@ -5939,14 +5939,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

@ -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

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))

View File

@ -339,7 +339,7 @@ static const uint16_t spec_order[] = {
int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, int avtab_read_item(struct avtab *a, void *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));
@ -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");

View File

@ -108,7 +108,7 @@ struct policydb;
int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, int avtab_read_item(struct avtab *a, void *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, void *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,

View File

@ -349,7 +349,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;

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 *

View File

@ -946,7 +946,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;
@ -967,6 +967,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:
case AVTAB_XPERMS_NLMSG: case AVTAB_XPERMS_NLMSG:
@ -985,17 +987,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,

View File

@ -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();