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 
policydb_from_image(sepol_handle_t * handle,void * data,size_t len,policydb_t * policydb)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 
policydb_to_image(sepol_handle_t * handle,policydb_t * policydb,void ** newdata,size_t * newlen)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