mirror of
https://github.com/SELinuxProject/selinux
synced 2024-12-30 18:12:10 +00:00
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@tycho.nsa.gov>
This commit is contained in:
parent
aab2d9f904
commit
82030de5dc
@ -39,6 +39,7 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <sepol/policydb/expand.h>
|
||||
#include <sepol/policydb/policydb.h>
|
||||
@ -3932,7 +3933,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;
|
||||
@ -3960,7 +3961,7 @@ int define_iomem_context(unsigned long low, unsigned long high)
|
||||
newc->u.iomem.high_iomem = high;
|
||||
|
||||
if (low > high) {
|
||||
yyerror2("low memory 0x%lx exceeds high memory 0x%lx", low, high);
|
||||
yyerror2("low memory 0x%"PRIx64" exceeds high memory 0x%"PRIx64"", low, high);
|
||||
free(newc);
|
||||
return -1;
|
||||
}
|
||||
@ -3972,13 +3973,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,
|
||||
yyerror2("iomemcon entry for 0x%"PRIx64"-0x%"PRIx64" overlaps with "
|
||||
"earlier entry 0x%"PRIx64"-0x%"PRIx64"", low, high,
|
||||
low2, high2);
|
||||
goto bad;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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; }
|
||||
;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <sepol/policydb/conditional.h>
|
||||
#include <sepol/errcodes.h>
|
||||
@ -236,7 +237,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 %"PRId64"-%"PRId64" ", iomemcon->iomem_low, iomemcon->iomem_high);
|
||||
cil_context_to_policy(file_arr, NETIFCONS, iomemcon->context);
|
||||
fprintf(file_arr[NETIFCONS], ";\n");
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <sepol/policydb/conditional.h>
|
||||
|
||||
@ -1392,7 +1393,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 ( %"PRId64" %"PRId64" )", iomemcon->iomem_low, iomemcon->iomem_high);
|
||||
if (iomemcon->context != NULL) {
|
||||
cil_tree_print_context(iomemcon->context);
|
||||
} else {
|
||||
|
@ -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
|
||||
|
@ -66,6 +66,13 @@ static struct policydb_compat_info policydb_compat[] = {
|
||||
.ocon_num = OCON_XEN_PCIDEVICE + 1,
|
||||
.target_platform = SEPOL_TARGET_XEN,
|
||||
},
|
||||
{
|
||||
.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,
|
||||
@ -171,6 +178,13 @@ static struct policydb_compat_info policydb_compat[] = {
|
||||
.ocon_num = OCON_NODE6 + 1,
|
||||
.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,
|
||||
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user