1 #include <stdlib.h> 2 3 #include "private.h" 4 #include "debug.h" 5 6 #include <sepol/policydb/policydb.h> 7 8 /* Construct a policydb from the supplied (data, len) pair */ 9 10 int policydb_from_image(sepol_handle_t * handle, 11 void *data, size_t len, policydb_t * policydb) 12 { 13 14 policy_file_t pf; 15 16 policy_file_init(&pf); 17 pf.type = PF_USE_MEMORY; 18 pf.data = data; 19 pf.len = len; 20 pf.handle = handle; 21 22 if (policydb_read(policydb, &pf, 0)) { 23 policydb_destroy(policydb); 24 ERR(handle, "policy image is invalid"); 25 errno = EINVAL; 26 return STATUS_ERR; 27 } 28 29 return STATUS_SUCCESS; 30 } 31 32 /* Write a policydb to a memory region, and return the (data, len) pair. */ 33 34 int policydb_to_image(sepol_handle_t * handle, 35 policydb_t * policydb, void **newdata, size_t * newlen) 36 { 37 38 void *tmp_data = NULL; 39 size_t tmp_len; 40 policy_file_t pf; 41 struct policydb tmp_policydb; 42 43 /* Compute the length for the new policy image. */ 44 policy_file_init(&pf); 45 pf.type = PF_LEN; 46 pf.handle = handle; 47 if (policydb_write(policydb, &pf)) { 48 ERR(handle, "could not compute policy length"); 49 errno = EINVAL; 50 goto err; 51 } 52 53 /* Allocate the new policy image. */ 54 pf.type = PF_USE_MEMORY; 55 pf.data = malloc(pf.len); 56 if (!pf.data) { 57 ERR(handle, "out of memory"); 58 goto err; 59 } 60 61 /* Need to save len and data prior to modification by policydb_write. */ 62 tmp_len = pf.len; 63 tmp_data = pf.data; 64 65 /* Write out the new policy image. */ 66 if (policydb_write(policydb, &pf)) { 67 ERR(handle, "could not write policy"); 68 errno = EINVAL; 69 goto err; 70 } 71 72 /* Verify the new policy image. */ 73 pf.type = PF_USE_MEMORY; 74 pf.data = tmp_data; 75 pf.len = tmp_len; 76 if (policydb_init(&tmp_policydb)) { 77 ERR(handle, "Out of memory"); 78 errno = ENOMEM; 79 goto err; 80 } 81 if (policydb_read(&tmp_policydb, &pf, 0)) { 82 ERR(handle, "new policy image is invalid"); 83 errno = EINVAL; 84 goto err; 85 } 86 policydb_destroy(&tmp_policydb); 87 88 /* Update (newdata, newlen) */ 89 *newdata = tmp_data; 90 *newlen = tmp_len; 91 92 /* Recover */ 93 return STATUS_SUCCESS; 94 95 err: 96 ERR(handle, "could not create policy image"); 97 98 /* Recover */ 99 free(tmp_data); 100 return STATUS_ERR; 101 } 102