113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Author: Karl MacMillan <kmacmillan@tresys.com> 213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Jason Tang <jtang@tresys.com> 313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Chris PeBenito <cpebenito@tresys.com> 413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Copyright (C) 2004-2005 Tresys Technology, LLC 613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * This library is free software; you can redistribute it and/or 813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * modify it under the terms of the GNU Lesser General Public 913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * License as published by the Free Software Foundation; either 1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * version 2.1 of the License, or (at your option) any later version. 1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * This library is distributed in the hope that it will be useful, 1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * but WITHOUT ANY WARRANTY; without even the implied warranty of 1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Lesser General Public License for more details. 1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * You should have received a copy of the GNU Lesser General Public 1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * License along with this library; if not, write to the Free Software 1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "policydb_internal.h" 2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "module_internal.h" 2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/link.h> 2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/expand.h> 2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/module.h> 2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "debug.h" 2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "private.h" 2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdio.h> 3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h> 3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <limits.h> 3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define SEPOL_PACKAGE_SECTION_FC 0xf97cff90 3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define SEPOL_PACKAGE_SECTION_SEUSER 0x97cff91 3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define SEPOL_PACKAGE_SECTION_USER_EXTRA 0x97cff92 3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define SEPOL_PACKAGE_SECTION_NETFILTER 0x97cff93 3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int policy_file_seek(struct policy_file *fp, size_t offset) 4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (fp->type) { 4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case PF_USE_STDIO: 4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (offset > LONG_MAX) { 4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle errno = EFAULT; 4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return fseek(fp->fp, (long)offset, SEEK_SET); 4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case PF_USE_MEMORY: 4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (offset > fp->size) { 5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle errno = EFAULT; 5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fp->data -= fp->size - fp->len; 5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fp->data += offset; 5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fp->len = fp->size - offset; 5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default: 5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 62afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Parisstatic int policy_file_length(struct policy_file *fp, size_t *out) 6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle long prev_offset, end_offset; 65afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris int rc; 6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (fp->type) { 6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case PF_USE_STDIO: 6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle prev_offset = ftell(fp->fp); 69afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris if (prev_offset < 0) 70afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris return prev_offset; 71afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris rc = fseek(fp->fp, 0L, SEEK_END); 72afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris if (rc < 0) 73afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris return rc; 7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle end_offset = ftell(fp->fp); 75afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris if (end_offset < 0) 76afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris return end_offset; 77afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris rc = fseek(fp->fp, prev_offset, SEEK_SET); 78afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris if (rc < 0) 79afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris return rc; 80afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris *out = end_offset; 81afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris break; 8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case PF_USE_MEMORY: 83afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris *out = fp->size; 84afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris break;; 8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default: 86afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris *out = 0; 87afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris break; 8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 89afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris return 0; 9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int module_package_init(sepol_module_package_t * p) 9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(p, 0, sizeof(sepol_module_package_t)); 9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (sepol_policydb_create(&p->policy)) 9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->version = 1; 9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int set_char(char **field, char *data, size_t len) 10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (*field) { 10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(*field); 10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *field = NULL; 10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (len) { 10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *field = malloc(len); 11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!*field) 11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memcpy(*field, data, len); 11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_module_package_create(sepol_module_package_t ** p) 11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 119afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris int rc; 120afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris 12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *p = calloc(1, sizeof(sepol_module_package_t)); 12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!(*p)) 12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 124afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris 125afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris rc = module_package_init(*p); 126afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris if (rc < 0) 127afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris free(*p); 128afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris 129afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris return rc; 13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_module_package_create) 13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Deallocates all memory associated with a module package, including 13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * the pointer itself. Does nothing if p is NULL. 13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid sepol_module_package_free(sepol_module_package_t * p) 13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p == NULL) 14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return; 14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_policydb_free(p->policy); 14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(p->file_contexts); 14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(p->seusers); 14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(p->user_extra); 14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(p->netfilter_contexts); 14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(p); 14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 15013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(sepol_module_package_free) 15113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlechar *sepol_module_package_get_file_contexts(sepol_module_package_t * p) 15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return p->file_contexts; 15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 15713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlesize_t sepol_module_package_get_file_contexts_len(sepol_module_package_t * p) 15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 15913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return p->file_contexts_len; 16013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlechar *sepol_module_package_get_seusers(sepol_module_package_t * p) 16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return p->seusers; 16513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 16613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 16713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlesize_t sepol_module_package_get_seusers_len(sepol_module_package_t * p) 16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 16913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return p->seusers_len; 17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlechar *sepol_module_package_get_user_extra(sepol_module_package_t * p) 17313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 17413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return p->user_extra; 17513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 17613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 17713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlesize_t sepol_module_package_get_user_extra_len(sepol_module_package_t * p) 17813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 17913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return p->user_extra_len; 18013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 18113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 18213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlechar *sepol_module_package_get_netfilter_contexts(sepol_module_package_t * p) 18313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 18413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return p->netfilter_contexts; 18513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 18613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 18713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlesize_t sepol_module_package_get_netfilter_contexts_len(sepol_module_package_t * 18813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p) 18913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 19013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return p->netfilter_contexts_len; 19113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 19213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 19313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_module_package_set_file_contexts(sepol_module_package_t * p, 19413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *data, size_t len) 19513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 19613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (set_char(&p->file_contexts, data, len)) 19713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 19813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 19913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->file_contexts_len = len; 20013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 20113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 20213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 20313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_module_package_set_seusers(sepol_module_package_t * p, 20413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *data, size_t len) 20513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 20613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (set_char(&p->seusers, data, len)) 20713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 20813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 20913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->seusers_len = len; 21013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 21113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 21213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 21313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_module_package_set_user_extra(sepol_module_package_t * p, 21413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *data, size_t len) 21513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 21613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (set_char(&p->user_extra, data, len)) 21713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 21813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 21913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->user_extra_len = len; 22013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 22113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 22213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 22313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_module_package_set_netfilter_contexts(sepol_module_package_t * p, 22413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *data, size_t len) 22513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 22613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (set_char(&p->netfilter_contexts, data, len)) 22713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 22813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 22913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->netfilter_contexts_len = len; 23013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 23113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 23213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 23313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlesepol_policydb_t *sepol_module_package_get_policy(sepol_module_package_t * p) 23413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 23513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return p->policy; 23613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 23713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 23813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Append each of the file contexts from each module to the base 23913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * policy's file context. 'base_context' will be reallocated to a 24013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * larger size (and thus it is an in/out reference 24113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * variable). 'base_fc_len' is the length of base's file context; it 24213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * too is a reference variable. Return 0 on success, -1 if out of 24313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * memory. */ 24413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int link_file_contexts(sepol_module_package_t * base, 24513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_module_package_t ** modules, 24613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int num_modules) 24713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 24813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle size_t fc_len; 24913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int i; 25013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *s; 25113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 25213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fc_len = base->file_contexts_len; 25313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < num_modules; i++) { 25413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fc_len += modules[i]->file_contexts_len; 25513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 25613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 25713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((s = (char *)realloc(base->file_contexts, fc_len)) == NULL) { 25813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 25913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 26013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base->file_contexts = s; 26113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < num_modules; i++) { 26213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memcpy(base->file_contexts + base->file_contexts_len, 26313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle modules[i]->file_contexts, 26413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle modules[i]->file_contexts_len); 26513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base->file_contexts_len += modules[i]->file_contexts_len; 26613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 26713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 26813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 26913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 27013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Append each of the netfilter contexts from each module to the base 27113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * policy's netfilter context. 'base_context' will be reallocated to a 27213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * larger size (and thus it is an in/out reference 27313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * variable). 'base_nc_len' is the length of base's netfilter contexts; it 27413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * too is a reference variable. Return 0 on success, -1 if out of 27513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * memory. */ 27613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int link_netfilter_contexts(sepol_module_package_t * base, 27713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_module_package_t ** modules, 27813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int num_modules) 27913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 28013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle size_t base_nc_len; 28113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int i; 28213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *base_context; 28313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 28413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_nc_len = base->netfilter_contexts_len; 28513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < num_modules; i++) { 28613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_nc_len += modules[i]->netfilter_contexts_len; 28713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 28813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 28913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((base_context = 29013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (char *)realloc(base->netfilter_contexts, base_nc_len)) == NULL) { 29113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 29213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 29313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base->netfilter_contexts = base_context; 29413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < num_modules; i++) { 29513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memcpy(base->netfilter_contexts + base->netfilter_contexts_len, 29613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle modules[i]->netfilter_contexts, 29713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle modules[i]->netfilter_contexts_len); 29813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base->netfilter_contexts_len += 29913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle modules[i]->netfilter_contexts_len; 30013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 30113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 30213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 30313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 30413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Links the module packages into the base. Returns 0 on success, -1 30513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * if a requirement was not met, or -2 for all other errors. */ 30613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_link_packages(sepol_handle_t * handle, 30713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_module_package_t * base, 30813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_module_package_t ** modules, int num_modules, 30913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int verbose) 31013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 31113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t **mod_pols = NULL; 31213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int i, retval; 31313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 31413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((mod_pols = calloc(num_modules, sizeof(*mod_pols))) == NULL) { 31513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Out of memory!"); 31613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -2; 31713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 31813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < num_modules; i++) { 31913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod_pols[i] = &modules[i]->policy->p; 32013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 32113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 32213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = link_modules(handle, &base->policy->p, mod_pols, num_modules, 32313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle verbose); 32413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(mod_pols); 32513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (retval == -3) { 32613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 32713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (retval < 0) { 32813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -2; 32913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 33013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 33113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (link_file_contexts(base, modules, num_modules) == -1) { 33213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Out of memory!"); 33313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -2; 33413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 33513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 33613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (link_netfilter_contexts(base, modules, num_modules) == -1) { 33713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Out of memory!"); 33813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -2; 33913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 34013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 34113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 34213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 34313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 34413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* buf must be large enough - no checks are performed */ 34513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define _read_helper_bufsize BUFSIZ 34613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int read_helper(char *buf, struct policy_file *file, uint32_t bytes) 34713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 34813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t offset, nel, read_len; 34913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int rc; 35013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 35113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle offset = 0; 35213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle nel = bytes; 35313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 35413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (nel) { 35513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (nel < _read_helper_bufsize) 35613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle read_len = nel; 35713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else 35813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle read_len = _read_helper_bufsize; 35913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = next_entry(&buf[offset], file, read_len); 36013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc < 0) 36113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 36213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle offset += read_len; 36313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle nel -= read_len; 36413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 36513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 36613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 36713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 36813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define MAXSECTIONS 100 36913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 37013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Get the section offsets from a package file, offsets will be malloc'd to 37113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * the appropriate size and the caller must free() them */ 37213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int module_package_read_offsets(sepol_module_package_t * mod, 37313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct policy_file *file, 37413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle size_t ** offsets, uint32_t * sections) 37513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 37613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t *buf = NULL, nsec; 37713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned i; 37813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle size_t *off = NULL; 37913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int rc; 38013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 38113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle buf = malloc(sizeof(uint32_t)*3); 38213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!buf) { 38313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "out of memory"); 38413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 38513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 38613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 38713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = next_entry(buf, file, sizeof(uint32_t) * 3); 38813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc < 0) { 38913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "module package header truncated"); 39013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 39113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 39213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (le32_to_cpu(buf[0]) != SEPOL_MODULE_PACKAGE_MAGIC) { 39313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 39413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "wrong magic number for module package: expected %#08x, got %#08x", 39513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle SEPOL_MODULE_PACKAGE_MAGIC, le32_to_cpu(buf[0])); 39613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 39713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 39813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 39913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->version = le32_to_cpu(buf[1]); 40013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle nsec = *sections = le32_to_cpu(buf[2]); 40113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 40213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (nsec > MAXSECTIONS) { 40313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "too many sections (%u) in module package", 40413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle nsec); 40513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 40613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 40713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 40813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle off = (size_t *) malloc((nsec + 1) * sizeof(size_t)); 40913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!off) { 41013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "out of memory"); 41113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 41213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 41313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 41413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(buf); 41513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle buf = malloc(sizeof(uint32_t) * nsec); 41613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!buf) { 41713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "out of memory"); 41813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 41913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 42013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = next_entry(buf, file, sizeof(uint32_t) * nsec); 42113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc < 0) { 42213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "module package offset array truncated"); 42313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 42413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 42513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 42613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < nsec; i++) { 42713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle off[i] = le32_to_cpu(buf[i]); 42813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (i && off[i] < off[i - 1]) { 42913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "offsets are not increasing (at %u, " 43013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "offset %zu -> %zu", i, off[i - 1], 43113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle off[i]); 432a0440a66c3418842f309fc4f78f2aad87ba6c96fStephen Smalley goto err; 43313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 43413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 43513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 436afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris rc = policy_file_length(file, &off[nsec]); 437afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris if (rc < 0) 438afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris goto err; 439afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris 440a0440a66c3418842f309fc4f78f2aad87ba6c96fStephen Smalley if (nsec && off[nsec] < off[nsec-1]) { 441a0440a66c3418842f309fc4f78f2aad87ba6c96fStephen Smalley ERR(file->handle, "offset greater than file size (at %u, " 442a0440a66c3418842f309fc4f78f2aad87ba6c96fStephen Smalley "offset %zu -> %zu", nsec, off[nsec - 1], 443a0440a66c3418842f309fc4f78f2aad87ba6c96fStephen Smalley off[nsec]); 444a0440a66c3418842f309fc4f78f2aad87ba6c96fStephen Smalley goto err; 445a0440a66c3418842f309fc4f78f2aad87ba6c96fStephen Smalley } 44613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *offsets = off; 447a0440a66c3418842f309fc4f78f2aad87ba6c96fStephen Smalley free(buf); 44813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 44913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 45013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleerr: 45113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(buf); 45213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(off); 45313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 45413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 45513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 45613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Flags for which sections have been seen during parsing of module package. */ 45713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define SEEN_MOD 1 45813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define SEEN_FC 2 45913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define SEEN_SEUSER 4 46013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define SEEN_USER_EXTRA 8 46113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define SEEN_NETFILTER 16 46213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 46313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_module_package_read(sepol_module_package_t * mod, 46413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct sepol_policy_file *spf, int verbose) 46513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 46613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct policy_file *file = &spf->pf; 46713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t buf[1], nsec; 46813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle size_t *offsets, len; 46913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int rc; 47013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned i, seen = 0; 47113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 47213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (module_package_read_offsets(mod, file, &offsets, &nsec)) 47313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 47413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 47513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* we know the section offsets, seek to them and read in the data */ 47613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 47713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < nsec; i++) { 47813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 47913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policy_file_seek(file, offsets[i])) { 48013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "error seeking to offset %zu for " 48113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "module package section %u", offsets[i], i); 48213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 48313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 48413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 48513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle len = offsets[i + 1] - offsets[i]; 48613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 48713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (len < sizeof(uint32_t)) { 48813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "module package section %u " 48913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "has too small length %zu", i, len); 49013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 49113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 49213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 49313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* read the magic number, so that we know which function to call */ 49413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = next_entry(buf, file, sizeof(uint32_t)); 49513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc < 0) { 49613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 49713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "module package section %u truncated, lacks magic number", 49813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 49913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 50013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 50113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 50213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (le32_to_cpu(buf[0])) { 50313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PACKAGE_SECTION_FC: 50413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (seen & SEEN_FC) { 50513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 50613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "found multiple file contexts sections in module package (at section %u)", 50713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 50813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 50913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 51013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 51113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->file_contexts_len = len - sizeof(uint32_t); 51213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->file_contexts = 51313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (char *)malloc(mod->file_contexts_len); 51413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!mod->file_contexts) { 51513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "out of memory"); 51613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 51713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 51813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (read_helper 51913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (mod->file_contexts, file, 52013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->file_contexts_len)) { 52113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 52213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "invalid file contexts section at section %u", 52313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 52413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(mod->file_contexts); 52513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->file_contexts = NULL; 52613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 52713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 52813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle seen |= SEEN_FC; 52913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 53013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PACKAGE_SECTION_SEUSER: 53113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (seen & SEEN_SEUSER) { 53213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 53313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "found multiple seuser sections in module package (at section %u)", 53413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 53513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 53613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 53713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 53813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->seusers_len = len - sizeof(uint32_t); 53913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->seusers = (char *)malloc(mod->seusers_len); 54013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!mod->seusers) { 54113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "out of memory"); 54213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 54313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 54413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (read_helper(mod->seusers, file, mod->seusers_len)) { 54513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 54613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "invalid seuser section at section %u", i); 54713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(mod->seusers); 54813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->seusers = NULL; 54913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 55013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 55113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle seen |= SEEN_SEUSER; 55213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 55313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PACKAGE_SECTION_USER_EXTRA: 55413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (seen & SEEN_USER_EXTRA) { 55513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 55613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "found multiple user_extra sections in module package (at section %u)", 55713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 55813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 55913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 56013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 56113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->user_extra_len = len - sizeof(uint32_t); 56213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->user_extra = (char *)malloc(mod->user_extra_len); 56313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!mod->user_extra) { 56413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "out of memory"); 56513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 56613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 56713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (read_helper 56813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (mod->user_extra, file, mod->user_extra_len)) { 56913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 57013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "invalid user_extra section at section %u", 57113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 57213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(mod->user_extra); 57313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->user_extra = NULL; 57413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 57513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 57613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle seen |= SEEN_USER_EXTRA; 57713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 57813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PACKAGE_SECTION_NETFILTER: 57913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (seen & SEEN_NETFILTER) { 58013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 58113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "found multiple netfilter contexts sections in module package (at section %u)", 58213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 58313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 58413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 58513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 58613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->netfilter_contexts_len = len - sizeof(uint32_t); 58713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->netfilter_contexts = 58813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (char *)malloc(mod->netfilter_contexts_len); 58913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!mod->netfilter_contexts) { 59013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "out of memory"); 59113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 59213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 59313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (read_helper 59413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (mod->netfilter_contexts, file, 59513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->netfilter_contexts_len)) { 59613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 59713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "invalid netfilter contexts section at section %u", 59813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 59913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(mod->netfilter_contexts); 60013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->netfilter_contexts = NULL; 60113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 60213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 60313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle seen |= SEEN_NETFILTER; 60413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 60513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case POLICYDB_MOD_MAGIC: 60613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (seen & SEEN_MOD) { 60713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 60813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "found multiple module sections in module package (at section %u)", 60913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 61013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 61113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 61213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 61313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* seek back to where the magic number was */ 61413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policy_file_seek(file, offsets[i])) 61513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 61613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 61713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = policydb_read(&mod->policy->p, file, verbose); 61813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc < 0) { 61913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 62013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "invalid module in module package (at section %u)", 62113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 62213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 62313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 62413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle seen |= SEEN_MOD; 62513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 62613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default: 62713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* unknown section, ignore */ 62813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 62913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "unknown magic number at section %u, offset: %zx, number: %ux ", 63013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i, offsets[i], le32_to_cpu(buf[0])); 63113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 63213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 63313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 63413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 63513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((seen & SEEN_MOD) == 0) { 63613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "missing module in module package"); 63713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 63813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 63913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 64013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(offsets); 64113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 64213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 64313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 64413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(offsets); 64513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 64613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 64713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 64813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_module_package_info(struct sepol_policy_file *spf, int *type, 64913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char **name, char **version) 65013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 65113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct policy_file *file = &spf->pf; 65213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_module_package_t *mod = NULL; 65313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t buf[5], len, nsec; 65413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle size_t *offsets = NULL; 65513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned i, seen = 0; 65613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id; 65713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int rc; 65813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 65913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (sepol_module_package_create(&mod)) 66013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 66113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 66213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (module_package_read_offsets(mod, file, &offsets, &nsec)) { 66313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 66413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 66513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 66613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < nsec; i++) { 66713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 66813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policy_file_seek(file, offsets[i])) { 66913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "error seeking to offset " 67013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "%zu for module package section %u", offsets[i], i); 67113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 67213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 67313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 67413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle len = offsets[i + 1] - offsets[i]; 67513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 67613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (len < sizeof(uint32_t)) { 67713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 67813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "module package section %u has too small length %u", 67913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i, len); 68013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 68113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 68213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 68313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* read the magic number, so that we know which function to call */ 68413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = next_entry(buf, file, sizeof(uint32_t) * 2); 68513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc < 0) { 68613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 68713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "module package section %u truncated, lacks magic number", 68813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 68913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 69013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 69113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 69213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (le32_to_cpu(buf[0])) { 69313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PACKAGE_SECTION_FC: 69413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* skip file contexts */ 69513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (seen & SEEN_FC) { 69613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 69713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "found multiple file contexts sections in module package (at section %u)", 69813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 69913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 70013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 70113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle seen |= SEEN_FC; 70213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 70313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PACKAGE_SECTION_SEUSER: 70413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* skip seuser */ 70513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (seen & SEEN_SEUSER) { 70613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 70713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "found seuser sections in module package (at section %u)", 70813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 70913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 71013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 71113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle seen |= SEEN_SEUSER; 71213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 71313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PACKAGE_SECTION_USER_EXTRA: 71413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* skip user_extra */ 71513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (seen & SEEN_USER_EXTRA) { 71613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 71713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "found user_extra sections in module package (at section %u)", 71813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 71913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 72013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 72113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle seen |= SEEN_USER_EXTRA; 72213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 72313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PACKAGE_SECTION_NETFILTER: 72413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* skip netfilter contexts */ 72513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (seen & SEEN_NETFILTER) { 72613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 72713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "found multiple netfilter contexts sections in module package (at section %u)", 72813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 72913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 73013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 73113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle seen |= SEEN_NETFILTER; 73213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 73313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case POLICYDB_MOD_MAGIC: 73413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (seen & SEEN_MOD) { 73513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 73613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "found multiple module sections in module package (at section %u)", 73713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 73813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 73913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 74013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle len = le32_to_cpu(buf[1]); 74113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (len != strlen(POLICYDB_MOD_STRING)) { 74213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 74313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "module string length is wrong (at section %u)", 74413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 74513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 74613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 74713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 74813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* skip id */ 74913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id = malloc(len + 1); 75013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!id) { 75113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 75213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "out of memory (at section %u)", 75313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 75413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 75513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 75613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = next_entry(id, file, len); 75713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(id); 75813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc < 0) { 75913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 76013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "cannot get module string (at section %u)", 76113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 76213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 76313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 76413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 76513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = next_entry(buf, file, sizeof(uint32_t) * 5); 76613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc < 0) { 76713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 76813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "cannot get module header (at section %u)", 76913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 77013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 77113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 77213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 77313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *type = le32_to_cpu(buf[0]); 77413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* if base - we're done */ 77513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (*type == POLICY_BASE) { 77613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *name = NULL; 77713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *version = NULL; 77813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle seen |= SEEN_MOD; 77913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 78013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (*type != POLICY_MOD) { 78113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 78213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "module has invalid type %d (at section %u)", 78313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *type, i); 78413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 78513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 78613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 78713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* read the name and version */ 78813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = next_entry(buf, file, sizeof(uint32_t)); 78913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc < 0) { 79013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 79113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "cannot get module name len (at section %u)", 79213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 79313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 79413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 79513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle len = le32_to_cpu(buf[0]); 79613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *name = malloc(len + 1); 79713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!*name) { 79813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "out of memory"); 79913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 80013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 80113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = next_entry(*name, file, len); 80213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc < 0) { 80313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 80413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "cannot get module name string (at section %u)", 80513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 80613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 80713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 80813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (*name)[len] = '\0'; 80913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = next_entry(buf, file, sizeof(uint32_t)); 81013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc < 0) { 81113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 81213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "cannot get module version len (at section %u)", 81313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 81413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 81513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 81613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle len = le32_to_cpu(buf[0]); 81713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *version = malloc(len + 1); 81813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!*version) { 81913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "out of memory"); 82013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 82113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 82213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = next_entry(*version, file, len); 82313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc < 0) { 82413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 82513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "cannot get module version string (at section %u)", 82613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i); 82713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 82813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 82913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (*version)[len] = '\0'; 83013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle seen |= SEEN_MOD; 83113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 83213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default: 83313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 83413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 83513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 83613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 83713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 83813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((seen & SEEN_MOD) == 0) { 83913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, "missing module in module package"); 84013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 84113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 84213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 84313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_module_package_free(mod); 84413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(offsets); 84513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 84613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 84713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 84813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_module_package_free(mod); 84913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(offsets); 85013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 85113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 85213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 85313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int write_helper(char *data, size_t len, struct policy_file *file) 85413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 85513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int idx = 0; 85613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle size_t len2; 85713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 85813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (len) { 85913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (len > BUFSIZ) 86013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle len2 = BUFSIZ; 86113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else 86213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle len2 = len; 86313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 86413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (put_entry(&data[idx], 1, len2, file) != len2) { 86513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 86613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 86713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle len -= len2; 86813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle idx += len2; 86913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 87013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 87113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 87213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 87313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_module_package_write(sepol_module_package_t * p, 87413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct sepol_policy_file *spf) 87513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 87613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct policy_file *file = &spf->pf; 87713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_file_t polfile; 87813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t buf[5], offsets[5], len, nsec = 0; 87913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int i; 88013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 88113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->policy) { 88213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* compute policy length */ 88313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_file_init(&polfile); 88413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle polfile.type = PF_LEN; 88513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle polfile.handle = file->handle; 88613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policydb_write(&p->policy->p, &polfile)) 88713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 88813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle len = polfile.len; 88913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!polfile.len) 89013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 89113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle nsec++; 89213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 89313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 89413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* We don't support writing a package without a module at this point */ 89513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 89613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 89713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 89813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* seusers and user_extra only supported in base at the moment */ 89913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((p->seusers || p->user_extra) 90013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle && (p->policy->p.policy_type != SEPOL_POLICY_BASE)) { 90113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(file->handle, 90213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "seuser and user_extra sections only supported in base"); 90313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 90413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 90513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 90613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->file_contexts) 90713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle nsec++; 90813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 90913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->seusers) 91013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle nsec++; 91113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 91213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->user_extra) 91313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle nsec++; 91413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 91513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->netfilter_contexts) 91613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle nsec++; 91713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 91813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle buf[0] = cpu_to_le32(SEPOL_MODULE_PACKAGE_MAGIC); 91913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle buf[1] = cpu_to_le32(p->version); 92013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle buf[2] = cpu_to_le32(nsec); 92113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (put_entry(buf, sizeof(uint32_t), 3, file) != 3) 92213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 92313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 92413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* calculate offsets */ 92513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle offsets[0] = (nsec + 3) * sizeof(uint32_t); 92613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle buf[0] = cpu_to_le32(offsets[0]); 92713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 92813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i = 1; 92913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->file_contexts) { 93013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle offsets[i] = offsets[i - 1] + len; 93113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle buf[i] = cpu_to_le32(offsets[i]); 93213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* add a uint32_t to compensate for the magic number */ 93313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle len = p->file_contexts_len + sizeof(uint32_t); 93413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i++; 93513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 93613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->seusers) { 93713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle offsets[i] = offsets[i - 1] + len; 93813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle buf[i] = cpu_to_le32(offsets[i]); 93913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle len = p->seusers_len + sizeof(uint32_t); 94013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i++; 94113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 94213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->user_extra) { 94313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle offsets[i] = offsets[i - 1] + len; 94413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle buf[i] = cpu_to_le32(offsets[i]); 94513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle len = p->user_extra_len + sizeof(uint32_t); 94613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i++; 94713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 94813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->netfilter_contexts) { 94913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle offsets[i] = offsets[i - 1] + len; 95013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle buf[i] = cpu_to_le32(offsets[i]); 95113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle len = p->netfilter_contexts_len + sizeof(uint32_t); 95213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i++; 95313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 95413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (put_entry(buf, sizeof(uint32_t), nsec, file) != nsec) 95513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 95613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 95713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* write sections */ 95813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 95913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policydb_write(&p->policy->p, file)) 96013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 96113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 96213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->file_contexts) { 96313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_FC); 96413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (put_entry(buf, sizeof(uint32_t), 1, file) != 1) 96513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 96613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (write_helper(p->file_contexts, p->file_contexts_len, file)) 96713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 96813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 96913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->seusers) { 97013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_SEUSER); 97113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (put_entry(buf, sizeof(uint32_t), 1, file) != 1) 97213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 97313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (write_helper(p->seusers, p->seusers_len, file)) 97413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 97513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 97613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 97713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->user_extra) { 97813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_USER_EXTRA); 97913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (put_entry(buf, sizeof(uint32_t), 1, file) != 1) 98013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 98113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (write_helper(p->user_extra, p->user_extra_len, file)) 98213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 98313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 98413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->netfilter_contexts) { 98513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_NETFILTER); 98613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (put_entry(buf, sizeof(uint32_t), 1, file) != 1) 98713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 98813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (write_helper 98913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (p->netfilter_contexts, p->netfilter_contexts_len, file)) 99013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 99113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 99213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 99313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 99413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 99513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_link_modules(sepol_handle_t * handle, 99613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_policydb_t * base, 99713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_policydb_t ** modules, size_t len, int verbose) 99813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 99913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return link_modules(handle, &base->p, (policydb_t **) modules, len, 100013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle verbose); 100113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 100213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 100313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_expand_module(sepol_handle_t * handle, 100413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_policydb_t * base, 100513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_policydb_t * out, int verbose, int check) 100613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 100713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return expand_module(handle, &base->p, &out->p, verbose, check); 100813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 1009