On Mon, 2017-05-15 at 23:42 +0300, Dan Jurgens wrote: > From: Daniel Jurgens <danielj@xxxxxxxxxxxx> > > Add checkpolicy support for scanning and parsing ibpkeycon labels. > Also > create a new ocontext for Infiniband Pkeys and define a new policydb > version for infiniband support. > > Signed-off-by: Daniel Jurgens <danielj@xxxxxxxxxxxx> > > --- > v1: > Stephen Smalley: > - Always use s6_addr instead of s6_addr32. > - Add comment about POLICYDB_VERSION_INFINIBAND being linux specific. > > Signed-off-by: Daniel Jurgens <danielj@xxxxxxxxxxxx> > --- > checkpolicy/policy_define.c | 105 > +++++++++++++++++++++++++++++ > checkpolicy/policy_define.h | 1 + > checkpolicy/policy_parse.y | 15 ++++- > checkpolicy/policy_scan.l | 3 + > libsepol/include/sepol/policydb/policydb.h | 32 +++++---- > 5 files changed, 143 insertions(+), 13 deletions(-) > > diff --git a/checkpolicy/policy_define.c > b/checkpolicy/policy_define.c > index 8fab214..ffdc5f8 100644 > --- a/checkpolicy/policy_define.c > +++ b/checkpolicy/policy_define.c > @@ -20,6 +20,7 @@ > * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. > * Copyright (C) 2003 - 2008 Tresys Technology, LLC > * Copyright (C) 2007 Red Hat Inc. > + * Copyright (C) 2017 Mellanox Techonologies Inc. > * This program is free software; you can redistribute it > and/or modify > * it under the terms of the GNU General Public License as > published by > * the Free Software Foundation, version 2. > @@ -5057,6 +5058,110 @@ int define_port_context(unsigned int low, > unsigned int high) > return -1; > } > > +int define_ibpkey_context(unsigned int low, unsigned int high) > +{ > + ocontext_t *newc, *c, *l, *head; > + struct in6_addr subnet_prefix; > + char *id; > + int rc = 0; > + > + if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { > + yyerror("ibpkeycon not supported for target"); > + return -1; > + } > + > + if (pass == 1) { > + id = (char *)queue_remove(id_queue); > + free(id); > + parse_security_context(NULL); > + return 0; > + } > + > + newc = malloc(sizeof(*newc)); > + if (!newc) { > + yyerror("out of memory"); > + return -1; > + } > + memset(newc, 0, sizeof(*newc)); > + > + id = queue_remove(id_queue); > + if (!id) { > + yyerror("failed to read the subnet prefix"); > + rc = -1; > + goto out; > + } > + > + rc = inet_pton(AF_INET6, id, &subnet_prefix); > + free(id); > + if (rc < 1) { > + yyerror("failed to parse the subnet prefix"); > + if (rc == 0) > + rc = -1; > + goto out; > + } > + > + if (subnet_prefix.s6_addr[2] || subnet_prefix.s6_addr[3]) { > + yyerror("subnet prefix should be 0's in the low > order 64 bits."); > + rc = -1; > + goto out; > + } > + > + memcpy(&newc->u.ibpkey.subnet_prefix[0], > &subnet_prefix.s6_addr[0], > + sizeof(newc->u.ibpkey.subnet_prefix)); > + > + newc->u.ibpkey.low_pkey = low; > + newc->u.ibpkey.high_pkey = high; Kernel patch also rejects low or high > 0xffff, so we likely ought to do the same here? > + > + if (low > high) { > + yyerror2("low pkey %d exceeds high pkey %d", low, > high); > + rc = -1; > + goto out; > + } > + > + rc = parse_security_context(&newc->context[0]); > + if (rc) > + goto out; > + > + /* Preserve the matching order specified in the > configuration. */ > + head = policydbp->ocontexts[OCON_IBPKEY]; > + for (l = NULL, c = head; c; l = c, c = c->next) { > + unsigned int low2, high2; > + > + low2 = c->u.ibpkey.low_pkey; > + high2 = c->u.ibpkey.high_pkey; > + > + if (low == low2 && high == high2 && > + !memcmp(&c->u.ibpkey.subnet_prefix[0], > + &newc->u.ibpkey.subnet_prefix[0], > + sizeof(c->u.ibpkey.subnet_prefix))) { > + yyerror2("duplicate ibpkeycon entry for %d- > %d ", > + low, high); > + rc = -1; > + goto out; > + } > + if (low2 <= low && high2 >= high && > + !memcmp(&c->u.ibpkey.subnet_prefix[0], > + &newc->u.ibpkey.subnet_prefix[0], > + sizeof(c->u.ibpkey.subnet_prefix))) { > + yyerror2("ibpkeycon entry for %d-%d hidden > by earlier entry for %d-%d", > + low, high, low2, high2); > + rc = -1; > + goto out; > + } > + } > + > + if (l) > + l->next = newc; > + else > + policydbp->ocontexts[OCON_IBPKEY] = newc; > + > + return 0; > + > +out: > + free(newc); > + return rc; > +} > + > int define_netif_context(void) > { > ocontext_t *newc, *c, *head; > diff --git a/checkpolicy/policy_define.h > b/checkpolicy/policy_define.h > index 9f4b6d0..75e3683 100644 > --- a/checkpolicy/policy_define.h > +++ b/checkpolicy/policy_define.h > @@ -43,6 +43,7 @@ int define_level(void); > int define_netif_context(void); > int define_permissive(void); > int define_polcap(void); > +int define_ibpkey_context(unsigned int low, unsigned int high); > int define_port_context(unsigned int low, unsigned int high); > int define_pirq_context(unsigned int pirq); > int define_iomem_context(uint64_t low, uint64_t high); > diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y > index 1ac1c96..35b433b 100644 > --- a/checkpolicy/policy_parse.y > +++ b/checkpolicy/policy_parse.y > @@ -21,6 +21,7 @@ > * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. > * Copyright (C) 2003 - 2008 Tresys Technology, LLC > * Copyright (C) 2007 Red Hat Inc. > + * Copyright (C) 2017 Mellanox Technologies Inc. > * This program is free software; you can redistribute it > and/or modify > * it under the terms of the GNU General Public License as > published by > * the Free Software Foundation, version 2. > @@ -135,6 +136,7 @@ typedef int (* require_func_t)(int pass); > %token TARGET > %token SAMEUSER > %token FSCON PORTCON NETIFCON NODECON > +%token IBPKEYCON > %token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON DEVICETREECON > %token FSUSEXATTR FSUSETASK FSUSETRANS > %token GENFSCON > @@ -170,7 +172,7 @@ base_policy : { if > (define_policy(pass, 0) == -1) return -1; } > opt_default_rules opt_mls te_rbac users > opt_constraints > { if (pass == 1) { if > (policydb_index_bools(policydbp)) return -1;} > else if (pass == 2) { if > (policydb_index_others(NULL, policydbp, 0)) return -1;}} > - initial_sid_contexts opt_fs_contexts > opt_fs_uses opt_genfs_contexts net_contexts opt_dev_contexts > + initial_sid_contexts opt_fs_contexts > opt_fs_uses opt_genfs_contexts net_contexts opt_dev_contexts > opt_ibpkey_contexts > ; > classes : class_def > | classes class_def > @@ -713,6 +715,17 @@ port_context_def : PORTCON identifier > number security_context_def > | PORTCON identifier number '-' number > security_context_def > {if (define_port_context($3,$5)) return -1;} > ; > +opt_ibpkey_contexts : ibpkey_contexts > + | > + ; > +ibpkey_contexts : ibpkey_context_def > + | ibpkey_contexts ibpkey_context_def > + ; > +ibpkey_context_def : IBPKEYCON ipv6_addr number > security_context_def > + {if (define_ibpkey_context($3,$3)) return > -1;} > + | IBPKEYCON ipv6_addr number '-' number > security_context_def > + {if (define_ibpkey_context($3,$5)) return > -1;} > + ; > opt_netif_contexts : netif_contexts > | > ; > diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l > index 028bd25..f742939 100644 > --- a/checkpolicy/policy_scan.l > +++ b/checkpolicy/policy_scan.l > @@ -12,6 +12,7 @@ > * Added support for binary policy modules > * > * Copyright (C) 2003-5 Tresys Technology, LLC > + * Copyright (C) 2017 Mellanox Technologies Inc. > * This program is free software; you can redistribute it > and/or modify > * it under the terms of the GNU General Public License as > published by > * the Free Software Foundation, version 2. > @@ -183,6 +184,8 @@ INCOMP | > incomp { return(INCOMP);} > fscon | > FSCON { return(FSCON);} > +ibpkeycon | > +IBPKEYCON { return(IBPKEYCON);} > portcon | > PORTCON { return(PORTCON);} > netifcon | > diff --git a/libsepol/include/sepol/policydb/policydb.h > b/libsepol/include/sepol/policydb/policydb.h > index 37e0c9e..844191c 100644 > --- a/libsepol/include/sepol/policydb/policydb.h > +++ b/libsepol/include/sepol/policydb/policydb.h > @@ -24,6 +24,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 Techonolgies Inc. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Lesser General Public > @@ -358,6 +359,11 @@ typedef struct ocontext { > uint32_t low_ioport; > uint32_t high_ioport; > } ioport; > + struct { > + uint32_t subnet_prefix[4]; > + uint16_t low_pkey; > + uint16_t high_pkey; > + } ibpkey; > } u; > union { > uint32_t sclass; /* security class for genfs > */ > @@ -386,14 +392,14 @@ typedef struct genfs { > #define SYM_NUM 8 > > /* object context array indices */ > -#define OCON_ISID 0 /* initial SIDs */ > -#define OCON_FS 1 /* unlabeled file systems */ > -#define OCON_PORT 2 /* TCP and UDP port numbers */ > -#define OCON_NETIF 3 /* network interfaces */ > -#define OCON_NODE 4 /* nodes */ > -#define OCON_FSUSE 5 /* fs_use */ > -#define OCON_NODE6 6 /* IPv6 nodes */ > -#define OCON_GENFS 7 /* needed for ocontext_supported */ > +#define OCON_ISID 0 /* initial SIDs */ > +#define OCON_FS 1 /* unlabeled file systems */ > +#define OCON_PORT 2 /* TCP and UDP port numbers */ > +#define OCON_NETIF 3 /* network interfaces */ > +#define OCON_NODE 4 /* nodes */ > +#define OCON_FSUSE 5 /* fs_use */ > +#define OCON_NODE6 6 /* IPv6 nodes */ > +#define OCON_IBPKEY 7 /* Infiniband PKEY */ > > /* object context array indices for Xen */ > #define OCON_XEN_ISID 0 /* initial SIDs */ > @@ -404,7 +410,7 @@ typedef struct genfs { > #define OCON_XEN_DEVICETREE 5 /* device tree node */ > > /* OCON_NUM needs to be the largest index in any platform's ocontext > array */ > -#define OCON_NUM 7 > +#define OCON_NUM 8 > > /* section: module information */ > > @@ -726,10 +732,11 @@ extern int > policydb_set_target_platform(policydb_t *p, int platform); > #define POLICYDB_VERSION_CONSTRAINT_NAMES 29 > #define POLICYDB_VERSION_XEN_DEVICETREE 30 /* Xen- > specific */ > #define POLICYDB_VERSION_XPERMS_IOCTL 30 /* Linux-specific */ > +#define POLICYDB_VERSION_INFINIBAND 31 /* Linux- > specific */ > > /* Range of policy versions we understand*/ > #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE > -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_XPERMS_IOCTL > +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_INFINIBAND > > /* Module versions and specific changes*/ > #define MOD_POLICYDB_VERSION_BASE 4 > @@ -747,10 +754,11 @@ extern int > policydb_set_target_platform(policydb_t *p, int platform); > #define MOD_POLICYDB_VERSION_TUNABLE_SEP 14 > #define MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 15 > #define MOD_POLICYDB_VERSION_DEFAULT_TYPE 16 > -#define MOD_POLICYDB_VERSION_CONSTRAINT_NAMES 17 > +#define MOD_POLICYDB_VERSION_CONSTRAINT_NAMES 17 > +#define MOD_POLICYDB_VERSION_INFINIBAND 18 > > #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE > -#define MOD_POLICYDB_VERSION_MAX > MOD_POLICYDB_VERSION_CONSTRAINT_NAMES > +#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_INFINIBAND > > #define POLICYDB_CONFIG_MLS 1 >