mirror of
https://github.com/topjohnwu/selinux.git
synced 2024-12-11 13:26:01 +00:00
libsepol: Add ibendport ocontext handling
Add support for reading, writing, and copying IB end port ocontext data. Also add support for querying a IB end port sid to checkpolicy. Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
This commit is contained in:
parent
5bc05dd2a5
commit
118c0cd103
@ -701,6 +701,7 @@ int main(int argc, char **argv)
|
|||||||
printf("i) display constraint expressions\n");
|
printf("i) display constraint expressions\n");
|
||||||
printf("j) display validatetrans expressions\n");
|
printf("j) display validatetrans expressions\n");
|
||||||
printf("k) Call ibpkey_sid\n");
|
printf("k) Call ibpkey_sid\n");
|
||||||
|
printf("l) Call ibendport_sid\n");
|
||||||
#ifdef EQUIVTYPES
|
#ifdef EQUIVTYPES
|
||||||
printf("z) Show equivalent types\n");
|
printf("z) Show equivalent types\n");
|
||||||
#endif
|
#endif
|
||||||
@ -1247,6 +1248,25 @@ int main(int argc, char **argv)
|
|||||||
printf("sid %d\n", ssid);
|
printf("sid %d\n", ssid);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
printf("device name (eg. mlx4_0)? ");
|
||||||
|
FGETS(ans, sizeof(ans), stdin);
|
||||||
|
ans[strlen(ans) - 1] = 0;
|
||||||
|
|
||||||
|
name = malloc((strlen(ans) + 1) * sizeof(char));
|
||||||
|
if (!name) {
|
||||||
|
fprintf(stderr, "couldn't malloc string.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
strcpy(name, ans);
|
||||||
|
|
||||||
|
printf("port? ");
|
||||||
|
FGETS(ans, sizeof(ans), stdin);
|
||||||
|
port = atoi(ans);
|
||||||
|
sepol_ibendport_sid(name, port, &ssid);
|
||||||
|
printf("sid %d\n", ssid);
|
||||||
|
free(name);
|
||||||
|
break;
|
||||||
#ifdef EQUIVTYPES
|
#ifdef EQUIVTYPES
|
||||||
case 'z':
|
case 'z':
|
||||||
identify_equiv_types();
|
identify_equiv_types();
|
||||||
|
@ -195,6 +195,14 @@ extern int sepol_ibpkey_sid(uint64_t subnet_prefix_p,
|
|||||||
uint16_t pkey,
|
uint16_t pkey,
|
||||||
sepol_security_id_t *out_sid);
|
sepol_security_id_t *out_sid);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the SID of the ibendport specified by
|
||||||
|
* `dev_name', and `port'.
|
||||||
|
*/
|
||||||
|
extern int sepol_ibendport_sid(char *dev_name,
|
||||||
|
uint8_t port,
|
||||||
|
sepol_security_id_t *out_sid);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the SIDs to use for a network interface
|
* Return the SIDs to use for a network interface
|
||||||
* with the name `name'. The `if_sid' SID is returned for
|
* with the name `name'. The `if_sid' SID is returned for
|
||||||
|
@ -2224,6 +2224,14 @@ static int ocontext_copy_selinux(expand_state_t *state)
|
|||||||
n->u.ibpkey.low_pkey = c->u.ibpkey.low_pkey;
|
n->u.ibpkey.low_pkey = c->u.ibpkey.low_pkey;
|
||||||
n->u.ibpkey.high_pkey = c->u.ibpkey.high_pkey;
|
n->u.ibpkey.high_pkey = c->u.ibpkey.high_pkey;
|
||||||
break;
|
break;
|
||||||
|
case OCON_IBENDPORT:
|
||||||
|
n->u.ibendport.dev_name = strdup(c->u.ibendport.dev_name);
|
||||||
|
if (!n->u.ibendport.dev_name) {
|
||||||
|
ERR(state->handle, "Out of memory!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
n->u.ibendport.port = c->u.ibendport.port;
|
||||||
|
break;
|
||||||
case OCON_PORT:
|
case OCON_PORT:
|
||||||
n->u.port.protocol = c->u.port.protocol;
|
n->u.port.protocol = c->u.port.protocol;
|
||||||
n->u.port.low_port = c->u.port.low_port;
|
n->u.port.low_port = c->u.port.low_port;
|
||||||
|
@ -2841,6 +2841,43 @@ exit:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int write_selinux_ibendport_rules_to_cil(FILE *out, struct policydb *pdb)
|
||||||
|
{
|
||||||
|
struct ocontext *ibendportcon;
|
||||||
|
char port_str[4];
|
||||||
|
char *ctx;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
for (ibendportcon = pdb->ocontexts[OCON_IBENDPORT];
|
||||||
|
ibendportcon != NULL; ibendportcon = ibendportcon->next) {
|
||||||
|
rc = snprintf(port_str, 4, "%u", ibendportcon->u.ibendport.port);
|
||||||
|
if (rc < 0 || rc >= 4) {
|
||||||
|
rc = -1;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = context_to_str(pdb, &ibendportcon->context[0]);
|
||||||
|
if (!ctx) {
|
||||||
|
rc = -1;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
sepol_printf(out, "(ibendportcon %s %s %s)\n",
|
||||||
|
ibendportcon->u.ibendport.dev_name, port_str, ctx);
|
||||||
|
|
||||||
|
free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (rc != 0) {
|
||||||
|
sepol_log_err("Error writing ibendportcon rules to CIL\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int write_xen_isid_rules_to_cil(FILE *out, struct policydb *pdb)
|
static int write_xen_isid_rules_to_cil(FILE *out, struct policydb *pdb)
|
||||||
{
|
{
|
||||||
return write_sid_context_rules_to_cil(out, pdb, xen_sid_to_str);
|
return write_sid_context_rules_to_cil(out, pdb, xen_sid_to_str);
|
||||||
@ -3242,6 +3279,11 @@ int sepol_kernel_policydb_to_cil(FILE *out, struct policydb *pdb)
|
|||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = write_selinux_ibendport_rules_to_cil(out, pdb);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
} else if (pdb->target_platform == SEPOL_TARGET_XEN) {
|
} else if (pdb->target_platform == SEPOL_TARGET_XEN) {
|
||||||
rc = write_xen_isid_rules_to_cil(out, pdb);
|
rc = write_xen_isid_rules_to_cil(out, pdb);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
|
@ -532,6 +532,19 @@ static int ibpkey_data_cmp(const void *a, const void *b)
|
|||||||
(*bb)->u.ibpkey.low_pkey, (*bb)->u.ibpkey.high_pkey);
|
(*bb)->u.ibpkey.low_pkey, (*bb)->u.ibpkey.high_pkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ibendport_data_cmp(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
struct ocontext *const *aa = a;
|
||||||
|
struct ocontext *const *bb = b;
|
||||||
|
|
||||||
|
rc = strcmp((*aa)->u.ibendport.dev_name, (*bb)->u.ibendport.dev_name);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
return (*aa)->u.ibendport.port - (*bb)->u.ibendport.port;
|
||||||
|
}
|
||||||
|
|
||||||
static int pirq_data_cmp(const void *a, const void *b)
|
static int pirq_data_cmp(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
struct ocontext *const *aa = a;
|
struct ocontext *const *aa = a;
|
||||||
@ -660,6 +673,11 @@ int sort_ocontexts(struct policydb *pdb)
|
|||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = sort_ocontext_data(&pdb->ocontexts[OCON_IBENDPORT], ibendport_data_cmp);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
} else if (pdb->target_platform == SEPOL_TARGET_XEN) {
|
} else if (pdb->target_platform == SEPOL_TARGET_XEN) {
|
||||||
rc = sort_ocontext_data(&pdb->ocontexts[1], pirq_data_cmp);
|
rc = sort_ocontext_data(&pdb->ocontexts[1], pirq_data_cmp);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
|
@ -2703,6 +2703,42 @@ exit:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int write_selinux_ibendport_rules_to_conf(FILE *out, struct policydb *pdb)
|
||||||
|
{
|
||||||
|
struct ocontext *ibendportcon;
|
||||||
|
char port_str[4];
|
||||||
|
char *ctx;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
for (ibendportcon = pdb->ocontexts[OCON_IBENDPORT];
|
||||||
|
ibendportcon != NULL; ibendportcon = ibendportcon->next) {
|
||||||
|
rc = snprintf(port_str, 4, "%u", ibendportcon->u.ibendport.port);
|
||||||
|
if (rc < 0 || rc >= 4) {
|
||||||
|
rc = -1;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = context_to_str(pdb, &ibendportcon->context[0]);
|
||||||
|
if (!ctx) {
|
||||||
|
rc = -1;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
sepol_printf(out, "ibendportcon %s %s %s\n", ibendportcon->u.ibendport.dev_name, port_str, ctx);
|
||||||
|
|
||||||
|
free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (rc != 0) {
|
||||||
|
sepol_log_err("Error writing ibendportcon rules to policy.conf\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int write_xen_isid_rules_to_conf(FILE *out, struct policydb *pdb)
|
static int write_xen_isid_rules_to_conf(FILE *out, struct policydb *pdb)
|
||||||
{
|
{
|
||||||
return write_sid_context_rules_to_conf(out, pdb, xen_sid_to_str);
|
return write_sid_context_rules_to_conf(out, pdb, xen_sid_to_str);
|
||||||
@ -3108,6 +3144,11 @@ int sepol_kernel_policydb_to_conf(FILE *out, struct policydb *pdb)
|
|||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = write_selinux_ibendport_rules_to_conf(out, pdb);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
} else if (pdb->target_platform == SEPOL_TARGET_XEN) {
|
} else if (pdb->target_platform == SEPOL_TARGET_XEN) {
|
||||||
rc = write_xen_isid_rules_to_conf(out, pdb);
|
rc = write_xen_isid_rules_to_conf(out, pdb);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
|
@ -7,6 +7,7 @@ LIBSEPOL_1.0 {
|
|||||||
sepol_iface_*;
|
sepol_iface_*;
|
||||||
sepol_port_*;
|
sepol_port_*;
|
||||||
sepol_ibpkey_*;
|
sepol_ibpkey_*;
|
||||||
|
sepol_ibendport_*;
|
||||||
sepol_node_*;
|
sepol_node_*;
|
||||||
sepol_user_*; sepol_genusers; sepol_set_delusers;
|
sepol_user_*; sepol_genusers; sepol_set_delusers;
|
||||||
sepol_msg_*; sepol_debug;
|
sepol_msg_*; sepol_debug;
|
||||||
|
@ -2782,6 +2782,19 @@ exit:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ocontext_selinux_ibendport_to_cil(struct policydb *pdb, struct ocontext *ibendports)
|
||||||
|
{
|
||||||
|
struct ocontext *ibendport;
|
||||||
|
|
||||||
|
for (ibendport = ibendports; ibendport; ibendport = ibendport->next) {
|
||||||
|
cil_printf("(ibendportcon %s %u ", ibendport->u.ibendport.dev_name, ibendport->u.ibendport.port);
|
||||||
|
context_to_cil(pdb, &ibendport->context[0]);
|
||||||
|
|
||||||
|
cil_printf(")\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ocontext_selinux_fsuse_to_cil(struct policydb *pdb, struct ocontext *fsuses)
|
static int ocontext_selinux_fsuse_to_cil(struct policydb *pdb, struct ocontext *fsuses)
|
||||||
{
|
{
|
||||||
@ -2936,6 +2949,7 @@ static int ocontexts_to_cil(struct policydb *pdb)
|
|||||||
ocontext_selinux_fsuse_to_cil,
|
ocontext_selinux_fsuse_to_cil,
|
||||||
ocontext_selinux_node6_to_cil,
|
ocontext_selinux_node6_to_cil,
|
||||||
ocontext_selinux_ibpkey_to_cil,
|
ocontext_selinux_ibpkey_to_cil,
|
||||||
|
ocontext_selinux_ibendport_to_cil,
|
||||||
};
|
};
|
||||||
static int (*ocon_xen_funcs[OCON_NUM])(struct policydb *pdb, struct ocontext *ocon) = {
|
static int (*ocon_xen_funcs[OCON_NUM])(struct policydb *pdb, struct ocontext *ocon) = {
|
||||||
ocontext_xen_isid_to_cil,
|
ocontext_xen_isid_to_cil,
|
||||||
|
@ -190,7 +190,7 @@ static struct policydb_compat_info policydb_compat[] = {
|
|||||||
.type = POLICY_KERN,
|
.type = POLICY_KERN,
|
||||||
.version = POLICYDB_VERSION_INFINIBAND,
|
.version = POLICYDB_VERSION_INFINIBAND,
|
||||||
.sym_num = SYM_NUM,
|
.sym_num = SYM_NUM,
|
||||||
.ocon_num = OCON_IBPKEY + 1,
|
.ocon_num = OCON_IBENDPORT + 1,
|
||||||
.target_platform = SEPOL_TARGET_SELINUX,
|
.target_platform = SEPOL_TARGET_SELINUX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -302,7 +302,7 @@ static struct policydb_compat_info policydb_compat[] = {
|
|||||||
.type = POLICY_BASE,
|
.type = POLICY_BASE,
|
||||||
.version = MOD_POLICYDB_VERSION_INFINIBAND,
|
.version = MOD_POLICYDB_VERSION_INFINIBAND,
|
||||||
.sym_num = SYM_NUM,
|
.sym_num = SYM_NUM,
|
||||||
.ocon_num = OCON_IBPKEY + 1,
|
.ocon_num = OCON_IBENDPORT + 1,
|
||||||
.target_platform = SEPOL_TARGET_SELINUX,
|
.target_platform = SEPOL_TARGET_SELINUX,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2804,7 +2804,7 @@ static int ocontext_read_selinux(struct policydb_compat_info *info,
|
|||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return -1;
|
return -1;
|
||||||
len = le32_to_cpu(buf[0]);
|
len = le32_to_cpu(buf[0]);
|
||||||
if (zero_or_saturated(len))
|
if (zero_or_saturated(len) || len > 63)
|
||||||
return -1;
|
return -1;
|
||||||
c->u.name = malloc(len + 1);
|
c->u.name = malloc(len + 1);
|
||||||
if (!c->u.name)
|
if (!c->u.name)
|
||||||
@ -2831,6 +2831,26 @@ static int ocontext_read_selinux(struct policydb_compat_info *info,
|
|||||||
c->u.ibpkey.low_pkey = le32_to_cpu(buf[2]);
|
c->u.ibpkey.low_pkey = le32_to_cpu(buf[2]);
|
||||||
c->u.ibpkey.high_pkey = le32_to_cpu(buf[3]);
|
c->u.ibpkey.high_pkey = le32_to_cpu(buf[3]);
|
||||||
|
|
||||||
|
if (context_read_and_validate
|
||||||
|
(&c->context[0], p, fp))
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
case OCON_IBENDPORT:
|
||||||
|
rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
|
||||||
|
if (rc < 0)
|
||||||
|
return -1;
|
||||||
|
len = le32_to_cpu(buf[0]);
|
||||||
|
if (len == 0 || len > IB_DEVICE_NAME_MAX - 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
c->u.ibendport.dev_name = malloc(len + 1);
|
||||||
|
if (!c->u.ibendport.dev_name)
|
||||||
|
return -1;
|
||||||
|
rc = next_entry(c->u.ibendport.dev_name, fp, len);
|
||||||
|
if (rc < 0)
|
||||||
|
return -1;
|
||||||
|
c->u.ibendport.dev_name[len] = 0;
|
||||||
|
c->u.ibendport.port = le32_to_cpu(buf[1]);
|
||||||
if (context_read_and_validate
|
if (context_read_and_validate
|
||||||
(&c->context[0], p, fp))
|
(&c->context[0], p, fp))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1947,6 +1947,43 @@ out:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the SID of the subnet management interface specified by
|
||||||
|
* `device name', and `port'.
|
||||||
|
*/
|
||||||
|
int hidden sepol_ibendport_sid(char *dev_name,
|
||||||
|
uint8_t port,
|
||||||
|
sepol_security_id_t *out_sid)
|
||||||
|
{
|
||||||
|
ocontext_t *c;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
c = policydb->ocontexts[OCON_IBENDPORT];
|
||||||
|
while (c) {
|
||||||
|
if (c->u.ibendport.port == port &&
|
||||||
|
!strcmp(dev_name, c->u.ibendport.dev_name))
|
||||||
|
break;
|
||||||
|
c = c->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c) {
|
||||||
|
if (!c->sid[0]) {
|
||||||
|
rc = sepol_sidtab_context_to_sid(sidtab,
|
||||||
|
&c->context[0],
|
||||||
|
&c->sid[0]);
|
||||||
|
if (rc)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
*out_sid = c->sid[0];
|
||||||
|
} else {
|
||||||
|
*out_sid = SECINITSID_UNLABELED;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the SID of the port specified by
|
* Return the SID of the port specified by
|
||||||
* `domain', `type', `protocol', and `port'.
|
* `domain', `type', `protocol', and `port'.
|
||||||
|
@ -1424,6 +1424,20 @@ static int ocontext_write_selinux(struct policydb_compat_info *info,
|
|||||||
if (items != 4)
|
if (items != 4)
|
||||||
return POLICYDB_ERROR;
|
return POLICYDB_ERROR;
|
||||||
|
|
||||||
|
if (context_write(p, &c->context[0], fp))
|
||||||
|
return POLICYDB_ERROR;
|
||||||
|
break;
|
||||||
|
case OCON_IBENDPORT:
|
||||||
|
len = strlen(c->u.ibendport.dev_name);
|
||||||
|
buf[0] = cpu_to_le32(len);
|
||||||
|
buf[1] = cpu_to_le32(c->u.ibendport.port);
|
||||||
|
items = put_entry(buf, sizeof(uint32_t), 2, fp);
|
||||||
|
if (items != 2)
|
||||||
|
return POLICYDB_ERROR;
|
||||||
|
items = put_entry(c->u.ibendport.dev_name, 1, len, fp);
|
||||||
|
if (items != len)
|
||||||
|
return POLICYDB_ERROR;
|
||||||
|
|
||||||
if (context_write(p, &c->context[0], fp))
|
if (context_write(p, &c->context[0], fp))
|
||||||
return POLICYDB_ERROR;
|
return POLICYDB_ERROR;
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user