1255e72915d4cbddceb435e13d81601755714e9fSE Android/* Author: Karl MacMillan <kmacmillan@tresys.com> 2255e72915d4cbddceb435e13d81601755714e9fSE Android * Jason Tang <jtang@tresys.com> 3255e72915d4cbddceb435e13d81601755714e9fSE Android * Chris PeBenito <cpebenito@tresys.com> 4255e72915d4cbddceb435e13d81601755714e9fSE Android * 5255e72915d4cbddceb435e13d81601755714e9fSE Android * Copyright (C) 2004-2005 Tresys Technology, LLC 6255e72915d4cbddceb435e13d81601755714e9fSE Android * 7255e72915d4cbddceb435e13d81601755714e9fSE Android * This library is free software; you can redistribute it and/or 8255e72915d4cbddceb435e13d81601755714e9fSE Android * modify it under the terms of the GNU Lesser General Public 9255e72915d4cbddceb435e13d81601755714e9fSE Android * License as published by the Free Software Foundation; either 10255e72915d4cbddceb435e13d81601755714e9fSE Android * version 2.1 of the License, or (at your option) any later version. 11255e72915d4cbddceb435e13d81601755714e9fSE Android * 12255e72915d4cbddceb435e13d81601755714e9fSE Android * This library is distributed in the hope that it will be useful, 13255e72915d4cbddceb435e13d81601755714e9fSE Android * but WITHOUT ANY WARRANTY; without even the implied warranty of 14255e72915d4cbddceb435e13d81601755714e9fSE Android * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15255e72915d4cbddceb435e13d81601755714e9fSE Android * Lesser General Public License for more details. 16255e72915d4cbddceb435e13d81601755714e9fSE Android * 17255e72915d4cbddceb435e13d81601755714e9fSE Android * You should have received a copy of the GNU Lesser General Public 18255e72915d4cbddceb435e13d81601755714e9fSE Android * License along with this library; if not, write to the Free Software 19255e72915d4cbddceb435e13d81601755714e9fSE Android * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20255e72915d4cbddceb435e13d81601755714e9fSE Android */ 21255e72915d4cbddceb435e13d81601755714e9fSE Android 22255e72915d4cbddceb435e13d81601755714e9fSE Android#include "policydb_internal.h" 23255e72915d4cbddceb435e13d81601755714e9fSE Android#include "module_internal.h" 24255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/link.h> 25255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/expand.h> 26255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/module.h> 27255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h" 28255e72915d4cbddceb435e13d81601755714e9fSE Android#include "private.h" 29255e72915d4cbddceb435e13d81601755714e9fSE Android 30255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdio.h> 31255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h> 32255e72915d4cbddceb435e13d81601755714e9fSE Android#include <limits.h> 33255e72915d4cbddceb435e13d81601755714e9fSE Android 34255e72915d4cbddceb435e13d81601755714e9fSE Android#define SEPOL_PACKAGE_SECTION_FC 0xf97cff90 35255e72915d4cbddceb435e13d81601755714e9fSE Android#define SEPOL_PACKAGE_SECTION_SEUSER 0x97cff91 36255e72915d4cbddceb435e13d81601755714e9fSE Android#define SEPOL_PACKAGE_SECTION_USER_EXTRA 0x97cff92 37255e72915d4cbddceb435e13d81601755714e9fSE Android#define SEPOL_PACKAGE_SECTION_NETFILTER 0x97cff93 38255e72915d4cbddceb435e13d81601755714e9fSE Android 39255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int policy_file_seek(struct policy_file *fp, size_t offset) 40255e72915d4cbddceb435e13d81601755714e9fSE Android{ 41255e72915d4cbddceb435e13d81601755714e9fSE Android switch (fp->type) { 42255e72915d4cbddceb435e13d81601755714e9fSE Android case PF_USE_STDIO: 43255e72915d4cbddceb435e13d81601755714e9fSE Android if (offset > LONG_MAX) { 44255e72915d4cbddceb435e13d81601755714e9fSE Android errno = EFAULT; 45255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 46255e72915d4cbddceb435e13d81601755714e9fSE Android } 47255e72915d4cbddceb435e13d81601755714e9fSE Android return fseek(fp->fp, (long)offset, SEEK_SET); 48255e72915d4cbddceb435e13d81601755714e9fSE Android case PF_USE_MEMORY: 49255e72915d4cbddceb435e13d81601755714e9fSE Android if (offset > fp->size) { 50255e72915d4cbddceb435e13d81601755714e9fSE Android errno = EFAULT; 51255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 52255e72915d4cbddceb435e13d81601755714e9fSE Android } 53255e72915d4cbddceb435e13d81601755714e9fSE Android fp->data -= fp->size - fp->len; 54255e72915d4cbddceb435e13d81601755714e9fSE Android fp->data += offset; 55255e72915d4cbddceb435e13d81601755714e9fSE Android fp->len = fp->size - offset; 56255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 57255e72915d4cbddceb435e13d81601755714e9fSE Android default: 58255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 59255e72915d4cbddceb435e13d81601755714e9fSE Android } 60255e72915d4cbddceb435e13d81601755714e9fSE Android} 61255e72915d4cbddceb435e13d81601755714e9fSE Android 62255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic size_t policy_file_length(struct policy_file *fp) 63255e72915d4cbddceb435e13d81601755714e9fSE Android{ 64255e72915d4cbddceb435e13d81601755714e9fSE Android long prev_offset, end_offset; 65255e72915d4cbddceb435e13d81601755714e9fSE Android switch (fp->type) { 66255e72915d4cbddceb435e13d81601755714e9fSE Android case PF_USE_STDIO: 67255e72915d4cbddceb435e13d81601755714e9fSE Android prev_offset = ftell(fp->fp); 68255e72915d4cbddceb435e13d81601755714e9fSE Android fseek(fp->fp, 0L, SEEK_END); 69255e72915d4cbddceb435e13d81601755714e9fSE Android end_offset = ftell(fp->fp); 70255e72915d4cbddceb435e13d81601755714e9fSE Android fseek(fp->fp, prev_offset, SEEK_SET); 71255e72915d4cbddceb435e13d81601755714e9fSE Android return end_offset; 72255e72915d4cbddceb435e13d81601755714e9fSE Android case PF_USE_MEMORY: 73255e72915d4cbddceb435e13d81601755714e9fSE Android return fp->size; 74255e72915d4cbddceb435e13d81601755714e9fSE Android default: 75255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 76255e72915d4cbddceb435e13d81601755714e9fSE Android } 77255e72915d4cbddceb435e13d81601755714e9fSE Android} 78255e72915d4cbddceb435e13d81601755714e9fSE Android 79255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int module_package_init(sepol_module_package_t * p) 80255e72915d4cbddceb435e13d81601755714e9fSE Android{ 81255e72915d4cbddceb435e13d81601755714e9fSE Android memset(p, 0, sizeof(sepol_module_package_t)); 82255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_policydb_create(&p->policy)) 83255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 84255e72915d4cbddceb435e13d81601755714e9fSE Android 85255e72915d4cbddceb435e13d81601755714e9fSE Android p->version = 1; 86255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 87255e72915d4cbddceb435e13d81601755714e9fSE Android} 88255e72915d4cbddceb435e13d81601755714e9fSE Android 89255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int set_char(char **field, char *data, size_t len) 90255e72915d4cbddceb435e13d81601755714e9fSE Android{ 91255e72915d4cbddceb435e13d81601755714e9fSE Android if (*field) { 92255e72915d4cbddceb435e13d81601755714e9fSE Android free(*field); 93255e72915d4cbddceb435e13d81601755714e9fSE Android *field = NULL; 94255e72915d4cbddceb435e13d81601755714e9fSE Android } 95255e72915d4cbddceb435e13d81601755714e9fSE Android if (len) { 96255e72915d4cbddceb435e13d81601755714e9fSE Android *field = malloc(len); 97255e72915d4cbddceb435e13d81601755714e9fSE Android if (!*field) 98255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 99255e72915d4cbddceb435e13d81601755714e9fSE Android memcpy(*field, data, len); 100255e72915d4cbddceb435e13d81601755714e9fSE Android } 101255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 102255e72915d4cbddceb435e13d81601755714e9fSE Android} 103255e72915d4cbddceb435e13d81601755714e9fSE Android 104255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_module_package_create(sepol_module_package_t ** p) 105255e72915d4cbddceb435e13d81601755714e9fSE Android{ 106255e72915d4cbddceb435e13d81601755714e9fSE Android *p = calloc(1, sizeof(sepol_module_package_t)); 107255e72915d4cbddceb435e13d81601755714e9fSE Android if (!(*p)) 108255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 109255e72915d4cbddceb435e13d81601755714e9fSE Android return module_package_init(*p); 110255e72915d4cbddceb435e13d81601755714e9fSE Android} 111255e72915d4cbddceb435e13d81601755714e9fSE Android 112255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_module_package_create) 113255e72915d4cbddceb435e13d81601755714e9fSE Android 114255e72915d4cbddceb435e13d81601755714e9fSE Android/* Deallocates all memory associated with a module package, including 115255e72915d4cbddceb435e13d81601755714e9fSE Android * the pointer itself. Does nothing if p is NULL. 116255e72915d4cbddceb435e13d81601755714e9fSE Android */ 117255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_module_package_free(sepol_module_package_t * p) 118255e72915d4cbddceb435e13d81601755714e9fSE Android{ 119255e72915d4cbddceb435e13d81601755714e9fSE Android if (p == NULL) 120255e72915d4cbddceb435e13d81601755714e9fSE Android return; 121255e72915d4cbddceb435e13d81601755714e9fSE Android 122255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_policydb_free(p->policy); 123255e72915d4cbddceb435e13d81601755714e9fSE Android free(p->file_contexts); 124255e72915d4cbddceb435e13d81601755714e9fSE Android free(p->seusers); 125255e72915d4cbddceb435e13d81601755714e9fSE Android free(p->user_extra); 126255e72915d4cbddceb435e13d81601755714e9fSE Android free(p->netfilter_contexts); 127255e72915d4cbddceb435e13d81601755714e9fSE Android free(p); 128255e72915d4cbddceb435e13d81601755714e9fSE Android} 129255e72915d4cbddceb435e13d81601755714e9fSE Android 130255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_module_package_free) 131255e72915d4cbddceb435e13d81601755714e9fSE Android 132255e72915d4cbddceb435e13d81601755714e9fSE Androidchar *sepol_module_package_get_file_contexts(sepol_module_package_t * p) 133255e72915d4cbddceb435e13d81601755714e9fSE Android{ 134255e72915d4cbddceb435e13d81601755714e9fSE Android return p->file_contexts; 135255e72915d4cbddceb435e13d81601755714e9fSE Android} 136255e72915d4cbddceb435e13d81601755714e9fSE Android 137255e72915d4cbddceb435e13d81601755714e9fSE Androidsize_t sepol_module_package_get_file_contexts_len(sepol_module_package_t * p) 138255e72915d4cbddceb435e13d81601755714e9fSE Android{ 139255e72915d4cbddceb435e13d81601755714e9fSE Android return p->file_contexts_len; 140255e72915d4cbddceb435e13d81601755714e9fSE Android} 141255e72915d4cbddceb435e13d81601755714e9fSE Android 142255e72915d4cbddceb435e13d81601755714e9fSE Androidchar *sepol_module_package_get_seusers(sepol_module_package_t * p) 143255e72915d4cbddceb435e13d81601755714e9fSE Android{ 144255e72915d4cbddceb435e13d81601755714e9fSE Android return p->seusers; 145255e72915d4cbddceb435e13d81601755714e9fSE Android} 146255e72915d4cbddceb435e13d81601755714e9fSE Android 147255e72915d4cbddceb435e13d81601755714e9fSE Androidsize_t sepol_module_package_get_seusers_len(sepol_module_package_t * p) 148255e72915d4cbddceb435e13d81601755714e9fSE Android{ 149255e72915d4cbddceb435e13d81601755714e9fSE Android return p->seusers_len; 150255e72915d4cbddceb435e13d81601755714e9fSE Android} 151255e72915d4cbddceb435e13d81601755714e9fSE Android 152255e72915d4cbddceb435e13d81601755714e9fSE Androidchar *sepol_module_package_get_user_extra(sepol_module_package_t * p) 153255e72915d4cbddceb435e13d81601755714e9fSE Android{ 154255e72915d4cbddceb435e13d81601755714e9fSE Android return p->user_extra; 155255e72915d4cbddceb435e13d81601755714e9fSE Android} 156255e72915d4cbddceb435e13d81601755714e9fSE Android 157255e72915d4cbddceb435e13d81601755714e9fSE Androidsize_t sepol_module_package_get_user_extra_len(sepol_module_package_t * p) 158255e72915d4cbddceb435e13d81601755714e9fSE Android{ 159255e72915d4cbddceb435e13d81601755714e9fSE Android return p->user_extra_len; 160255e72915d4cbddceb435e13d81601755714e9fSE Android} 161255e72915d4cbddceb435e13d81601755714e9fSE Android 162255e72915d4cbddceb435e13d81601755714e9fSE Androidchar *sepol_module_package_get_netfilter_contexts(sepol_module_package_t * p) 163255e72915d4cbddceb435e13d81601755714e9fSE Android{ 164255e72915d4cbddceb435e13d81601755714e9fSE Android return p->netfilter_contexts; 165255e72915d4cbddceb435e13d81601755714e9fSE Android} 166255e72915d4cbddceb435e13d81601755714e9fSE Android 167255e72915d4cbddceb435e13d81601755714e9fSE Androidsize_t sepol_module_package_get_netfilter_contexts_len(sepol_module_package_t * 168255e72915d4cbddceb435e13d81601755714e9fSE Android p) 169255e72915d4cbddceb435e13d81601755714e9fSE Android{ 170255e72915d4cbddceb435e13d81601755714e9fSE Android return p->netfilter_contexts_len; 171255e72915d4cbddceb435e13d81601755714e9fSE Android} 172255e72915d4cbddceb435e13d81601755714e9fSE Android 173255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_module_package_set_file_contexts(sepol_module_package_t * p, 174255e72915d4cbddceb435e13d81601755714e9fSE Android char *data, size_t len) 175255e72915d4cbddceb435e13d81601755714e9fSE Android{ 176255e72915d4cbddceb435e13d81601755714e9fSE Android if (set_char(&p->file_contexts, data, len)) 177255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 178255e72915d4cbddceb435e13d81601755714e9fSE Android 179255e72915d4cbddceb435e13d81601755714e9fSE Android p->file_contexts_len = len; 180255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 181255e72915d4cbddceb435e13d81601755714e9fSE Android} 182255e72915d4cbddceb435e13d81601755714e9fSE Android 183255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_module_package_set_seusers(sepol_module_package_t * p, 184255e72915d4cbddceb435e13d81601755714e9fSE Android char *data, size_t len) 185255e72915d4cbddceb435e13d81601755714e9fSE Android{ 186255e72915d4cbddceb435e13d81601755714e9fSE Android if (set_char(&p->seusers, data, len)) 187255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 188255e72915d4cbddceb435e13d81601755714e9fSE Android 189255e72915d4cbddceb435e13d81601755714e9fSE Android p->seusers_len = len; 190255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 191255e72915d4cbddceb435e13d81601755714e9fSE Android} 192255e72915d4cbddceb435e13d81601755714e9fSE Android 193255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_module_package_set_user_extra(sepol_module_package_t * p, 194255e72915d4cbddceb435e13d81601755714e9fSE Android char *data, size_t len) 195255e72915d4cbddceb435e13d81601755714e9fSE Android{ 196255e72915d4cbddceb435e13d81601755714e9fSE Android if (set_char(&p->user_extra, data, len)) 197255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 198255e72915d4cbddceb435e13d81601755714e9fSE Android 199255e72915d4cbddceb435e13d81601755714e9fSE Android p->user_extra_len = len; 200255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 201255e72915d4cbddceb435e13d81601755714e9fSE Android} 202255e72915d4cbddceb435e13d81601755714e9fSE Android 203255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_module_package_set_netfilter_contexts(sepol_module_package_t * p, 204255e72915d4cbddceb435e13d81601755714e9fSE Android char *data, size_t len) 205255e72915d4cbddceb435e13d81601755714e9fSE Android{ 206255e72915d4cbddceb435e13d81601755714e9fSE Android if (set_char(&p->netfilter_contexts, data, len)) 207255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 208255e72915d4cbddceb435e13d81601755714e9fSE Android 209255e72915d4cbddceb435e13d81601755714e9fSE Android p->netfilter_contexts_len = len; 210255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 211255e72915d4cbddceb435e13d81601755714e9fSE Android} 212255e72915d4cbddceb435e13d81601755714e9fSE Android 213255e72915d4cbddceb435e13d81601755714e9fSE Androidsepol_policydb_t *sepol_module_package_get_policy(sepol_module_package_t * p) 214255e72915d4cbddceb435e13d81601755714e9fSE Android{ 215255e72915d4cbddceb435e13d81601755714e9fSE Android return p->policy; 216255e72915d4cbddceb435e13d81601755714e9fSE Android} 217255e72915d4cbddceb435e13d81601755714e9fSE Android 218255e72915d4cbddceb435e13d81601755714e9fSE Android/* Append each of the file contexts from each module to the base 219255e72915d4cbddceb435e13d81601755714e9fSE Android * policy's file context. 'base_context' will be reallocated to a 220255e72915d4cbddceb435e13d81601755714e9fSE Android * larger size (and thus it is an in/out reference 221255e72915d4cbddceb435e13d81601755714e9fSE Android * variable). 'base_fc_len' is the length of base's file context; it 222255e72915d4cbddceb435e13d81601755714e9fSE Android * too is a reference variable. Return 0 on success, -1 if out of 223255e72915d4cbddceb435e13d81601755714e9fSE Android * memory. */ 224255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int link_file_contexts(sepol_module_package_t * base, 225255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_module_package_t ** modules, 226255e72915d4cbddceb435e13d81601755714e9fSE Android int num_modules) 227255e72915d4cbddceb435e13d81601755714e9fSE Android{ 228255e72915d4cbddceb435e13d81601755714e9fSE Android size_t fc_len; 229255e72915d4cbddceb435e13d81601755714e9fSE Android int i; 230255e72915d4cbddceb435e13d81601755714e9fSE Android char *s; 231255e72915d4cbddceb435e13d81601755714e9fSE Android 232255e72915d4cbddceb435e13d81601755714e9fSE Android fc_len = base->file_contexts_len; 233255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < num_modules; i++) { 234255e72915d4cbddceb435e13d81601755714e9fSE Android fc_len += modules[i]->file_contexts_len; 235255e72915d4cbddceb435e13d81601755714e9fSE Android } 236255e72915d4cbddceb435e13d81601755714e9fSE Android 237255e72915d4cbddceb435e13d81601755714e9fSE Android if ((s = (char *)realloc(base->file_contexts, fc_len)) == NULL) { 238255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 239255e72915d4cbddceb435e13d81601755714e9fSE Android } 240255e72915d4cbddceb435e13d81601755714e9fSE Android base->file_contexts = s; 241255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < num_modules; i++) { 242255e72915d4cbddceb435e13d81601755714e9fSE Android memcpy(base->file_contexts + base->file_contexts_len, 243255e72915d4cbddceb435e13d81601755714e9fSE Android modules[i]->file_contexts, 244255e72915d4cbddceb435e13d81601755714e9fSE Android modules[i]->file_contexts_len); 245255e72915d4cbddceb435e13d81601755714e9fSE Android base->file_contexts_len += modules[i]->file_contexts_len; 246255e72915d4cbddceb435e13d81601755714e9fSE Android } 247255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 248255e72915d4cbddceb435e13d81601755714e9fSE Android} 249255e72915d4cbddceb435e13d81601755714e9fSE Android 250255e72915d4cbddceb435e13d81601755714e9fSE Android/* Append each of the netfilter contexts from each module to the base 251255e72915d4cbddceb435e13d81601755714e9fSE Android * policy's netfilter context. 'base_context' will be reallocated to a 252255e72915d4cbddceb435e13d81601755714e9fSE Android * larger size (and thus it is an in/out reference 253255e72915d4cbddceb435e13d81601755714e9fSE Android * variable). 'base_nc_len' is the length of base's netfilter contexts; it 254255e72915d4cbddceb435e13d81601755714e9fSE Android * too is a reference variable. Return 0 on success, -1 if out of 255255e72915d4cbddceb435e13d81601755714e9fSE Android * memory. */ 256255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int link_netfilter_contexts(sepol_module_package_t * base, 257255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_module_package_t ** modules, 258255e72915d4cbddceb435e13d81601755714e9fSE Android int num_modules) 259255e72915d4cbddceb435e13d81601755714e9fSE Android{ 260255e72915d4cbddceb435e13d81601755714e9fSE Android size_t base_nc_len; 261255e72915d4cbddceb435e13d81601755714e9fSE Android int i; 262255e72915d4cbddceb435e13d81601755714e9fSE Android char *base_context; 263255e72915d4cbddceb435e13d81601755714e9fSE Android 264255e72915d4cbddceb435e13d81601755714e9fSE Android base_nc_len = base->netfilter_contexts_len; 265255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < num_modules; i++) { 266255e72915d4cbddceb435e13d81601755714e9fSE Android base_nc_len += modules[i]->netfilter_contexts_len; 267255e72915d4cbddceb435e13d81601755714e9fSE Android } 268255e72915d4cbddceb435e13d81601755714e9fSE Android 269255e72915d4cbddceb435e13d81601755714e9fSE Android if ((base_context = 270255e72915d4cbddceb435e13d81601755714e9fSE Android (char *)realloc(base->netfilter_contexts, base_nc_len)) == NULL) { 271255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 272255e72915d4cbddceb435e13d81601755714e9fSE Android } 273255e72915d4cbddceb435e13d81601755714e9fSE Android base->netfilter_contexts = base_context; 274255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < num_modules; i++) { 275255e72915d4cbddceb435e13d81601755714e9fSE Android memcpy(base->netfilter_contexts + base->netfilter_contexts_len, 276255e72915d4cbddceb435e13d81601755714e9fSE Android modules[i]->netfilter_contexts, 277255e72915d4cbddceb435e13d81601755714e9fSE Android modules[i]->netfilter_contexts_len); 278255e72915d4cbddceb435e13d81601755714e9fSE Android base->netfilter_contexts_len += 279255e72915d4cbddceb435e13d81601755714e9fSE Android modules[i]->netfilter_contexts_len; 280255e72915d4cbddceb435e13d81601755714e9fSE Android } 281255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 282255e72915d4cbddceb435e13d81601755714e9fSE Android} 283255e72915d4cbddceb435e13d81601755714e9fSE Android 284255e72915d4cbddceb435e13d81601755714e9fSE Android/* Links the module packages into the base. Returns 0 on success, -1 285255e72915d4cbddceb435e13d81601755714e9fSE Android * if a requirement was not met, or -2 for all other errors. */ 286255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_link_packages(sepol_handle_t * handle, 287255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_module_package_t * base, 288255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_module_package_t ** modules, int num_modules, 289255e72915d4cbddceb435e13d81601755714e9fSE Android int verbose) 290255e72915d4cbddceb435e13d81601755714e9fSE Android{ 291255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t **mod_pols = NULL; 292255e72915d4cbddceb435e13d81601755714e9fSE Android int i, retval; 293255e72915d4cbddceb435e13d81601755714e9fSE Android 294255e72915d4cbddceb435e13d81601755714e9fSE Android if ((mod_pols = calloc(num_modules, sizeof(*mod_pols))) == NULL) { 295255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Out of memory!"); 296255e72915d4cbddceb435e13d81601755714e9fSE Android return -2; 297255e72915d4cbddceb435e13d81601755714e9fSE Android } 298255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < num_modules; i++) { 299255e72915d4cbddceb435e13d81601755714e9fSE Android mod_pols[i] = &modules[i]->policy->p; 300255e72915d4cbddceb435e13d81601755714e9fSE Android } 301255e72915d4cbddceb435e13d81601755714e9fSE Android 302255e72915d4cbddceb435e13d81601755714e9fSE Android retval = link_modules(handle, &base->policy->p, mod_pols, num_modules, 303255e72915d4cbddceb435e13d81601755714e9fSE Android verbose); 304255e72915d4cbddceb435e13d81601755714e9fSE Android free(mod_pols); 305255e72915d4cbddceb435e13d81601755714e9fSE Android if (retval == -3) { 306255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 307255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (retval < 0) { 308255e72915d4cbddceb435e13d81601755714e9fSE Android return -2; 309255e72915d4cbddceb435e13d81601755714e9fSE Android } 310255e72915d4cbddceb435e13d81601755714e9fSE Android 311255e72915d4cbddceb435e13d81601755714e9fSE Android if (link_file_contexts(base, modules, num_modules) == -1) { 312255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Out of memory!"); 313255e72915d4cbddceb435e13d81601755714e9fSE Android return -2; 314255e72915d4cbddceb435e13d81601755714e9fSE Android } 315255e72915d4cbddceb435e13d81601755714e9fSE Android 316255e72915d4cbddceb435e13d81601755714e9fSE Android if (link_netfilter_contexts(base, modules, num_modules) == -1) { 317255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Out of memory!"); 318255e72915d4cbddceb435e13d81601755714e9fSE Android return -2; 319255e72915d4cbddceb435e13d81601755714e9fSE Android } 320255e72915d4cbddceb435e13d81601755714e9fSE Android 321255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 322255e72915d4cbddceb435e13d81601755714e9fSE Android} 323255e72915d4cbddceb435e13d81601755714e9fSE Android 324255e72915d4cbddceb435e13d81601755714e9fSE Android/* buf must be large enough - no checks are performed */ 325255e72915d4cbddceb435e13d81601755714e9fSE Android#define _read_helper_bufsize BUFSIZ 326255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int read_helper(char *buf, struct policy_file *file, uint32_t bytes) 327255e72915d4cbddceb435e13d81601755714e9fSE Android{ 328255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t offset, nel, read_len; 329255e72915d4cbddceb435e13d81601755714e9fSE Android int rc; 330255e72915d4cbddceb435e13d81601755714e9fSE Android 331255e72915d4cbddceb435e13d81601755714e9fSE Android offset = 0; 332255e72915d4cbddceb435e13d81601755714e9fSE Android nel = bytes; 333255e72915d4cbddceb435e13d81601755714e9fSE Android 334255e72915d4cbddceb435e13d81601755714e9fSE Android while (nel) { 335255e72915d4cbddceb435e13d81601755714e9fSE Android if (nel < _read_helper_bufsize) 336255e72915d4cbddceb435e13d81601755714e9fSE Android read_len = nel; 337255e72915d4cbddceb435e13d81601755714e9fSE Android else 338255e72915d4cbddceb435e13d81601755714e9fSE Android read_len = _read_helper_bufsize; 339255e72915d4cbddceb435e13d81601755714e9fSE Android rc = next_entry(&buf[offset], file, read_len); 340255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc < 0) 341255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 342255e72915d4cbddceb435e13d81601755714e9fSE Android offset += read_len; 343255e72915d4cbddceb435e13d81601755714e9fSE Android nel -= read_len; 344255e72915d4cbddceb435e13d81601755714e9fSE Android } 345255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 346255e72915d4cbddceb435e13d81601755714e9fSE Android} 347255e72915d4cbddceb435e13d81601755714e9fSE Android 348255e72915d4cbddceb435e13d81601755714e9fSE Android#define MAXSECTIONS 100 349255e72915d4cbddceb435e13d81601755714e9fSE Android 350255e72915d4cbddceb435e13d81601755714e9fSE Android/* Get the section offsets from a package file, offsets will be malloc'd to 351255e72915d4cbddceb435e13d81601755714e9fSE Android * the appropriate size and the caller must free() them */ 352255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int module_package_read_offsets(sepol_module_package_t * mod, 353255e72915d4cbddceb435e13d81601755714e9fSE Android struct policy_file *file, 354255e72915d4cbddceb435e13d81601755714e9fSE Android size_t ** offsets, uint32_t * sections) 355255e72915d4cbddceb435e13d81601755714e9fSE Android{ 356255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t *buf = NULL, nsec; 357255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned i; 358255e72915d4cbddceb435e13d81601755714e9fSE Android size_t *off = NULL; 359255e72915d4cbddceb435e13d81601755714e9fSE Android int rc; 360255e72915d4cbddceb435e13d81601755714e9fSE Android 361255e72915d4cbddceb435e13d81601755714e9fSE Android buf = malloc(sizeof(uint32_t)*3); 362255e72915d4cbddceb435e13d81601755714e9fSE Android if (!buf) { 363255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "out of memory"); 364255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 365255e72915d4cbddceb435e13d81601755714e9fSE Android } 366255e72915d4cbddceb435e13d81601755714e9fSE Android 367255e72915d4cbddceb435e13d81601755714e9fSE Android rc = next_entry(buf, file, sizeof(uint32_t) * 3); 368255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc < 0) { 369255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "module package header truncated"); 370255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 371255e72915d4cbddceb435e13d81601755714e9fSE Android } 372255e72915d4cbddceb435e13d81601755714e9fSE Android if (le32_to_cpu(buf[0]) != SEPOL_MODULE_PACKAGE_MAGIC) { 373255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 374255e72915d4cbddceb435e13d81601755714e9fSE Android "wrong magic number for module package: expected %#08x, got %#08x", 375255e72915d4cbddceb435e13d81601755714e9fSE Android SEPOL_MODULE_PACKAGE_MAGIC, le32_to_cpu(buf[0])); 376255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 377255e72915d4cbddceb435e13d81601755714e9fSE Android } 378255e72915d4cbddceb435e13d81601755714e9fSE Android 379255e72915d4cbddceb435e13d81601755714e9fSE Android mod->version = le32_to_cpu(buf[1]); 380255e72915d4cbddceb435e13d81601755714e9fSE Android nsec = *sections = le32_to_cpu(buf[2]); 381255e72915d4cbddceb435e13d81601755714e9fSE Android 382255e72915d4cbddceb435e13d81601755714e9fSE Android if (nsec > MAXSECTIONS) { 383255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "too many sections (%u) in module package", 384255e72915d4cbddceb435e13d81601755714e9fSE Android nsec); 385255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 386255e72915d4cbddceb435e13d81601755714e9fSE Android } 387255e72915d4cbddceb435e13d81601755714e9fSE Android 388255e72915d4cbddceb435e13d81601755714e9fSE Android off = (size_t *) malloc((nsec + 1) * sizeof(size_t)); 389255e72915d4cbddceb435e13d81601755714e9fSE Android if (!off) { 390255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "out of memory"); 391255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 392255e72915d4cbddceb435e13d81601755714e9fSE Android } 393255e72915d4cbddceb435e13d81601755714e9fSE Android 394255e72915d4cbddceb435e13d81601755714e9fSE Android free(buf); 395255e72915d4cbddceb435e13d81601755714e9fSE Android buf = malloc(sizeof(uint32_t) * nsec); 396255e72915d4cbddceb435e13d81601755714e9fSE Android if (!buf) { 397255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "out of memory"); 398255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 399255e72915d4cbddceb435e13d81601755714e9fSE Android } 400255e72915d4cbddceb435e13d81601755714e9fSE Android rc = next_entry(buf, file, sizeof(uint32_t) * nsec); 401255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc < 0) { 402255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "module package offset array truncated"); 403255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 404255e72915d4cbddceb435e13d81601755714e9fSE Android } 405255e72915d4cbddceb435e13d81601755714e9fSE Android 406255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < nsec; i++) { 407255e72915d4cbddceb435e13d81601755714e9fSE Android off[i] = le32_to_cpu(buf[i]); 408255e72915d4cbddceb435e13d81601755714e9fSE Android if (i && off[i] < off[i - 1]) { 409255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "offsets are not increasing (at %u, " 410255e72915d4cbddceb435e13d81601755714e9fSE Android "offset %zu -> %zu", i, off[i - 1], 411255e72915d4cbddceb435e13d81601755714e9fSE Android off[i]); 412255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 413255e72915d4cbddceb435e13d81601755714e9fSE Android } 414255e72915d4cbddceb435e13d81601755714e9fSE Android } 415255e72915d4cbddceb435e13d81601755714e9fSE Android 416255e72915d4cbddceb435e13d81601755714e9fSE Android off[nsec] = policy_file_length(file); 417255e72915d4cbddceb435e13d81601755714e9fSE Android if (nsec && off[nsec] < off[nsec-1]) { 418255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "offset greater than file size (at %u, " 419255e72915d4cbddceb435e13d81601755714e9fSE Android "offset %zu -> %zu", nsec, off[nsec - 1], 420255e72915d4cbddceb435e13d81601755714e9fSE Android off[nsec]); 421255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 422255e72915d4cbddceb435e13d81601755714e9fSE Android } 423255e72915d4cbddceb435e13d81601755714e9fSE Android *offsets = off; 424255e72915d4cbddceb435e13d81601755714e9fSE Android free(buf); 425255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 426255e72915d4cbddceb435e13d81601755714e9fSE Android 427255e72915d4cbddceb435e13d81601755714e9fSE Androiderr: 428255e72915d4cbddceb435e13d81601755714e9fSE Android free(buf); 429255e72915d4cbddceb435e13d81601755714e9fSE Android free(off); 430255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 431255e72915d4cbddceb435e13d81601755714e9fSE Android} 432255e72915d4cbddceb435e13d81601755714e9fSE Android 433255e72915d4cbddceb435e13d81601755714e9fSE Android/* Flags for which sections have been seen during parsing of module package. */ 434255e72915d4cbddceb435e13d81601755714e9fSE Android#define SEEN_MOD 1 435255e72915d4cbddceb435e13d81601755714e9fSE Android#define SEEN_FC 2 436255e72915d4cbddceb435e13d81601755714e9fSE Android#define SEEN_SEUSER 4 437255e72915d4cbddceb435e13d81601755714e9fSE Android#define SEEN_USER_EXTRA 8 438255e72915d4cbddceb435e13d81601755714e9fSE Android#define SEEN_NETFILTER 16 439255e72915d4cbddceb435e13d81601755714e9fSE Android 440255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_module_package_read(sepol_module_package_t * mod, 441255e72915d4cbddceb435e13d81601755714e9fSE Android struct sepol_policy_file *spf, int verbose) 442255e72915d4cbddceb435e13d81601755714e9fSE Android{ 443255e72915d4cbddceb435e13d81601755714e9fSE Android struct policy_file *file = &spf->pf; 444255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t buf[1], nsec; 445255e72915d4cbddceb435e13d81601755714e9fSE Android size_t *offsets, len; 446255e72915d4cbddceb435e13d81601755714e9fSE Android int rc; 447255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned i, seen = 0; 448255e72915d4cbddceb435e13d81601755714e9fSE Android 449255e72915d4cbddceb435e13d81601755714e9fSE Android if (module_package_read_offsets(mod, file, &offsets, &nsec)) 450255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 451255e72915d4cbddceb435e13d81601755714e9fSE Android 452255e72915d4cbddceb435e13d81601755714e9fSE Android /* we know the section offsets, seek to them and read in the data */ 453255e72915d4cbddceb435e13d81601755714e9fSE Android 454255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < nsec; i++) { 455255e72915d4cbddceb435e13d81601755714e9fSE Android 456255e72915d4cbddceb435e13d81601755714e9fSE Android if (policy_file_seek(file, offsets[i])) { 457255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "error seeking to offset %zu for " 458255e72915d4cbddceb435e13d81601755714e9fSE Android "module package section %u", offsets[i], i); 459255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 460255e72915d4cbddceb435e13d81601755714e9fSE Android } 461255e72915d4cbddceb435e13d81601755714e9fSE Android 462255e72915d4cbddceb435e13d81601755714e9fSE Android len = offsets[i + 1] - offsets[i]; 463255e72915d4cbddceb435e13d81601755714e9fSE Android 464255e72915d4cbddceb435e13d81601755714e9fSE Android if (len < sizeof(uint32_t)) { 465255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "module package section %u " 466255e72915d4cbddceb435e13d81601755714e9fSE Android "has too small length %zu", i, len); 467255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 468255e72915d4cbddceb435e13d81601755714e9fSE Android } 469255e72915d4cbddceb435e13d81601755714e9fSE Android 470255e72915d4cbddceb435e13d81601755714e9fSE Android /* read the magic number, so that we know which function to call */ 471255e72915d4cbddceb435e13d81601755714e9fSE Android rc = next_entry(buf, file, sizeof(uint32_t)); 472255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc < 0) { 473255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 474255e72915d4cbddceb435e13d81601755714e9fSE Android "module package section %u truncated, lacks magic number", 475255e72915d4cbddceb435e13d81601755714e9fSE Android i); 476255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 477255e72915d4cbddceb435e13d81601755714e9fSE Android } 478255e72915d4cbddceb435e13d81601755714e9fSE Android 479255e72915d4cbddceb435e13d81601755714e9fSE Android switch (le32_to_cpu(buf[0])) { 480255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PACKAGE_SECTION_FC: 481255e72915d4cbddceb435e13d81601755714e9fSE Android if (seen & SEEN_FC) { 482255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 483255e72915d4cbddceb435e13d81601755714e9fSE Android "found multiple file contexts sections in module package (at section %u)", 484255e72915d4cbddceb435e13d81601755714e9fSE Android i); 485255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 486255e72915d4cbddceb435e13d81601755714e9fSE Android } 487255e72915d4cbddceb435e13d81601755714e9fSE Android 488255e72915d4cbddceb435e13d81601755714e9fSE Android mod->file_contexts_len = len - sizeof(uint32_t); 489255e72915d4cbddceb435e13d81601755714e9fSE Android mod->file_contexts = 490255e72915d4cbddceb435e13d81601755714e9fSE Android (char *)malloc(mod->file_contexts_len); 491255e72915d4cbddceb435e13d81601755714e9fSE Android if (!mod->file_contexts) { 492255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "out of memory"); 493255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 494255e72915d4cbddceb435e13d81601755714e9fSE Android } 495255e72915d4cbddceb435e13d81601755714e9fSE Android if (read_helper 496255e72915d4cbddceb435e13d81601755714e9fSE Android (mod->file_contexts, file, 497255e72915d4cbddceb435e13d81601755714e9fSE Android mod->file_contexts_len)) { 498255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 499255e72915d4cbddceb435e13d81601755714e9fSE Android "invalid file contexts section at section %u", 500255e72915d4cbddceb435e13d81601755714e9fSE Android i); 501255e72915d4cbddceb435e13d81601755714e9fSE Android free(mod->file_contexts); 502255e72915d4cbddceb435e13d81601755714e9fSE Android mod->file_contexts = NULL; 503255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 504255e72915d4cbddceb435e13d81601755714e9fSE Android } 505255e72915d4cbddceb435e13d81601755714e9fSE Android seen |= SEEN_FC; 506255e72915d4cbddceb435e13d81601755714e9fSE Android break; 507255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PACKAGE_SECTION_SEUSER: 508255e72915d4cbddceb435e13d81601755714e9fSE Android if (seen & SEEN_SEUSER) { 509255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 510255e72915d4cbddceb435e13d81601755714e9fSE Android "found multiple seuser sections in module package (at section %u)", 511255e72915d4cbddceb435e13d81601755714e9fSE Android i); 512255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 513255e72915d4cbddceb435e13d81601755714e9fSE Android } 514255e72915d4cbddceb435e13d81601755714e9fSE Android 515255e72915d4cbddceb435e13d81601755714e9fSE Android mod->seusers_len = len - sizeof(uint32_t); 516255e72915d4cbddceb435e13d81601755714e9fSE Android mod->seusers = (char *)malloc(mod->seusers_len); 517255e72915d4cbddceb435e13d81601755714e9fSE Android if (!mod->seusers) { 518255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "out of memory"); 519255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 520255e72915d4cbddceb435e13d81601755714e9fSE Android } 521255e72915d4cbddceb435e13d81601755714e9fSE Android if (read_helper(mod->seusers, file, mod->seusers_len)) { 522255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 523255e72915d4cbddceb435e13d81601755714e9fSE Android "invalid seuser section at section %u", i); 524255e72915d4cbddceb435e13d81601755714e9fSE Android free(mod->seusers); 525255e72915d4cbddceb435e13d81601755714e9fSE Android mod->seusers = NULL; 526255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 527255e72915d4cbddceb435e13d81601755714e9fSE Android } 528255e72915d4cbddceb435e13d81601755714e9fSE Android seen |= SEEN_SEUSER; 529255e72915d4cbddceb435e13d81601755714e9fSE Android break; 530255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PACKAGE_SECTION_USER_EXTRA: 531255e72915d4cbddceb435e13d81601755714e9fSE Android if (seen & SEEN_USER_EXTRA) { 532255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 533255e72915d4cbddceb435e13d81601755714e9fSE Android "found multiple user_extra sections in module package (at section %u)", 534255e72915d4cbddceb435e13d81601755714e9fSE Android i); 535255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 536255e72915d4cbddceb435e13d81601755714e9fSE Android } 537255e72915d4cbddceb435e13d81601755714e9fSE Android 538255e72915d4cbddceb435e13d81601755714e9fSE Android mod->user_extra_len = len - sizeof(uint32_t); 539255e72915d4cbddceb435e13d81601755714e9fSE Android mod->user_extra = (char *)malloc(mod->user_extra_len); 540255e72915d4cbddceb435e13d81601755714e9fSE Android if (!mod->user_extra) { 541255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "out of memory"); 542255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 543255e72915d4cbddceb435e13d81601755714e9fSE Android } 544255e72915d4cbddceb435e13d81601755714e9fSE Android if (read_helper 545255e72915d4cbddceb435e13d81601755714e9fSE Android (mod->user_extra, file, mod->user_extra_len)) { 546255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 547255e72915d4cbddceb435e13d81601755714e9fSE Android "invalid user_extra section at section %u", 548255e72915d4cbddceb435e13d81601755714e9fSE Android i); 549255e72915d4cbddceb435e13d81601755714e9fSE Android free(mod->user_extra); 550255e72915d4cbddceb435e13d81601755714e9fSE Android mod->user_extra = NULL; 551255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 552255e72915d4cbddceb435e13d81601755714e9fSE Android } 553255e72915d4cbddceb435e13d81601755714e9fSE Android seen |= SEEN_USER_EXTRA; 554255e72915d4cbddceb435e13d81601755714e9fSE Android break; 555255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PACKAGE_SECTION_NETFILTER: 556255e72915d4cbddceb435e13d81601755714e9fSE Android if (seen & SEEN_NETFILTER) { 557255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 558255e72915d4cbddceb435e13d81601755714e9fSE Android "found multiple netfilter contexts sections in module package (at section %u)", 559255e72915d4cbddceb435e13d81601755714e9fSE Android i); 560255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 561255e72915d4cbddceb435e13d81601755714e9fSE Android } 562255e72915d4cbddceb435e13d81601755714e9fSE Android 563255e72915d4cbddceb435e13d81601755714e9fSE Android mod->netfilter_contexts_len = len - sizeof(uint32_t); 564255e72915d4cbddceb435e13d81601755714e9fSE Android mod->netfilter_contexts = 565255e72915d4cbddceb435e13d81601755714e9fSE Android (char *)malloc(mod->netfilter_contexts_len); 566255e72915d4cbddceb435e13d81601755714e9fSE Android if (!mod->netfilter_contexts) { 567255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "out of memory"); 568255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 569255e72915d4cbddceb435e13d81601755714e9fSE Android } 570255e72915d4cbddceb435e13d81601755714e9fSE Android if (read_helper 571255e72915d4cbddceb435e13d81601755714e9fSE Android (mod->netfilter_contexts, file, 572255e72915d4cbddceb435e13d81601755714e9fSE Android mod->netfilter_contexts_len)) { 573255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 574255e72915d4cbddceb435e13d81601755714e9fSE Android "invalid netfilter contexts section at section %u", 575255e72915d4cbddceb435e13d81601755714e9fSE Android i); 576255e72915d4cbddceb435e13d81601755714e9fSE Android free(mod->netfilter_contexts); 577255e72915d4cbddceb435e13d81601755714e9fSE Android mod->netfilter_contexts = NULL; 578255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 579255e72915d4cbddceb435e13d81601755714e9fSE Android } 580255e72915d4cbddceb435e13d81601755714e9fSE Android seen |= SEEN_NETFILTER; 581255e72915d4cbddceb435e13d81601755714e9fSE Android break; 582255e72915d4cbddceb435e13d81601755714e9fSE Android case POLICYDB_MOD_MAGIC: 583255e72915d4cbddceb435e13d81601755714e9fSE Android if (seen & SEEN_MOD) { 584255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 585255e72915d4cbddceb435e13d81601755714e9fSE Android "found multiple module sections in module package (at section %u)", 586255e72915d4cbddceb435e13d81601755714e9fSE Android i); 587255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 588255e72915d4cbddceb435e13d81601755714e9fSE Android } 589255e72915d4cbddceb435e13d81601755714e9fSE Android 590255e72915d4cbddceb435e13d81601755714e9fSE Android /* seek back to where the magic number was */ 591255e72915d4cbddceb435e13d81601755714e9fSE Android if (policy_file_seek(file, offsets[i])) 592255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 593255e72915d4cbddceb435e13d81601755714e9fSE Android 594255e72915d4cbddceb435e13d81601755714e9fSE Android rc = policydb_read(&mod->policy->p, file, verbose); 595255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc < 0) { 596255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 597255e72915d4cbddceb435e13d81601755714e9fSE Android "invalid module in module package (at section %u)", 598255e72915d4cbddceb435e13d81601755714e9fSE Android i); 599255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 600255e72915d4cbddceb435e13d81601755714e9fSE Android } 601255e72915d4cbddceb435e13d81601755714e9fSE Android seen |= SEEN_MOD; 602255e72915d4cbddceb435e13d81601755714e9fSE Android break; 603255e72915d4cbddceb435e13d81601755714e9fSE Android default: 604255e72915d4cbddceb435e13d81601755714e9fSE Android /* unknown section, ignore */ 605255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 606255e72915d4cbddceb435e13d81601755714e9fSE Android "unknown magic number at section %u, offset: %zx, number: %ux ", 607255e72915d4cbddceb435e13d81601755714e9fSE Android i, offsets[i], le32_to_cpu(buf[0])); 608255e72915d4cbddceb435e13d81601755714e9fSE Android break; 609255e72915d4cbddceb435e13d81601755714e9fSE Android } 610255e72915d4cbddceb435e13d81601755714e9fSE Android } 611255e72915d4cbddceb435e13d81601755714e9fSE Android 612255e72915d4cbddceb435e13d81601755714e9fSE Android if ((seen & SEEN_MOD) == 0) { 613255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "missing module in module package"); 614255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 615255e72915d4cbddceb435e13d81601755714e9fSE Android } 616255e72915d4cbddceb435e13d81601755714e9fSE Android 617255e72915d4cbddceb435e13d81601755714e9fSE Android free(offsets); 618255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 619255e72915d4cbddceb435e13d81601755714e9fSE Android 620255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 621255e72915d4cbddceb435e13d81601755714e9fSE Android free(offsets); 622255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 623255e72915d4cbddceb435e13d81601755714e9fSE Android} 624255e72915d4cbddceb435e13d81601755714e9fSE Android 625255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_module_package_info(struct sepol_policy_file *spf, int *type, 626255e72915d4cbddceb435e13d81601755714e9fSE Android char **name, char **version) 627255e72915d4cbddceb435e13d81601755714e9fSE Android{ 628255e72915d4cbddceb435e13d81601755714e9fSE Android struct policy_file *file = &spf->pf; 629255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_module_package_t *mod = NULL; 630255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t buf[5], len, nsec; 631255e72915d4cbddceb435e13d81601755714e9fSE Android size_t *offsets = NULL; 632255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned i, seen = 0; 633255e72915d4cbddceb435e13d81601755714e9fSE Android char *id; 634255e72915d4cbddceb435e13d81601755714e9fSE Android int rc; 635255e72915d4cbddceb435e13d81601755714e9fSE Android 636255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_module_package_create(&mod)) 637255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 638255e72915d4cbddceb435e13d81601755714e9fSE Android 639255e72915d4cbddceb435e13d81601755714e9fSE Android if (module_package_read_offsets(mod, file, &offsets, &nsec)) { 640255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 641255e72915d4cbddceb435e13d81601755714e9fSE Android } 642255e72915d4cbddceb435e13d81601755714e9fSE Android 643255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < nsec; i++) { 644255e72915d4cbddceb435e13d81601755714e9fSE Android 645255e72915d4cbddceb435e13d81601755714e9fSE Android if (policy_file_seek(file, offsets[i])) { 646255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "error seeking to offset " 647255e72915d4cbddceb435e13d81601755714e9fSE Android "%zu for module package section %u", offsets[i], i); 648255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 649255e72915d4cbddceb435e13d81601755714e9fSE Android } 650255e72915d4cbddceb435e13d81601755714e9fSE Android 651255e72915d4cbddceb435e13d81601755714e9fSE Android len = offsets[i + 1] - offsets[i]; 652255e72915d4cbddceb435e13d81601755714e9fSE Android 653255e72915d4cbddceb435e13d81601755714e9fSE Android if (len < sizeof(uint32_t)) { 654255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 655255e72915d4cbddceb435e13d81601755714e9fSE Android "module package section %u has too small length %u", 656255e72915d4cbddceb435e13d81601755714e9fSE Android i, len); 657255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 658255e72915d4cbddceb435e13d81601755714e9fSE Android } 659255e72915d4cbddceb435e13d81601755714e9fSE Android 660255e72915d4cbddceb435e13d81601755714e9fSE Android /* read the magic number, so that we know which function to call */ 661255e72915d4cbddceb435e13d81601755714e9fSE Android rc = next_entry(buf, file, sizeof(uint32_t) * 2); 662255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc < 0) { 663255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 664255e72915d4cbddceb435e13d81601755714e9fSE Android "module package section %u truncated, lacks magic number", 665255e72915d4cbddceb435e13d81601755714e9fSE Android i); 666255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 667255e72915d4cbddceb435e13d81601755714e9fSE Android } 668255e72915d4cbddceb435e13d81601755714e9fSE Android 669255e72915d4cbddceb435e13d81601755714e9fSE Android switch (le32_to_cpu(buf[0])) { 670255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PACKAGE_SECTION_FC: 671255e72915d4cbddceb435e13d81601755714e9fSE Android /* skip file contexts */ 672255e72915d4cbddceb435e13d81601755714e9fSE Android if (seen & SEEN_FC) { 673255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 674255e72915d4cbddceb435e13d81601755714e9fSE Android "found multiple file contexts sections in module package (at section %u)", 675255e72915d4cbddceb435e13d81601755714e9fSE Android i); 676255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 677255e72915d4cbddceb435e13d81601755714e9fSE Android } 678255e72915d4cbddceb435e13d81601755714e9fSE Android seen |= SEEN_FC; 679255e72915d4cbddceb435e13d81601755714e9fSE Android break; 680255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PACKAGE_SECTION_SEUSER: 681255e72915d4cbddceb435e13d81601755714e9fSE Android /* skip seuser */ 682255e72915d4cbddceb435e13d81601755714e9fSE Android if (seen & SEEN_SEUSER) { 683255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 684255e72915d4cbddceb435e13d81601755714e9fSE Android "found seuser sections in module package (at section %u)", 685255e72915d4cbddceb435e13d81601755714e9fSE Android i); 686255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 687255e72915d4cbddceb435e13d81601755714e9fSE Android } 688255e72915d4cbddceb435e13d81601755714e9fSE Android seen |= SEEN_SEUSER; 689255e72915d4cbddceb435e13d81601755714e9fSE Android break; 690255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PACKAGE_SECTION_USER_EXTRA: 691255e72915d4cbddceb435e13d81601755714e9fSE Android /* skip user_extra */ 692255e72915d4cbddceb435e13d81601755714e9fSE Android if (seen & SEEN_USER_EXTRA) { 693255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 694255e72915d4cbddceb435e13d81601755714e9fSE Android "found user_extra sections in module package (at section %u)", 695255e72915d4cbddceb435e13d81601755714e9fSE Android i); 696255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 697255e72915d4cbddceb435e13d81601755714e9fSE Android } 698255e72915d4cbddceb435e13d81601755714e9fSE Android seen |= SEEN_USER_EXTRA; 699255e72915d4cbddceb435e13d81601755714e9fSE Android break; 700255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PACKAGE_SECTION_NETFILTER: 701255e72915d4cbddceb435e13d81601755714e9fSE Android /* skip netfilter contexts */ 702255e72915d4cbddceb435e13d81601755714e9fSE Android if (seen & SEEN_NETFILTER) { 703255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 704255e72915d4cbddceb435e13d81601755714e9fSE Android "found multiple netfilter contexts sections in module package (at section %u)", 705255e72915d4cbddceb435e13d81601755714e9fSE Android i); 706255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 707255e72915d4cbddceb435e13d81601755714e9fSE Android } 708255e72915d4cbddceb435e13d81601755714e9fSE Android seen |= SEEN_NETFILTER; 709255e72915d4cbddceb435e13d81601755714e9fSE Android break; 710255e72915d4cbddceb435e13d81601755714e9fSE Android case POLICYDB_MOD_MAGIC: 711255e72915d4cbddceb435e13d81601755714e9fSE Android if (seen & SEEN_MOD) { 712255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 713255e72915d4cbddceb435e13d81601755714e9fSE Android "found multiple module sections in module package (at section %u)", 714255e72915d4cbddceb435e13d81601755714e9fSE Android i); 715255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 716255e72915d4cbddceb435e13d81601755714e9fSE Android } 717255e72915d4cbddceb435e13d81601755714e9fSE Android len = le32_to_cpu(buf[1]); 718255e72915d4cbddceb435e13d81601755714e9fSE Android if (len != strlen(POLICYDB_MOD_STRING)) { 719255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 720255e72915d4cbddceb435e13d81601755714e9fSE Android "module string length is wrong (at section %u)", 721255e72915d4cbddceb435e13d81601755714e9fSE Android i); 722255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 723255e72915d4cbddceb435e13d81601755714e9fSE Android } 724255e72915d4cbddceb435e13d81601755714e9fSE Android 725255e72915d4cbddceb435e13d81601755714e9fSE Android /* skip id */ 726255e72915d4cbddceb435e13d81601755714e9fSE Android id = malloc(len + 1); 727255e72915d4cbddceb435e13d81601755714e9fSE Android if (!id) { 728255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 729255e72915d4cbddceb435e13d81601755714e9fSE Android "out of memory (at section %u)", 730255e72915d4cbddceb435e13d81601755714e9fSE Android i); 731255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 732255e72915d4cbddceb435e13d81601755714e9fSE Android } 733255e72915d4cbddceb435e13d81601755714e9fSE Android rc = next_entry(id, file, len); 734255e72915d4cbddceb435e13d81601755714e9fSE Android free(id); 735255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc < 0) { 736255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 737255e72915d4cbddceb435e13d81601755714e9fSE Android "cannot get module string (at section %u)", 738255e72915d4cbddceb435e13d81601755714e9fSE Android i); 739255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 740255e72915d4cbddceb435e13d81601755714e9fSE Android } 741255e72915d4cbddceb435e13d81601755714e9fSE Android 742255e72915d4cbddceb435e13d81601755714e9fSE Android rc = next_entry(buf, file, sizeof(uint32_t) * 5); 743255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc < 0) { 744255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 745255e72915d4cbddceb435e13d81601755714e9fSE Android "cannot get module header (at section %u)", 746255e72915d4cbddceb435e13d81601755714e9fSE Android i); 747255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 748255e72915d4cbddceb435e13d81601755714e9fSE Android } 749255e72915d4cbddceb435e13d81601755714e9fSE Android 750255e72915d4cbddceb435e13d81601755714e9fSE Android *type = le32_to_cpu(buf[0]); 751255e72915d4cbddceb435e13d81601755714e9fSE Android /* if base - we're done */ 752255e72915d4cbddceb435e13d81601755714e9fSE Android if (*type == POLICY_BASE) { 753255e72915d4cbddceb435e13d81601755714e9fSE Android *name = NULL; 754255e72915d4cbddceb435e13d81601755714e9fSE Android *version = NULL; 755255e72915d4cbddceb435e13d81601755714e9fSE Android seen |= SEEN_MOD; 756255e72915d4cbddceb435e13d81601755714e9fSE Android break; 757255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (*type != POLICY_MOD) { 758255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 759255e72915d4cbddceb435e13d81601755714e9fSE Android "module has invalid type %d (at section %u)", 760255e72915d4cbddceb435e13d81601755714e9fSE Android *type, i); 761255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 762255e72915d4cbddceb435e13d81601755714e9fSE Android } 763255e72915d4cbddceb435e13d81601755714e9fSE Android 764255e72915d4cbddceb435e13d81601755714e9fSE Android /* read the name and version */ 765255e72915d4cbddceb435e13d81601755714e9fSE Android rc = next_entry(buf, file, sizeof(uint32_t)); 766255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc < 0) { 767255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 768255e72915d4cbddceb435e13d81601755714e9fSE Android "cannot get module name len (at section %u)", 769255e72915d4cbddceb435e13d81601755714e9fSE Android i); 770255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 771255e72915d4cbddceb435e13d81601755714e9fSE Android } 772255e72915d4cbddceb435e13d81601755714e9fSE Android len = le32_to_cpu(buf[0]); 773255e72915d4cbddceb435e13d81601755714e9fSE Android *name = malloc(len + 1); 774255e72915d4cbddceb435e13d81601755714e9fSE Android if (!*name) { 775255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "out of memory"); 776255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 777255e72915d4cbddceb435e13d81601755714e9fSE Android } 778255e72915d4cbddceb435e13d81601755714e9fSE Android rc = next_entry(*name, file, len); 779255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc < 0) { 780255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 781255e72915d4cbddceb435e13d81601755714e9fSE Android "cannot get module name string (at section %u)", 782255e72915d4cbddceb435e13d81601755714e9fSE Android i); 783255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 784255e72915d4cbddceb435e13d81601755714e9fSE Android } 785255e72915d4cbddceb435e13d81601755714e9fSE Android (*name)[len] = '\0'; 786255e72915d4cbddceb435e13d81601755714e9fSE Android rc = next_entry(buf, file, sizeof(uint32_t)); 787255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc < 0) { 788255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 789255e72915d4cbddceb435e13d81601755714e9fSE Android "cannot get module version len (at section %u)", 790255e72915d4cbddceb435e13d81601755714e9fSE Android i); 791255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 792255e72915d4cbddceb435e13d81601755714e9fSE Android } 793255e72915d4cbddceb435e13d81601755714e9fSE Android len = le32_to_cpu(buf[0]); 794255e72915d4cbddceb435e13d81601755714e9fSE Android *version = malloc(len + 1); 795255e72915d4cbddceb435e13d81601755714e9fSE Android if (!*version) { 796255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "out of memory"); 797255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 798255e72915d4cbddceb435e13d81601755714e9fSE Android } 799255e72915d4cbddceb435e13d81601755714e9fSE Android rc = next_entry(*version, file, len); 800255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc < 0) { 801255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 802255e72915d4cbddceb435e13d81601755714e9fSE Android "cannot get module version string (at section %u)", 803255e72915d4cbddceb435e13d81601755714e9fSE Android i); 804255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 805255e72915d4cbddceb435e13d81601755714e9fSE Android } 806255e72915d4cbddceb435e13d81601755714e9fSE Android (*version)[len] = '\0'; 807255e72915d4cbddceb435e13d81601755714e9fSE Android seen |= SEEN_MOD; 808255e72915d4cbddceb435e13d81601755714e9fSE Android break; 809255e72915d4cbddceb435e13d81601755714e9fSE Android default: 810255e72915d4cbddceb435e13d81601755714e9fSE Android break; 811255e72915d4cbddceb435e13d81601755714e9fSE Android } 812255e72915d4cbddceb435e13d81601755714e9fSE Android 813255e72915d4cbddceb435e13d81601755714e9fSE Android } 814255e72915d4cbddceb435e13d81601755714e9fSE Android 815255e72915d4cbddceb435e13d81601755714e9fSE Android if ((seen & SEEN_MOD) == 0) { 816255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, "missing module in module package"); 817255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 818255e72915d4cbddceb435e13d81601755714e9fSE Android } 819255e72915d4cbddceb435e13d81601755714e9fSE Android 820255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_module_package_free(mod); 821255e72915d4cbddceb435e13d81601755714e9fSE Android free(offsets); 822255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 823255e72915d4cbddceb435e13d81601755714e9fSE Android 824255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 825255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_module_package_free(mod); 826255e72915d4cbddceb435e13d81601755714e9fSE Android free(offsets); 827255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 828255e72915d4cbddceb435e13d81601755714e9fSE Android} 829255e72915d4cbddceb435e13d81601755714e9fSE Android 830255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int write_helper(char *data, size_t len, struct policy_file *file) 831255e72915d4cbddceb435e13d81601755714e9fSE Android{ 832255e72915d4cbddceb435e13d81601755714e9fSE Android int idx = 0; 833255e72915d4cbddceb435e13d81601755714e9fSE Android size_t len2; 834255e72915d4cbddceb435e13d81601755714e9fSE Android 835255e72915d4cbddceb435e13d81601755714e9fSE Android while (len) { 836255e72915d4cbddceb435e13d81601755714e9fSE Android if (len > BUFSIZ) 837255e72915d4cbddceb435e13d81601755714e9fSE Android len2 = BUFSIZ; 838255e72915d4cbddceb435e13d81601755714e9fSE Android else 839255e72915d4cbddceb435e13d81601755714e9fSE Android len2 = len; 840255e72915d4cbddceb435e13d81601755714e9fSE Android 841255e72915d4cbddceb435e13d81601755714e9fSE Android if (put_entry(&data[idx], 1, len2, file) != len2) { 842255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 843255e72915d4cbddceb435e13d81601755714e9fSE Android } 844255e72915d4cbddceb435e13d81601755714e9fSE Android len -= len2; 845255e72915d4cbddceb435e13d81601755714e9fSE Android idx += len2; 846255e72915d4cbddceb435e13d81601755714e9fSE Android } 847255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 848255e72915d4cbddceb435e13d81601755714e9fSE Android} 849255e72915d4cbddceb435e13d81601755714e9fSE Android 850255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_module_package_write(sepol_module_package_t * p, 851255e72915d4cbddceb435e13d81601755714e9fSE Android struct sepol_policy_file *spf) 852255e72915d4cbddceb435e13d81601755714e9fSE Android{ 853255e72915d4cbddceb435e13d81601755714e9fSE Android struct policy_file *file = &spf->pf; 854255e72915d4cbddceb435e13d81601755714e9fSE Android policy_file_t polfile; 855255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t buf[5], offsets[5], len, nsec = 0; 856255e72915d4cbddceb435e13d81601755714e9fSE Android int i; 857255e72915d4cbddceb435e13d81601755714e9fSE Android 858255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->policy) { 859255e72915d4cbddceb435e13d81601755714e9fSE Android /* compute policy length */ 860255e72915d4cbddceb435e13d81601755714e9fSE Android policy_file_init(&polfile); 861255e72915d4cbddceb435e13d81601755714e9fSE Android polfile.type = PF_LEN; 862255e72915d4cbddceb435e13d81601755714e9fSE Android polfile.handle = file->handle; 863255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_write(&p->policy->p, &polfile)) 864255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 865255e72915d4cbddceb435e13d81601755714e9fSE Android len = polfile.len; 866255e72915d4cbddceb435e13d81601755714e9fSE Android if (!polfile.len) 867255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 868255e72915d4cbddceb435e13d81601755714e9fSE Android nsec++; 869255e72915d4cbddceb435e13d81601755714e9fSE Android 870255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 871255e72915d4cbddceb435e13d81601755714e9fSE Android /* We don't support writing a package without a module at this point */ 872255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 873255e72915d4cbddceb435e13d81601755714e9fSE Android } 874255e72915d4cbddceb435e13d81601755714e9fSE Android 875255e72915d4cbddceb435e13d81601755714e9fSE Android /* seusers and user_extra only supported in base at the moment */ 876255e72915d4cbddceb435e13d81601755714e9fSE Android if ((p->seusers || p->user_extra) 877255e72915d4cbddceb435e13d81601755714e9fSE Android && (p->policy->p.policy_type != SEPOL_POLICY_BASE)) { 878255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(file->handle, 879255e72915d4cbddceb435e13d81601755714e9fSE Android "seuser and user_extra sections only supported in base"); 880255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 881255e72915d4cbddceb435e13d81601755714e9fSE Android } 882255e72915d4cbddceb435e13d81601755714e9fSE Android 883255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->file_contexts) 884255e72915d4cbddceb435e13d81601755714e9fSE Android nsec++; 885255e72915d4cbddceb435e13d81601755714e9fSE Android 886255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->seusers) 887255e72915d4cbddceb435e13d81601755714e9fSE Android nsec++; 888255e72915d4cbddceb435e13d81601755714e9fSE Android 889255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->user_extra) 890255e72915d4cbddceb435e13d81601755714e9fSE Android nsec++; 891255e72915d4cbddceb435e13d81601755714e9fSE Android 892255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->netfilter_contexts) 893255e72915d4cbddceb435e13d81601755714e9fSE Android nsec++; 894255e72915d4cbddceb435e13d81601755714e9fSE Android 895255e72915d4cbddceb435e13d81601755714e9fSE Android buf[0] = cpu_to_le32(SEPOL_MODULE_PACKAGE_MAGIC); 896255e72915d4cbddceb435e13d81601755714e9fSE Android buf[1] = cpu_to_le32(p->version); 897255e72915d4cbddceb435e13d81601755714e9fSE Android buf[2] = cpu_to_le32(nsec); 898255e72915d4cbddceb435e13d81601755714e9fSE Android if (put_entry(buf, sizeof(uint32_t), 3, file) != 3) 899255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 900255e72915d4cbddceb435e13d81601755714e9fSE Android 901255e72915d4cbddceb435e13d81601755714e9fSE Android /* calculate offsets */ 902255e72915d4cbddceb435e13d81601755714e9fSE Android offsets[0] = (nsec + 3) * sizeof(uint32_t); 903255e72915d4cbddceb435e13d81601755714e9fSE Android buf[0] = cpu_to_le32(offsets[0]); 904255e72915d4cbddceb435e13d81601755714e9fSE Android 905255e72915d4cbddceb435e13d81601755714e9fSE Android i = 1; 906255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->file_contexts) { 907255e72915d4cbddceb435e13d81601755714e9fSE Android offsets[i] = offsets[i - 1] + len; 908255e72915d4cbddceb435e13d81601755714e9fSE Android buf[i] = cpu_to_le32(offsets[i]); 909255e72915d4cbddceb435e13d81601755714e9fSE Android /* add a uint32_t to compensate for the magic number */ 910255e72915d4cbddceb435e13d81601755714e9fSE Android len = p->file_contexts_len + sizeof(uint32_t); 911255e72915d4cbddceb435e13d81601755714e9fSE Android i++; 912255e72915d4cbddceb435e13d81601755714e9fSE Android } 913255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->seusers) { 914255e72915d4cbddceb435e13d81601755714e9fSE Android offsets[i] = offsets[i - 1] + len; 915255e72915d4cbddceb435e13d81601755714e9fSE Android buf[i] = cpu_to_le32(offsets[i]); 916255e72915d4cbddceb435e13d81601755714e9fSE Android len = p->seusers_len + sizeof(uint32_t); 917255e72915d4cbddceb435e13d81601755714e9fSE Android i++; 918255e72915d4cbddceb435e13d81601755714e9fSE Android } 919255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->user_extra) { 920255e72915d4cbddceb435e13d81601755714e9fSE Android offsets[i] = offsets[i - 1] + len; 921255e72915d4cbddceb435e13d81601755714e9fSE Android buf[i] = cpu_to_le32(offsets[i]); 922255e72915d4cbddceb435e13d81601755714e9fSE Android len = p->user_extra_len + sizeof(uint32_t); 923255e72915d4cbddceb435e13d81601755714e9fSE Android i++; 924255e72915d4cbddceb435e13d81601755714e9fSE Android } 925255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->netfilter_contexts) { 926255e72915d4cbddceb435e13d81601755714e9fSE Android offsets[i] = offsets[i - 1] + len; 927255e72915d4cbddceb435e13d81601755714e9fSE Android buf[i] = cpu_to_le32(offsets[i]); 928255e72915d4cbddceb435e13d81601755714e9fSE Android len = p->netfilter_contexts_len + sizeof(uint32_t); 929255e72915d4cbddceb435e13d81601755714e9fSE Android i++; 930255e72915d4cbddceb435e13d81601755714e9fSE Android } 931255e72915d4cbddceb435e13d81601755714e9fSE Android if (put_entry(buf, sizeof(uint32_t), nsec, file) != nsec) 932255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 933255e72915d4cbddceb435e13d81601755714e9fSE Android 934255e72915d4cbddceb435e13d81601755714e9fSE Android /* write sections */ 935255e72915d4cbddceb435e13d81601755714e9fSE Android 936255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_write(&p->policy->p, file)) 937255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 938255e72915d4cbddceb435e13d81601755714e9fSE Android 939255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->file_contexts) { 940255e72915d4cbddceb435e13d81601755714e9fSE Android buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_FC); 941255e72915d4cbddceb435e13d81601755714e9fSE Android if (put_entry(buf, sizeof(uint32_t), 1, file) != 1) 942255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 943255e72915d4cbddceb435e13d81601755714e9fSE Android if (write_helper(p->file_contexts, p->file_contexts_len, file)) 944255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 945255e72915d4cbddceb435e13d81601755714e9fSE Android } 946255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->seusers) { 947255e72915d4cbddceb435e13d81601755714e9fSE Android buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_SEUSER); 948255e72915d4cbddceb435e13d81601755714e9fSE Android if (put_entry(buf, sizeof(uint32_t), 1, file) != 1) 949255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 950255e72915d4cbddceb435e13d81601755714e9fSE Android if (write_helper(p->seusers, p->seusers_len, file)) 951255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 952255e72915d4cbddceb435e13d81601755714e9fSE Android 953255e72915d4cbddceb435e13d81601755714e9fSE Android } 954255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->user_extra) { 955255e72915d4cbddceb435e13d81601755714e9fSE Android buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_USER_EXTRA); 956255e72915d4cbddceb435e13d81601755714e9fSE Android if (put_entry(buf, sizeof(uint32_t), 1, file) != 1) 957255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 958255e72915d4cbddceb435e13d81601755714e9fSE Android if (write_helper(p->user_extra, p->user_extra_len, file)) 959255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 960255e72915d4cbddceb435e13d81601755714e9fSE Android } 961255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->netfilter_contexts) { 962255e72915d4cbddceb435e13d81601755714e9fSE Android buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_NETFILTER); 963255e72915d4cbddceb435e13d81601755714e9fSE Android if (put_entry(buf, sizeof(uint32_t), 1, file) != 1) 964255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 965255e72915d4cbddceb435e13d81601755714e9fSE Android if (write_helper 966255e72915d4cbddceb435e13d81601755714e9fSE Android (p->netfilter_contexts, p->netfilter_contexts_len, file)) 967255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 968255e72915d4cbddceb435e13d81601755714e9fSE Android } 969255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 970255e72915d4cbddceb435e13d81601755714e9fSE Android} 971255e72915d4cbddceb435e13d81601755714e9fSE Android 972255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_link_modules(sepol_handle_t * handle, 973255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_policydb_t * base, 974255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_policydb_t ** modules, size_t len, int verbose) 975255e72915d4cbddceb435e13d81601755714e9fSE Android{ 976255e72915d4cbddceb435e13d81601755714e9fSE Android return link_modules(handle, &base->p, (policydb_t **) modules, len, 977255e72915d4cbddceb435e13d81601755714e9fSE Android verbose); 978255e72915d4cbddceb435e13d81601755714e9fSE Android} 979255e72915d4cbddceb435e13d81601755714e9fSE Android 980255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_expand_module(sepol_handle_t * handle, 981255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_policydb_t * base, 982255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_policydb_t * out, int verbose, int check) 983255e72915d4cbddceb435e13d81601755714e9fSE Android{ 984255e72915d4cbddceb435e13d81601755714e9fSE Android return expand_module(handle, &base->p, &out->p, verbose, check); 985255e72915d4cbddceb435e13d81601755714e9fSE Android} 986