[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 2/3] libsepol, checkpolicy: widen Xen IOMEM ocontext entries



This expands IOMEMCON device context entries to 64 bits.  This change is
required to support static I/O memory range labeling for systems with
over 16TB of physical address space.  The policy version number change
is shared with the next patch.

While this makes no changes to SELinux policy, a new SELinux policy
compatibility entry was added in order to avoid breaking compilation of
an SELinux policy without explicitly specifying the policy version.

Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
---
 checkpolicy/policy_define.c                |  6 +++---
 checkpolicy/policy_define.h                |  2 +-
 checkpolicy/policy_parse.y                 |  9 ++++++--
 libsepol/cil/src/cil_build_ast.c           | 32 ++++++++++++++++++++++++++---
 libsepol/cil/src/cil_build_ast.h           |  1 +
 libsepol/cil/src/cil_internal.h            |  4 ++--
 libsepol/cil/src/cil_policy.c              |  2 +-
 libsepol/cil/src/cil_tree.c                |  2 +-
 libsepol/include/sepol/policydb/policydb.h |  7 ++++---
 libsepol/src/policydb.c                    | 33 +++++++++++++++++++++++++-----
 libsepol/src/write.c                       | 32 ++++++++++++++++++++++-------
 policycoreutils/hll/pp/pp.c                |  4 ++--
 12 files changed, 104 insertions(+), 30 deletions(-)

diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index a6c5d65..f4c6fba 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -3932,7 +3932,7 @@ bad:
        return -1;
 }
 
-int define_iomem_context(unsigned long low, unsigned long high)
+int define_iomem_context(uint64_t low, uint64_t high)
 {
        ocontext_t *newc, *c, *l, *head;
        char *id;
@@ -3972,13 +3972,13 @@ int define_iomem_context(unsigned long low, unsigned 
long high)
 
        head = policydbp->ocontexts[OCON_XEN_IOMEM];
        for (l = NULL, c = head; c; l = c, c = c->next) {
-               uint32_t low2, high2;
+               uint64_t low2, high2;
 
                low2 = c->u.iomem.low_iomem;
                high2 = c->u.iomem.high_iomem;
                if (low <= high2 && low2 <= high) {
                        yyerror2("iomemcon entry for 0x%lx-0x%lx overlaps with "
-                               "earlier entry 0x%x-0x%x", low, high,
+                               "earlier entry 0x%lx-0x%lx", low, high,
                                low2, high2);
                        goto bad;
                }
diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h
index 4ef0f4f..14d30e1 100644
--- a/checkpolicy/policy_define.h
+++ b/checkpolicy/policy_define.h
@@ -46,7 +46,7 @@ int define_permissive(void);
 int define_polcap(void);
 int define_port_context(unsigned int low, unsigned int high);
 int define_pirq_context(unsigned int pirq);
-int define_iomem_context(unsigned long low, unsigned long high);
+int define_iomem_context(uint64_t low, uint64_t high);
 int define_ioport_context(unsigned long low, unsigned long high);
 int define_pcidevice_context(unsigned long device);
 int define_range_trans(int class_specified);
diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
index e5210bd..e3899b9 100644
--- a/checkpolicy/policy_parse.y
+++ b/checkpolicy/policy_parse.y
@@ -67,6 +67,7 @@ typedef int (* require_func_t)(int pass);
 
 %union {
        unsigned int val;
+       uint64_t val64;
        uintptr_t valptr;
        void *ptr;
         require_func_t require_func;
@@ -78,6 +79,7 @@ typedef int (* require_func_t)(int pass);
 %type <ptr> role_def roles
 %type <valptr> cexpr cexpr_prim op role_mls_op
 %type <val> ipv4_addr_def number
+%type <val64> number64
 %type <require_func> require_decl_def
 
 %token PATH
@@ -647,9 +649,9 @@ dev_context_def             : pirq_context_def |
 pirq_context_def       : PIRQCON number security_context_def
                        {if (define_pirq_context($2)) return -1;}
                        ;
-iomem_context_def      : IOMEMCON number security_context_def
+iomem_context_def      : IOMEMCON number64 security_context_def
                        {if (define_iomem_context($2,$2)) return -1;}
-                       | IOMEMCON number '-' number security_context_def
+                       | IOMEMCON number64 '-' number64 security_context_def
                        {if (define_iomem_context($2,$4)) return -1;}
                        ;
 ioport_context_def     : IOPORTCON number security_context_def
@@ -815,6 +817,9 @@ filename            : FILENAME
 number                 : NUMBER 
                        { $$ = strtoul(yytext,NULL,0); }
                        ;
+number64               : NUMBER
+                       { $$ = strtoull(yytext,NULL,0); }
+                       ;
 ipv6_addr              : IPV6_ADDR
                        { if (insert_id(yytext,0)) return -1; }
                        ;
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
index 419c20f..1949d2b 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -4319,12 +4319,12 @@ int cil_gen_iomemcon(__attribute__((unused)) struct 
cil_db *db, struct cil_tree_
        if (parse_current->next->cl_head != NULL) {
                if (parse_current->next->cl_head->next != NULL &&
                    parse_current->next->cl_head->next->next == NULL) {
-                       rc = cil_fill_integer(parse_current->next->cl_head, 
&iomemcon->iomem_low);
+                       rc = cil_fill_integer64(parse_current->next->cl_head, 
&iomemcon->iomem_low);
                        if (rc != SEPOL_OK) {
                                cil_log(CIL_ERR, "Improper iomem specified\n");
                                goto exit;
                        }
-                       rc = 
cil_fill_integer(parse_current->next->cl_head->next, &iomemcon->iomem_high);
+                       rc = 
cil_fill_integer64(parse_current->next->cl_head->next, &iomemcon->iomem_high);
                        if (rc != SEPOL_OK) {
                                cil_log(CIL_ERR, "Improper iomem specified\n");
                                goto exit;
@@ -4335,7 +4335,7 @@ int cil_gen_iomemcon(__attribute__((unused)) struct 
cil_db *db, struct cil_tree_
                        goto exit;
                }
        } else {
-               rc = cil_fill_integer(parse_current->next, 
&iomemcon->iomem_low);;
+               rc = cil_fill_integer64(parse_current->next, 
&iomemcon->iomem_low);;
                if (rc != SEPOL_OK) {
                        cil_log(CIL_ERR, "Improper iomem specified\n");
                        goto exit;
@@ -5054,6 +5054,32 @@ exit:
        return rc;
 }
 
+int cil_fill_integer64(struct cil_tree_node *int_node, uint64_t *integer)
+{
+       int rc = SEPOL_ERR;
+       char *endptr = NULL;
+       uint64_t val;
+
+       if (int_node == NULL || integer == NULL) {
+               goto exit;
+       }
+
+       errno = 0;
+       val = strtoull(int_node->data, &endptr, 10);
+       if (errno != 0 || endptr == int_node->data || *endptr != '\0') {
+               rc = SEPOL_ERR;
+               goto exit;
+       }
+
+       *integer = val;
+
+       return SEPOL_OK;
+
+exit:
+       cil_log(CIL_ERR, "Failed to create integer from string\n");
+       return rc;
+}
+
 int cil_fill_ipaddr(struct cil_tree_node *addr_node, struct cil_ipaddr *addr)
 {
        int rc = SEPOL_ERR;
diff --git a/libsepol/cil/src/cil_build_ast.h b/libsepol/cil/src/cil_build_ast.h
index 5b07c14..1bd33ce 100644
--- a/libsepol/cil/src/cil_build_ast.h
+++ b/libsepol/cil/src/cil_build_ast.h
@@ -211,6 +211,7 @@ int cil_fill_cats(struct cil_tree_node *curr, struct 
cil_cats **cats);
 void cil_destroy_cats(struct cil_cats *cats);
 int cil_fill_context(struct cil_tree_node *user_node, struct cil_context 
*context);
 int cil_fill_integer(struct cil_tree_node *int_node, uint32_t *integer);
+int cil_fill_integer64(struct cil_tree_node *int_node, uint64_t *integer);
 int cil_fill_ipaddr(struct cil_tree_node *addr_node, struct cil_ipaddr *addr);
 int cil_fill_level(struct cil_tree_node *sens, struct cil_level *level);
 
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
index cf0a8b1..11a2085 100644
--- a/libsepol/cil/src/cil_internal.h
+++ b/libsepol/cil/src/cil_internal.h
@@ -719,8 +719,8 @@ struct cil_pirqcon {
 };
 
 struct cil_iomemcon {
-       uint32_t iomem_low;
-       uint32_t iomem_high;
+       uint64_t iomem_low;
+       uint64_t iomem_high;
        char *context_str;
        struct cil_context *context;
 };
diff --git a/libsepol/cil/src/cil_policy.c b/libsepol/cil/src/cil_policy.c
index ec38f69..7707a75 100644
--- a/libsepol/cil/src/cil_policy.c
+++ b/libsepol/cil/src/cil_policy.c
@@ -236,7 +236,7 @@ int cil_iomemcon_to_policy(FILE **file_arr, struct cil_sort 
*sort)
 
        for (i = 0; i < sort->count; i++) {
                struct cil_iomemcon *iomemcon = (struct 
cil_iomemcon*)sort->array[i];
-               fprintf(file_arr[NETIFCONS], "iomemcon %d-%d ", 
iomemcon->iomem_low, iomemcon->iomem_high);
+               fprintf(file_arr[NETIFCONS], "iomemcon %ld-%ld ", 
iomemcon->iomem_low, iomemcon->iomem_high);
                cil_context_to_policy(file_arr, NETIFCONS, iomemcon->context);
                fprintf(file_arr[NETIFCONS], ";\n");
        }
diff --git a/libsepol/cil/src/cil_tree.c b/libsepol/cil/src/cil_tree.c
index 4f9f480..5420af2 100644
--- a/libsepol/cil/src/cil_tree.c
+++ b/libsepol/cil/src/cil_tree.c
@@ -1392,7 +1392,7 @@ void cil_tree_print_node(struct cil_tree_node *node)
                case CIL_IOMEMCON: {
                        struct cil_iomemcon *iomemcon = node->data;
 
-                       cil_log(CIL_INFO, "IOMEMCON ( %d %d )", 
iomemcon->iomem_low, iomemcon->iomem_high);
+                       cil_log(CIL_INFO, "IOMEMCON ( %ld %ld )", 
iomemcon->iomem_low, iomemcon->iomem_high);
                        if (iomemcon->context != NULL) {
                                cil_tree_print_context(iomemcon->context);
                        } else {
diff --git a/libsepol/include/sepol/policydb/policydb.h 
b/libsepol/include/sepol/policydb/policydb.h
index 6254fef..946cbaf 100644
--- a/libsepol/include/sepol/policydb/policydb.h
+++ b/libsepol/include/sepol/policydb/policydb.h
@@ -325,8 +325,8 @@ typedef struct ocontext {
                uint32_t device;
                uint16_t pirq;
                struct {
-                       uint32_t low_iomem;
-                       uint32_t high_iomem;
+                       uint64_t low_iomem;
+                       uint64_t high_iomem;
                } iomem;
                struct {
                        uint32_t low_ioport;
@@ -689,10 +689,11 @@ extern int policydb_set_target_platform(policydb_t *p, 
int platform);
 #define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS   27
 #define POLICYDB_VERSION_DEFAULT_TYPE  28
 #define POLICYDB_VERSION_CONSTRAINT_NAMES      29
+#define POLICYDB_VERSION_XEN_DEVICETREE 30
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
-#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_CONSTRAINT_NAMES
+#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_XEN_DEVICETREE
 
 /* Module versions and specific changes*/
 #define MOD_POLICYDB_VERSION_BASE              4
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index 667e98a..d54eb9e 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -68,6 +68,13 @@ static struct policydb_compat_info policydb_compat[] = {
         },
        {
         .type = POLICY_KERN,
+        .version = POLICYDB_VERSION_XEN_DEVICETREE,
+        .sym_num = SYM_NUM,
+        .ocon_num = OCON_XEN_PCIDEVICE + 1,
+        .target_platform = SEPOL_TARGET_XEN,
+        },
+       {
+        .type = POLICY_KERN,
         .version = POLICYDB_VERSION_BASE,
         .sym_num = SYM_NUM - 3,
         .ocon_num = OCON_FSUSE + 1,
@@ -172,6 +179,13 @@ static struct policydb_compat_info policydb_compat[] = {
         .target_platform = SEPOL_TARGET_SELINUX,
        },
        {
+        .type = POLICY_KERN,
+        .version = POLICYDB_VERSION_XEN_DEVICETREE,
+        .sym_num = SYM_NUM,
+        .ocon_num = OCON_NODE6 + 1,
+        .target_platform = SEPOL_TARGET_SELINUX,
+       },
+       {
         .type = POLICY_BASE,
         .version = MOD_POLICYDB_VERSION_BASE,
         .sym_num = SYM_NUM,
@@ -2514,11 +2528,20 @@ static int ocontext_read_xen(struct 
policydb_compat_info *info,
                                        return -1;
                                break;
                        case OCON_XEN_IOMEM:
-                               rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
-                               if (rc < 0)
-                                       return -1;
-                               c->u.iomem.low_iomem = le32_to_cpu(buf[0]);
-                               c->u.iomem.high_iomem = le32_to_cpu(buf[1]);
+                               if (p->policyvers >= 
POLICYDB_VERSION_XEN_DEVICETREE) {
+                                       uint64_t b64[2];
+                                       rc = next_entry(b64, fp, 
sizeof(uint64_t) * 2);
+                                       if (rc < 0)
+                                               return -1;
+                                       c->u.iomem.low_iomem = 
le64_to_cpu(b64[0]);
+                                       c->u.iomem.high_iomem = 
le64_to_cpu(b64[1]);
+                               } else {
+                                       rc = next_entry(buf, fp, 
sizeof(uint32_t) * 2);
+                                       if (rc < 0)
+                                               return -1;
+                                       c->u.iomem.low_iomem = 
le32_to_cpu(buf[0]);
+                                       c->u.iomem.high_iomem = 
le32_to_cpu(buf[1]);
+                               }
                                if (context_read_and_validate
                                    (&c->context[0], p, fp))
                                        return -1;
diff --git a/libsepol/src/write.c b/libsepol/src/write.c
index d03dc20..3452017 100644
--- a/libsepol/src/write.c
+++ b/libsepol/src/write.c
@@ -1252,13 +1252,31 @@ static int ocontext_write_xen(struct 
policydb_compat_info *info, policydb_t *p,
                                        return POLICYDB_ERROR;
                                break;
                        case OCON_XEN_IOMEM:
-                               buf[0] = c->u.iomem.low_iomem;
-                               buf[1] = c->u.iomem.high_iomem;
-                               for (j = 0; j < 2; j++)
-                                       buf[j] = cpu_to_le32(buf[j]);
-                               items = put_entry(buf, sizeof(uint32_t), 2, fp);
-                               if (items != 2)
-                                       return POLICYDB_ERROR;
+                               if (p->policyvers >= 
POLICYDB_VERSION_XEN_DEVICETREE) {
+                                       uint64_t b64[2];
+                                       b64[0] = c->u.iomem.low_iomem;
+                                       b64[1] = c->u.iomem.high_iomem;
+                                       for (j = 0; j < 2; j++)
+                                               b64[j] = cpu_to_le64(b64[j]);
+                                       items = put_entry(b64, 
sizeof(uint64_t), 2, fp);
+                                       if (items != 2)
+                                               return POLICYDB_ERROR;
+                               } else {
+                                       if (c->u.iomem.high_iomem > 
0xFFFFFFFFULL) {
+                                               ERR(fp->handle, "policy version 
%d"
+                                                       " cannot represent 
IOMEM addresses over 16TB",
+                                                       p->policyvers);
+                                               return POLICYDB_ERROR;
+                                       }
+
+                                       buf[0] = c->u.iomem.low_iomem;
+                                       buf[1] = c->u.iomem.high_iomem;
+                                       for (j = 0; j < 2; j++)
+                                               buf[j] = cpu_to_le32(buf[j]);
+                                       items = put_entry(buf, 
sizeof(uint32_t), 2, fp);
+                                       if (items != 2)
+                                               return POLICYDB_ERROR;
+                               }
                                if (context_write(p, &c->context[0], fp))
                                        return POLICYDB_ERROR;
                                break;
diff --git a/policycoreutils/hll/pp/pp.c b/policycoreutils/hll/pp/pp.c
index b863346..60c493d 100644
--- a/policycoreutils/hll/pp/pp.c
+++ b/policycoreutils/hll/pp/pp.c
@@ -2695,8 +2695,8 @@ static int ocontext_xen_ioport_to_cil(struct policydb 
*pdb, struct ocontext *iop
 static int ocontext_xen_iomem_to_cil(struct policydb *pdb, struct ocontext 
*iomems)
 {
        struct ocontext *iomem;
-       uint32_t low;
-       uint32_t high;
+       uint64_t low;
+       uint64_t high;
 
        for (iomem = iomems; iomem != NULL; iomem = iomem->next) {
                low = iomem->u.iomem.low_iomem;
-- 
2.1.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.