1255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h> 2255e72915d4cbddceb435e13d81601755714e9fSE Android 3255e72915d4cbddceb435e13d81601755714e9fSE Android#include "private.h" 4255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h" 5255e72915d4cbddceb435e13d81601755714e9fSE Android 6255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/policydb.h> 7255e72915d4cbddceb435e13d81601755714e9fSE Android 8255e72915d4cbddceb435e13d81601755714e9fSE Android/* Construct a policydb from the supplied (data, len) pair */ 9255e72915d4cbddceb435e13d81601755714e9fSE Android 10255e72915d4cbddceb435e13d81601755714e9fSE Androidint policydb_from_image(sepol_handle_t * handle, 11255e72915d4cbddceb435e13d81601755714e9fSE Android void *data, size_t len, policydb_t * policydb) 12255e72915d4cbddceb435e13d81601755714e9fSE Android{ 13255e72915d4cbddceb435e13d81601755714e9fSE Android 14255e72915d4cbddceb435e13d81601755714e9fSE Android policy_file_t pf; 15255e72915d4cbddceb435e13d81601755714e9fSE Android 16255e72915d4cbddceb435e13d81601755714e9fSE Android policy_file_init(&pf); 17255e72915d4cbddceb435e13d81601755714e9fSE Android pf.type = PF_USE_MEMORY; 18255e72915d4cbddceb435e13d81601755714e9fSE Android pf.data = data; 19255e72915d4cbddceb435e13d81601755714e9fSE Android pf.len = len; 20255e72915d4cbddceb435e13d81601755714e9fSE Android pf.handle = handle; 21255e72915d4cbddceb435e13d81601755714e9fSE Android 22255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_read(policydb, &pf, 0)) { 23b0e0162a246f2c051427154909c0ecd694cc4805Alice Chu policydb_destroy(policydb); 24255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "policy image is invalid"); 25255e72915d4cbddceb435e13d81601755714e9fSE Android errno = EINVAL; 26255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 27255e72915d4cbddceb435e13d81601755714e9fSE Android } 28255e72915d4cbddceb435e13d81601755714e9fSE Android 29255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 30255e72915d4cbddceb435e13d81601755714e9fSE Android} 31255e72915d4cbddceb435e13d81601755714e9fSE Android 32255e72915d4cbddceb435e13d81601755714e9fSE Android/* Write a policydb to a memory region, and return the (data, len) pair. */ 33255e72915d4cbddceb435e13d81601755714e9fSE Android 34255e72915d4cbddceb435e13d81601755714e9fSE Androidint policydb_to_image(sepol_handle_t * handle, 35255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t * policydb, void **newdata, size_t * newlen) 36255e72915d4cbddceb435e13d81601755714e9fSE Android{ 37255e72915d4cbddceb435e13d81601755714e9fSE Android 38255e72915d4cbddceb435e13d81601755714e9fSE Android void *tmp_data = NULL; 39255e72915d4cbddceb435e13d81601755714e9fSE Android size_t tmp_len; 40255e72915d4cbddceb435e13d81601755714e9fSE Android policy_file_t pf; 41255e72915d4cbddceb435e13d81601755714e9fSE Android struct policydb tmp_policydb; 42255e72915d4cbddceb435e13d81601755714e9fSE Android 43255e72915d4cbddceb435e13d81601755714e9fSE Android /* Compute the length for the new policy image. */ 44255e72915d4cbddceb435e13d81601755714e9fSE Android policy_file_init(&pf); 45255e72915d4cbddceb435e13d81601755714e9fSE Android pf.type = PF_LEN; 46255e72915d4cbddceb435e13d81601755714e9fSE Android pf.handle = handle; 47255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_write(policydb, &pf)) { 48255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not compute policy length"); 49255e72915d4cbddceb435e13d81601755714e9fSE Android errno = EINVAL; 50255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 51255e72915d4cbddceb435e13d81601755714e9fSE Android } 52255e72915d4cbddceb435e13d81601755714e9fSE Android 53255e72915d4cbddceb435e13d81601755714e9fSE Android /* Allocate the new policy image. */ 54255e72915d4cbddceb435e13d81601755714e9fSE Android pf.type = PF_USE_MEMORY; 55255e72915d4cbddceb435e13d81601755714e9fSE Android pf.data = malloc(pf.len); 56255e72915d4cbddceb435e13d81601755714e9fSE Android if (!pf.data) { 57255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "out of memory"); 58255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 59255e72915d4cbddceb435e13d81601755714e9fSE Android } 60255e72915d4cbddceb435e13d81601755714e9fSE Android 61255e72915d4cbddceb435e13d81601755714e9fSE Android /* Need to save len and data prior to modification by policydb_write. */ 62255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_len = pf.len; 63255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_data = pf.data; 64255e72915d4cbddceb435e13d81601755714e9fSE Android 65255e72915d4cbddceb435e13d81601755714e9fSE Android /* Write out the new policy image. */ 66255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_write(policydb, &pf)) { 67255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not write policy"); 68255e72915d4cbddceb435e13d81601755714e9fSE Android errno = EINVAL; 69255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 70255e72915d4cbddceb435e13d81601755714e9fSE Android } 71255e72915d4cbddceb435e13d81601755714e9fSE Android 72255e72915d4cbddceb435e13d81601755714e9fSE Android /* Verify the new policy image. */ 73255e72915d4cbddceb435e13d81601755714e9fSE Android pf.type = PF_USE_MEMORY; 74255e72915d4cbddceb435e13d81601755714e9fSE Android pf.data = tmp_data; 75255e72915d4cbddceb435e13d81601755714e9fSE Android pf.len = tmp_len; 76255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_init(&tmp_policydb)) { 77255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Out of memory"); 78255e72915d4cbddceb435e13d81601755714e9fSE Android errno = ENOMEM; 79255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 80255e72915d4cbddceb435e13d81601755714e9fSE Android } 81255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_read(&tmp_policydb, &pf, 0)) { 82255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "new policy image is invalid"); 83255e72915d4cbddceb435e13d81601755714e9fSE Android errno = EINVAL; 84255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 85255e72915d4cbddceb435e13d81601755714e9fSE Android } 86255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_destroy(&tmp_policydb); 87255e72915d4cbddceb435e13d81601755714e9fSE Android 88255e72915d4cbddceb435e13d81601755714e9fSE Android /* Update (newdata, newlen) */ 89255e72915d4cbddceb435e13d81601755714e9fSE Android *newdata = tmp_data; 90255e72915d4cbddceb435e13d81601755714e9fSE Android *newlen = tmp_len; 91255e72915d4cbddceb435e13d81601755714e9fSE Android 92255e72915d4cbddceb435e13d81601755714e9fSE Android /* Recover */ 93255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 94255e72915d4cbddceb435e13d81601755714e9fSE Android 95255e72915d4cbddceb435e13d81601755714e9fSE Android err: 96255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not create policy image"); 97255e72915d4cbddceb435e13d81601755714e9fSE Android 98255e72915d4cbddceb435e13d81601755714e9fSE Android /* Recover */ 99255e72915d4cbddceb435e13d81601755714e9fSE Android free(tmp_data); 100255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 101255e72915d4cbddceb435e13d81601755714e9fSE Android} 102