From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <1494443390.24408.17.camel@tycho.nsa.gov> Subject: Re: [PATCH 5/9] libsepol: Add ibendport ocontext handling From: Stephen Smalley To: Dan Jurgens , selinux@tycho.nsa.gov Date: Wed, 10 May 2017 15:09:50 -0400 In-Reply-To: <1494363042-121766-6-git-send-email-danielj@mellanox.com> References: <1494363042-121766-1-git-send-email-danielj@mellanox.com> <1494363042-121766-6-git-send-email-danielj@mellanox.com> Content-Type: text/plain; charset="UTF-8" Mime-Version: 1.0 List-Id: "Security-Enhanced Linux \(SELinux\) mailing list" List-Post: List-Help: On Tue, 2017-05-09 at 23:50 +0300, Dan Jurgens wrote: > From: Daniel Jurgens > > 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 > --- >  checkpolicy/checkpolicy.c                  |   20 ++++++++++++++ >  libsepol/include/sepol/policydb/services.h |   10 +++++++ >  libsepol/src/expand.c                      |    8 +++++ >  libsepol/src/libsepol.map.in               |    1 + >  libsepol/src/module_to_cil.c               |   15 ++++++++++ >  libsepol/src/policydb.c                    |   21 +++++++++++++- >  libsepol/src/services.c                    |   39 > ++++++++++++++++++++++++++++ >  libsepol/src/write.c                       |   14 ++++++++++ >  8 files changed, 126 insertions(+), 2 deletions(-) > > diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c > index 0f12347..72431d6 100644 > --- a/checkpolicy/checkpolicy.c > +++ b/checkpolicy/checkpolicy.c > @@ -701,6 +701,7 @@ int main(int argc, char **argv) >   printf("i)  display constraint expressions\n"); >   printf("j)  display validatetrans expressions\n"); >   printf("k)  Call ibpkey_sid\n"); > + printf("l)  Call ibendport_sid\n"); >  #ifdef EQUIVTYPES >   printf("z)  Show equivalent types\n"); >  #endif > @@ -1247,6 +1248,25 @@ int main(int argc, char **argv) >   printf("sid %d\n", ssid); >   } >   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(0, 0, name, port, > &ssid); > + printf("sid %d\n", ssid); > + free(name); > + 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 2d7aed1..aa8d718 100644 > --- a/libsepol/include/sepol/policydb/services.h > +++ b/libsepol/include/sepol/policydb/services.h > @@ -199,6 +199,16 @@ extern int sepol_ibpkey_sid(uint16_t domain, >     sepol_security_id_t *out_sid); >   >  /* > + * Return the SID of the ibendport specified by > + * `domain', `type', `dev_name', and `port'. > + */ > +extern int sepol_ibendport_sid(uint16_t domain, > +        uint16_t type, > +        char *dev_name, > +        uint8_t port, > +        sepol_security_id_t *out_sid); Why (domain, type) arguments? > + > +/* >   * 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 c45ecbe..061945e 100644 > --- a/libsepol/src/expand.c > +++ b/libsepol/src/expand.c > @@ -2226,6 +2226,14 @@ static int > ocontext_copy_selinux(expand_state_t *state) >   n->u.ibpkey.low_pkey = c- > >u.ibpkey.low_pkey; >   n->u.ibpkey.high_pkey = c- > >u.ibpkey.high_pkey; >   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: >   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 36225d1..dd1fec2 100644 > --- a/libsepol/src/libsepol.map.in > +++ b/libsepol/src/libsepol.map.in > @@ -7,6 +7,7 @@ LIBSEPOL_1.0 { >   sepol_iface_*;  >   sepol_port_*; >   sepol_ibpkey_*; > + sepol_ibendport_*; >   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 db3f9c8..4b9f2c8 100644 > --- a/libsepol/src/module_to_cil.c > +++ b/libsepol/src/module_to_cil.c > @@ -2585,6 +2585,7 @@ static int ocontext_selinux_isid_to_cil(struct > policydb *pdb, struct ocontext *i >   "scmp_packet", >   "devnull", >   "ibpkey", > + "ibendport", No new initial SIDs. >   NULL >   }; >   > @@ -2763,6 +2764,19 @@ exit: >   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) >  { > @@ -2917,6 +2931,7 @@ static int ocontexts_to_cil(struct policydb > *pdb) >   ocontext_selinux_fsuse_to_cil, >   ocontext_selinux_node6_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) = { >   ocontext_xen_isid_to_cil, > diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c > index 8b76c6a..6c9f2f9 100644 > --- a/libsepol/src/policydb.c > +++ b/libsepol/src/policydb.c > @@ -198,7 +198,7 @@ static struct policydb_compat_info > policydb_compat[] = { >    .type = POLICY_KERN, >    .version = POLICYDB_VERSION_INFINIBAND, >    .sym_num = SYM_NUM, > -  .ocon_num = OCON_IBPKEY + 1, > +  .ocon_num = OCON_IBENDPORT + 1, >    .target_platform = SEPOL_TARGET_SELINUX, >   }, >   { > @@ -303,7 +303,7 @@ static struct policydb_compat_info > policydb_compat[] = { >    .type = POLICY_BASE, >    .version = MOD_POLICYDB_VERSION_INFINIBAND, >    .sym_num = SYM_NUM, > -  .ocon_num = OCON_IBPKEY + 1, > +  .ocon_num = OCON_IBENDPORT + 1, >    .target_platform = SEPOL_TARGET_SELINUX, >   }, >   { > @@ -2829,6 +2829,23 @@ static int ocontext_read_selinux(struct > policydb_compat_info *info, >       (&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 (zero_or_saturated(len)) 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 > +     (&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 39903d1..d4a068a 100644 > --- a/libsepol/src/services.c > +++ b/libsepol/src/services.c > @@ -1970,6 +1970,45 @@ out: >  } >   >  /* > + * Return the SID of the subnet management interface specified by > + * `domain', `type', `device name', and `port'. > + */ > +int hidden sepol_ibendport_sid(uint16_t domain __attribute__ > ((unused)), > +        uint16_t type __attribute__ > ((unused)), > +        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 && > +     !strncmp(dev_name, c->u.ibendport.dev_name, 64)) > + break; Do you ensure that dev_name cannot be > 64 bytes in checkpolicy and in ocontext_read_selinux()? And do we really want strncmp() here rather than just strcmp()? What's the advantage? > + 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 fa1b7d1..e3ff389 100644 > --- a/libsepol/src/write.c > +++ b/libsepol/src/write.c > @@ -1426,6 +1426,20 @@ static int ocontext_write_selinux(struct > policydb_compat_info *info, >   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)) > + return POLICYDB_ERROR; > + break; >   case OCON_PORT: >   buf[0] = c->u.port.protocol; >   buf[1] = c->u.port.low_port;