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