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
10int 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
34int 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