On Tue, 2017-05-09 at 23:50 +0300, Dan Jurgens wrote: > From: Daniel Jurgens <dani...@mellanox.com> > > Add support for reading, writing, and copying Infinabinda Pkey
s/Infinabinda/Infiniband/ > ocontext > data. Also add support for querying a Pkey sid to checkpolicy. > > Signed-off-by: Daniel Jurgens <dani...@mellanox.com> > --- > checkpolicy/checkpolicy.c | 27 +++++++++++++ > libsepol/include/sepol/policydb/services.h | 11 +++++ > libsepol/src/expand.c | 9 ++++ > libsepol/src/libsepol.map.in | 1 + > libsepol/src/module_to_cil.c | 39 ++++++++++++++++++ > libsepol/src/policydb.c | 47 > ++++++++++++++++++++++ > libsepol/src/services.c | 59 > ++++++++++++++++++++++++++++ > libsepol/src/write.c | 16 +++++++ > 8 files changed, 209 insertions(+), 0 deletions(-) > > diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c > index 534fc22..0f12347 100644 > --- a/checkpolicy/checkpolicy.c > +++ b/checkpolicy/checkpolicy.c > @@ -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 <jmor...@redhat.co > m> > @@ -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; > + int len; > + struct in6_addr addr6; > + unsigned int pkey; > + > + printf("subnet prefix? "); > + FGETS(ans, sizeof(ans), stdin); > + ans[strlen(ans) - 1] = 0; > + p = (char *)&addr6; > + len = sizeof(addr6); > + > + if (inet_pton(AF_INET6, ans, p) < 1) > { > + printf("error parsing subnet > prefix\n"); > + break; > + } > + > + printf("pkey? "); > + FGETS(ans, sizeof(ans), stdin); > + pkey = atoi(ans); > + sepol_ibpkey_sid(0, 0, p, len, pkey, > &ssid); > + printf("sid %d\n", ssid); > + } > + break; > #ifdef EQUIVTYPES > case 'z': > identify_equiv_types(); > diff --git a/libsepol/include/sepol/policydb/services.h > b/libsepol/include/sepol/policydb/services.h > index 9162149..2d7aed1 100644 > --- a/libsepol/include/sepol/policydb/services.h > +++ b/libsepol/include/sepol/policydb/services.h > @@ -188,6 +188,17 @@ 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 > + * `domain', `type', `subnet prefix', and `pkey'. > + */ Can you explain why you are passing a (domain,type) pair to this interface and why subnet_prefix is not fixed length as it is in corresponding kernel interface (security_pkey_sid)? Will these arguments ever be used? Could the length change in the future? For that matter, and I guess I should have asked this on the kernel patches, why are you storing and passing the subnet prefix as a complete IPv6 address? Is that just for the convenience of being able to use inet_pton() and inet_ntop()? Is this typical for handling of IB subnet prefixes? Seems a bit wasteful. > +extern int sepol_ibpkey_sid(uint16_t domain, > + uint16_t type, > + void *subnet_prefix_p, > + size_t splen, > + 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 > diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c > index 54bf781..c45ecbe 100644 > --- a/libsepol/src/expand.c > +++ b/libsepol/src/expand.c > @@ -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,14 @@ static int > ocontext_copy_selinux(expand_state_t *state) > return -1; > } > break; > + case OCON_IBPKEY: > + n->u.ibpkey.subnet_prefix[0] = c- > >u.ibpkey.subnet_prefix[0]; > + n->u.ibpkey.subnet_prefix[1] = c- > >u.ibpkey.subnet_prefix[1]; > + n->u.ibpkey.subnet_prefix[2] = c- > >u.ibpkey.subnet_prefix[2]; > + n->u.ibpkey.subnet_prefix[3] = c- > >u.ibpkey.subnet_prefix[3]; > + 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; > diff --git a/libsepol/src/libsepol.map.in > b/libsepol/src/libsepol.map.in > index 4042640..36225d1 100644 > --- a/libsepol/src/libsepol.map.in > +++ b/libsepol/src/libsepol.map.in > @@ -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; > diff --git a/libsepol/src/module_to_cil.c > b/libsepol/src/module_to_cil.c > index ac095c3..db3f9c8 100644 > --- a/libsepol/src/module_to_cil.c > +++ b/libsepol/src/module_to_cil.c > @@ -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 > @@ -2583,6 +2584,7 @@ static int ocontext_selinux_isid_to_cil(struct > policydb *pdb, struct ocontext *i > "policy", > "scmp_packet", > "devnull", > + "ibpkey", I thought we dropped the separate initial SID for it? > NULL > }; > > @@ -2645,6 +2647,42 @@ 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[INET6_ADDRSTRLEN]; > + 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; > + > + if (inet_ntop(AF_INET6, &ibpkeycon- > >u.ibpkey.subnet_prefix, > + subnet_prefix, 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, low); > + else > + cil_printf("(ibpkeycon %s (%i %i) ", > subnet_prefix, 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; > @@ -2878,6 +2916,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, > diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c > index 7093b29..8b76c6a 100644 > --- a/libsepol/src/policydb.c > +++ b/libsepol/src/policydb.c > @@ -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 > @@ -185,6 +186,21 @@ static struct policydb_compat_info > policydb_compat[] = { > .ocon_num = OCON_NODE6 + 1, > .target_platform = SEPOL_TARGET_SELINUX, > }, > + > + { > + .type = POLICY_KERN, > + .version = POLICYDB_VERSION_XPERMS_IOCTL, > + .sym_num = SYM_NUM, > + .ocon_num = OCON_NODE6 + 1, > + .target_platform = SEPOL_TARGET_SELINUX, > + }, This seems duplicated? > + { > + .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, > @@ -284,6 +300,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, > @@ -381,6 +404,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 > @@ -2782,6 +2812,23 @@ 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) * 6); > + if (rc < 0) > + return -1; > + > + c->u.ibpkey.subnet_prefix[0] = > buf[0]; > + c->u.ibpkey.subnet_prefix[1] = > buf[1]; > + c->u.ibpkey.subnet_prefix[2] = > buf[2]; > + c->u.ibpkey.subnet_prefix[3] = > buf[3]; Why load all the values rather than just confirming that [2] and [3] are zero as in the kernel? > + > + c->u.ibpkey.low_pkey = > le32_to_cpu(buf[4]); > + c->u.ibpkey.high_pkey = > le32_to_cpu(buf[5]); > + > + 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) > diff --git a/libsepol/src/services.c b/libsepol/src/services.c > index 03fb120..39903d1 100644 > --- a/libsepol/src/services.c > +++ b/libsepol/src/services.c > @@ -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 > @@ -1910,6 +1911,64 @@ int hidden sepol_fs_sid(char *name, > return rc; > } > > +static int match_subnet_prefix(uint32_t *input, uint32_t > *subnet_prefix) > +{ > + int i, fail = 0; > + > + for (i = 0; i < 4; i++) > + if (subnet_prefix[i] != input[i]) { > + fail = 1; > + break; > + } > + > + return !fail; > +} > + > +/* > + * Return the SID of the ibpkey specified by > + * `domain', `type', `subnet prefix', and `pkey number'. > + */ > +int hidden sepol_ibpkey_sid(uint16_t domain __attribute__ > ((unused)), > + uint16_t type __attribute__ ((unused)), > + void *subnet_prefix_p, > + size_t splen, > + uint16_t pkey, sepol_security_id_t > *out_sid) > +{ > + ocontext_t *c; > + int rc = 0; > + > + if (splen != sizeof(uint64_t)) { > + rc = -EINVAL; > + goto out; > + } > + > + c = policydb->ocontexts[OCON_IBPKEY]; > + while (c) { > + if (c->u.ibpkey.low_pkey <= pkey && > + c->u.ibpkey.high_pkey >= pkey && > + match_subnet_prefix(subnet_prefix_p, > + 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'. > diff --git a/libsepol/src/write.c b/libsepol/src/write.c > index e75b9ab..fa1b7d1 100644 > --- a/libsepol/src/write.c > +++ b/libsepol/src/write.c > @@ -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 > @@ -1410,6 +1411,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 */ > + for (j = 0; j < 4; j++) > + buf[j] = c- > >u.ibpkey.subnet_prefix[j]; > + > + buf[4] = cpu_to_le32(c- > >u.ibpkey.low_pkey); > + buf[5] = cpu_to_le32(c- > >u.ibpkey.high_pkey); > + > + items = put_entry(buf, > sizeof(uint32_t), 6, fp); > + if (items != 6) > + 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;