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