diff --git checkpolicy-2.5/Android.mk checkpolicy-2.5/Android.mk index 98f5168..3b7ff8a 100644 --- checkpolicy-2.5/Android.mk +++ checkpolicy-2.5/Android.mk @@ -12,10 +12,6 @@ common_cflags := \ -Wall -Wshadow -O2 \ -pipe -fno-strict-aliasing \ -ifeq ($(HOST_OS),darwin) -common_cflags += -DDARWIN -endif - common_includes := \ $(LOCAL_PATH)/ \ $(LOCAL_PATH)/../libsepol/include/ \ diff --git checkpolicy-2.5/ChangeLog checkpolicy-2.5/ChangeLog index dfe4908..f2216ec 100644 --- checkpolicy-2.5/ChangeLog +++ checkpolicy-2.5/ChangeLog @@ -1,3 +1,11 @@ + * Extend checkpolicy pathname matching, from Stephen Smalley. + * Fix typos in test/dispol, from Petr Lautrbach. + * Set flex as default lexer, from Julien Pivotto. + * Fix checkmodule output message, from Petr Lautrbach. + * Build policy on systems not supporting DCCP protocol, from Richard Haines. + * Fail if module name different than output base filename, from James Carter + * Add support for portcon dccp protocol, from Richard Haines + 2.5 2016-02-23 * Add neverallow support for ioctl extended permissions, from Jeff Vander Stoep. * fix double free on name-based type transitions, from Stephen Smalley. diff --git checkpolicy-2.5/Makefile checkpolicy-2.5/Makefile index e5fae3d..53a3074 100644 --- checkpolicy-2.5/Makefile +++ checkpolicy-2.5/Makefile @@ -8,6 +8,7 @@ LIBDIR ?= $(PREFIX)/lib INCLUDEDIR ?= $(PREFIX)/include TARGETS = checkpolicy checkmodule +LEX = flex YACC = bison -y CFLAGS ?= -g -Wall -Werror -Wshadow -O2 -pipe -fno-strict-aliasing diff --git checkpolicy-2.5/checkmodule.c checkpolicy-2.5/checkmodule.c index 5957d29..53cc5a0 100644 --- checkpolicy-2.5/checkmodule.c +++ checkpolicy-2.5/checkmodule.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -258,6 +259,25 @@ int main(int argc, char **argv) } } + if (policy_type != POLICY_BASE && outfile) { + char *mod_name = modpolicydb.name; + char *out_path = strdup(outfile); + if (out_path == NULL) { + fprintf(stderr, "%s: out of memory\n", argv[0]); + exit(1); + } + char *out_name = basename(out_path); + char *separator = strrchr(out_name, '.'); + if (separator) { + *separator = '\0'; + } + if (strcmp(mod_name, out_name) != 0) { + fprintf(stderr, "%s: Module name %s is different than the output base filename %s\n", argv[0], mod_name, out_name); + exit(1); + } + free(out_path); + } + if (modpolicydb.policy_type == POLICY_BASE && !cil) { /* Verify that we can successfully expand the base module. */ policydb_t kernpolicydb; @@ -294,7 +314,7 @@ int main(int argc, char **argv) if (!cil) { printf("%s: writing binary representation (version %d) to %s\n", - argv[0], policyvers, file); + argv[0], policyvers, outfile); if (write_binary_policy(&modpolicydb, outfp) != 0) { fprintf(stderr, "%s: error writing %s\n", argv[0], outfile); diff --git checkpolicy-2.5/checkpolicy.c checkpolicy-2.5/checkpolicy.c index 9da661e..f682355 100644 --- checkpolicy-2.5/checkpolicy.c +++ checkpolicy-2.5/checkpolicy.c @@ -22,6 +22,7 @@ * * Policy Module support. * + * Copyright (C) 2017 Mellanox Technologies Inc. * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * Copyright (C) 2003 - 2005 Tresys Technology, LLC * Copyright (C) 2003 Red Hat, Inc., James Morris @@ -64,13 +65,19 @@ #include #include #include +#ifndef IPPROTO_DCCP +#define IPPROTO_DCCP 33 +#endif +#ifndef IPPROTO_SCTP +#define IPPROTO_SCTP 132 +#endif #include #include #include #include #include -#ifdef DARWIN +#ifdef __APPLE__ #include #endif @@ -679,6 +686,8 @@ int main(int argc, char **argv) printf("h) change a boolean value\n"); 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 @@ -919,6 +928,10 @@ int main(int argc, char **argv) protocol = IPPROTO_TCP; else if (!strcmp(ans, "udp") || !strcmp(ans, "UDP")) protocol = IPPROTO_UDP; + else if (!strcmp(ans, "dccp") || !strcmp(ans, "DCCP")) + protocol = IPPROTO_DCCP; + else if (!strcmp(ans, "sctp") || !strcmp(ans, "SCTP")) + protocol = IPPROTO_SCTP; else { printf("unknown protocol\n"); break; @@ -1198,6 +1211,50 @@ int main(int argc, char **argv) "\nNo validatetrans expressions found.\n"); } break; + case 'k': + { + char *p; + struct in6_addr addr6; + uint64_t subnet_prefix; + unsigned int pkey; + + printf("subnet prefix? "); + FGETS(ans, sizeof(ans), stdin); + ans[strlen(ans) - 1] = 0; + p = (char *)&addr6; + + if (inet_pton(AF_INET6, ans, p) < 1) { + printf("error parsing subnet prefix\n"); + break; + } + + memcpy(&subnet_prefix, p, sizeof(subnet_prefix)); + printf("pkey? "); + FGETS(ans, sizeof(ans), stdin); + pkey = atoi(ans); + sepol_ibpkey_sid(subnet_prefix, pkey, &ssid); + 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(name, port, &ssid); + printf("sid %d\n", ssid); + free(name); + break; #ifdef EQUIVTYPES case 'z': identify_equiv_types(); diff --git checkpolicy-2.5/policy_define.c checkpolicy-2.5/policy_define.c index ee20fea..a275e33 100644 --- checkpolicy-2.5/policy_define.c +++ checkpolicy-2.5/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. @@ -36,6 +37,12 @@ #include #include #include +#ifndef IPPROTO_DCCP +#define IPPROTO_DCCP 33 +#endif +#ifndef IPPROTO_SCTP +#define IPPROTO_SCTP 132 +#endif #include #include #include @@ -4876,6 +4883,10 @@ int define_port_context(unsigned int low, unsigned int high) protocol = IPPROTO_TCP; } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) { protocol = IPPROTO_UDP; + } else if ((strcmp(id, "dccp") == 0) || (strcmp(id, "DCCP") == 0)) { + protocol = IPPROTO_DCCP; + } else if ((strcmp(id, "sctp") == 0) || (strcmp(id, "SCTP") == 0)) { + protocol = IPPROTO_SCTP; } else { yyerror2("unrecognized protocol %s", id); free(newc); @@ -4931,6 +4942,192 @@ 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; + } + + if (low > 0xffff || high > 0xffff) { + yyerror("pkey value too large, pkeys are 16 bits."); + rc = -1; + goto out; + } + + memcpy(&newc->u.ibpkey.subnet_prefix, &subnet_prefix.s6_addr[0], + sizeof(newc->u.ibpkey.subnet_prefix)); + + newc->u.ibpkey.low_pkey = low; + newc->u.ibpkey.high_pkey = high; + + 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 && + c->u.ibpkey.subnet_prefix == newc->u.ibpkey.subnet_prefix) { + yyerror2("duplicate ibpkeycon entry for %d-%d ", + low, high); + rc = -1; + goto out; + } + if (low2 <= low && high2 >= high && + c->u.ibpkey.subnet_prefix == newc->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_ibendport_context(unsigned int port) +{ + ocontext_t *newc, *c, *l, *head; + char *id; + int rc = 0; + + if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { + yyerror("ibendportcon not supported for target"); + return -1; + } + + if (pass == 1) { + id = (char *)queue_remove(id_queue); + free(id); + parse_security_context(NULL); + return 0; + } + + if (port > 0xff || port == 0) { + yyerror("Invalid ibendport port number, should be 0 < port < 256"); + return -1; + } + + newc = malloc(sizeof(*newc)); + if (!newc) { + yyerror("out of memory"); + return -1; + } + memset(newc, 0, sizeof(*newc)); + + newc->u.ibendport.dev_name = queue_remove(id_queue); + if (!newc->u.ibendport.dev_name) { + yyerror("failed to read infiniband device name."); + rc = -1; + goto out; + } + + if (strlen(newc->u.ibendport.dev_name) > IB_DEVICE_NAME_MAX - 1) { + yyerror("infiniband device name exceeds max length of 63."); + rc = -1; + goto out; + } + + newc->u.ibendport.port = port; + + if (parse_security_context(&newc->context[0])) { + free(newc); + return -1; + } + + /* Preserve the matching order specified in the configuration. */ + head = policydbp->ocontexts[OCON_IBENDPORT]; + for (l = NULL, c = head; c; l = c, c = c->next) { + unsigned int port2; + + port2 = c->u.ibendport.port; + + if (port == port2 && + !strcmp(c->u.ibendport.dev_name, + newc->u.ibendport.dev_name)) { + yyerror2("duplicate ibendportcon entry for %s port %u", + newc->u.ibendport.dev_name, port); + rc = -1; + goto out; + } + } + + if (l) + l->next = newc; + else + policydbp->ocontexts[OCON_IBENDPORT] = newc; + + return 0; + +out: + free(newc->u.ibendport.dev_name); + free(newc); + return rc; +} + int define_netif_context(void) { ocontext_t *newc, *c, *head; @@ -5135,7 +5332,7 @@ int define_ipv6_node_context(void) memset(newc, 0, sizeof(ocontext_t)); -#ifdef DARWIN +#ifdef __APPLE__ memcpy(&newc->u.node6.addr[0], &addr.s6_addr[0], 16); memcpy(&newc->u.node6.mask[0], &mask.s6_addr[0], 16); #else diff --git checkpolicy-2.5/policy_define.h checkpolicy-2.5/policy_define.h index 964baae..3282aed 100644 --- checkpolicy-2.5/policy_define.h +++ checkpolicy-2.5/policy_define.h @@ -43,6 +43,8 @@ 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_ibendport_context(unsigned int port); 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 checkpolicy-2.5/policy_parse.y checkpolicy-2.5/policy_parse.y index 3b6a2f8..35b7a33 100644 --- checkpolicy-2.5/policy_parse.y +++ checkpolicy-2.5/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. @@ -134,6 +135,8 @@ typedef int (* require_func_t)(int pass); %token TARGET %token SAMEUSER %token FSCON PORTCON NETIFCON NODECON +%token IBPKEYCON +%token IBENDPORTCON %token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON DEVICETREECON %token FSUSEXATTR FSUSETASK FSUSETRANS %token GENFSCON @@ -169,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 opt_ibendport_contexts ; classes : class_def | classes class_def @@ -695,7 +698,7 @@ fs_contexts : fs_context_def fs_context_def : FSCON number number security_context_def security_context_def {if (define_fs_context($2,$3)) return -1;} ; -net_contexts : opt_port_contexts opt_netif_contexts opt_node_contexts +net_contexts : opt_port_contexts opt_netif_contexts opt_node_contexts ; opt_port_contexts : port_contexts | @@ -708,6 +711,26 @@ 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_ibendport_contexts : ibendport_contexts + | + ; +ibendport_contexts : ibendport_context_def + | ibendport_contexts ibendport_context_def + ; +ibendport_context_def : IBENDPORTCON identifier number security_context_def + {if (define_ibendport_context($3)) return -1;} + ; opt_netif_contexts : netif_contexts | ; diff --git checkpolicy-2.5/policy_scan.l checkpolicy-2.5/policy_scan.l index 22da338..f38dd22 100644 --- checkpolicy-2.5/policy_scan.l +++ checkpolicy-2.5/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. @@ -181,6 +182,10 @@ INCOMP | incomp { return(INCOMP);} fscon | FSCON { return(FSCON);} +ibpkeycon | +IBPKEYCON { return(IBPKEYCON);} +ibendportcon | +IBENDPORTCON { return(IBENDPORTCON);} portcon | PORTCON { return(PORTCON);} netifcon | @@ -249,9 +254,9 @@ high | HIGH { return(HIGH); } low | LOW { return(LOW); } -"/"({alnum}|[_\.\-/])* { return(PATH); } -\""/"[ !#-~]*\" { return(QPATH); } -\"({alnum}|[_\.\-\+\~\: ])+\" { return(FILENAME); } +"/"[^ \n\r\t\f]* { return(PATH); } +\""/"[^\"\n]*\" { return(QPATH); } +\"[^"/"\"\n]+\" { return(FILENAME); } {letter}({alnum}|[_\-])*([\.]?({alnum}|[_\-]))* { return(IDENTIFIER); } {digit}+|0x{hexval}+ { return(NUMBER); } {alnum}*{letter}{alnum}* { return(FILESYSTEM); } diff --git checkpolicy-2.5/test/dismod.c checkpolicy-2.5/test/dismod.c index 08b039d..c91ab93 100644 --- checkpolicy-2.5/test/dismod.c +++ checkpolicy-2.5/test/dismod.c @@ -243,6 +243,13 @@ int display_avrule(avrule_t * avrule, policydb_t * policy, } } else if (avrule->specified & AVRULE_NEVERALLOW) { fprintf(fp, " neverallow"); + } else if (avrule->specified & AVRULE_XPERMS) { + if (avrule->specified & AVRULE_XPERMS_ALLOWED) + fprintf(fp, "allowxperm "); + else if (avrule->specified & AVRULE_XPERMS_AUDITALLOW) + fprintf(fp, "auditallowxperm "); + else if (avrule->specified & AVRULE_XPERMS_DONTAUDIT) + fprintf(fp, "dontauditxperm "); } else { fprintf(fp, " ERROR: no valid rule type specified\n"); return -1; @@ -282,6 +289,24 @@ int display_avrule(avrule_t * avrule, policydb_t * policy, policy, fp); } else if (avrule->specified & AVRULE_TYPE) { display_id(policy, fp, SYM_TYPES, avrule->perms->data - 1, ""); + } else if (avrule->specified & AVRULE_XPERMS) { + avtab_extended_perms_t xperms; + int i; + + if (avrule->xperms->specified == AVRULE_XPERMS_IOCTLFUNCTION) + xperms.specified = AVTAB_XPERMS_IOCTLFUNCTION; + else if (avrule->xperms->specified == AVRULE_XPERMS_IOCTLDRIVER) + xperms.specified = AVTAB_XPERMS_IOCTLDRIVER; + else { + fprintf(fp, " ERROR: no valid xperms specified\n"); + return -1; + } + + xperms.driver = avrule->xperms->driver; + for (i = 0; i < EXTENDED_PERMS_LEN; i++) + xperms.perms[i] = avrule->xperms->perms[i]; + + fprintf(fp, "%s", sepol_extended_perms_to_string(&xperms)); } fprintf(fp, ";\n"); diff --git checkpolicy-2.5/test/dispol.c checkpolicy-2.5/test/dispol.c index 86f5688..a78ce81 100644 --- checkpolicy-2.5/test/dispol.c +++ checkpolicy-2.5/test/dispol.c @@ -252,11 +252,11 @@ int display_cond_expressions(policydb_t * p, FILE * fp) int display_handle_unknown(policydb_t * p, FILE * out_fp) { if (p->handle_unknown == ALLOW_UNKNOWN) - fprintf(out_fp, "Allow unknown classes and permisions\n"); + fprintf(out_fp, "Allow unknown classes and permissions\n"); else if (p->handle_unknown == DENY_UNKNOWN) - fprintf(out_fp, "Deny unknown classes and permisions\n"); + fprintf(out_fp, "Deny unknown classes and permissions\n"); else if (p->handle_unknown == REJECT_UNKNOWN) - fprintf(out_fp, "Reject unknown classes and permisions\n"); + fprintf(out_fp, "Reject unknown classes and permissions\n"); return 0; } @@ -349,7 +349,7 @@ int menu(void) printf("\nSelect a command:\n"); printf("1) display unconditional AVTAB\n"); printf("2) display conditional AVTAB (entirely)\n"); - printf("3) display conditional AVTAG (only ENABLED rules)\n"); + printf("3) display conditional AVTAB (only ENABLED rules)\n"); printf("4) display conditional AVTAB (only DISABLED rules)\n"); printf("5) display conditional bools\n"); printf("6) display conditional expressions\n");