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 IB end port ocontext
> data.
> Also add support for querying a IB end port sid to checkpolicy.
> 
> Signed-off-by: Daniel Jurgens <dani...@mellanox.com>
> ---
>  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;

Reply via email to