From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <43F42612.2050907@cornell.edu> Date: Thu, 16 Feb 2006 02:13:22 -0500 From: Ivan Gyurdiev MIME-Version: 1.0 To: SELinux List CC: Stephen Smalley Subject: [SEMANAGE/SEPOL] Nodes: fix bug, and add netmask ordering support Content-Type: multipart/mixed; boundary="------------070500000404030009000307" Sender: owner-selinux@tycho.nsa.gov List-Id: selinux@tycho.nsa.gov This is a multi-part message in MIME format. --------------070500000404030009000307 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Changelog: - fix bug in ipv4 address expansion for nodes - the ipv4 address is 4 bytes long, not 1 Otherwise the addresses that get printed make no sense at all. (bug probably left from when I had it using integer arrays). - change the comparator for nodes to order on netmask first, and addr second, which matches our goals - implement a qsort run (MODE_SORT) in the function that merges local records into policy. Enable that for nodes. The run sorts in ascending order, according to the record's comparator function (but the order ends up being descending once the records are merged one by one). This also restructures most of the merge code - previously we did list() when clearing obsolete records, and then had an iterator for merging them into policy. This changes the code so we do exactly one list() call. Then sorting, clearing obsoletes, and merging things into policy all use the same resultant array. There's no more calls to iterate(). ========= Demo: [root@cobra selinux]# cd libsemanage.new/src [root@cobra src]# cat /etc/selinux/strict/modules/active/nodes.local # This file is auto-generated by libsemanage # Please use the semanage command to make changes nodecon ipv4 127.0.0.1 255.255.255.0 system_u:object_r:default_t:s0 nodecon ipv4 127.0.0.2 255.255.0.0 system_u:object_r:default_t:s0 nodecon ipv4 127.0.0.3 255.255.255.255 system_u:object_r:default_t:s0 nodecon ipv4 127.0.0.4 255.0.255.0 system_u:object_r:default_t:s0 nodecon ipv4 127.0.0.5 0.255.255.0 system_u:object_r:default_t:s0 nodecon ipv4 127.0.0.6 0.0.255.0 system_u:object_r:default_t:s0 nodecon ipv4 127.0.0.7 255.2.0.0 system_u:object_r:default_t:s0 nodecon ipv4 127.0.0.8 255.172.255.0 system_u:object_r:default_t:s0 nodecon ipv4 127.0.0.9 255.172.255.0 system_u:object_r:default_t:s0 nodecon ipv4 127.0.0.10 255.172.255.0 system_u:object_r:default_t:s0 nodecon ipv6 ::1 ffff:ffff:0000:ffff:0000:0000:0000:0000 system_u:object_r:default_t:s0 nodecon ipv6 ::2 ffff:ffff:0000:ffff:0000:0000:0000:00f0 system_u:object_r:default_t:s0 nodecon ipv6 ::3 ff00:ffff:0000:ffff:0000:0000:0000:0f00 system_u:object_r:default_t:s0 nodecon ipv6 ::4 f00f:ffff:0000:ffff:0000:0000:ffff:0000 system_u:object_r:default_t:s0 nodecon ipv6 ::5 0000:0000:0000:0000:ff00:0000:0000:0000 system_u:object_r:default_t:s0 nodecon ipv6 ::6 ffff:00ff:0000:ffff:0000:0000:0000:0000 system_u:object_r:default_t:s0 nodecon ipv6 ::7 0000:ffff:ffff:ffff:0000:0000:0000:0000 system_u:object_r:default_t:s0 nodecon ipv6 ::8 ffff:ffff:0000:ffff:0000:ffff:0000:0000 system_u:object_r:default_t:s0 nodecon ipv6 ::9 ffff:ffff:0000:ffff:ffff:0000:0000:0000 system_u:object_r:default_t:s0 [root@cobra src]# python pywrap-test.py -n Testing network nodes... Query status (commit number): 148 Network Node: 127.0.0.3 / 255.255.255.255 ( ipv4 ) Context: system_u:object_r:default_t:s0 Network Node: 127.0.0.1 / 255.255.255.0 ( ipv4 ) Context: system_u:object_r:default_t:s0 Network Node: 127.0.0.2 / 255.255.0.0 ( ipv4 ) Context: system_u:object_r:default_t:s0 Network Node: 127.0.0.10 / 255.172.255.0 ( ipv4 ) Context: system_u:object_r:default_t:s0 Network Node: 127.0.0.9 / 255.172.255.0 ( ipv4 ) Context: system_u:object_r:default_t:s0 Network Node: 127.0.0.8 / 255.172.255.0 ( ipv4 ) Context: system_u:object_r:default_t:s0 Network Node: 127.0.0.7 / 255.2.0.0 ( ipv4 ) Context: system_u:object_r:default_t:s0 Network Node: 127.0.0.4 / 255.0.255.0 ( ipv4 ) Context: system_u:object_r:default_t:s0 Network Node: 127.0.0.5 / 0.255.255.0 ( ipv4 ) Context: system_u:object_r:default_t:s0 Network Node: 127.0.0.6 / 0.0.255.0 ( ipv4 ) Context: system_u:object_r:default_t:s0 Network Node: 0.0.0.0 / 255.255.255.255 ( ipv4 ) Context: system_u:object_r:inaddr_any_node_t:s0 Network Node: 127.0.0.1 / 255.255.255.255 ( ipv4 ) Context: system_u:object_r:lo_node_t:s0 Network Node: ::9 / ffff:ffff:0:ffff:ffff:: ( ipv6 ) Context: system_u:object_r:default_t:s0 Network Node: ::8 / ffff:ffff:0:ffff:0:ffff:: ( ipv6 ) Context: system_u:object_r:default_t:s0 Network Node: ::2 / ffff:ffff:0:ffff::f0 ( ipv6 ) Context: system_u:object_r:default_t:s0 Network Node: ::1 / ffff:ffff:0:ffff:: ( ipv6 ) Context: system_u:object_r:default_t:s0 Network Node: ::6 / ffff:ff:0:ffff:: ( ipv6 ) Context: system_u:object_r:default_t:s0 Network Node: ::3 / ff00:ffff:0:ffff::f00 ( ipv6 ) Context: system_u:object_r:default_t:s0 Network Node: ::4 / f00f:ffff:0:ffff::ffff:0 ( ipv6 ) Context: system_u:object_r:default_t:s0 Network Node: ::7 / 0:ffff:ffff:ffff:: ( ipv6 ) Context: system_u:object_r:default_t:s0 Network Node: ::5 / ::ff00:0:0:0 ( ipv6 ) Context: system_u:object_r:default_t:s0 Network Node: :: / ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff ( ipv6 ) Context: system_u:object_r:unspec_node_t:s0 Network Node: :: / ffff:ffff:ffff:ffff:ffff:ffff:: ( ipv6 ) Context: system_u:object_r:compat_ipv4_node_t:s0 Network Node: ::ffff:0.0.0.0 / ffff:ffff:ffff:ffff:ffff:ffff:: ( ipv6 ) Context: system_u:object_r:mapped_ipv4_node_t:s0 Network Node: fe80:: / ffff:ffff:ffff:ffff:: ( ipv6 ) Context: system_u:object_r:link_local_node_t:s0 Network Node: fec0:: / ffc0:: ( ipv6 ) Context: system_u:object_r:site_local_node_t:s0 Network Node: ff00:: / ff00:: ( ipv6 ) Context: system_u:object_r:multicast_node_t:s0 --------------070500000404030009000307 Content-Type: text/x-patch; name="libsemanage.sepol.node_ordering+bugfix.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="libsemanage.sepol.node_ordering+bugfix.diff" diff -Naurp --exclude-from excludes old/libsemanage/src/policy_components.c new/libsemanage/src/policy_components.c --- old/libsemanage/src/policy_components.c 2006-02-16 02:04:52.000000000 -0500 +++ new/libsemanage/src/policy_components.c 2006-02-16 01:06:13.000000000 -0500 @@ -7,25 +7,25 @@ #include "modules.h" #include "debug.h" +/* Powers of two only */ #define MODE_SET 1 #define MODE_MODIFY 2 +#define MODE_SORT 4 static int clear_obsolete( semanage_handle_t* handle, + record_t** records, + unsigned int nrecords, dbase_config_t* src, dbase_config_t* dst) { record_key_t* key = NULL; - record_t** records = NULL; - unsigned int i, nrecords = 0; + unsigned int i; dbase_table_t* src_dtable = src->dtable; dbase_table_t* dst_dtable = dst->dtable; record_table_t* rtable = src_dtable->get_rtable(src->dbase); - if (src_dtable->list(handle, src->dbase, &records, &nrecords) < 0) - goto err; - for (i = 0; i < nrecords; i++) { int exists; @@ -39,6 +39,9 @@ static int clear_obsolete( if (src_dtable->del(handle, src->dbase, key) < 0) goto err; + rtable->free(records[i]); + records[i] = NULL; + /* FIXME: notice to user */ /* INFO(handle, "boolean %s is obsolete, unsetting configured value..."); */ } @@ -46,70 +49,60 @@ static int clear_obsolete( rtable->key_free(key); } - for (i=0; i < nrecords; i++) - rtable->free(records[i]); - free(records); return STATUS_SUCCESS; err: /* FIXME: handle error */ - for (i=0; i < nrecords; i++) - rtable->free(records[i]); - free(records); rtable->key_free(key); return STATUS_ERR; } -typedef struct load_handler_arg { - semanage_handle_t* handle; - dbase_config_t* dconfig; - int mode; -} load_handler_arg_t; - -static int load_handler( - const record_t* record, - void* varg) { +static int load_records( + semanage_handle_t* handle, + dbase_config_t* dst, + record_t** records, + unsigned int nrecords, + int mode) { + unsigned int i; record_key_t* rkey = NULL; - load_handler_arg_t* arg = - (load_handler_arg_t*) varg; - semanage_handle_t* handle = arg->handle; - dbase_t* dbase = arg->dconfig->dbase; - dbase_table_t* dtable = arg->dconfig->dtable; + dbase_t* dbase = dst->dbase; + dbase_table_t* dtable = dst->dtable; record_table_t* rtable = dtable->get_rtable(dbase); - if (rtable->key_extract(handle, record, &rkey) < 0) - goto err; + for (i = 0; i < nrecords; i++) { + + /* Possibly obsoleted */ + if (!records[i]) + continue; - switch (arg->mode) { - - case MODE_SET: - if (dtable->set(handle, dbase, rkey, record) < 0) - goto err; - break; + if (rtable->key_extract(handle, records[i], &rkey) < 0) + goto err; + + if (mode & MODE_SET && + dtable->set(handle, dbase, rkey, records[i]) < 0) + goto err; - default: - case MODE_MODIFY: - if (dtable->modify(handle, dbase, rkey, record) < 0) - goto err; - break; + else if (mode & MODE_MODIFY && + dtable->modify(handle, dbase, rkey, records[i]) < 0) + goto err; + rtable->key_free(rkey); } - rtable->key_free(rkey); - return 0; + return STATUS_SUCCESS; err: /* FIXME: handle error */ rtable->key_free(rkey); - return -1; + return STATUS_ERR; } typedef struct load_table { - dbase_config_t* from; - dbase_config_t* to; + dbase_config_t* src; + dbase_config_t* dst; int mode; } load_table_t; @@ -120,7 +113,8 @@ typedef struct load_table { int semanage_base_merge_components( semanage_handle_t* handle) { - int i; + unsigned int i,j; + int rc = STATUS_SUCCESS; /* Order is important here - change things carefully. * System components first, local next. Verify runs with @@ -149,39 +143,60 @@ int semanage_base_merge_components( semanage_seuser_dbase_policy(handle), MODE_MODIFY }, { semanage_node_dbase_local(handle), - semanage_node_dbase_policy(handle), MODE_MODIFY }, + semanage_node_dbase_policy(handle), MODE_MODIFY | MODE_SORT }, }; - const int CCOUNT = sizeof(components)/sizeof(components[0]); - - load_handler_arg_t load_arg; - load_arg.handle = handle; + const unsigned int CCOUNT = sizeof(components)/sizeof(components[0]); /* Merge components into policy (and validate) */ for (i = 0; i < CCOUNT; i++) { - dbase_config_t* from = components[i].from; - dbase_config_t* to = components[i].to; - load_arg.dconfig = to; - load_arg.mode = components[i].mode; + + record_t** records = NULL; + unsigned int nrecords = 0; + + dbase_config_t* src = components[i].src; + dbase_config_t* dst = components[i].dst; + int mode = components[i].mode; + record_table_t* rtable = src->dtable->get_rtable(src->dbase); /* Must invoke cache function first */ - if (from->dtable->cache(handle, from->dbase) < 0) + if (src->dtable->cache(handle, src->dbase) < 0) goto err; - - if (to->dtable->cache(handle, to->dbase) < 0) + if (dst->dtable->cache(handle, dst->dbase) < 0) goto err; - /* Clear obsolete items for MODE_SET */ - if (components[i].mode == MODE_SET) - if (clear_obsolete(handle, from, to) < 0) - goto err; - - /* Now iterate */ - if (from->dtable->iterate( - handle, from->dbase, load_handler, &load_arg) < 0) + /* List all records */ + if (src->dtable->list(handle, src->dbase, + &records, &nrecords) < 0) goto err; + + /* Sort records on MODE_SORT */ + if (mode & MODE_SORT) { + qsort(records, nrecords, sizeof(record_t*), + (int (*) (const void*, const void*)) rtable->compare2_qsort); + } + + /* Clear obsolete ones for MODE_SET */ + if (mode & MODE_SET && + clear_obsolete(handle, records, nrecords, src, dst) < 0) { + rc = STATUS_ERR; + goto dbase_exit; + } + + /* Load records */ + if (load_records(handle, dst, records, nrecords, mode) < 0) { + + rc = STATUS_ERR; + goto dbase_exit; + } + + /* Cleanup */ + dbase_exit: + for (j = 0; j < nrecords; j++) + rtable->free(records[j]); + free(records); } - return STATUS_SUCCESS; + return rc; err: ERR(handle, "could not merge local modifications into policy"); diff -Naurp --exclude-from excludes old/libsepol/include/sepol/policydb/policydb.h new/libsepol/include/sepol/policydb/policydb.h --- old/libsepol/include/sepol/policydb/policydb.h 2006-02-16 02:04:52.000000000 -0500 +++ new/libsepol/include/sepol/policydb/policydb.h 2006-02-16 02:04:29.000000000 -0500 @@ -152,7 +152,6 @@ typedef struct user_datum { typedef struct level_datum { mls_level_t *level; /* sensitivity and associated categories */ unsigned char isalias; /* is this sensitivity an alias for another? */ - unsigned char defined; } level_datum_t; /* Category attributes */ diff -Naurp --exclude-from excludes old/libsepol/src/node_record.c new/libsepol/src/node_record.c --- old/libsepol/src/node_record.c 2006-02-16 02:04:52.000000000 -0500 +++ new/libsepol/src/node_record.c 2006-02-16 02:00:20.000000000 -0500 @@ -147,8 +147,8 @@ static int node_expand_addr( { struct in_addr addr; memset(&addr, 0, sizeof(struct in_addr)); - addr.s_addr = addr_bytes[0]; - + memcpy(&addr.s_addr, addr_bytes, 4); + if (inet_ntop(AF_INET, &addr, addr_str, INET_ADDRSTRLEN) == NULL) { @@ -337,7 +337,7 @@ int sepol_node_compare( rc1 = memcmp(node->addr, key->addr, node->addr_sz); rc2 = memcmp(node->mask, key->mask, node->mask_sz); - return (rc1 != 0)? rc1: rc2; + return (rc2 != 0)? rc2: rc1; } int sepol_node_compare2( @@ -357,7 +357,7 @@ int sepol_node_compare2( rc1 = memcmp(node->addr, node2->addr, node->addr_sz); rc2 = memcmp(node->mask, node2->mask, node->mask_sz); - return (rc1 != 0)? rc1: rc2; + return (rc2 != 0)? rc2: rc1; } /* Addr */ --------------070500000404030009000307-- -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message.