@@ -22,6 +22,7 @@
*
* Policy Module support.
*
+ * Copyright (C) 2017 Mellanox Technologies Inc.
* Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
* Copyright (C) 2003 - 2005 Tresys Technology, LLC
* Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
@@ -699,6 +700,7 @@ int main(int argc, char **argv)
printf("h) change a boolean value\n");
printf("i) display constraint expressions\n");
printf("j) display validatetrans expressions\n");
+ printf("k) Call ibpkey_sid\n");
#ifdef EQUIVTYPES
printf("z) Show equivalent types\n");
#endif
@@ -1220,6 +1222,31 @@ int main(int argc, char **argv)
"\nNo validatetrans expressions found.\n");
}
break;
+ case 'k':
+ {
+ char *p;
+ struct in6_addr addr6;
+ uint64_t subnet_prefix;
+ unsigned int pkey;
+
+ printf("subnet prefix? ");
+ FGETS(ans, sizeof(ans), stdin);
+ ans[strlen(ans) - 1] = 0;
+ p = (char *)&addr6;
+
+ if (inet_pton(AF_INET6, ans, p) < 1) {
+ printf("error parsing subnet prefix\n");
+ break;
+ }
+
+ memcpy(&subnet_prefix, p, sizeof(subnet_prefix));
+ printf("pkey? ");
+ FGETS(ans, sizeof(ans), stdin);
+ pkey = atoi(ans);
+ sepol_ibpkey_sid(subnet_prefix, pkey, &ssid);
+ printf("sid %d\n", ssid);
+ }
+ break;
#ifdef EQUIVTYPES
case 'z':
identify_equiv_types();
@@ -188,6 +188,14 @@ extern int sepol_port_sid(uint16_t domain,
uint16_t port, sepol_security_id_t * out_sid);
/*
+ * Return the SID of the ibpkey specified by
+ * `subnet prefix', and `pkey'.
+ */
+extern int sepol_ibpkey_sid(uint64_t subnet_prefix_p,
+ uint16_t pkey,
+ sepol_security_id_t *out_sid);
+
+/*
* Return the SIDs to use for a network interface
* with the name `name'. The `if_sid' SID is returned for
* the interface and the `msg_sid' SID is returned as
@@ -4,6 +4,7 @@
*
* Copyright (C) 2004-2005 Tresys Technology, LLC
* Copyright (C) 2007 Red Hat, Inc.
+ * Copyright (C) 2017 Mellanox Technologies, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -2217,6 +2218,12 @@ static int ocontext_copy_selinux(expand_state_t *state)
return -1;
}
break;
+ case OCON_IBPKEY:
+ n->u.ibpkey.subnet_prefix = c->u.ibpkey.subnet_prefix;
+
+ n->u.ibpkey.low_pkey = c->u.ibpkey.low_pkey;
+ n->u.ibpkey.high_pkey = c->u.ibpkey.high_pkey;
+ break;
case OCON_PORT:
n->u.port.protocol = c->u.port.protocol;
n->u.port.low_port = c->u.port.low_port;
@@ -2784,6 +2784,63 @@ exit:
return rc;
}
+static int write_selinux_ibpkey_rules_to_cil(FILE *out, struct policydb *pdb)
+{
+ struct ocontext *ibpkeycon;
+ char subnet_prefix_str[INET6_ADDRSTRLEN];
+ struct in6_addr subnet_prefix = {0};
+ uint16_t low;
+ uint16_t high;
+ char low_high_str[44]; /* 2^64 <= 20 digits so "(low high)" <= 44 chars */
+ char *ctx;
+ int rc = 0;
+
+ for (ibpkeycon = pdb->ocontexts[OCON_IBPKEY]; ibpkeycon != NULL;
+ ibpkeycon = ibpkeycon->next) {
+ memcpy(&subnet_prefix.s6_addr, &ibpkeycon->u.ibpkey.subnet_prefix,
+ sizeof(ibpkeycon->u.ibpkey.subnet_prefix));
+
+ if (inet_ntop(AF_INET6, &subnet_prefix.s6_addr,
+ subnet_prefix_str, INET6_ADDRSTRLEN) == NULL) {
+ sepol_log_err("ibpkeycon subnet_prefix is invalid: %s",
+ strerror(errno));
+ rc = -1;
+ goto exit;
+ }
+
+ low = ibpkeycon->u.ibpkey.low_pkey;
+ high = ibpkeycon->u.ibpkey.high_pkey;
+ if (low == high) {
+ rc = snprintf(low_high_str, 44, "%u", low);
+ } else {
+ rc = snprintf(low_high_str, 44, "(%u %u)", low, high);
+ }
+ if (rc < 0 || rc >= 44) {
+ rc = -1;
+ goto exit;
+ }
+
+ ctx = context_to_str(pdb, &ibpkeycon->context[0]);
+ if (!ctx) {
+ rc = -1;
+ goto exit;
+ }
+
+ sepol_printf(out, "(ibpkeycon %s %s %s)\n", subnet_prefix_str, low_high_str, ctx);
+
+ free(ctx);
+ }
+
+ rc = 0;
+
+exit:
+ if (rc != 0) {
+ sepol_log_err("Error writing ibpkeycon rules to CIL\n");
+ }
+
+ return rc;
+}
+
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);
@@ -3180,6 +3237,11 @@ int sepol_kernel_policydb_to_cil(FILE *out, struct policydb *pdb)
if (rc != 0) {
goto exit;
}
+
+ rc = write_selinux_ibpkey_rules_to_cil(out, pdb);
+ if (rc != 0) {
+ goto exit;
+ }
} else if (pdb->target_platform == SEPOL_TARGET_XEN) {
rc = write_xen_isid_rules_to_cil(out, pdb);
if (rc != 0) {
@@ -518,6 +518,20 @@ static int node6_data_cmp(const void *a, const void *b)
return memcmp(&(*aa)->u.node6.addr, &(*bb)->u.node6.addr, sizeof((*aa)->u.node6.addr));
}
+static int ibpkey_data_cmp(const void *a, const void *b)
+{
+ int rc;
+ struct ocontext *const *aa = a;
+ struct ocontext *const *bb = b;
+
+ rc = (*aa)->u.ibpkey.subnet_prefix - (*bb)->u.ibpkey.subnet_prefix;
+ if (rc)
+ return rc;
+
+ return compare_ranges((*aa)->u.ibpkey.low_pkey, (*aa)->u.ibpkey.high_pkey,
+ (*bb)->u.ibpkey.low_pkey, (*bb)->u.ibpkey.high_pkey);
+}
+
static int pirq_data_cmp(const void *a, const void *b)
{
struct ocontext *const *aa = a;
@@ -641,6 +655,11 @@ int sort_ocontexts(struct policydb *pdb)
if (rc != 0) {
goto exit;
}
+
+ rc = sort_ocontext_data(&pdb->ocontexts[OCON_IBPKEY], ibpkey_data_cmp);
+ if (rc != 0) {
+ goto exit;
+ }
} else if (pdb->target_platform == SEPOL_TARGET_XEN) {
rc = sort_ocontext_data(&pdb->ocontexts[1], pirq_data_cmp);
if (rc != 0) {
@@ -2645,6 +2645,64 @@ exit:
return rc;
}
+static int write_selinux_ibpkey_rules_to_conf(FILE *out, struct policydb *pdb)
+{
+ struct ocontext *ibpkeycon;
+ char subnet_prefix_str[INET6_ADDRSTRLEN];
+ struct in6_addr subnet_prefix = {0};
+ uint16_t low;
+ uint16_t high;
+ char low_high_str[44]; /* 2^64 <= 20 digits so "low-high" <= 44 chars */
+ char *ctx;
+ int rc = 0;
+
+ for (ibpkeycon = pdb->ocontexts[OCON_IBPKEY]; ibpkeycon != NULL;
+ ibpkeycon = ibpkeycon->next) {
+ memcpy(&subnet_prefix.s6_addr, &ibpkeycon->u.ibpkey.subnet_prefix,
+ sizeof(ibpkeycon->u.ibpkey.subnet_prefix));
+
+ if (inet_ntop(AF_INET6, &subnet_prefix.s6_addr,
+ subnet_prefix_str, INET6_ADDRSTRLEN) == NULL) {
+ sepol_log_err("ibpkeycon address is invalid: %s",
+ strerror(errno));
+ rc = -1;
+ goto exit;
+ }
+
+ low = ibpkeycon->u.ibpkey.low_pkey;
+ high = ibpkeycon->u.ibpkey.high_pkey;
+ if (low == high) {
+ rc = snprintf(low_high_str, 44, "%u", low);
+ } else {
+ rc = snprintf(low_high_str, 44, "%u-%u", low, high);
+ }
+ if (rc < 0 || rc >= 44) {
+ rc = -1;
+ goto exit;
+ }
+
+ ctx = context_to_str(pdb, &ibpkeycon->context[0]);
+ if (!ctx) {
+ rc = -1;
+ goto exit;
+ }
+
+ sepol_printf(out, "ibpkeycon %s %s %s\n", subnet_prefix_str,
+ low_high_str, ctx);
+
+ free(ctx);
+ }
+
+ rc = 0;
+
+exit:
+ if (rc != 0) {
+ sepol_log_err("Error writing ibpkeycon rules to policy.conf\n");
+ }
+
+ return rc;
+}
+
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);
@@ -3045,6 +3103,11 @@ int sepol_kernel_policydb_to_conf(FILE *out, struct policydb *pdb)
if (rc != 0) {
goto exit;
}
+
+ rc = write_selinux_ibpkey_rules_to_conf(out, pdb);
+ if (rc != 0) {
+ goto exit;
+ }
} else if (pdb->target_platform == SEPOL_TARGET_XEN) {
rc = write_xen_isid_rules_to_conf(out, pdb);
if (rc != 0) {
@@ -6,6 +6,7 @@ LIBSEPOL_1.0 {
sepol_context_*; sepol_mls_*; sepol_check_context;
sepol_iface_*;
sepol_port_*;
+ sepol_ibpkey_*;
sepol_node_*;
sepol_user_*; sepol_genusers; sepol_set_delusers;
sepol_msg_*; sepol_debug;
@@ -3,6 +3,7 @@
* Functions to convert policy module to CIL
*
* Copyright (C) 2015 Tresys Technology, LLC
+ * Copyright (C) 2017 Mellanox Technologies Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -2656,6 +2657,45 @@ exit:
return rc;
}
+static int ocontext_selinux_ibpkey_to_cil(struct policydb *pdb,
+ struct ocontext *ibpkeycons)
+{
+ int rc = -1;
+ struct ocontext *ibpkeycon;
+ char subnet_prefix_str[INET6_ADDRSTRLEN];
+ struct in6_addr subnet_prefix = {0};
+ uint16_t high;
+ uint16_t low;
+
+ for (ibpkeycon = ibpkeycons; ibpkeycon; ibpkeycon = ibpkeycon->next) {
+ low = ibpkeycon->u.ibpkey.low_pkey;
+ high = ibpkeycon->u.ibpkey.high_pkey;
+ memcpy(&subnet_prefix.s6_addr, &ibpkeycon->u.ibpkey.subnet_prefix,
+ sizeof(ibpkeycon->u.ibpkey.subnet_prefix));
+
+ if (inet_ntop(AF_INET6, &subnet_prefix.s6_addr,
+ subnet_prefix_str, INET6_ADDRSTRLEN) == NULL) {
+ log_err("ibpkeycon subnet_prefix is invalid: %s",
+ strerror(errno));
+ rc = -1;
+ goto exit;
+ }
+
+ if (low == high)
+ cil_printf("(ibpkeycon %s %i ", subnet_prefix_str, low);
+ else
+ cil_printf("(ibpkeycon %s (%i %i) ", subnet_prefix_str, low,
+ high);
+
+ context_to_cil(pdb, &ibpkeycon->context[0]);
+
+ cil_printf(")\n");
+ }
+ return 0;
+exit:
+ return rc;
+}
+
static int ocontext_selinux_netif_to_cil(struct policydb *pdb, struct ocontext *netifs)
{
struct ocontext *netif;
@@ -2889,6 +2929,7 @@ static int ocontexts_to_cil(struct policydb *pdb)
ocontext_selinux_node_to_cil,
ocontext_selinux_fsuse_to_cil,
ocontext_selinux_node6_to_cil,
+ ocontext_selinux_ibpkey_to_cil,
};
static int (*ocon_xen_funcs[OCON_NUM])(struct policydb *pdb, struct ocontext *ocon) = {
ocontext_xen_isid_to_cil,
@@ -18,6 +18,7 @@
* Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
* Copyright (C) 2003 - 2005 Tresys Technology, LLC
* Copyright (C) 2003 - 2007 Red Hat, Inc.
+ * Copyright (C) 2017 Mellanox Technologies Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -186,6 +187,13 @@ static struct policydb_compat_info policydb_compat[] = {
.target_platform = SEPOL_TARGET_SELINUX,
},
{
+ .type = POLICY_KERN,
+ .version = POLICYDB_VERSION_INFINIBAND,
+ .sym_num = SYM_NUM,
+ .ocon_num = OCON_IBPKEY + 1,
+ .target_platform = SEPOL_TARGET_SELINUX,
+ },
+ {
.type = POLICY_BASE,
.version = MOD_POLICYDB_VERSION_BASE,
.sym_num = SYM_NUM,
@@ -291,6 +299,13 @@ static struct policydb_compat_info policydb_compat[] = {
.target_platform = SEPOL_TARGET_SELINUX,
},
{
+ .type = POLICY_BASE,
+ .version = MOD_POLICYDB_VERSION_INFINIBAND,
+ .sym_num = SYM_NUM,
+ .ocon_num = OCON_IBPKEY + 1,
+ .target_platform = SEPOL_TARGET_SELINUX,
+ },
+ {
.type = POLICY_MOD,
.version = MOD_POLICYDB_VERSION_BASE,
.sym_num = SYM_NUM,
@@ -395,6 +410,13 @@ static struct policydb_compat_info policydb_compat[] = {
.ocon_num = 0,
.target_platform = SEPOL_TARGET_SELINUX,
},
+ {
+ .type = POLICY_MOD,
+ .version = MOD_POLICYDB_VERSION_INFINIBAND,
+ .sym_num = SYM_NUM,
+ .ocon_num = 0,
+ .target_platform = SEPOL_TARGET_SELINUX,
+ },
};
#if 0
@@ -2798,6 +2820,21 @@ static int ocontext_read_selinux(struct policydb_compat_info *info,
(&c->context[1], p, fp))
return -1;
break;
+ case OCON_IBPKEY:
+ rc = next_entry(buf, fp, sizeof(uint32_t) * 4);
+ if (rc < 0 || buf[2] > 0xffff || buf[3] > 0xffff)
+ return -1;
+
+ memcpy(&c->u.ibpkey.subnet_prefix, buf,
+ sizeof(c->u.ibpkey.subnet_prefix));
+
+ c->u.ibpkey.low_pkey = le32_to_cpu(buf[2]);
+ 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_PORT:
rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
if (rc < 0)
@@ -21,6 +21,7 @@
* Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
* Copyright (C) 2003 - 2004 Tresys Technology, LLC
* Copyright (C) 2003 - 2004 Red Hat, Inc.
+ * Copyright (C) 2017 Mellanox Technologies Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -1911,6 +1912,42 @@ int hidden sepol_fs_sid(char *name,
}
/*
+ * Return the SID of the ibpkey specified by
+ * `subnet prefix', and `pkey number'.
+ */
+int hidden sepol_ibpkey_sid(uint64_t subnet_prefix,
+ uint16_t pkey, sepol_security_id_t *out_sid)
+{
+ ocontext_t *c;
+ int rc = 0;
+
+ c = policydb->ocontexts[OCON_IBPKEY];
+ while (c) {
+ if (c->u.ibpkey.low_pkey <= pkey &&
+ c->u.ibpkey.high_pkey >= pkey &&
+ subnet_prefix == c->u.ibpkey.subnet_prefix)
+ 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
* `domain', `type', `protocol', and `port'.
*/
@@ -16,6 +16,7 @@
*
* Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
* Copyright (C) 2003-2005 Tresys Technology, LLC
+ * Copyright (C) 2017 Mellanox Technologies Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -1411,6 +1412,21 @@ static int ocontext_write_selinux(struct policydb_compat_info *info,
if (context_write(p, &c->context[1], fp))
return POLICYDB_ERROR;
break;
+ case OCON_IBPKEY:
+ /* The subnet prefix is in network order */
+ memcpy(buf, &c->u.ibpkey.subnet_prefix,
+ sizeof(c->u.ibpkey.subnet_prefix));
+
+ buf[2] = cpu_to_le32(c->u.ibpkey.low_pkey);
+ buf[3] = cpu_to_le32(c->u.ibpkey.high_pkey);
+
+ items = put_entry(buf, sizeof(uint32_t), 4, fp);
+ if (items != 4)
+ return POLICYDB_ERROR;
+
+ if (context_write(p, &c->context[0], fp))
+ return POLICYDB_ERROR;
+ break;
case OCON_PORT:
buf[0] = c->u.port.protocol;
buf[1] = c->u.port.low_port;