16cd6a6acSopenharmony_ci#include <stdlib.h> 26cd6a6acSopenharmony_ci 36cd6a6acSopenharmony_ci#include "private.h" 46cd6a6acSopenharmony_ci#include "debug.h" 56cd6a6acSopenharmony_ci 66cd6a6acSopenharmony_ci#include <sepol/policydb/policydb.h> 76cd6a6acSopenharmony_ci 86cd6a6acSopenharmony_ci/* Construct a policydb from the supplied (data, len) pair */ 96cd6a6acSopenharmony_ci 106cd6a6acSopenharmony_ciint policydb_from_image(sepol_handle_t * handle, 116cd6a6acSopenharmony_ci void *data, size_t len, policydb_t * policydb) 126cd6a6acSopenharmony_ci{ 136cd6a6acSopenharmony_ci 146cd6a6acSopenharmony_ci policy_file_t pf; 156cd6a6acSopenharmony_ci 166cd6a6acSopenharmony_ci policy_file_init(&pf); 176cd6a6acSopenharmony_ci pf.type = PF_USE_MEMORY; 186cd6a6acSopenharmony_ci pf.data = data; 196cd6a6acSopenharmony_ci pf.len = len; 206cd6a6acSopenharmony_ci pf.handle = handle; 216cd6a6acSopenharmony_ci 226cd6a6acSopenharmony_ci if (policydb_read(policydb, &pf, 0)) { 236cd6a6acSopenharmony_ci policydb_destroy(policydb); 246cd6a6acSopenharmony_ci ERR(handle, "policy image is invalid"); 256cd6a6acSopenharmony_ci errno = EINVAL; 266cd6a6acSopenharmony_ci return STATUS_ERR; 276cd6a6acSopenharmony_ci } 286cd6a6acSopenharmony_ci 296cd6a6acSopenharmony_ci return STATUS_SUCCESS; 306cd6a6acSopenharmony_ci} 316cd6a6acSopenharmony_ci 326cd6a6acSopenharmony_ci/* Write a policydb to a memory region, and return the (data, len) pair. */ 336cd6a6acSopenharmony_ci 346cd6a6acSopenharmony_ciint policydb_to_image(sepol_handle_t * handle, 356cd6a6acSopenharmony_ci policydb_t * policydb, void **newdata, size_t * newlen) 366cd6a6acSopenharmony_ci{ 376cd6a6acSopenharmony_ci 386cd6a6acSopenharmony_ci void *tmp_data = NULL; 396cd6a6acSopenharmony_ci size_t tmp_len; 406cd6a6acSopenharmony_ci policy_file_t pf; 416cd6a6acSopenharmony_ci struct policydb tmp_policydb; 426cd6a6acSopenharmony_ci 436cd6a6acSopenharmony_ci /* Compute the length for the new policy image. */ 446cd6a6acSopenharmony_ci policy_file_init(&pf); 456cd6a6acSopenharmony_ci pf.type = PF_LEN; 466cd6a6acSopenharmony_ci pf.handle = handle; 476cd6a6acSopenharmony_ci if (policydb_write(policydb, &pf)) { 486cd6a6acSopenharmony_ci ERR(handle, "could not compute policy length"); 496cd6a6acSopenharmony_ci errno = EINVAL; 506cd6a6acSopenharmony_ci goto err; 516cd6a6acSopenharmony_ci } 526cd6a6acSopenharmony_ci 536cd6a6acSopenharmony_ci /* Allocate the new policy image. */ 546cd6a6acSopenharmony_ci pf.type = PF_USE_MEMORY; 556cd6a6acSopenharmony_ci pf.data = malloc(pf.len); 566cd6a6acSopenharmony_ci if (!pf.data) { 576cd6a6acSopenharmony_ci ERR(handle, "out of memory"); 586cd6a6acSopenharmony_ci goto err; 596cd6a6acSopenharmony_ci } 606cd6a6acSopenharmony_ci 616cd6a6acSopenharmony_ci /* Need to save len and data prior to modification by policydb_write. */ 626cd6a6acSopenharmony_ci tmp_len = pf.len; 636cd6a6acSopenharmony_ci tmp_data = pf.data; 646cd6a6acSopenharmony_ci 656cd6a6acSopenharmony_ci /* Write out the new policy image. */ 666cd6a6acSopenharmony_ci if (policydb_write(policydb, &pf)) { 676cd6a6acSopenharmony_ci ERR(handle, "could not write policy"); 686cd6a6acSopenharmony_ci errno = EINVAL; 696cd6a6acSopenharmony_ci goto err; 706cd6a6acSopenharmony_ci } 716cd6a6acSopenharmony_ci 726cd6a6acSopenharmony_ci /* Verify the new policy image. */ 736cd6a6acSopenharmony_ci pf.type = PF_USE_MEMORY; 746cd6a6acSopenharmony_ci pf.data = tmp_data; 756cd6a6acSopenharmony_ci pf.len = tmp_len; 766cd6a6acSopenharmony_ci if (policydb_init(&tmp_policydb)) { 776cd6a6acSopenharmony_ci ERR(handle, "Out of memory"); 786cd6a6acSopenharmony_ci errno = ENOMEM; 796cd6a6acSopenharmony_ci goto err; 806cd6a6acSopenharmony_ci } 816cd6a6acSopenharmony_ci if (policydb_read(&tmp_policydb, &pf, 0)) { 826cd6a6acSopenharmony_ci ERR(handle, "new policy image is invalid"); 836cd6a6acSopenharmony_ci errno = EINVAL; 846cd6a6acSopenharmony_ci goto err; 856cd6a6acSopenharmony_ci } 866cd6a6acSopenharmony_ci policydb_destroy(&tmp_policydb); 876cd6a6acSopenharmony_ci 886cd6a6acSopenharmony_ci /* Update (newdata, newlen) */ 896cd6a6acSopenharmony_ci *newdata = tmp_data; 906cd6a6acSopenharmony_ci *newlen = tmp_len; 916cd6a6acSopenharmony_ci 926cd6a6acSopenharmony_ci /* Recover */ 936cd6a6acSopenharmony_ci return STATUS_SUCCESS; 946cd6a6acSopenharmony_ci 956cd6a6acSopenharmony_ci err: 966cd6a6acSopenharmony_ci ERR(handle, "could not create policy image"); 976cd6a6acSopenharmony_ci 986cd6a6acSopenharmony_ci /* Recover */ 996cd6a6acSopenharmony_ci free(tmp_data); 1006cd6a6acSopenharmony_ci return STATUS_ERR; 1016cd6a6acSopenharmony_ci} 102