policydb.c revision 4ebc669d5dc59771284b2d61eb4cce53e6a7069e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */ 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Support for enhanced MLS infrastructure. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Added conditional policy language extensions 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Updated: Red Hat, Inc. James Morris <jmorris@redhat.com> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Fine-grained netlink support 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * IPv6 support 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * Code cleanup 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * Copyright (C) 2003 - 2005 Tresys Technology, LLC 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2003 - 2007 Red Hat, Inc. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This library is free software; you can redistribute it and/or 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modify it under the terms of the GNU Lesser General Public 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * License as published by the Free Software Foundation; either 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * version 2.1 of the License, or (at your option) any later version. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This library is distributed in the hope that it will be useful, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Lesser General Public License for more details. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * You should have received a copy of the GNU Lesser General Public 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * License along with this library; if not, write to the Free Software 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* FLASK */ 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Implementation of the policy database. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sepol/policydb/policydb.h> 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sepol/policydb/expand.h> 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sepol/policydb/conditional.h> 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sepol/policydb/avrule_block.h> 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sepol/policydb/util.h> 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sepol/policydb/flask.h> 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "private.h" 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "debug.h" 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "mls.h" 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define POLICYDB_TARGET_SZ ARRAY_SIZE(policydb_target_strings) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char *policydb_target_strings[] = { POLICYDB_STRING, POLICYDB_XEN_STRING }; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* These need to be updated if SYM_NUM or OCON_NUM changes */ 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct policydb_compat_info policydb_compat[] = { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_KERN, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = POLICYDB_VERSION_BOUNDARY, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_XEN_PCIDEVICE + 1, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_XEN, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_KERN, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = POLICYDB_VERSION_BASE, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM - 3, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_FSUSE + 1, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_KERN, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = POLICYDB_VERSION_BOOL, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM - 2, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_FSUSE + 1, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_KERN, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = POLICYDB_VERSION_IPV6, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM - 2, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_KERN, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = POLICYDB_VERSION_NLCLASS, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM - 2, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_KERN, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = POLICYDB_VERSION_MLS, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_KERN, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = POLICYDB_VERSION_AVTAB, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_KERN, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = POLICYDB_VERSION_RANGETRANS, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_KERN, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = POLICYDB_VERSION_POLCAP, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_KERN, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = POLICYDB_VERSION_PERMISSIVE, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_KERN, 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = POLICYDB_VERSION_BOUNDARY, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_KERN, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = POLICYDB_VERSION_FILENAME_TRANS, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_KERN, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = POLICYDB_VERSION_ROLETRANS, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_KERN, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_BASE, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_BASE, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_BASE, 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_MLS, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .type = POLICY_BASE, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_MLS_USERS, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_BASE, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_POLCAP, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_BASE, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_PERMISSIVE, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_BASE, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_BOUNDARY, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_BASE, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_BOUNDARY_ALIAS, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_BASE, 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_FILENAME_TRANS, 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_BASE, 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_ROLETRANS, 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_BASE, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_ROLEATTRIB, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_BASE, 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_TUNABLE_SEP, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_BASE, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = OCON_NODE6 + 1, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_MOD, 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_BASE, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = 0, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_MOD, 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_MLS, 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .sym_num = SYM_NUM, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = 0, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .type = POLICY_MOD, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_MLS_USERS, 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = 0, 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_MOD, 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_POLCAP, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = 0, 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_MOD, 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_PERMISSIVE, 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = 0, 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_MOD, 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_BOUNDARY, 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = 0, 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_MOD, 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_BOUNDARY_ALIAS, 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = 0, 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_MOD, 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_FILENAME_TRANS, 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = 0, 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_MOD, 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_ROLETRANS, 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = 0, 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_MOD, 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_ROLEATTRIB, 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = 0, 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_MOD, 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_TUNABLE_SEP, 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = 0, 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .type = POLICY_MOD, 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .sym_num = SYM_NUM, 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .ocon_num = 0, 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .target_platform = SEPOL_TARGET_SELINUX, 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static char *symtab_name[SYM_NUM] = { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "common prefixes", 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classes", 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "roles", 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "types", 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "users", 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bools" mls_symtab_names cond_symtab_names 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned int symtab_sizes[SYM_NUM] = { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2, 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32, 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16, 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 512, 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 128, 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16, 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16, 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16, 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct policydb_compat_info *policydb_lookup_compat(unsigned int version, 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int type, 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int target_platform) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int i; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct policydb_compat_info *info = NULL; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < sizeof(policydb_compat) / sizeof(*info); i++) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (policydb_compat[i].version == version && 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policydb_compat[i].type == type && 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policydb_compat[i].target_platform == target_platform) { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info = &policydb_compat[i]; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return info; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void type_set_init(type_set_t * x) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(x, 0, sizeof(type_set_t)); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_init(&x->types); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_init(&x->negset); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void type_set_destroy(type_set_t * x) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (x != NULL) { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_destroy(&x->types); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_destroy(&x->negset); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void role_set_init(role_set_t * x) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(x, 0, sizeof(role_set_t)); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_init(&x->roles); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void role_set_destroy(role_set_t * x) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_destroy(&x->roles); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void role_datum_init(role_datum_t * x) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(x, 0, sizeof(role_datum_t)); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_init(&x->dominates); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_set_init(&x->types); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_init(&x->cache); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_init(&x->roles); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void role_datum_destroy(role_datum_t * x) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (x != NULL) { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_destroy(&x->dominates); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_set_destroy(&x->types); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_destroy(&x->cache); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_destroy(&x->roles); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void type_datum_init(type_datum_t * x) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(x, 0, sizeof(*x)); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_init(&x->types); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void type_datum_destroy(type_datum_t * x) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (x != NULL) { 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_destroy(&x->types); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void user_datum_init(user_datum_t * x) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(x, 0, sizeof(user_datum_t)); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) role_set_init(&x->roles); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mls_semantic_range_init(&x->range); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mls_semantic_level_init(&x->dfltlevel); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_init(&x->cache); 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mls_range_init(&x->exp_range); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mls_level_init(&x->exp_dfltlevel); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void user_datum_destroy(user_datum_t * x) 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (x != NULL) { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) role_set_destroy(&x->roles); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mls_semantic_range_destroy(&x->range); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mls_semantic_level_destroy(&x->dfltlevel); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_destroy(&x->cache); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mls_range_destroy(&x->exp_range); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mls_level_destroy(&x->exp_dfltlevel); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void level_datum_init(level_datum_t * x) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(x, 0, sizeof(level_datum_t)); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void level_datum_destroy(level_datum_t * x __attribute__ ((unused))) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* the mls_level_t referenced by the level_datum is managed 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * separately for now, so there is nothing to destroy */ 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void cat_datum_init(cat_datum_t * x) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(x, 0, sizeof(cat_datum_t)); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void cat_datum_destroy(cat_datum_t * x __attribute__ ((unused))) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* it's currently a simple struct - really nothing to destroy */ 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void class_perm_node_init(class_perm_node_t * x) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(x, 0, sizeof(class_perm_node_t)); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void avrule_init(avrule_t * x) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(x, 0, sizeof(avrule_t)); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_set_init(&x->stypes); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_set_init(&x->ttypes); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void avrule_destroy(avrule_t * x) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class_perm_node_t *cur, *next; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (x == NULL) { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_set_destroy(&x->stypes); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_set_destroy(&x->ttypes); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = x->perms; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (next) { 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = next; 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = cur->next; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(cur); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void role_trans_rule_init(role_trans_rule_t * x) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(x, 0, sizeof(*x)); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) role_set_init(&x->roles); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_set_init(&x->types); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_init(&x->classes); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void role_trans_rule_destroy(role_trans_rule_t * x) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (x != NULL) { 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) role_set_destroy(&x->roles); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_set_destroy(&x->types); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ebitmap_destroy(&x->classes); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void role_trans_rule_list_destroy(role_trans_rule_t * x) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (x != NULL) { 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) role_trans_rule_t *next = x->next; 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) role_trans_rule_destroy(x); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(x); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = next; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void filename_trans_rule_init(filename_trans_rule_t * x) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(x, 0, sizeof(*x)); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_set_init(&x->stypes); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_set_init(&x->ttypes); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void filename_trans_rule_destroy(filename_trans_rule_t * x) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!x) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_set_destroy(&x->stypes); 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type_set_destroy(&x->ttypes); 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) free(x->name); 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void filename_trans_rule_list_destroy(filename_trans_rule_t * x) 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) filename_trans_rule_t *next; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (x) { 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = x->next; 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) filename_trans_rule_destroy(x); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(x); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x = next; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 557 558void role_allow_rule_init(role_allow_rule_t * x) 559{ 560 memset(x, 0, sizeof(role_allow_rule_t)); 561 role_set_init(&x->roles); 562 role_set_init(&x->new_roles); 563} 564 565void role_allow_rule_destroy(role_allow_rule_t * x) 566{ 567 role_set_destroy(&x->roles); 568 role_set_destroy(&x->new_roles); 569} 570 571void role_allow_rule_list_destroy(role_allow_rule_t * x) 572{ 573 while (x != NULL) { 574 role_allow_rule_t *next = x->next; 575 role_allow_rule_destroy(x); 576 free(x); 577 x = next; 578 } 579} 580 581void range_trans_rule_init(range_trans_rule_t * x) 582{ 583 type_set_init(&x->stypes); 584 type_set_init(&x->ttypes); 585 ebitmap_init(&x->tclasses); 586 mls_semantic_range_init(&x->trange); 587 x->next = NULL; 588} 589 590void range_trans_rule_destroy(range_trans_rule_t * x) 591{ 592 type_set_destroy(&x->stypes); 593 type_set_destroy(&x->ttypes); 594 ebitmap_destroy(&x->tclasses); 595 mls_semantic_range_destroy(&x->trange); 596} 597 598void range_trans_rule_list_destroy(range_trans_rule_t * x) 599{ 600 while (x != NULL) { 601 range_trans_rule_t *next = x->next; 602 range_trans_rule_destroy(x); 603 free(x); 604 x = next; 605 } 606} 607 608void avrule_list_destroy(avrule_t * x) 609{ 610 avrule_t *next, *cur; 611 612 if (!x) 613 return; 614 615 next = x; 616 while (next) { 617 cur = next; 618 next = next->next; 619 avrule_destroy(cur); 620 free(cur); 621 } 622} 623 624/* 625 * Initialize the role table by implicitly adding role 'object_r'. If 626 * the policy is a module, set object_r's scope to be SCOPE_REQ, 627 * otherwise set it to SCOPE_DECL. 628 */ 629static int roles_init(policydb_t * p) 630{ 631 char *key = 0; 632 int rc; 633 role_datum_t *role; 634 635 role = calloc(1, sizeof(role_datum_t)); 636 if (!role) { 637 rc = -ENOMEM; 638 goto out; 639 } 640 key = malloc(strlen(OBJECT_R) + 1); 641 if (!key) { 642 rc = -ENOMEM; 643 goto out_free_role; 644 } 645 strcpy(key, OBJECT_R); 646 rc = symtab_insert(p, SYM_ROLES, key, role, 647 (p->policy_type == 648 POLICY_MOD ? SCOPE_REQ : SCOPE_DECL), 1, 649 &role->s.value); 650 if (rc) 651 goto out_free_key; 652 if (role->s.value != OBJECT_R_VAL) { 653 rc = -EINVAL; 654 goto out_free_role; 655 } 656 out: 657 return rc; 658 659 out_free_key: 660 free(key); 661 out_free_role: 662 free(role); 663 goto out; 664} 665 666/* 667 * Initialize a policy database structure. 668 */ 669int policydb_init(policydb_t * p) 670{ 671 int i, rc; 672 673 memset(p, 0, sizeof(policydb_t)); 674 675 ebitmap_init(&p->policycaps); 676 677 ebitmap_init(&p->permissive_map); 678 679 for (i = 0; i < SYM_NUM; i++) { 680 p->sym_val_to_name[i] = NULL; 681 rc = symtab_init(&p->symtab[i], symtab_sizes[i]); 682 if (rc) 683 goto out_free_symtab; 684 } 685 686 /* initialize the module stuff */ 687 for (i = 0; i < SYM_NUM; i++) { 688 if (symtab_init(&p->scope[i], symtab_sizes[i])) { 689 goto out_free_symtab; 690 } 691 } 692 if ((p->global = avrule_block_create()) == NULL || 693 (p->global->branch_list = avrule_decl_create(1)) == NULL) { 694 goto out_free_symtab; 695 } 696 p->decl_val_to_struct = NULL; 697 698 rc = avtab_init(&p->te_avtab); 699 if (rc) 700 goto out_free_symtab; 701 702 rc = roles_init(p); 703 if (rc) 704 goto out_free_symtab; 705 706 rc = cond_policydb_init(p); 707 if (rc) 708 goto out_free_symtab; 709 out: 710 return rc; 711 712 out_free_symtab: 713 for (i = 0; i < SYM_NUM; i++) { 714 hashtab_destroy(p->symtab[i].table); 715 hashtab_destroy(p->scope[i].table); 716 } 717 avrule_block_list_destroy(p->global); 718 goto out; 719} 720 721int policydb_role_cache(hashtab_key_t key 722 __attribute__ ((unused)), hashtab_datum_t datum, 723 void *arg) 724{ 725 policydb_t *p; 726 role_datum_t *role; 727 728 role = (role_datum_t *) datum; 729 p = (policydb_t *) arg; 730 731 ebitmap_destroy(&role->cache); 732 if (type_set_expand(&role->types, &role->cache, p, 1)) { 733 return -1; 734 } 735 736 return 0; 737} 738 739int policydb_user_cache(hashtab_key_t key 740 __attribute__ ((unused)), hashtab_datum_t datum, 741 void *arg) 742{ 743 policydb_t *p; 744 user_datum_t *user; 745 746 user = (user_datum_t *) datum; 747 p = (policydb_t *) arg; 748 749 ebitmap_destroy(&user->cache); 750 if (role_set_expand(&user->roles, &user->cache, p, NULL, NULL)) { 751 return -1; 752 } 753 754 /* we do not expand user's MLS info in kernel policies because the 755 * semantic representation is not present and we do not expand user's 756 * MLS info in module policies because all of the necessary mls 757 * information is not present */ 758 if (p->policy_type != POLICY_KERN && p->policy_type != POLICY_MOD) { 759 mls_range_destroy(&user->exp_range); 760 if (mls_semantic_range_expand(&user->range, 761 &user->exp_range, p, NULL)) { 762 return -1; 763 } 764 765 mls_level_destroy(&user->exp_dfltlevel); 766 if (mls_semantic_level_expand(&user->dfltlevel, 767 &user->exp_dfltlevel, p, NULL)) { 768 return -1; 769 } 770 } 771 772 return 0; 773} 774 775/* 776 * The following *_index functions are used to 777 * define the val_to_name and val_to_struct arrays 778 * in a policy database structure. The val_to_name 779 * arrays are used when converting security context 780 * structures into string representations. The 781 * val_to_struct arrays are used when the attributes 782 * of a class, role, or user are needed. 783 */ 784 785static int common_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) 786{ 787 policydb_t *p; 788 common_datum_t *comdatum; 789 790 comdatum = (common_datum_t *) datum; 791 p = (policydb_t *) datap; 792 if (!comdatum->s.value || comdatum->s.value > p->p_commons.nprim) 793 return -EINVAL; 794 p->p_common_val_to_name[comdatum->s.value - 1] = (char *)key; 795 796 return 0; 797} 798 799static int class_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) 800{ 801 policydb_t *p; 802 class_datum_t *cladatum; 803 804 cladatum = (class_datum_t *) datum; 805 p = (policydb_t *) datap; 806 if (!cladatum->s.value || cladatum->s.value > p->p_classes.nprim) 807 return -EINVAL; 808 p->p_class_val_to_name[cladatum->s.value - 1] = (char *)key; 809 p->class_val_to_struct[cladatum->s.value - 1] = cladatum; 810 811 return 0; 812} 813 814static int role_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) 815{ 816 policydb_t *p; 817 role_datum_t *role; 818 819 role = (role_datum_t *) datum; 820 p = (policydb_t *) datap; 821 if (!role->s.value || role->s.value > p->p_roles.nprim) 822 return -EINVAL; 823 p->p_role_val_to_name[role->s.value - 1] = (char *)key; 824 p->role_val_to_struct[role->s.value - 1] = role; 825 826 return 0; 827} 828 829static int type_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) 830{ 831 policydb_t *p; 832 type_datum_t *typdatum; 833 834 typdatum = (type_datum_t *) datum; 835 p = (policydb_t *) datap; 836 837 if (typdatum->primary) { 838 if (!typdatum->s.value || typdatum->s.value > p->p_types.nprim) 839 return -EINVAL; 840 p->p_type_val_to_name[typdatum->s.value - 1] = (char *)key; 841 p->type_val_to_struct[typdatum->s.value - 1] = typdatum; 842 } 843 844 return 0; 845} 846 847static int user_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) 848{ 849 policydb_t *p; 850 user_datum_t *usrdatum; 851 852 usrdatum = (user_datum_t *) datum; 853 p = (policydb_t *) datap; 854 855 if (!usrdatum->s.value || usrdatum->s.value > p->p_users.nprim) 856 return -EINVAL; 857 858 p->p_user_val_to_name[usrdatum->s.value - 1] = (char *)key; 859 p->user_val_to_struct[usrdatum->s.value - 1] = usrdatum; 860 861 return 0; 862} 863 864static int sens_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) 865{ 866 policydb_t *p; 867 level_datum_t *levdatum; 868 869 levdatum = (level_datum_t *) datum; 870 p = (policydb_t *) datap; 871 872 if (!levdatum->isalias) { 873 if (!levdatum->level->sens || 874 levdatum->level->sens > p->p_levels.nprim) 875 return -EINVAL; 876 p->p_sens_val_to_name[levdatum->level->sens - 1] = (char *)key; 877 } 878 879 return 0; 880} 881 882static int cat_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) 883{ 884 policydb_t *p; 885 cat_datum_t *catdatum; 886 887 catdatum = (cat_datum_t *) datum; 888 p = (policydb_t *) datap; 889 890 if (!catdatum->isalias) { 891 if (!catdatum->s.value || catdatum->s.value > p->p_cats.nprim) 892 return -EINVAL; 893 p->p_cat_val_to_name[catdatum->s.value - 1] = (char *)key; 894 } 895 896 return 0; 897} 898 899static int (*index_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, 900 void *datap) = { 901common_index, class_index, role_index, type_index, user_index, 902 cond_index_bool, sens_index, cat_index,}; 903 904/* 905 * Define the common val_to_name array and the class 906 * val_to_name and val_to_struct arrays in a policy 907 * database structure. 908 */ 909int policydb_index_classes(policydb_t * p) 910{ 911 free(p->p_common_val_to_name); 912 p->p_common_val_to_name = (char **) 913 malloc(p->p_commons.nprim * sizeof(char *)); 914 if (!p->p_common_val_to_name) 915 return -1; 916 917 if (hashtab_map(p->p_commons.table, common_index, p)) 918 return -1; 919 920 free(p->class_val_to_struct); 921 p->class_val_to_struct = (class_datum_t **) 922 malloc(p->p_classes.nprim * sizeof(class_datum_t *)); 923 if (!p->class_val_to_struct) 924 return -1; 925 926 free(p->p_class_val_to_name); 927 p->p_class_val_to_name = (char **) 928 malloc(p->p_classes.nprim * sizeof(char *)); 929 if (!p->p_class_val_to_name) 930 return -1; 931 932 if (hashtab_map(p->p_classes.table, class_index, p)) 933 return -1; 934 935 return 0; 936} 937 938int policydb_index_bools(policydb_t * p) 939{ 940 941 if (cond_init_bool_indexes(p) == -1) 942 return -1; 943 p->p_bool_val_to_name = (char **) 944 malloc(p->p_bools.nprim * sizeof(char *)); 945 if (!p->p_bool_val_to_name) 946 return -1; 947 if (hashtab_map(p->p_bools.table, cond_index_bool, p)) 948 return -1; 949 return 0; 950} 951 952int policydb_index_decls(policydb_t * p) 953{ 954 avrule_block_t *curblock; 955 avrule_decl_t *decl; 956 int num_decls = 0; 957 958 free(p->decl_val_to_struct); 959 960 for (curblock = p->global; curblock != NULL; curblock = curblock->next) { 961 for (decl = curblock->branch_list; decl != NULL; 962 decl = decl->next) { 963 num_decls++; 964 } 965 } 966 967 p->decl_val_to_struct = 968 calloc(num_decls, sizeof(*(p->decl_val_to_struct))); 969 if (!p->decl_val_to_struct) { 970 return -1; 971 } 972 973 for (curblock = p->global; curblock != NULL; curblock = curblock->next) { 974 for (decl = curblock->branch_list; decl != NULL; 975 decl = decl->next) { 976 p->decl_val_to_struct[decl->decl_id - 1] = decl; 977 } 978 } 979 980 return 0; 981} 982 983/* 984 * Define the other val_to_name and val_to_struct arrays 985 * in a policy database structure. 986 */ 987int policydb_index_others(sepol_handle_t * handle, 988 policydb_t * p, unsigned verbose) 989{ 990 int i; 991 992 if (verbose) { 993 INFO(handle, 994 "security: %d users, %d roles, %d types, %d bools", 995 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, 996 p->p_bools.nprim); 997 998 if (p->mls) 999 INFO(handle, "security: %d sens, %d cats", 1000 p->p_levels.nprim, p->p_cats.nprim); 1001 1002 INFO(handle, "security: %d classes, %d rules, %d cond rules", 1003 p->p_classes.nprim, p->te_avtab.nel, p->te_cond_avtab.nel); 1004 } 1005#if 0 1006 avtab_hash_eval(&p->te_avtab, "rules"); 1007 for (i = 0; i < SYM_NUM; i++) 1008 hashtab_hash_eval(p->symtab[i].table, symtab_name[i]); 1009#endif 1010 1011 free(p->role_val_to_struct); 1012 p->role_val_to_struct = (role_datum_t **) 1013 malloc(p->p_roles.nprim * sizeof(role_datum_t *)); 1014 if (!p->role_val_to_struct) 1015 return -1; 1016 1017 free(p->user_val_to_struct); 1018 p->user_val_to_struct = (user_datum_t **) 1019 malloc(p->p_users.nprim * sizeof(user_datum_t *)); 1020 if (!p->user_val_to_struct) 1021 return -1; 1022 1023 free(p->type_val_to_struct); 1024 p->type_val_to_struct = (type_datum_t **) 1025 calloc(p->p_types.nprim, sizeof(type_datum_t *)); 1026 if (!p->type_val_to_struct) 1027 return -1; 1028 1029 cond_init_bool_indexes(p); 1030 1031 for (i = SYM_ROLES; i < SYM_NUM; i++) { 1032 free(p->sym_val_to_name[i]); 1033 p->sym_val_to_name[i] = NULL; 1034 if (p->symtab[i].nprim) { 1035 p->sym_val_to_name[i] = (char **) 1036 calloc(p->symtab[i].nprim, sizeof(char *)); 1037 if (!p->sym_val_to_name[i]) 1038 return -1; 1039 if (hashtab_map(p->symtab[i].table, index_f[i], p)) 1040 return -1; 1041 } 1042 } 1043 1044 /* This pre-expands the roles and users for context validity checking */ 1045 if (hashtab_map(p->p_roles.table, policydb_role_cache, p)) 1046 return -1; 1047 1048 if (hashtab_map(p->p_users.table, policydb_user_cache, p)) 1049 return -1; 1050 1051 return 0; 1052} 1053 1054/* 1055 * The following *_destroy functions are used to 1056 * free any memory allocated for each kind of 1057 * symbol data in the policy database. 1058 */ 1059 1060static int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1061 __attribute__ ((unused))) 1062{ 1063 if (key) 1064 free(key); 1065 free(datum); 1066 return 0; 1067} 1068 1069static int common_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1070 __attribute__ ((unused))) 1071{ 1072 common_datum_t *comdatum; 1073 1074 if (key) 1075 free(key); 1076 comdatum = (common_datum_t *) datum; 1077 hashtab_map(comdatum->permissions.table, perm_destroy, 0); 1078 hashtab_destroy(comdatum->permissions.table); 1079 free(datum); 1080 return 0; 1081} 1082 1083static int class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1084 __attribute__ ((unused))) 1085{ 1086 class_datum_t *cladatum; 1087 constraint_node_t *constraint, *ctemp; 1088 constraint_expr_t *e, *etmp; 1089 1090 if (key) 1091 free(key); 1092 cladatum = (class_datum_t *) datum; 1093 if (cladatum == NULL) { 1094 return 0; 1095 } 1096 hashtab_map(cladatum->permissions.table, perm_destroy, 0); 1097 hashtab_destroy(cladatum->permissions.table); 1098 constraint = cladatum->constraints; 1099 while (constraint) { 1100 e = constraint->expr; 1101 while (e) { 1102 etmp = e; 1103 e = e->next; 1104 constraint_expr_destroy(etmp); 1105 } 1106 ctemp = constraint; 1107 constraint = constraint->next; 1108 free(ctemp); 1109 } 1110 1111 constraint = cladatum->validatetrans; 1112 while (constraint) { 1113 e = constraint->expr; 1114 while (e) { 1115 etmp = e; 1116 e = e->next; 1117 constraint_expr_destroy(etmp); 1118 } 1119 ctemp = constraint; 1120 constraint = constraint->next; 1121 free(ctemp); 1122 } 1123 1124 if (cladatum->comkey) 1125 free(cladatum->comkey); 1126 free(datum); 1127 return 0; 1128} 1129 1130static int role_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1131 __attribute__ ((unused))) 1132{ 1133 free(key); 1134 role_datum_destroy((role_datum_t *) datum); 1135 free(datum); 1136 return 0; 1137} 1138 1139static int type_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1140 __attribute__ ((unused))) 1141{ 1142 free(key); 1143 type_datum_destroy((type_datum_t *) datum); 1144 free(datum); 1145 return 0; 1146} 1147 1148static int user_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1149 __attribute__ ((unused))) 1150{ 1151 free(key); 1152 user_datum_destroy((user_datum_t *) datum); 1153 free(datum); 1154 return 0; 1155} 1156 1157static int sens_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1158 __attribute__ ((unused))) 1159{ 1160 level_datum_t *levdatum; 1161 1162 if (key) 1163 free(key); 1164 levdatum = (level_datum_t *) datum; 1165 mls_level_destroy(levdatum->level); 1166 free(levdatum->level); 1167 level_datum_destroy(levdatum); 1168 free(levdatum); 1169 return 0; 1170} 1171 1172static int cat_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1173 __attribute__ ((unused))) 1174{ 1175 if (key) 1176 free(key); 1177 cat_datum_destroy((cat_datum_t *) datum); 1178 free(datum); 1179 return 0; 1180} 1181 1182static int (*destroy_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, 1183 void *datap) = { 1184common_destroy, class_destroy, role_destroy, type_destroy, user_destroy, 1185 cond_destroy_bool, sens_destroy, cat_destroy,}; 1186 1187void ocontext_selinux_free(ocontext_t **ocontexts) 1188{ 1189 ocontext_t *c, *ctmp; 1190 int i; 1191 1192 for (i = 0; i < OCON_NUM; i++) { 1193 c = ocontexts[i]; 1194 while (c) { 1195 ctmp = c; 1196 c = c->next; 1197 context_destroy(&ctmp->context[0]); 1198 context_destroy(&ctmp->context[1]); 1199 if (i == OCON_ISID || i == OCON_FS || i == OCON_NETIF 1200 || i == OCON_FSUSE) 1201 free(ctmp->u.name); 1202 free(ctmp); 1203 } 1204 } 1205} 1206 1207void ocontext_xen_free(ocontext_t **ocontexts) 1208{ 1209 ocontext_t *c, *ctmp; 1210 int i; 1211 1212 for (i = 0; i < OCON_NUM; i++) { 1213 c = ocontexts[i]; 1214 while (c) { 1215 ctmp = c; 1216 c = c->next; 1217 context_destroy(&ctmp->context[0]); 1218 context_destroy(&ctmp->context[1]); 1219 if (i == OCON_ISID) 1220 free(ctmp->u.name); 1221 free(ctmp); 1222 } 1223 } 1224} 1225 1226/* 1227 * Free any memory allocated by a policy database structure. 1228 */ 1229void policydb_destroy(policydb_t * p) 1230{ 1231 ocontext_t *c, *ctmp; 1232 genfs_t *g, *gtmp; 1233 unsigned int i; 1234 role_allow_t *ra, *lra = NULL; 1235 role_trans_t *tr, *ltr = NULL; 1236 range_trans_t *rt, *lrt = NULL; 1237 filename_trans_t *ft, *nft; 1238 1239 if (!p) 1240 return; 1241 1242 ebitmap_destroy(&p->policycaps); 1243 1244 ebitmap_destroy(&p->permissive_map); 1245 1246 symtabs_destroy(p->symtab); 1247 1248 for (i = 0; i < SYM_NUM; i++) { 1249 if (p->sym_val_to_name[i]) 1250 free(p->sym_val_to_name[i]); 1251 } 1252 1253 if (p->class_val_to_struct) 1254 free(p->class_val_to_struct); 1255 if (p->role_val_to_struct) 1256 free(p->role_val_to_struct); 1257 if (p->user_val_to_struct) 1258 free(p->user_val_to_struct); 1259 if (p->type_val_to_struct) 1260 free(p->type_val_to_struct); 1261 free(p->decl_val_to_struct); 1262 1263 for (i = 0; i < SYM_NUM; i++) { 1264 hashtab_map(p->scope[i].table, scope_destroy, 0); 1265 hashtab_destroy(p->scope[i].table); 1266 } 1267 avrule_block_list_destroy(p->global); 1268 free(p->name); 1269 free(p->version); 1270 1271 avtab_destroy(&p->te_avtab); 1272 1273 if (p->target_platform == SEPOL_TARGET_SELINUX) 1274 ocontext_selinux_free(p->ocontexts); 1275 else if (p->target_platform == SEPOL_TARGET_XEN) 1276 ocontext_xen_free(p->ocontexts); 1277 1278 g = p->genfs; 1279 while (g) { 1280 free(g->fstype); 1281 c = g->head; 1282 while (c) { 1283 ctmp = c; 1284 c = c->next; 1285 context_destroy(&ctmp->context[0]); 1286 free(ctmp->u.name); 1287 free(ctmp); 1288 } 1289 gtmp = g; 1290 g = g->next; 1291 free(gtmp); 1292 } 1293 cond_policydb_destroy(p); 1294 1295 for (tr = p->role_tr; tr; tr = tr->next) { 1296 if (ltr) 1297 free(ltr); 1298 ltr = tr; 1299 } 1300 if (ltr) 1301 free(ltr); 1302 1303 ft = p->filename_trans; 1304 while (ft) { 1305 nft = ft->next; 1306 free(ft->name); 1307 free(ft); 1308 ft = nft; 1309 } 1310 1311 for (ra = p->role_allow; ra; ra = ra->next) { 1312 if (lra) 1313 free(lra); 1314 lra = ra; 1315 } 1316 if (lra) 1317 free(lra); 1318 1319 for (rt = p->range_tr; rt; rt = rt->next) { 1320 if (lrt) { 1321 ebitmap_destroy(&lrt->target_range.level[0].cat); 1322 ebitmap_destroy(&lrt->target_range.level[1].cat); 1323 free(lrt); 1324 } 1325 lrt = rt; 1326 } 1327 if (lrt) { 1328 ebitmap_destroy(&lrt->target_range.level[0].cat); 1329 ebitmap_destroy(&lrt->target_range.level[1].cat); 1330 free(lrt); 1331 } 1332 1333 if (p->type_attr_map) { 1334 for (i = 0; i < p->p_types.nprim; i++) { 1335 ebitmap_destroy(&p->type_attr_map[i]); 1336 } 1337 free(p->type_attr_map); 1338 } 1339 1340 if (p->attr_type_map) { 1341 for (i = 0; i < p->p_types.nprim; i++) { 1342 ebitmap_destroy(&p->attr_type_map[i]); 1343 } 1344 free(p->attr_type_map); 1345 } 1346 1347 return; 1348} 1349 1350void symtabs_destroy(symtab_t * symtab) 1351{ 1352 int i; 1353 for (i = 0; i < SYM_NUM; i++) { 1354 hashtab_map(symtab[i].table, destroy_f[i], 0); 1355 hashtab_destroy(symtab[i].table); 1356 } 1357} 1358 1359int scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1360 __attribute__ ((unused))) 1361{ 1362 scope_datum_t *cur = (scope_datum_t *) datum; 1363 free(key); 1364 if (cur != NULL) { 1365 free(cur->decl_ids); 1366 } 1367 free(cur); 1368 return 0; 1369} 1370 1371hashtab_destroy_func_t get_symtab_destroy_func(int sym_num) 1372{ 1373 if (sym_num < 0 || sym_num >= SYM_NUM) { 1374 return NULL; 1375 } 1376 return (hashtab_destroy_func_t) destroy_f[sym_num]; 1377} 1378 1379/* 1380 * Load the initial SIDs specified in a policy database 1381 * structure into a SID table. 1382 */ 1383int policydb_load_isids(policydb_t * p, sidtab_t * s) 1384{ 1385 ocontext_t *head, *c; 1386 1387 if (sepol_sidtab_init(s)) { 1388 ERR(NULL, "out of memory on SID table init"); 1389 return -1; 1390 } 1391 1392 head = p->ocontexts[OCON_ISID]; 1393 for (c = head; c; c = c->next) { 1394 if (!c->context[0].user) { 1395 ERR(NULL, "SID %s was never defined", c->u.name); 1396 return -1; 1397 } 1398 if (sepol_sidtab_insert(s, c->sid[0], &c->context[0])) { 1399 ERR(NULL, "unable to load initial SID %s", c->u.name); 1400 return -1; 1401 } 1402 } 1403 1404 return 0; 1405} 1406 1407/* Declare a symbol for a certain avrule_block context. Insert it 1408 * into a symbol table for a policy. This function will handle 1409 * inserting the appropriate scope information in addition to 1410 * inserting the symbol into the hash table. 1411 * 1412 * arguments: 1413 * policydb_t *pol module policy to modify 1414 * uint32_t sym the symbole table for insertion (SYM_*) 1415 * hashtab_key_t key the key for the symbol - not cloned 1416 * hashtab_datum_t data the data for the symbol - not cloned 1417 * scope scope of this symbol, either SCOPE_REQ or SCOPE_DECL 1418 * avrule_decl_id identifier for this symbol's encapsulating declaration 1419 * value (out) assigned value to the symbol (if value is not NULL) 1420 * 1421 * returns: 1422 * 0 success 1423 * 1 success, but symbol already existed as a requirement 1424 * (datum was not inserted and needs to be free()d) 1425 * -1 general error 1426 * -2 scope conflicted 1427 * -ENOMEM memory error 1428 * error codes from hashtab_insert 1429 */ 1430int symtab_insert(policydb_t * pol, uint32_t sym, 1431 hashtab_key_t key, hashtab_datum_t datum, 1432 uint32_t scope, uint32_t avrule_decl_id, uint32_t * value) 1433{ 1434 int rc, retval = 0; 1435 unsigned int i; 1436 scope_datum_t *scope_datum; 1437 1438 /* check if the symbol is already there. multiple 1439 * declarations of non-roles/non-users are illegal, but 1440 * multiple requires are allowed. */ 1441 1442 /* FIX ME - the failures after the hashtab_insert will leave 1443 * the policy in a inconsistent state. */ 1444 rc = hashtab_insert(pol->symtab[sym].table, key, datum); 1445 if (rc == SEPOL_OK) { 1446 /* if no value is passed in the symbol is not primary 1447 * (i.e. aliases) */ 1448 if (value) 1449 *value = ++pol->symtab[sym].nprim; 1450 } else if (rc == SEPOL_EEXIST) { 1451 retval = 1; /* symbol not added -- need to free() later */ 1452 } else { 1453 return rc; 1454 } 1455 1456 /* get existing scope information; if there is not one then 1457 * create it */ 1458 scope_datum = 1459 (scope_datum_t *) hashtab_search(pol->scope[sym].table, key); 1460 if (scope_datum == NULL) { 1461 hashtab_key_t key2 = strdup((char *)key); 1462 if (!key2) 1463 return -ENOMEM; 1464 if ((scope_datum = malloc(sizeof(*scope_datum))) == NULL) { 1465 free(key2); 1466 return -ENOMEM; 1467 } 1468 scope_datum->scope = scope; 1469 scope_datum->decl_ids = NULL; 1470 scope_datum->decl_ids_len = 0; 1471 if ((rc = 1472 hashtab_insert(pol->scope[sym].table, key2, 1473 scope_datum)) != 0) { 1474 free(key2); 1475 free(scope_datum); 1476 return rc; 1477 } 1478 } else if (scope_datum->scope == SCOPE_DECL && scope == SCOPE_DECL) { 1479 /* disallow multiple declarations for non-roles/users */ 1480 if (sym != SYM_ROLES && sym != SYM_USERS) { 1481 return -2; 1482 } 1483 /* Further confine that a role attribute can't have the same 1484 * name as another regular role, and a role attribute can't 1485 * be declared more than once. */ 1486 if (sym == SYM_ROLES) { 1487 role_datum_t *base_role; 1488 role_datum_t *cur_role = (role_datum_t *)datum; 1489 1490 base_role = (role_datum_t *) 1491 hashtab_search(pol->symtab[sym].table, 1492 key); 1493 assert(base_role != NULL); 1494 1495 if (!((base_role->flavor == ROLE_ROLE) && 1496 (cur_role->flavor == ROLE_ROLE))) { 1497 /* Only regular roles are allowed to have 1498 * multiple declarations. */ 1499 return -2; 1500 } 1501 } 1502 } else if (scope_datum->scope == SCOPE_REQ && scope == SCOPE_DECL) { 1503 scope_datum->scope = SCOPE_DECL; 1504 } else if (scope_datum->scope != scope) { 1505 /* This only happens in DECL then REQUIRE case, which is handled by caller */ 1506 return -2; 1507 } 1508 1509 /* search through the pre-existing list to avoid adding duplicates */ 1510 for (i = 0; i < scope_datum->decl_ids_len; i++) { 1511 if (scope_datum->decl_ids[i] == avrule_decl_id) { 1512 /* already there, so don't modify its scope */ 1513 return retval; 1514 } 1515 } 1516 1517 if (add_i_to_a(avrule_decl_id, 1518 &scope_datum->decl_ids_len, 1519 &scope_datum->decl_ids) == -1) { 1520 return -ENOMEM; 1521 } 1522 1523 return retval; 1524} 1525 1526int type_set_or(type_set_t * dst, type_set_t * a, type_set_t * b) 1527{ 1528 type_set_init(dst); 1529 1530 if (ebitmap_or(&dst->types, &a->types, &b->types)) { 1531 return -1; 1532 } 1533 if (ebitmap_or(&dst->negset, &a->negset, &b->negset)) { 1534 return -1; 1535 } 1536 1537 dst->flags |= a->flags; 1538 dst->flags |= b->flags; 1539 1540 return 0; 1541} 1542 1543int type_set_cpy(type_set_t * dst, type_set_t * src) 1544{ 1545 type_set_init(dst); 1546 1547 dst->flags = src->flags; 1548 if (ebitmap_cpy(&dst->types, &src->types)) 1549 return -1; 1550 if (ebitmap_cpy(&dst->negset, &src->negset)) 1551 return -1; 1552 1553 return 0; 1554} 1555 1556int type_set_or_eq(type_set_t * dst, type_set_t * other) 1557{ 1558 int ret; 1559 type_set_t tmp; 1560 1561 if (type_set_or(&tmp, dst, other)) 1562 return -1; 1563 type_set_destroy(dst); 1564 ret = type_set_cpy(dst, &tmp); 1565 type_set_destroy(&tmp); 1566 1567 return ret; 1568} 1569 1570int role_set_get_role(role_set_t * x, uint32_t role) 1571{ 1572 if (x->flags & ROLE_STAR) 1573 return 1; 1574 1575 if (ebitmap_get_bit(&x->roles, role - 1)) { 1576 if (x->flags & ROLE_COMP) 1577 return 0; 1578 else 1579 return 1; 1580 } else { 1581 if (x->flags & ROLE_COMP) 1582 return 1; 1583 else 1584 return 0; 1585 } 1586} 1587 1588/***********************************************************************/ 1589/* everything below is for policy reads */ 1590 1591/* The following are read functions for module structures */ 1592 1593static int role_set_read(role_set_t * r, struct policy_file *fp) 1594{ 1595 uint32_t buf[1]; 1596 int rc; 1597 1598 if (ebitmap_read(&r->roles, fp)) 1599 return -1; 1600 rc = next_entry(buf, fp, sizeof(uint32_t)); 1601 if (rc < 0) 1602 return -1; 1603 r->flags = le32_to_cpu(buf[0]); 1604 1605 return 0; 1606} 1607 1608static int type_set_read(type_set_t * t, struct policy_file *fp) 1609{ 1610 uint32_t buf[1]; 1611 int rc; 1612 1613 if (ebitmap_read(&t->types, fp)) 1614 return -1; 1615 if (ebitmap_read(&t->negset, fp)) 1616 return -1; 1617 1618 rc = next_entry(buf, fp, sizeof(uint32_t)); 1619 if (rc < 0) 1620 return -1; 1621 t->flags = le32_to_cpu(buf[0]); 1622 1623 return 0; 1624} 1625 1626/* 1627 * Read a MLS range structure from a policydb binary 1628 * representation file. 1629 */ 1630static int mls_read_range_helper(mls_range_t * r, struct policy_file *fp) 1631{ 1632 uint32_t buf[2], items; 1633 int rc; 1634 1635 rc = next_entry(buf, fp, sizeof(uint32_t)); 1636 if (rc < 0) 1637 goto out; 1638 1639 items = le32_to_cpu(buf[0]); 1640 if (items > ARRAY_SIZE(buf)) { 1641 ERR(fp->handle, "range overflow"); 1642 rc = -EINVAL; 1643 goto out; 1644 } 1645 rc = next_entry(buf, fp, sizeof(uint32_t) * items); 1646 if (rc < 0) { 1647 ERR(fp->handle, "truncated range"); 1648 goto out; 1649 } 1650 r->level[0].sens = le32_to_cpu(buf[0]); 1651 if (items > 1) 1652 r->level[1].sens = le32_to_cpu(buf[1]); 1653 else 1654 r->level[1].sens = r->level[0].sens; 1655 1656 rc = ebitmap_read(&r->level[0].cat, fp); 1657 if (rc) { 1658 ERR(fp->handle, "error reading low categories"); 1659 goto out; 1660 } 1661 if (items > 1) { 1662 rc = ebitmap_read(&r->level[1].cat, fp); 1663 if (rc) { 1664 ERR(fp->handle, "error reading high categories"); 1665 goto bad_high; 1666 } 1667 } else { 1668 rc = ebitmap_cpy(&r->level[1].cat, &r->level[0].cat); 1669 if (rc) { 1670 ERR(fp->handle, "out of memory"); 1671 goto bad_high; 1672 } 1673 } 1674 1675 rc = 0; 1676 out: 1677 return rc; 1678 bad_high: 1679 ebitmap_destroy(&r->level[0].cat); 1680 goto out; 1681} 1682 1683/* 1684 * Read a semantic MLS level structure from a policydb binary 1685 * representation file. 1686 */ 1687static int mls_read_semantic_level_helper(mls_semantic_level_t * l, 1688 struct policy_file *fp) 1689{ 1690 uint32_t buf[2], ncat; 1691 unsigned int i; 1692 mls_semantic_cat_t *cat; 1693 int rc; 1694 1695 mls_semantic_level_init(l); 1696 1697 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 1698 if (rc < 0) { 1699 ERR(fp->handle, "truncated level"); 1700 goto bad; 1701 } 1702 l->sens = le32_to_cpu(buf[0]); 1703 1704 ncat = le32_to_cpu(buf[1]); 1705 for (i = 0; i < ncat; i++) { 1706 cat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t)); 1707 if (!cat) { 1708 ERR(fp->handle, "out of memory"); 1709 goto bad; 1710 } 1711 1712 mls_semantic_cat_init(cat); 1713 cat->next = l->cat; 1714 l->cat = cat; 1715 1716 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 1717 if (rc < 0) { 1718 ERR(fp->handle, "error reading level categories"); 1719 goto bad; 1720 } 1721 cat->low = le32_to_cpu(buf[0]); 1722 cat->high = le32_to_cpu(buf[1]); 1723 } 1724 1725 return 0; 1726 1727 bad: 1728 return -EINVAL; 1729} 1730 1731/* 1732 * Read a semantic MLS range structure from a policydb binary 1733 * representation file. 1734 */ 1735static int mls_read_semantic_range_helper(mls_semantic_range_t * r, 1736 struct policy_file *fp) 1737{ 1738 int rc; 1739 1740 rc = mls_read_semantic_level_helper(&r->level[0], fp); 1741 if (rc) 1742 return rc; 1743 1744 rc = mls_read_semantic_level_helper(&r->level[1], fp); 1745 1746 return rc; 1747} 1748 1749static int mls_level_to_semantic(mls_level_t * l, mls_semantic_level_t * sl) 1750{ 1751 unsigned int i; 1752 ebitmap_node_t *cnode; 1753 mls_semantic_cat_t *open_cat = NULL; 1754 1755 mls_semantic_level_init(sl); 1756 sl->sens = l->sens; 1757 ebitmap_for_each_bit(&l->cat, cnode, i) { 1758 if (ebitmap_node_get_bit(cnode, i)) { 1759 if (open_cat) 1760 continue; 1761 open_cat = (mls_semantic_cat_t *) 1762 malloc(sizeof(mls_semantic_cat_t)); 1763 if (!open_cat) 1764 return -1; 1765 1766 mls_semantic_cat_init(open_cat); 1767 open_cat->low = i + 1; 1768 open_cat->next = sl->cat; 1769 sl->cat = open_cat; 1770 } else { 1771 if (!open_cat) 1772 continue; 1773 open_cat->high = i; 1774 open_cat = NULL; 1775 } 1776 } 1777 if (open_cat) 1778 open_cat->high = i; 1779 1780 return 0; 1781} 1782 1783static int mls_range_to_semantic(mls_range_t * r, mls_semantic_range_t * sr) 1784{ 1785 if (mls_level_to_semantic(&r->level[0], &sr->level[0])) 1786 return -1; 1787 1788 if (mls_level_to_semantic(&r->level[1], &sr->level[1])) 1789 return -1; 1790 1791 return 0; 1792} 1793 1794/* 1795 * Read and validate a security context structure 1796 * from a policydb binary representation file. 1797 */ 1798static int context_read_and_validate(context_struct_t * c, 1799 policydb_t * p, struct policy_file *fp) 1800{ 1801 uint32_t buf[3]; 1802 int rc; 1803 1804 rc = next_entry(buf, fp, sizeof(uint32_t) * 3); 1805 if (rc < 0) { 1806 ERR(fp->handle, "context truncated"); 1807 return -1; 1808 } 1809 c->user = le32_to_cpu(buf[0]); 1810 c->role = le32_to_cpu(buf[1]); 1811 c->type = le32_to_cpu(buf[2]); 1812 if ((p->policy_type == POLICY_KERN 1813 && p->policyvers >= POLICYDB_VERSION_MLS) 1814 || (p->policy_type == POLICY_BASE 1815 && p->policyvers >= MOD_POLICYDB_VERSION_MLS)) { 1816 if (mls_read_range_helper(&c->range, fp)) { 1817 ERR(fp->handle, "error reading MLS range " 1818 "of context"); 1819 return -1; 1820 } 1821 } 1822 1823 if (!policydb_context_isvalid(p, c)) { 1824 ERR(fp->handle, "invalid security context"); 1825 context_destroy(c); 1826 return -1; 1827 } 1828 return 0; 1829} 1830 1831/* 1832 * The following *_read functions are used to 1833 * read the symbol data from a policy database 1834 * binary representation file. 1835 */ 1836 1837static int perm_read(policydb_t * p 1838 __attribute__ ((unused)), hashtab_t h, 1839 struct policy_file *fp) 1840{ 1841 char *key = 0; 1842 perm_datum_t *perdatum; 1843 uint32_t buf[2]; 1844 size_t len; 1845 int rc; 1846 1847 perdatum = calloc(1, sizeof(perm_datum_t)); 1848 if (!perdatum) 1849 return -1; 1850 1851 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 1852 if (rc < 0) 1853 goto bad; 1854 1855 len = le32_to_cpu(buf[0]); 1856 perdatum->s.value = le32_to_cpu(buf[1]); 1857 1858 key = malloc(len + 1); 1859 if (!key) 1860 goto bad; 1861 rc = next_entry(key, fp, len); 1862 if (rc < 0) 1863 goto bad; 1864 key[len] = 0; 1865 1866 if (hashtab_insert(h, key, perdatum)) 1867 goto bad; 1868 1869 return 0; 1870 1871 bad: 1872 perm_destroy(key, perdatum, NULL); 1873 return -1; 1874} 1875 1876static int common_read(policydb_t * p, hashtab_t h, struct policy_file *fp) 1877{ 1878 char *key = 0; 1879 common_datum_t *comdatum; 1880 uint32_t buf[4]; 1881 size_t len, nel; 1882 unsigned int i; 1883 int rc; 1884 1885 comdatum = calloc(1, sizeof(common_datum_t)); 1886 if (!comdatum) 1887 return -1; 1888 1889 rc = next_entry(buf, fp, sizeof(uint32_t) * 4); 1890 if (rc < 0) 1891 goto bad; 1892 1893 len = le32_to_cpu(buf[0]); 1894 comdatum->s.value = le32_to_cpu(buf[1]); 1895 1896 if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) 1897 goto bad; 1898 comdatum->permissions.nprim = le32_to_cpu(buf[2]); 1899 nel = le32_to_cpu(buf[3]); 1900 1901 key = malloc(len + 1); 1902 if (!key) 1903 goto bad; 1904 rc = next_entry(key, fp, len); 1905 if (rc < 0) 1906 goto bad; 1907 key[len] = 0; 1908 1909 for (i = 0; i < nel; i++) { 1910 if (perm_read(p, comdatum->permissions.table, fp)) 1911 goto bad; 1912 } 1913 1914 if (hashtab_insert(h, key, comdatum)) 1915 goto bad; 1916 1917 return 0; 1918 1919 bad: 1920 common_destroy(key, comdatum, NULL); 1921 return -1; 1922} 1923 1924static int read_cons_helper(policydb_t * p, constraint_node_t ** nodep, 1925 unsigned int ncons, 1926 int allowxtarget, struct policy_file *fp) 1927{ 1928 constraint_node_t *c, *lc; 1929 constraint_expr_t *e, *le; 1930 uint32_t buf[3]; 1931 size_t nexpr; 1932 unsigned int i, j; 1933 int rc, depth; 1934 1935 lc = NULL; 1936 for (i = 0; i < ncons; i++) { 1937 c = calloc(1, sizeof(constraint_node_t)); 1938 if (!c) 1939 return -1; 1940 1941 if (lc) 1942 lc->next = c; 1943 else 1944 *nodep = c; 1945 1946 rc = next_entry(buf, fp, (sizeof(uint32_t) * 2)); 1947 if (rc < 0) 1948 return -1; 1949 c->permissions = le32_to_cpu(buf[0]); 1950 nexpr = le32_to_cpu(buf[1]); 1951 le = NULL; 1952 depth = -1; 1953 for (j = 0; j < nexpr; j++) { 1954 e = malloc(sizeof(constraint_expr_t)); 1955 if (!e) 1956 return -1; 1957 if (constraint_expr_init(e) == -1) { 1958 free(e); 1959 return -1; 1960 } 1961 if (le) { 1962 le->next = e; 1963 } else { 1964 c->expr = e; 1965 } 1966 1967 rc = next_entry(buf, fp, (sizeof(uint32_t) * 3)); 1968 if (rc < 0) 1969 return -1; 1970 e->expr_type = le32_to_cpu(buf[0]); 1971 e->attr = le32_to_cpu(buf[1]); 1972 e->op = le32_to_cpu(buf[2]); 1973 1974 switch (e->expr_type) { 1975 case CEXPR_NOT: 1976 if (depth < 0) 1977 return -1; 1978 break; 1979 case CEXPR_AND: 1980 case CEXPR_OR: 1981 if (depth < 1) 1982 return -1; 1983 depth--; 1984 break; 1985 case CEXPR_ATTR: 1986 if (depth == (CEXPR_MAXDEPTH - 1)) 1987 return -1; 1988 depth++; 1989 break; 1990 case CEXPR_NAMES: 1991 if (!allowxtarget && (e->attr & CEXPR_XTARGET)) 1992 return -1; 1993 if (depth == (CEXPR_MAXDEPTH - 1)) 1994 return -1; 1995 depth++; 1996 if (ebitmap_read(&e->names, fp)) 1997 return -1; 1998 if (p->policy_type != POLICY_KERN && 1999 type_set_read(e->type_names, fp)) 2000 return -1; 2001 break; 2002 default: 2003 return -1; 2004 } 2005 le = e; 2006 } 2007 if (depth != 0) 2008 return -1; 2009 lc = c; 2010 } 2011 2012 return 0; 2013} 2014 2015static int class_read(policydb_t * p, hashtab_t h, struct policy_file *fp) 2016{ 2017 char *key = 0; 2018 class_datum_t *cladatum; 2019 uint32_t buf[6]; 2020 size_t len, len2, ncons, nel; 2021 unsigned int i; 2022 int rc; 2023 2024 cladatum = (class_datum_t *) calloc(1, sizeof(class_datum_t)); 2025 if (!cladatum) 2026 return -1; 2027 2028 rc = next_entry(buf, fp, sizeof(uint32_t) * 6); 2029 if (rc < 0) 2030 goto bad; 2031 2032 len = le32_to_cpu(buf[0]); 2033 len2 = le32_to_cpu(buf[1]); 2034 cladatum->s.value = le32_to_cpu(buf[2]); 2035 2036 if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) 2037 goto bad; 2038 cladatum->permissions.nprim = le32_to_cpu(buf[3]); 2039 nel = le32_to_cpu(buf[4]); 2040 2041 ncons = le32_to_cpu(buf[5]); 2042 2043 key = malloc(len + 1); 2044 if (!key) 2045 goto bad; 2046 rc = next_entry(key, fp, len); 2047 if (rc < 0) 2048 goto bad; 2049 key[len] = 0; 2050 2051 if (len2) { 2052 cladatum->comkey = malloc(len2 + 1); 2053 if (!cladatum->comkey) 2054 goto bad; 2055 rc = next_entry(cladatum->comkey, fp, len2); 2056 if (rc < 0) 2057 goto bad; 2058 cladatum->comkey[len2] = 0; 2059 2060 cladatum->comdatum = hashtab_search(p->p_commons.table, 2061 cladatum->comkey); 2062 if (!cladatum->comdatum) { 2063 ERR(fp->handle, "unknown common %s", cladatum->comkey); 2064 goto bad; 2065 } 2066 } 2067 for (i = 0; i < nel; i++) { 2068 if (perm_read(p, cladatum->permissions.table, fp)) 2069 goto bad; 2070 } 2071 2072 if (read_cons_helper(p, &cladatum->constraints, ncons, 0, fp)) 2073 goto bad; 2074 2075 if ((p->policy_type == POLICY_KERN 2076 && p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) 2077 || (p->policy_type == POLICY_BASE 2078 && p->policyvers >= MOD_POLICYDB_VERSION_VALIDATETRANS)) { 2079 /* grab the validatetrans rules */ 2080 rc = next_entry(buf, fp, sizeof(uint32_t)); 2081 if (rc < 0) 2082 goto bad; 2083 ncons = le32_to_cpu(buf[0]); 2084 if (read_cons_helper(p, &cladatum->validatetrans, ncons, 1, fp)) 2085 goto bad; 2086 } 2087 2088 if ((p->policy_type == POLICY_KERN && 2089 p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) || 2090 (p->policy_type == POLICY_BASE && 2091 p->policyvers >= MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS)) { 2092 rc = next_entry(buf, fp, sizeof(uint32_t) * 3); 2093 if (rc < 0) 2094 goto bad; 2095 cladatum->default_user = le32_to_cpu(buf[0]); 2096 cladatum->default_role = le32_to_cpu(buf[1]); 2097 cladatum->default_range = le32_to_cpu(buf[2]); 2098 } 2099 2100 if (hashtab_insert(h, key, cladatum)) 2101 goto bad; 2102 2103 return 0; 2104 2105 bad: 2106 class_destroy(key, cladatum, NULL); 2107 return -1; 2108} 2109 2110static int role_read(policydb_t * p 2111 __attribute__ ((unused)), hashtab_t h, 2112 struct policy_file *fp) 2113{ 2114 char *key = 0; 2115 role_datum_t *role; 2116 uint32_t buf[3]; 2117 size_t len; 2118 int rc, to_read = 2; 2119 2120 role = calloc(1, sizeof(role_datum_t)); 2121 if (!role) 2122 return -1; 2123 2124 if (policydb_has_boundary_feature(p)) 2125 to_read = 3; 2126 2127 rc = next_entry(buf, fp, sizeof(uint32_t) * to_read); 2128 if (rc < 0) 2129 goto bad; 2130 2131 len = le32_to_cpu(buf[0]); 2132 role->s.value = le32_to_cpu(buf[1]); 2133 if (policydb_has_boundary_feature(p)) 2134 role->bounds = le32_to_cpu(buf[2]); 2135 2136 key = malloc(len + 1); 2137 if (!key) 2138 goto bad; 2139 rc = next_entry(key, fp, len); 2140 if (rc < 0) 2141 goto bad; 2142 key[len] = 0; 2143 2144 if (ebitmap_read(&role->dominates, fp)) 2145 goto bad; 2146 2147 if (p->policy_type == POLICY_KERN) { 2148 if (ebitmap_read(&role->types.types, fp)) 2149 goto bad; 2150 } else { 2151 if (type_set_read(&role->types, fp)) 2152 goto bad; 2153 } 2154 2155 if (p->policy_type != POLICY_KERN && 2156 p->policyvers >= MOD_POLICYDB_VERSION_ROLEATTRIB) { 2157 rc = next_entry(buf, fp, sizeof(uint32_t)); 2158 if (rc < 0) 2159 goto bad; 2160 2161 role->flavor = le32_to_cpu(buf[0]); 2162 2163 if (ebitmap_read(&role->roles, fp)) 2164 goto bad; 2165 } 2166 2167 if (strcmp(key, OBJECT_R) == 0) { 2168 if (role->s.value != OBJECT_R_VAL) { 2169 ERR(fp->handle, "role %s has wrong value %d", 2170 OBJECT_R, role->s.value); 2171 role_destroy(key, role, NULL); 2172 return -1; 2173 } 2174 role_destroy(key, role, NULL); 2175 return 0; 2176 } 2177 2178 if (hashtab_insert(h, key, role)) 2179 goto bad; 2180 2181 return 0; 2182 2183 bad: 2184 role_destroy(key, role, NULL); 2185 return -1; 2186} 2187 2188static int type_read(policydb_t * p 2189 __attribute__ ((unused)), hashtab_t h, 2190 struct policy_file *fp) 2191{ 2192 char *key = 0; 2193 type_datum_t *typdatum; 2194 uint32_t buf[5]; 2195 size_t len; 2196 int rc, to_read; 2197 int pos = 0; 2198 2199 typdatum = calloc(1, sizeof(type_datum_t)); 2200 if (!typdatum) 2201 return -1; 2202 2203 if (policydb_has_boundary_feature(p)) { 2204 if (p->policy_type != POLICY_KERN 2205 && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS) 2206 to_read = 5; 2207 else 2208 to_read = 4; 2209 } 2210 else if (p->policy_type == POLICY_KERN) 2211 to_read = 3; 2212 else if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE) 2213 to_read = 5; 2214 else 2215 to_read = 4; 2216 2217 rc = next_entry(buf, fp, sizeof(uint32_t) * to_read); 2218 if (rc < 0) 2219 goto bad; 2220 2221 len = le32_to_cpu(buf[pos]); 2222 typdatum->s.value = le32_to_cpu(buf[++pos]); 2223 if (policydb_has_boundary_feature(p)) { 2224 uint32_t properties; 2225 2226 if (p->policy_type != POLICY_KERN 2227 && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS) { 2228 typdatum->primary = le32_to_cpu(buf[++pos]); 2229 properties = le32_to_cpu(buf[++pos]); 2230 } 2231 else { 2232 properties = le32_to_cpu(buf[++pos]); 2233 2234 if (properties & TYPEDATUM_PROPERTY_PRIMARY) 2235 typdatum->primary = 1; 2236 } 2237 2238 if (properties & TYPEDATUM_PROPERTY_ATTRIBUTE) 2239 typdatum->flavor = TYPE_ATTRIB; 2240 if (properties & TYPEDATUM_PROPERTY_ALIAS 2241 && p->policy_type != POLICY_KERN) 2242 typdatum->flavor = TYPE_ALIAS; 2243 if (properties & TYPEDATUM_PROPERTY_PERMISSIVE 2244 && p->policy_type != POLICY_KERN) 2245 typdatum->flags |= TYPE_FLAGS_PERMISSIVE; 2246 2247 typdatum->bounds = le32_to_cpu(buf[++pos]); 2248 } else { 2249 typdatum->primary = le32_to_cpu(buf[++pos]); 2250 if (p->policy_type != POLICY_KERN) { 2251 typdatum->flavor = le32_to_cpu(buf[++pos]); 2252 if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE) 2253 typdatum->flags = le32_to_cpu(buf[++pos]); 2254 } 2255 } 2256 2257 if (p->policy_type != POLICY_KERN) { 2258 if (ebitmap_read(&typdatum->types, fp)) 2259 goto bad; 2260 } 2261 2262 key = malloc(len + 1); 2263 if (!key) 2264 goto bad; 2265 rc = next_entry(key, fp, len); 2266 if (rc < 0) 2267 goto bad; 2268 key[len] = 0; 2269 2270 if (hashtab_insert(h, key, typdatum)) 2271 goto bad; 2272 2273 return 0; 2274 2275 bad: 2276 type_destroy(key, typdatum, NULL); 2277 return -1; 2278} 2279 2280int role_trans_read(policydb_t *p, struct policy_file *fp) 2281{ 2282 role_trans_t **t = &p->role_tr; 2283 unsigned int i; 2284 uint32_t buf[3], nel; 2285 role_trans_t *tr, *ltr; 2286 int rc; 2287 int new_roletr = (p->policy_type == POLICY_KERN && 2288 p->policyvers >= POLICYDB_VERSION_ROLETRANS); 2289 2290 rc = next_entry(buf, fp, sizeof(uint32_t)); 2291 if (rc < 0) 2292 return -1; 2293 nel = le32_to_cpu(buf[0]); 2294 ltr = NULL; 2295 for (i = 0; i < nel; i++) { 2296 tr = calloc(1, sizeof(struct role_trans)); 2297 if (!tr) { 2298 return -1; 2299 } 2300 if (ltr) { 2301 ltr->next = tr; 2302 } else { 2303 *t = tr; 2304 } 2305 rc = next_entry(buf, fp, sizeof(uint32_t) * 3); 2306 if (rc < 0) 2307 return -1; 2308 tr->role = le32_to_cpu(buf[0]); 2309 tr->type = le32_to_cpu(buf[1]); 2310 tr->new_role = le32_to_cpu(buf[2]); 2311 if (new_roletr) { 2312 rc = next_entry(buf, fp, sizeof(uint32_t)); 2313 if (rc < 0) 2314 return -1; 2315 tr->tclass = le32_to_cpu(buf[0]); 2316 } else 2317 tr->tclass = SECCLASS_PROCESS; 2318 ltr = tr; 2319 } 2320 return 0; 2321} 2322 2323int role_allow_read(role_allow_t ** r, struct policy_file *fp) 2324{ 2325 unsigned int i; 2326 uint32_t buf[2], nel; 2327 role_allow_t *ra, *lra; 2328 int rc; 2329 2330 rc = next_entry(buf, fp, sizeof(uint32_t)); 2331 if (rc < 0) 2332 return -1; 2333 nel = le32_to_cpu(buf[0]); 2334 lra = NULL; 2335 for (i = 0; i < nel; i++) { 2336 ra = calloc(1, sizeof(struct role_allow)); 2337 if (!ra) { 2338 return -1; 2339 } 2340 if (lra) { 2341 lra->next = ra; 2342 } else { 2343 *r = ra; 2344 } 2345 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 2346 if (rc < 0) 2347 return -1; 2348 ra->role = le32_to_cpu(buf[0]); 2349 ra->new_role = le32_to_cpu(buf[1]); 2350 lra = ra; 2351 } 2352 return 0; 2353} 2354 2355int filename_trans_read(filename_trans_t **t, struct policy_file *fp) 2356{ 2357 unsigned int i; 2358 uint32_t buf[4], nel, len; 2359 filename_trans_t *ft, *lft; 2360 int rc; 2361 char *name; 2362 2363 rc = next_entry(buf, fp, sizeof(uint32_t)); 2364 if (rc < 0) 2365 return -1; 2366 nel = le32_to_cpu(buf[0]); 2367 2368 lft = NULL; 2369 for (i = 0; i < nel; i++) { 2370 ft = calloc(1, sizeof(struct filename_trans)); 2371 if (!ft) 2372 return -1; 2373 if (lft) 2374 lft->next = ft; 2375 else 2376 *t = ft; 2377 lft = ft; 2378 rc = next_entry(buf, fp, sizeof(uint32_t)); 2379 if (rc < 0) 2380 return -1; 2381 len = le32_to_cpu(buf[0]); 2382 2383 name = calloc(len + 1, sizeof(*name)); 2384 if (!name) 2385 return -1; 2386 2387 ft->name = name; 2388 2389 rc = next_entry(name, fp, len); 2390 if (rc < 0) 2391 return -1; 2392 2393 rc = next_entry(buf, fp, sizeof(uint32_t) * 4); 2394 if (rc < 0) 2395 return -1; 2396 2397 ft->stype = le32_to_cpu(buf[0]); 2398 ft->ttype = le32_to_cpu(buf[1]); 2399 ft->tclass = le32_to_cpu(buf[2]); 2400 ft->otype = le32_to_cpu(buf[3]); 2401 } 2402 return 0; 2403} 2404 2405static int ocontext_read_xen(struct policydb_compat_info *info, 2406 policydb_t *p, struct policy_file *fp) 2407{ 2408 unsigned int i, j; 2409 size_t nel; 2410 ocontext_t *l, *c; 2411 uint32_t buf[8]; 2412 int rc; 2413 2414 for (i = 0; i < info->ocon_num; i++) { 2415 rc = next_entry(buf, fp, sizeof(uint32_t)); 2416 if (rc < 0) 2417 return -1; 2418 nel = le32_to_cpu(buf[0]); 2419 l = NULL; 2420 for (j = 0; j < nel; j++) { 2421 c = calloc(1, sizeof(ocontext_t)); 2422 if (!c) 2423 return -1; 2424 if (l) 2425 l->next = c; 2426 else 2427 p->ocontexts[i] = c; 2428 l = c; 2429 switch (i) { 2430 case OCON_XEN_ISID: 2431 rc = next_entry(buf, fp, sizeof(uint32_t)); 2432 if (rc < 0) 2433 return -1; 2434 c->sid[0] = le32_to_cpu(buf[0]); 2435 if (context_read_and_validate 2436 (&c->context[0], p, fp)) 2437 return -1; 2438 break; 2439 case OCON_XEN_PIRQ: 2440 rc = next_entry(buf, fp, sizeof(uint32_t)); 2441 if (rc < 0) 2442 return -1; 2443 c->u.pirq = le32_to_cpu(buf[0]); 2444 if (context_read_and_validate 2445 (&c->context[0], p, fp)) 2446 return -1; 2447 break; 2448 case OCON_XEN_IOPORT: 2449 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 2450 if (rc < 0) 2451 return -1; 2452 c->u.ioport.low_ioport = le32_to_cpu(buf[0]); 2453 c->u.ioport.high_ioport = le32_to_cpu(buf[1]); 2454 if (context_read_and_validate 2455 (&c->context[0], p, fp)) 2456 return -1; 2457 break; 2458 case OCON_XEN_IOMEM: 2459 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 2460 if (rc < 0) 2461 return -1; 2462 c->u.iomem.low_iomem = le32_to_cpu(buf[0]); 2463 c->u.iomem.high_iomem = le32_to_cpu(buf[1]); 2464 if (context_read_and_validate 2465 (&c->context[0], p, fp)) 2466 return -1; 2467 break; 2468 case OCON_XEN_PCIDEVICE: 2469 rc = next_entry(buf, fp, sizeof(uint32_t)); 2470 if (rc < 0) 2471 return -1; 2472 c->u.device = le32_to_cpu(buf[0]); 2473 if (context_read_and_validate 2474 (&c->context[0], p, fp)) 2475 return -1; 2476 break; 2477 default: 2478 /* should never get here */ 2479 ERR(fp->handle, "Unknown Xen ocontext"); 2480 return -1; 2481 } 2482 } 2483 } 2484 return 0; 2485} 2486static int ocontext_read_selinux(struct policydb_compat_info *info, 2487 policydb_t * p, struct policy_file *fp) 2488{ 2489 unsigned int i, j; 2490 size_t nel, len; 2491 ocontext_t *l, *c; 2492 uint32_t buf[8]; 2493 int rc; 2494 2495 for (i = 0; i < info->ocon_num; i++) { 2496 rc = next_entry(buf, fp, sizeof(uint32_t)); 2497 if (rc < 0) 2498 return -1; 2499 nel = le32_to_cpu(buf[0]); 2500 l = NULL; 2501 for (j = 0; j < nel; j++) { 2502 c = calloc(1, sizeof(ocontext_t)); 2503 if (!c) { 2504 return -1; 2505 } 2506 if (l) { 2507 l->next = c; 2508 } else { 2509 p->ocontexts[i] = c; 2510 } 2511 l = c; 2512 switch (i) { 2513 case OCON_ISID: 2514 rc = next_entry(buf, fp, sizeof(uint32_t)); 2515 if (rc < 0) 2516 return -1; 2517 c->sid[0] = le32_to_cpu(buf[0]); 2518 if (context_read_and_validate 2519 (&c->context[0], p, fp)) 2520 return -1; 2521 break; 2522 case OCON_FS: 2523 case OCON_NETIF: 2524 rc = next_entry(buf, fp, sizeof(uint32_t)); 2525 if (rc < 0) 2526 return -1; 2527 len = le32_to_cpu(buf[0]); 2528 c->u.name = malloc(len + 1); 2529 if (!c->u.name) 2530 return -1; 2531 rc = next_entry(c->u.name, fp, len); 2532 if (rc < 0) 2533 return -1; 2534 c->u.name[len] = 0; 2535 if (context_read_and_validate 2536 (&c->context[0], p, fp)) 2537 return -1; 2538 if (context_read_and_validate 2539 (&c->context[1], p, fp)) 2540 return -1; 2541 break; 2542 case OCON_PORT: 2543 rc = next_entry(buf, fp, sizeof(uint32_t) * 3); 2544 if (rc < 0) 2545 return -1; 2546 c->u.port.protocol = le32_to_cpu(buf[0]); 2547 c->u.port.low_port = le32_to_cpu(buf[1]); 2548 c->u.port.high_port = le32_to_cpu(buf[2]); 2549 if (context_read_and_validate 2550 (&c->context[0], p, fp)) 2551 return -1; 2552 break; 2553 case OCON_NODE: 2554 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 2555 if (rc < 0) 2556 return -1; 2557 c->u.node.addr = buf[0]; /* network order */ 2558 c->u.node.mask = buf[1]; /* network order */ 2559 if (context_read_and_validate 2560 (&c->context[0], p, fp)) 2561 return -1; 2562 break; 2563 case OCON_FSUSE: 2564 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 2565 if (rc < 0) 2566 return -1; 2567 c->v.behavior = le32_to_cpu(buf[0]); 2568 len = le32_to_cpu(buf[1]); 2569 c->u.name = malloc(len + 1); 2570 if (!c->u.name) 2571 return -1; 2572 rc = next_entry(c->u.name, fp, len); 2573 if (rc < 0) 2574 return -1; 2575 c->u.name[len] = 0; 2576 if (context_read_and_validate 2577 (&c->context[0], p, fp)) 2578 return -1; 2579 break; 2580 case OCON_NODE6:{ 2581 int k; 2582 2583 rc = next_entry(buf, fp, sizeof(uint32_t) * 8); 2584 if (rc < 0) 2585 return -1; 2586 for (k = 0; k < 4; k++) 2587 /* network order */ 2588 c->u.node6.addr[k] = buf[k]; 2589 for (k = 0; k < 4; k++) 2590 /* network order */ 2591 c->u.node6.mask[k] = buf[k + 4]; 2592 if (context_read_and_validate 2593 (&c->context[0], p, fp)) 2594 return -1; 2595 break; 2596 } 2597 default:{ 2598 ERR(fp->handle, "Unknown SELinux ocontext"); 2599 return -1; 2600 } 2601 } 2602 } 2603 } 2604 return 0; 2605} 2606 2607static int ocontext_read(struct policydb_compat_info *info, 2608 policydb_t *p, struct policy_file *fp) 2609{ 2610 int rc = -1; 2611 switch (p->target_platform) { 2612 case SEPOL_TARGET_SELINUX: 2613 rc = ocontext_read_selinux(info, p, fp); 2614 break; 2615 case SEPOL_TARGET_XEN: 2616 rc = ocontext_read_xen(info, p, fp); 2617 break; 2618 default: 2619 ERR(fp->handle, "Unknown target"); 2620 } 2621 return rc; 2622} 2623 2624static int genfs_read(policydb_t * p, struct policy_file *fp) 2625{ 2626 uint32_t buf[1]; 2627 size_t nel, nel2, len, len2; 2628 genfs_t *genfs_p, *newgenfs, *genfs; 2629 unsigned int i, j; 2630 ocontext_t *l, *c, *newc = NULL; 2631 int rc; 2632 2633 rc = next_entry(buf, fp, sizeof(uint32_t)); 2634 if (rc < 0) 2635 goto bad; 2636 nel = le32_to_cpu(buf[0]); 2637 genfs_p = NULL; 2638 for (i = 0; i < nel; i++) { 2639 rc = next_entry(buf, fp, sizeof(uint32_t)); 2640 if (rc < 0) 2641 goto bad; 2642 len = le32_to_cpu(buf[0]); 2643 newgenfs = calloc(1, sizeof(genfs_t)); 2644 if (!newgenfs) 2645 goto bad; 2646 newgenfs->fstype = malloc(len + 1); 2647 if (!newgenfs->fstype) { 2648 free(newgenfs); 2649 goto bad; 2650 } 2651 rc = next_entry(newgenfs->fstype, fp, len); 2652 if (rc < 0) { 2653 free(newgenfs->fstype); 2654 free(newgenfs); 2655 goto bad; 2656 } 2657 newgenfs->fstype[len] = 0; 2658 for (genfs_p = NULL, genfs = p->genfs; genfs; 2659 genfs_p = genfs, genfs = genfs->next) { 2660 if (strcmp(newgenfs->fstype, genfs->fstype) == 0) { 2661 ERR(fp->handle, "dup genfs fstype %s", 2662 newgenfs->fstype); 2663 free(newgenfs->fstype); 2664 free(newgenfs); 2665 goto bad; 2666 } 2667 if (strcmp(newgenfs->fstype, genfs->fstype) < 0) 2668 break; 2669 } 2670 newgenfs->next = genfs; 2671 if (genfs_p) 2672 genfs_p->next = newgenfs; 2673 else 2674 p->genfs = newgenfs; 2675 rc = next_entry(buf, fp, sizeof(uint32_t)); 2676 if (rc < 0) 2677 goto bad; 2678 nel2 = le32_to_cpu(buf[0]); 2679 for (j = 0; j < nel2; j++) { 2680 newc = calloc(1, sizeof(ocontext_t)); 2681 if (!newc) { 2682 goto bad; 2683 } 2684 rc = next_entry(buf, fp, sizeof(uint32_t)); 2685 if (rc < 0) 2686 goto bad; 2687 len = le32_to_cpu(buf[0]); 2688 newc->u.name = malloc(len + 1); 2689 if (!newc->u.name) { 2690 goto bad; 2691 } 2692 rc = next_entry(newc->u.name, fp, len); 2693 if (rc < 0) 2694 goto bad; 2695 newc->u.name[len] = 0; 2696 rc = next_entry(buf, fp, sizeof(uint32_t)); 2697 if (rc < 0) 2698 goto bad; 2699 newc->v.sclass = le32_to_cpu(buf[0]); 2700 if (context_read_and_validate(&newc->context[0], p, fp)) 2701 goto bad; 2702 for (l = NULL, c = newgenfs->head; c; 2703 l = c, c = c->next) { 2704 if (!strcmp(newc->u.name, c->u.name) && 2705 (!c->v.sclass || !newc->v.sclass || 2706 newc->v.sclass == c->v.sclass)) { 2707 ERR(fp->handle, "dup genfs entry " 2708 "(%s,%s)", newgenfs->fstype, 2709 c->u.name); 2710 goto bad; 2711 } 2712 len = strlen(newc->u.name); 2713 len2 = strlen(c->u.name); 2714 if (len > len2) 2715 break; 2716 } 2717 newc->next = c; 2718 if (l) 2719 l->next = newc; 2720 else 2721 newgenfs->head = newc; 2722 } 2723 } 2724 2725 return 0; 2726 2727 bad: 2728 if (newc) { 2729 context_destroy(&newc->context[0]); 2730 context_destroy(&newc->context[1]); 2731 free(newc->u.name); 2732 free(newc); 2733 } 2734 return -1; 2735} 2736 2737/* 2738 * Read a MLS level structure from a policydb binary 2739 * representation file. 2740 */ 2741static int mls_read_level(mls_level_t * lp, struct policy_file *fp) 2742{ 2743 uint32_t buf[1]; 2744 int rc; 2745 2746 mls_level_init(lp); 2747 2748 rc = next_entry(buf, fp, sizeof(uint32_t)); 2749 if (rc < 0) { 2750 ERR(fp->handle, "truncated level"); 2751 goto bad; 2752 } 2753 lp->sens = le32_to_cpu(buf[0]); 2754 2755 if (ebitmap_read(&lp->cat, fp)) { 2756 ERR(fp->handle, "error reading level categories"); 2757 goto bad; 2758 } 2759 return 0; 2760 2761 bad: 2762 return -EINVAL; 2763} 2764 2765static int user_read(policydb_t * p, hashtab_t h, struct policy_file *fp) 2766{ 2767 char *key = 0; 2768 user_datum_t *usrdatum; 2769 uint32_t buf[3]; 2770 size_t len; 2771 int rc, to_read = 2; 2772 2773 usrdatum = calloc(1, sizeof(user_datum_t)); 2774 if (!usrdatum) 2775 return -1; 2776 2777 if (policydb_has_boundary_feature(p)) 2778 to_read = 3; 2779 2780 rc = next_entry(buf, fp, sizeof(uint32_t) * to_read); 2781 if (rc < 0) 2782 goto bad; 2783 2784 len = le32_to_cpu(buf[0]); 2785 usrdatum->s.value = le32_to_cpu(buf[1]); 2786 if (policydb_has_boundary_feature(p)) 2787 usrdatum->bounds = le32_to_cpu(buf[2]); 2788 2789 key = malloc(len + 1); 2790 if (!key) 2791 goto bad; 2792 rc = next_entry(key, fp, len); 2793 if (rc < 0) 2794 goto bad; 2795 key[len] = 0; 2796 2797 if (p->policy_type == POLICY_KERN) { 2798 if (ebitmap_read(&usrdatum->roles.roles, fp)) 2799 goto bad; 2800 } else { 2801 if (role_set_read(&usrdatum->roles, fp)) 2802 goto bad; 2803 } 2804 2805 /* users were not allowed in mls modules before version 2806 * MOD_POLICYDB_VERSION_MLS_USERS, but they could have been 2807 * required - the mls fields will be empty. user declarations in 2808 * non-mls modules will also have empty mls fields */ 2809 if ((p->policy_type == POLICY_KERN 2810 && p->policyvers >= POLICYDB_VERSION_MLS) 2811 || (p->policy_type == POLICY_MOD 2812 && p->policyvers >= MOD_POLICYDB_VERSION_MLS 2813 && p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS) 2814 || (p->policy_type == POLICY_BASE 2815 && p->policyvers >= MOD_POLICYDB_VERSION_MLS 2816 && p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS)) { 2817 if (mls_read_range_helper(&usrdatum->exp_range, fp)) 2818 goto bad; 2819 if (mls_read_level(&usrdatum->exp_dfltlevel, fp)) 2820 goto bad; 2821 if (p->policy_type != POLICY_KERN) { 2822 if (mls_range_to_semantic(&usrdatum->exp_range, 2823 &usrdatum->range)) 2824 goto bad; 2825 if (mls_level_to_semantic(&usrdatum->exp_dfltlevel, 2826 &usrdatum->dfltlevel)) 2827 goto bad; 2828 } 2829 } else if ((p->policy_type == POLICY_MOD 2830 && p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS) 2831 || (p->policy_type == POLICY_BASE 2832 && p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS)) { 2833 if (mls_read_semantic_range_helper(&usrdatum->range, fp)) 2834 goto bad; 2835 if (mls_read_semantic_level_helper(&usrdatum->dfltlevel, fp)) 2836 goto bad; 2837 } 2838 2839 if (hashtab_insert(h, key, usrdatum)) 2840 goto bad; 2841 2842 return 0; 2843 2844 bad: 2845 user_destroy(key, usrdatum, NULL); 2846 return -1; 2847} 2848 2849static int sens_read(policydb_t * p 2850 __attribute__ ((unused)), hashtab_t h, 2851 struct policy_file *fp) 2852{ 2853 char *key = 0; 2854 level_datum_t *levdatum; 2855 uint32_t buf[2], len; 2856 int rc; 2857 2858 levdatum = malloc(sizeof(level_datum_t)); 2859 if (!levdatum) 2860 return -1; 2861 level_datum_init(levdatum); 2862 2863 rc = next_entry(buf, fp, (sizeof(uint32_t) * 2)); 2864 if (rc < 0) 2865 goto bad; 2866 2867 len = le32_to_cpu(buf[0]); 2868 levdatum->isalias = le32_to_cpu(buf[1]); 2869 2870 key = malloc(len + 1); 2871 if (!key) 2872 goto bad; 2873 rc = next_entry(key, fp, len); 2874 if (rc < 0) 2875 goto bad; 2876 key[len] = 0; 2877 2878 levdatum->level = malloc(sizeof(mls_level_t)); 2879 if (!levdatum->level || mls_read_level(levdatum->level, fp)) 2880 goto bad; 2881 2882 if (hashtab_insert(h, key, levdatum)) 2883 goto bad; 2884 2885 return 0; 2886 2887 bad: 2888 sens_destroy(key, levdatum, NULL); 2889 return -1; 2890} 2891 2892static int cat_read(policydb_t * p 2893 __attribute__ ((unused)), hashtab_t h, 2894 struct policy_file *fp) 2895{ 2896 char *key = 0; 2897 cat_datum_t *catdatum; 2898 uint32_t buf[3], len; 2899 int rc; 2900 2901 catdatum = malloc(sizeof(cat_datum_t)); 2902 if (!catdatum) 2903 return -1; 2904 cat_datum_init(catdatum); 2905 2906 rc = next_entry(buf, fp, (sizeof(uint32_t) * 3)); 2907 if (rc < 0) 2908 goto bad; 2909 2910 len = le32_to_cpu(buf[0]); 2911 catdatum->s.value = le32_to_cpu(buf[1]); 2912 catdatum->isalias = le32_to_cpu(buf[2]); 2913 2914 key = malloc(len + 1); 2915 if (!key) 2916 goto bad; 2917 rc = next_entry(key, fp, len); 2918 if (rc < 0) 2919 goto bad; 2920 key[len] = 0; 2921 2922 if (hashtab_insert(h, key, catdatum)) 2923 goto bad; 2924 2925 return 0; 2926 2927 bad: 2928 cat_destroy(key, catdatum, NULL); 2929 return -1; 2930} 2931 2932static int (*read_f[SYM_NUM]) (policydb_t * p, hashtab_t h, 2933 struct policy_file * fp) = { 2934common_read, class_read, role_read, type_read, user_read, 2935 cond_read_bool, sens_read, cat_read,}; 2936 2937/************** module reading functions below **************/ 2938 2939static avrule_t *avrule_read(policydb_t * p 2940 __attribute__ ((unused)), struct policy_file *fp) 2941{ 2942 unsigned int i; 2943 uint32_t buf[2], len; 2944 class_perm_node_t *cur, *tail = NULL; 2945 avrule_t *avrule; 2946 int rc; 2947 2948 avrule = (avrule_t *) malloc(sizeof(avrule_t)); 2949 if (!avrule) 2950 return NULL; 2951 2952 avrule_init(avrule); 2953 2954 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 2955 if (rc < 0) 2956 goto bad; 2957 2958 (avrule)->specified = le32_to_cpu(buf[0]); 2959 (avrule)->flags = le32_to_cpu(buf[1]); 2960 2961 if (type_set_read(&avrule->stypes, fp)) 2962 goto bad; 2963 2964 if (type_set_read(&avrule->ttypes, fp)) 2965 goto bad; 2966 2967 rc = next_entry(buf, fp, sizeof(uint32_t)); 2968 if (rc < 0) 2969 goto bad; 2970 len = le32_to_cpu(buf[0]); 2971 2972 for (i = 0; i < len; i++) { 2973 cur = (class_perm_node_t *) malloc(sizeof(class_perm_node_t)); 2974 if (!cur) 2975 goto bad; 2976 class_perm_node_init(cur); 2977 2978 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 2979 if (rc < 0) { 2980 free(cur); 2981 goto bad; 2982 } 2983 2984 cur->class = le32_to_cpu(buf[0]); 2985 cur->data = le32_to_cpu(buf[1]); 2986 2987 if (!tail) { 2988 avrule->perms = cur; 2989 } else { 2990 tail->next = cur; 2991 } 2992 tail = cur; 2993 } 2994 2995 return avrule; 2996 bad: 2997 if (avrule) { 2998 avrule_destroy(avrule); 2999 free(avrule); 3000 } 3001 return NULL; 3002} 3003 3004static int range_read(policydb_t * p, struct policy_file *fp) 3005{ 3006 uint32_t buf[2], nel; 3007 range_trans_t *rt, *lrt; 3008 range_trans_rule_t *rtr, *lrtr = NULL; 3009 unsigned int i; 3010 int new_rangetr = (p->policy_type == POLICY_KERN && 3011 p->policyvers >= POLICYDB_VERSION_RANGETRANS); 3012 int rc; 3013 3014 rc = next_entry(buf, fp, sizeof(uint32_t)); 3015 if (rc < 0) 3016 return -1; 3017 nel = le32_to_cpu(buf[0]); 3018 lrt = NULL; 3019 for (i = 0; i < nel; i++) { 3020 rt = calloc(1, sizeof(range_trans_t)); 3021 if (!rt) 3022 return -1; 3023 if (lrt) 3024 lrt->next = rt; 3025 else 3026 p->range_tr = rt; 3027 rc = next_entry(buf, fp, (sizeof(uint32_t) * 2)); 3028 if (rc < 0) 3029 return -1; 3030 rt->source_type = le32_to_cpu(buf[0]); 3031 rt->target_type = le32_to_cpu(buf[1]); 3032 if (new_rangetr) { 3033 rc = next_entry(buf, fp, (sizeof(uint32_t))); 3034 if (rc < 0) 3035 return -1; 3036 rt->target_class = le32_to_cpu(buf[0]); 3037 } else 3038 rt->target_class = SECCLASS_PROCESS; 3039 if (mls_read_range_helper(&rt->target_range, fp)) 3040 return -1; 3041 lrt = rt; 3042 } 3043 3044 /* if this is a kernel policy, we are done - otherwise we need to 3045 * convert these structs to range_trans_rule_ts */ 3046 if (p->policy_type == POLICY_KERN) 3047 return 0; 3048 3049 /* create range_trans_rules_ts that correspond to the range_trans_ts 3050 * that were just read in from an older policy */ 3051 for (rt = p->range_tr; rt; rt = rt->next) { 3052 rtr = malloc(sizeof(range_trans_rule_t)); 3053 if (!rtr) { 3054 return -1; 3055 } 3056 range_trans_rule_init(rtr); 3057 3058 if (lrtr) 3059 lrtr->next = rtr; 3060 else 3061 p->global->enabled->range_tr_rules = rtr; 3062 3063 if (ebitmap_set_bit(&rtr->stypes.types, rt->source_type - 1, 1)) 3064 return -1; 3065 3066 if (ebitmap_set_bit(&rtr->ttypes.types, rt->target_type - 1, 1)) 3067 return -1; 3068 3069 if (ebitmap_set_bit(&rtr->tclasses, rt->target_class - 1, 1)) 3070 return -1; 3071 3072 if (mls_range_to_semantic(&rt->target_range, &rtr->trange)) 3073 return -1; 3074 3075 lrtr = rtr; 3076 } 3077 3078 /* now destroy the range_trans_ts */ 3079 lrt = NULL; 3080 for (rt = p->range_tr; rt; rt = rt->next) { 3081 if (lrt) { 3082 ebitmap_destroy(&lrt->target_range.level[0].cat); 3083 ebitmap_destroy(&lrt->target_range.level[1].cat); 3084 free(lrt); 3085 } 3086 lrt = rt; 3087 } 3088 if (lrt) { 3089 ebitmap_destroy(&lrt->target_range.level[0].cat); 3090 ebitmap_destroy(&lrt->target_range.level[1].cat); 3091 free(lrt); 3092 } 3093 p->range_tr = NULL; 3094 3095 return 0; 3096} 3097 3098int avrule_read_list(policydb_t * p, avrule_t ** avrules, 3099 struct policy_file *fp) 3100{ 3101 unsigned int i; 3102 avrule_t *cur, *tail; 3103 uint32_t buf[1], len; 3104 int rc; 3105 3106 *avrules = tail = NULL; 3107 3108 rc = next_entry(buf, fp, sizeof(uint32_t)); 3109 if (rc < 0) { 3110 return -1; 3111 } 3112 len = le32_to_cpu(buf[0]); 3113 3114 for (i = 0; i < len; i++) { 3115 cur = avrule_read(p, fp); 3116 if (!cur) { 3117 return -1; 3118 } 3119 3120 if (!tail) { 3121 *avrules = cur; 3122 } else { 3123 tail->next = cur; 3124 } 3125 tail = cur; 3126 } 3127 3128 return 0; 3129} 3130 3131static int role_trans_rule_read(policydb_t *p, role_trans_rule_t ** r, 3132 struct policy_file *fp) 3133{ 3134 uint32_t buf[1], nel; 3135 unsigned int i; 3136 role_trans_rule_t *tr, *ltr; 3137 int rc; 3138 3139 rc = next_entry(buf, fp, sizeof(uint32_t)); 3140 if (rc < 0) 3141 return -1; 3142 nel = le32_to_cpu(buf[0]); 3143 ltr = NULL; 3144 for (i = 0; i < nel; i++) { 3145 tr = malloc(sizeof(role_trans_rule_t)); 3146 if (!tr) { 3147 return -1; 3148 } 3149 role_trans_rule_init(tr); 3150 3151 if (ltr) { 3152 ltr->next = tr; 3153 } else { 3154 *r = tr; 3155 } 3156 3157 if (role_set_read(&tr->roles, fp)) 3158 return -1; 3159 3160 if (type_set_read(&tr->types, fp)) 3161 return -1; 3162 3163 if (p->policyvers >= MOD_POLICYDB_VERSION_ROLETRANS) { 3164 if (ebitmap_read(&tr->classes, fp)) 3165 return -1; 3166 } else { 3167 if (ebitmap_set_bit(&tr->classes, SECCLASS_PROCESS - 1, 1)) 3168 return -1; 3169 } 3170 3171 rc = next_entry(buf, fp, sizeof(uint32_t)); 3172 if (rc < 0) 3173 return -1; 3174 tr->new_role = le32_to_cpu(buf[0]); 3175 ltr = tr; 3176 } 3177 3178 return 0; 3179} 3180 3181static int role_allow_rule_read(role_allow_rule_t ** r, struct policy_file *fp) 3182{ 3183 unsigned int i; 3184 uint32_t buf[1], nel; 3185 role_allow_rule_t *ra, *lra; 3186 int rc; 3187 3188 rc = next_entry(buf, fp, sizeof(uint32_t)); 3189 if (rc < 0) 3190 return -1; 3191 nel = le32_to_cpu(buf[0]); 3192 lra = NULL; 3193 for (i = 0; i < nel; i++) { 3194 ra = malloc(sizeof(role_allow_rule_t)); 3195 if (!ra) { 3196 return -1; 3197 } 3198 role_allow_rule_init(ra); 3199 3200 if (lra) { 3201 lra->next = ra; 3202 } else { 3203 *r = ra; 3204 } 3205 3206 if (role_set_read(&ra->roles, fp)) 3207 return -1; 3208 3209 if (role_set_read(&ra->new_roles, fp)) 3210 return -1; 3211 3212 lra = ra; 3213 } 3214 return 0; 3215} 3216 3217static int filename_trans_rule_read(filename_trans_rule_t ** r, struct policy_file *fp) 3218{ 3219 uint32_t buf[2], nel; 3220 unsigned int i, len; 3221 filename_trans_rule_t *ftr, *lftr; 3222 int rc; 3223 3224 rc = next_entry(buf, fp, sizeof(uint32_t)); 3225 if (rc < 0) 3226 return -1; 3227 nel = le32_to_cpu(buf[0]); 3228 lftr = NULL; 3229 for (i = 0; i < nel; i++) { 3230 ftr = malloc(sizeof(*ftr)); 3231 if (!ftr) 3232 return -1; 3233 3234 filename_trans_rule_init(ftr); 3235 3236 if (lftr) 3237 lftr->next = ftr; 3238 else 3239 *r = ftr; 3240 lftr = ftr; 3241 3242 rc = next_entry(buf, fp, sizeof(uint32_t)); 3243 if (rc < 0) 3244 return -1; 3245 3246 len = le32_to_cpu(buf[0]); 3247 3248 ftr->name = malloc(len + 1); 3249 if (!ftr->name) 3250 return -1; 3251 3252 rc = next_entry(ftr->name, fp, len); 3253 if (rc) 3254 return -1; 3255 ftr->name[len] = 0; 3256 3257 if (type_set_read(&ftr->stypes, fp)) 3258 return -1; 3259 3260 if (type_set_read(&ftr->ttypes, fp)) 3261 return -1; 3262 3263 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 3264 if (rc < 0) 3265 return -1; 3266 ftr->tclass = le32_to_cpu(buf[0]); 3267 ftr->otype = le32_to_cpu(buf[1]); 3268 } 3269 3270 return 0; 3271} 3272 3273static int range_trans_rule_read(range_trans_rule_t ** r, 3274 struct policy_file *fp) 3275{ 3276 uint32_t buf[1], nel; 3277 unsigned int i; 3278 range_trans_rule_t *rt, *lrt = NULL; 3279 int rc; 3280 3281 rc = next_entry(buf, fp, sizeof(uint32_t)); 3282 if (rc < 0) 3283 return -1; 3284 nel = le32_to_cpu(buf[0]); 3285 for (i = 0; i < nel; i++) { 3286 rt = malloc(sizeof(range_trans_rule_t)); 3287 if (!rt) { 3288 return -1; 3289 } 3290 range_trans_rule_init(rt); 3291 3292 if (lrt) 3293 lrt->next = rt; 3294 else 3295 *r = rt; 3296 3297 if (type_set_read(&rt->stypes, fp)) 3298 return -1; 3299 3300 if (type_set_read(&rt->ttypes, fp)) 3301 return -1; 3302 3303 if (ebitmap_read(&rt->tclasses, fp)) 3304 return -1; 3305 3306 if (mls_read_semantic_range_helper(&rt->trange, fp)) 3307 return -1; 3308 3309 lrt = rt; 3310 } 3311 3312 return 0; 3313} 3314 3315static int scope_index_read(scope_index_t * scope_index, 3316 unsigned int num_scope_syms, struct policy_file *fp) 3317{ 3318 unsigned int i; 3319 uint32_t buf[1]; 3320 int rc; 3321 3322 for (i = 0; i < num_scope_syms; i++) { 3323 if (ebitmap_read(scope_index->scope + i, fp) == -1) { 3324 return -1; 3325 } 3326 } 3327 rc = next_entry(buf, fp, sizeof(uint32_t)); 3328 if (rc < 0) 3329 return -1; 3330 scope_index->class_perms_len = le32_to_cpu(buf[0]); 3331 if (scope_index->class_perms_len == 0) { 3332 scope_index->class_perms_map = NULL; 3333 return 0; 3334 } 3335 if ((scope_index->class_perms_map = 3336 calloc(scope_index->class_perms_len, 3337 sizeof(*scope_index->class_perms_map))) == NULL) { 3338 return -1; 3339 } 3340 for (i = 0; i < scope_index->class_perms_len; i++) { 3341 if (ebitmap_read(scope_index->class_perms_map + i, fp) == -1) { 3342 return -1; 3343 } 3344 } 3345 return 0; 3346} 3347 3348static int avrule_decl_read(policydb_t * p, avrule_decl_t * decl, 3349 unsigned int num_scope_syms, struct policy_file *fp) 3350{ 3351 uint32_t buf[2], nprim, nel; 3352 unsigned int i, j; 3353 int rc; 3354 3355 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 3356 if (rc < 0) 3357 return -1; 3358 decl->decl_id = le32_to_cpu(buf[0]); 3359 decl->enabled = le32_to_cpu(buf[1]); 3360 if (cond_read_list(p, &decl->cond_list, fp) == -1 || 3361 avrule_read_list(p, &decl->avrules, fp) == -1 || 3362 role_trans_rule_read(p, &decl->role_tr_rules, fp) == -1 || 3363 role_allow_rule_read(&decl->role_allow_rules, fp) == -1) { 3364 return -1; 3365 } 3366 3367 if (p->policyvers >= MOD_POLICYDB_VERSION_FILENAME_TRANS && 3368 filename_trans_rule_read(&decl->filename_trans_rules, fp)) 3369 return -1; 3370 3371 if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS && 3372 range_trans_rule_read(&decl->range_tr_rules, fp) == -1) { 3373 return -1; 3374 } 3375 if (scope_index_read(&decl->required, num_scope_syms, fp) == -1 || 3376 scope_index_read(&decl->declared, num_scope_syms, fp) == -1) { 3377 return -1; 3378 } 3379 3380 for (i = 0; i < num_scope_syms; i++) { 3381 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 3382 if (rc < 0) 3383 return -1; 3384 nprim = le32_to_cpu(buf[0]); 3385 nel = le32_to_cpu(buf[1]); 3386 for (j = 0; j < nel; j++) { 3387 if (read_f[i] (p, decl->symtab[i].table, fp)) { 3388 return -1; 3389 } 3390 } 3391 decl->symtab[i].nprim = nprim; 3392 } 3393 return 0; 3394} 3395 3396static int avrule_block_read(policydb_t * p, 3397 avrule_block_t ** block, 3398 unsigned int num_scope_syms, 3399 struct policy_file *fp) 3400{ 3401 avrule_block_t *last_block = NULL, *curblock; 3402 uint32_t buf[1], num_blocks, nel; 3403 int rc; 3404 3405 rc = next_entry(buf, fp, sizeof(uint32_t)); 3406 if (rc < 0) 3407 return -1; 3408 num_blocks = le32_to_cpu(buf[0]); 3409 nel = num_blocks; 3410 while (num_blocks > 0) { 3411 avrule_decl_t *last_decl = NULL, *curdecl; 3412 uint32_t num_decls; 3413 if ((curblock = calloc(1, sizeof(*curblock))) == NULL) { 3414 return -1; 3415 } 3416 rc = next_entry(buf, fp, sizeof(uint32_t)); 3417 if (rc < 0) { 3418 free(curblock); 3419 return -1; 3420 } 3421 /* if this is the first block its non-optional, else its optional */ 3422 if (num_blocks != nel) 3423 curblock->flags |= AVRULE_OPTIONAL; 3424 3425 num_decls = le32_to_cpu(buf[0]); 3426 while (num_decls > 0) { 3427 if ((curdecl = avrule_decl_create(0)) == NULL) { 3428 avrule_block_destroy(curblock); 3429 return -1; 3430 } 3431 if (avrule_decl_read(p, curdecl, num_scope_syms, fp) == 3432 -1) { 3433 avrule_decl_destroy(curdecl); 3434 avrule_block_destroy(curblock); 3435 return -1; 3436 } 3437 if (curdecl->enabled) { 3438 if (curblock->enabled != NULL) { 3439 /* probably a corrupt file */ 3440 avrule_decl_destroy(curdecl); 3441 avrule_block_destroy(curblock); 3442 return -1; 3443 } 3444 curblock->enabled = curdecl; 3445 } 3446 /* one must be careful to reconstruct the 3447 * decl chain in its correct order */ 3448 if (curblock->branch_list == NULL) { 3449 curblock->branch_list = curdecl; 3450 } else { 3451 last_decl->next = curdecl; 3452 } 3453 last_decl = curdecl; 3454 num_decls--; 3455 } 3456 3457 if (*block == NULL) { 3458 *block = curblock; 3459 } else { 3460 last_block->next = curblock; 3461 } 3462 last_block = curblock; 3463 3464 num_blocks--; 3465 } 3466 3467 return 0; 3468} 3469 3470static int scope_read(policydb_t * p, int symnum, struct policy_file *fp) 3471{ 3472 scope_datum_t *scope = NULL; 3473 uint32_t buf[2]; 3474 char *key = NULL; 3475 size_t key_len; 3476 unsigned int i; 3477 hashtab_t h = p->scope[symnum].table; 3478 int rc; 3479 3480 rc = next_entry(buf, fp, sizeof(uint32_t)); 3481 if (rc < 0) 3482 goto cleanup; 3483 key_len = le32_to_cpu(buf[0]); 3484 key = malloc(key_len + 1); 3485 if (!key) 3486 goto cleanup; 3487 rc = next_entry(key, fp, key_len); 3488 if (rc < 0) 3489 goto cleanup; 3490 key[key_len] = '\0'; 3491 3492 /* ensure that there already exists a symbol with this key */ 3493 if (hashtab_search(p->symtab[symnum].table, key) == NULL) { 3494 goto cleanup; 3495 } 3496 3497 if ((scope = calloc(1, sizeof(*scope))) == NULL) { 3498 goto cleanup; 3499 } 3500 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 3501 if (rc < 0) 3502 goto cleanup; 3503 scope->scope = le32_to_cpu(buf[0]); 3504 scope->decl_ids_len = le32_to_cpu(buf[1]); 3505 assert(scope->decl_ids_len > 0); 3506 if ((scope->decl_ids = 3507 malloc(scope->decl_ids_len * sizeof(uint32_t))) == NULL) { 3508 goto cleanup; 3509 } 3510 rc = next_entry(scope->decl_ids, fp, sizeof(uint32_t) * scope->decl_ids_len); 3511 if (rc < 0) 3512 goto cleanup; 3513 for (i = 0; i < scope->decl_ids_len; i++) { 3514 scope->decl_ids[i] = le32_to_cpu(scope->decl_ids[i]); 3515 } 3516 3517 if (strcmp(key, "object_r") == 0 && h == p->p_roles_scope.table) { 3518 /* object_r was already added to this table in roles_init() */ 3519 scope_destroy(key, scope, NULL); 3520 } else { 3521 if (hashtab_insert(h, key, scope)) { 3522 goto cleanup; 3523 } 3524 } 3525 3526 return 0; 3527 3528 cleanup: 3529 scope_destroy(key, scope, NULL); 3530 return -1; 3531} 3532 3533/* 3534 * Read the configuration data from a policy database binary 3535 * representation file into a policy database structure. 3536 */ 3537int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) 3538{ 3539 3540 unsigned int i, j, r_policyvers; 3541 uint32_t buf[5]; 3542 size_t len, nprim, nel; 3543 char *policydb_str; 3544 struct policydb_compat_info *info; 3545 unsigned int policy_type, bufindex; 3546 ebitmap_node_t *tnode; 3547 int rc; 3548 3549 /* Read the magic number and string length. */ 3550 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 3551 if (rc < 0) 3552 return POLICYDB_ERROR; 3553 for (i = 0; i < 2; i++) 3554 buf[i] = le32_to_cpu(buf[i]); 3555 3556 if (buf[0] == POLICYDB_MAGIC) { 3557 policy_type = POLICY_KERN; 3558 } else if (buf[0] == POLICYDB_MOD_MAGIC) { 3559 policy_type = POLICY_MOD; 3560 } else { 3561 ERR(fp->handle, "policydb magic number %#08x does not " 3562 "match expected magic number %#08x or %#08x", 3563 buf[0], POLICYDB_MAGIC, POLICYDB_MOD_MAGIC); 3564 return POLICYDB_ERROR; 3565 } 3566 3567 len = buf[1]; 3568 if (len > POLICYDB_STRING_MAX_LENGTH) { 3569 ERR(fp->handle, "policydb string length too long "); 3570 return POLICYDB_ERROR; 3571 } 3572 3573 policydb_str = malloc(len + 1); 3574 if (!policydb_str) { 3575 ERR(fp->handle, "unable to allocate memory for policydb " 3576 "string of length %zu", len); 3577 return POLICYDB_ERROR; 3578 } 3579 rc = next_entry(policydb_str, fp, len); 3580 if (rc < 0) { 3581 ERR(fp->handle, "truncated policydb string identifier"); 3582 free(policydb_str); 3583 return POLICYDB_ERROR; 3584 } 3585 policydb_str[len] = 0; 3586 3587 if (policy_type == POLICY_KERN) { 3588 for (i = 0; i < POLICYDB_TARGET_SZ; i++) { 3589 if ((strcmp(policydb_str, policydb_target_strings[i]) 3590 == 0)) { 3591 policydb_set_target_platform(p, i); 3592 break; 3593 } 3594 } 3595 3596 if (i == POLICYDB_TARGET_SZ) { 3597 ERR(fp->handle, "cannot find a valid target for policy " 3598 "string %s", policydb_str); 3599 free(policydb_str); 3600 return POLICYDB_ERROR; 3601 } 3602 } else { 3603 if (strcmp(policydb_str, POLICYDB_MOD_STRING)) { 3604 ERR(fp->handle, "invalid string identifier %s", 3605 policydb_str); 3606 free(policydb_str); 3607 return POLICYDB_ERROR; 3608 } 3609 } 3610 3611 /* Done with policydb_str. */ 3612 free(policydb_str); 3613 policydb_str = NULL; 3614 3615 /* Read the version, config, and table sizes (and policy type if it's a module). */ 3616 if (policy_type == POLICY_KERN) 3617 nel = 4; 3618 else 3619 nel = 5; 3620 3621 rc = next_entry(buf, fp, sizeof(uint32_t) * nel); 3622 if (rc < 0) 3623 return POLICYDB_ERROR; 3624 for (i = 0; i < nel; i++) 3625 buf[i] = le32_to_cpu(buf[i]); 3626 3627 bufindex = 0; 3628 3629 if (policy_type == POLICY_MOD) { 3630 /* We know it's a module but not whether it's a base 3631 module or regular binary policy module. buf[0] 3632 tells us which. */ 3633 policy_type = buf[bufindex]; 3634 if (policy_type != POLICY_MOD && policy_type != POLICY_BASE) { 3635 ERR(fp->handle, "unknown module type: %#08x", 3636 policy_type); 3637 return POLICYDB_ERROR; 3638 } 3639 bufindex++; 3640 } 3641 3642 r_policyvers = buf[bufindex]; 3643 if (policy_type == POLICY_KERN) { 3644 if (r_policyvers < POLICYDB_VERSION_MIN || 3645 r_policyvers > POLICYDB_VERSION_MAX) { 3646 ERR(fp->handle, "policydb version %d does not match " 3647 "my version range %d-%d", buf[bufindex], 3648 POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); 3649 return POLICYDB_ERROR; 3650 } 3651 } else if (policy_type == POLICY_BASE || policy_type == POLICY_MOD) { 3652 if (r_policyvers < MOD_POLICYDB_VERSION_MIN || 3653 r_policyvers > MOD_POLICYDB_VERSION_MAX) { 3654 ERR(fp->handle, "policydb module version %d does " 3655 "not match my version range %d-%d", 3656 buf[bufindex], MOD_POLICYDB_VERSION_MIN, 3657 MOD_POLICYDB_VERSION_MAX); 3658 return POLICYDB_ERROR; 3659 } 3660 } else { 3661 assert(0); 3662 } 3663 bufindex++; 3664 3665 /* Set the policy type and version from the read values. */ 3666 p->policy_type = policy_type; 3667 p->policyvers = r_policyvers; 3668 3669 if (buf[bufindex] & POLICYDB_CONFIG_MLS) { 3670 p->mls = 1; 3671 } else { 3672 p->mls = 0; 3673 } 3674 3675 p->handle_unknown = buf[bufindex] & POLICYDB_CONFIG_UNKNOWN_MASK; 3676 3677 bufindex++; 3678 3679 info = policydb_lookup_compat(r_policyvers, policy_type, 3680 p->target_platform); 3681 if (!info) { 3682 ERR(fp->handle, "unable to find policy compat info " 3683 "for version %d", r_policyvers); 3684 goto bad; 3685 } 3686 3687 if (buf[bufindex] != info->sym_num 3688 || buf[bufindex + 1] != info->ocon_num) { 3689 ERR(fp->handle, 3690 "policydb table sizes (%d,%d) do not " "match mine (%d,%d)", 3691 buf[bufindex], buf[bufindex + 1], info->sym_num, 3692 info->ocon_num); 3693 goto bad; 3694 } 3695 3696 if (p->policy_type == POLICY_MOD) { 3697 /* Get the module name and version */ 3698 if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) { 3699 goto bad; 3700 } 3701 len = le32_to_cpu(buf[0]); 3702 if ((p->name = malloc(len + 1)) == NULL) { 3703 goto bad; 3704 } 3705 if ((rc = next_entry(p->name, fp, len)) < 0) { 3706 goto bad; 3707 } 3708 p->name[len] = '\0'; 3709 if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) { 3710 goto bad; 3711 } 3712 len = le32_to_cpu(buf[0]); 3713 if ((p->version = malloc(len + 1)) == NULL) { 3714 goto bad; 3715 } 3716 if ((rc = next_entry(p->version, fp, len)) < 0) { 3717 goto bad; 3718 } 3719 p->version[len] = '\0'; 3720 } 3721 3722 if ((p->policyvers >= POLICYDB_VERSION_POLCAP && 3723 p->policy_type == POLICY_KERN) || 3724 (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP && 3725 p->policy_type == POLICY_BASE) || 3726 (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP && 3727 p->policy_type == POLICY_MOD)) { 3728 if (ebitmap_read(&p->policycaps, fp)) 3729 goto bad; 3730 } 3731 3732 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && 3733 p->policy_type == POLICY_KERN) { 3734 if (ebitmap_read(&p->permissive_map, fp)) 3735 goto bad; 3736 } 3737 3738 for (i = 0; i < info->sym_num; i++) { 3739 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 3740 if (rc < 0) 3741 goto bad; 3742 nprim = le32_to_cpu(buf[0]); 3743 nel = le32_to_cpu(buf[1]); 3744 for (j = 0; j < nel; j++) { 3745 if (read_f[i] (p, p->symtab[i].table, fp)) 3746 goto bad; 3747 } 3748 3749 p->symtab[i].nprim = nprim; 3750 } 3751 3752 if (policy_type == POLICY_KERN) { 3753 if (avtab_read(&p->te_avtab, fp, r_policyvers)) 3754 goto bad; 3755 if (r_policyvers >= POLICYDB_VERSION_BOOL) 3756 if (cond_read_list(p, &p->cond_list, fp)) 3757 goto bad; 3758 if (role_trans_read(p, fp)) 3759 goto bad; 3760 if (role_allow_read(&p->role_allow, fp)) 3761 goto bad; 3762 if (r_policyvers >= POLICYDB_VERSION_FILENAME_TRANS && 3763 filename_trans_read(&p->filename_trans, fp)) 3764 goto bad; 3765 } else { 3766 /* first read the AV rule blocks, then the scope tables */ 3767 avrule_block_destroy(p->global); 3768 p->global = NULL; 3769 if (avrule_block_read(p, &p->global, info->sym_num, fp) == -1) { 3770 goto bad; 3771 } 3772 for (i = 0; i < info->sym_num; i++) { 3773 if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) { 3774 goto bad; 3775 } 3776 nel = le32_to_cpu(buf[0]); 3777 for (j = 0; j < nel; j++) { 3778 if (scope_read(p, i, fp)) 3779 goto bad; 3780 } 3781 } 3782 3783 } 3784 3785 if (policydb_index_decls(p)) 3786 goto bad; 3787 3788 if (policydb_index_classes(p)) 3789 goto bad; 3790 3791 if (policydb_index_others(fp->handle, p, verbose)) 3792 goto bad; 3793 3794 if (ocontext_read(info, p, fp) == -1) { 3795 goto bad; 3796 } 3797 3798 if (genfs_read(p, fp) == -1) { 3799 goto bad; 3800 } 3801 3802 if ((p->policy_type == POLICY_KERN 3803 && p->policyvers >= POLICYDB_VERSION_MLS) 3804 || (p->policy_type == POLICY_BASE 3805 && p->policyvers >= MOD_POLICYDB_VERSION_MLS 3806 && p->policyvers < MOD_POLICYDB_VERSION_RANGETRANS)) { 3807 if (range_read(p, fp)) { 3808 goto bad; 3809 } 3810 } 3811 3812 if (policy_type == POLICY_KERN) { 3813 p->type_attr_map = malloc(p->p_types.nprim * sizeof(ebitmap_t)); 3814 p->attr_type_map = malloc(p->p_types.nprim * sizeof(ebitmap_t)); 3815 if (!p->type_attr_map || !p->attr_type_map) 3816 goto bad; 3817 for (i = 0; i < p->p_types.nprim; i++) { 3818 ebitmap_init(&p->type_attr_map[i]); 3819 ebitmap_init(&p->attr_type_map[i]); 3820 } 3821 for (i = 0; i < p->p_types.nprim; i++) { 3822 if (r_policyvers >= POLICYDB_VERSION_AVTAB) { 3823 if (ebitmap_read(&p->type_attr_map[i], fp)) 3824 goto bad; 3825 ebitmap_for_each_bit(&p->type_attr_map[i], 3826 tnode, j) { 3827 if (!ebitmap_node_get_bit(tnode, j) 3828 || i == j) 3829 continue; 3830 if (ebitmap_set_bit 3831 (&p->attr_type_map[j], i, 1)) 3832 goto bad; 3833 } 3834 } 3835 /* add the type itself as the degenerate case */ 3836 if (ebitmap_set_bit(&p->type_attr_map[i], i, 1)) 3837 goto bad; 3838 } 3839 } 3840 3841 return POLICYDB_SUCCESS; 3842 bad: 3843 return POLICYDB_ERROR; 3844} 3845 3846int policydb_reindex_users(policydb_t * p) 3847{ 3848 unsigned int i = SYM_USERS; 3849 3850 if (p->user_val_to_struct) 3851 free(p->user_val_to_struct); 3852 if (p->sym_val_to_name[i]) 3853 free(p->sym_val_to_name[i]); 3854 3855 p->user_val_to_struct = (user_datum_t **) 3856 malloc(p->p_users.nprim * sizeof(user_datum_t *)); 3857 if (!p->user_val_to_struct) 3858 return -1; 3859 3860 p->sym_val_to_name[i] = (char **) 3861 malloc(p->symtab[i].nprim * sizeof(char *)); 3862 if (!p->sym_val_to_name[i]) 3863 return -1; 3864 3865 if (hashtab_map(p->symtab[i].table, index_f[i], p)) 3866 return -1; 3867 3868 /* Expand user roles for context validity checking */ 3869 if (hashtab_map(p->p_users.table, policydb_user_cache, p)) 3870 return -1; 3871 3872 return 0; 3873} 3874 3875void policy_file_init(policy_file_t *pf) 3876{ 3877 memset(pf, 0, sizeof(policy_file_t)); 3878} 3879 3880int policydb_set_target_platform(policydb_t *p, int platform) 3881{ 3882 if (platform == SEPOL_TARGET_SELINUX) 3883 p->target_platform = SEPOL_TARGET_SELINUX; 3884 else if (platform == SEPOL_TARGET_XEN) 3885 p->target_platform = SEPOL_TARGET_XEN; 3886 else 3887 return -1; 3888 3889 return 0; 3890} 3891 3892