Advertisement
Guest User

Untitled

a guest
Jan 8th, 2016
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.05 KB | None | 0 0
  1. /*
  2. * This was derived from public domain works with updates to
  3. * work with more modern SELinux libraries.
  4. *
  5. * It is released into the public domain.
  6. *
  7. */
  8.  
  9. #include <getopt.h>
  10. #include <unistd.h>
  11. #include <stdlib.h>
  12. #include <sys/mman.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include <fcntl.h>
  16. #include <stdio.h>
  17. #include <sepol/policydb/policydb.h>
  18. #include <sepol/policydb/services.h>
  19.  
  20. void usage(char *arg0) {
  21. fprintf(stderr, "%s -s <source type> -t <target type> -c <class> -p <perm>[,<perm2>,<perm3>,...] [-P <policy file>] [-o <output file>] [-l|--load]\n", arg0);
  22. fprintf(stderr, "%s -Z permissive_type [-P <policy file>] [-o <output file>] [-l|--load]\n", arg0);
  23. fprintf(stderr, "%s -R\n", arg0);
  24. exit(1);
  25. }
  26.  
  27. void *cmalloc(size_t s) {
  28. void *t = malloc(s);
  29. if (t == NULL) {
  30. fprintf(stderr, "Out of memory\n");
  31. exit(1);
  32. }
  33. return t;
  34. }
  35.  
  36. int add_rule(char *s, char *t, char *c, char *p, policydb_t *policy) {
  37. type_datum_t *src, *tgt;
  38. class_datum_t *cls;
  39. perm_datum_t *perm;
  40. avtab_datum_t *av;
  41. avtab_key_t key;
  42.  
  43. src = hashtab_search(policy->p_types.table, s);
  44. if (src == NULL) {
  45. fprintf(stderr, "source type %s does not exist\n", s);
  46. return 2;
  47. }
  48. tgt = hashtab_search(policy->p_types.table, t);
  49. if (tgt == NULL) {
  50. fprintf(stderr, "target type %s does not exist\n", t);
  51. return 2;
  52. }
  53. cls = hashtab_search(policy->p_classes.table, c);
  54. if (cls == NULL) {
  55. fprintf(stderr, "class %s does not exist\n", c);
  56. return 2;
  57. }
  58. perm = hashtab_search(cls->permissions.table, p);
  59. if (perm == NULL) {
  60. if (cls->comdatum == NULL) {
  61. fprintf(stderr, "perm %s does not exist in class %s\n", p, c);
  62. return 2;
  63. }
  64. perm = hashtab_search(cls->comdatum->permissions.table, p);
  65. if (perm == NULL) {
  66. fprintf(stderr, "perm %s does not exist in class %s\n", p, c);
  67. return 2;
  68. }
  69. }
  70.  
  71. // See if there is already a rule
  72. key.source_type = src->s.value;
  73. key.target_type = tgt->s.value;
  74. key.target_class = cls->s.value;
  75. key.specified = AVTAB_ALLOWED;
  76. av = avtab_search(&policy->te_avtab, &key);
  77.  
  78. if (av == NULL) {
  79. av = cmalloc(sizeof av);
  80. av->data |= 1U << (perm->s.value - 1);
  81. int ret = avtab_insert(&policy->te_avtab, &key, av);
  82. if (ret) {
  83. fprintf(stderr, "Error inserting into avtab\n");
  84. return 1;
  85. }
  86. }
  87.  
  88. av->data |= 1U << (perm->s.value - 1);
  89.  
  90. return 0;
  91. }
  92.  
  93. int load_policy(char *filename, policydb_t *policydb, struct policy_file *pf) {
  94. int fd;
  95. struct stat sb;
  96. void *map;
  97. int ret;
  98.  
  99. fd = open(filename, O_RDONLY);
  100. if (fd < 0) {
  101. fprintf(stderr, "Can't open '%s': %s\n",
  102. filename, strerror(errno));
  103. return 1;
  104. }
  105. if (fstat(fd, &sb) < 0) {
  106. fprintf(stderr, "Can't stat '%s': %s\n",
  107. filename, strerror(errno));
  108. return 1;
  109. }
  110. map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
  111. fd, 0);
  112. if (map == MAP_FAILED) {
  113. fprintf(stderr, "Can't mmap '%s': %s\n",
  114. filename, strerror(errno));
  115. close(fd);
  116. return 1;
  117. }
  118.  
  119. policy_file_init(pf);
  120. pf->type = PF_USE_MEMORY;
  121. pf->data = map;
  122. pf->len = sb.st_size;
  123. if (policydb_init(policydb)) {
  124. fprintf(stderr, "policydb_init: Out of memory!\n");
  125. munmap(map, sb.st_size);
  126. close(fd);
  127. return 1;
  128. }
  129. ret = policydb_read(policydb, pf, 1);
  130. if (ret) {
  131. fprintf(stderr, "error(s) encountered while parsing configuration\n");
  132. munmap(map, sb.st_size);
  133. close(fd);
  134. return 1;
  135. }
  136.  
  137. munmap(map, sb.st_size);
  138. close(fd);
  139. return 0;
  140. }
  141.  
  142. int load_policy_into_kernel(policydb_t *policydb) {
  143. char *filename = "/sys/fs/selinux/load";
  144. int fd, ret;
  145. void *data = NULL;
  146. size_t len;
  147.  
  148. policydb_to_image(NULL, policydb, &data, &len);
  149.  
  150. // based on libselinux security_load_policy()
  151. fd = open(filename, O_RDWR);
  152. if (fd < 0) {
  153. fprintf(stderr, "Can't open '%s': %s\n",
  154. filename, strerror(errno));
  155. return 1;
  156. }
  157. ret = write(fd, data, len);
  158. close(fd);
  159. if (ret < 0) {
  160. fprintf(stderr, "Could not write policy to %s\n",
  161. filename);
  162. return 1;
  163. }
  164. return 0;
  165. }
  166.  
  167. int main(int argc, char **argv) {
  168. char *policy = NULL, *source = NULL, *target = NULL, *class = NULL, *perm = NULL, *perm_token = NULL, *perm_saveptr = NULL, *outfile = NULL, *permissive = NULL;
  169. policydb_t policydb;
  170. struct policy_file pf, outpf;
  171. sidtab_t sidtab;
  172. int ch;
  173. int ret_add_rule;
  174. int load = 0;
  175. int reload = 0;
  176. FILE *fp;
  177.  
  178. struct option long_options[] = {
  179. {"source", required_argument, NULL, 's'},
  180. {"target", required_argument, NULL, 't'},
  181. {"class", required_argument, NULL, 'c'},
  182. {"perm", required_argument, NULL, 'p'},
  183. {"policy", required_argument, NULL, 'P'},
  184. {"output", required_argument, NULL, 'o'},
  185. {"permissive", required_argument, NULL, 'Z'},
  186. {"load", no_argument, NULL, 'l'},
  187. {"reload", no_argument, NULL, 'R'},
  188. {NULL, 0, NULL, 0}
  189. };
  190.  
  191. while ((ch = getopt_long(argc, argv, "s:t:c:p:P:o:Z:lR", long_options, NULL)) != -1) {
  192. switch (ch) {
  193. case 's':
  194. source = optarg;
  195. break;
  196. case 't':
  197. target = optarg;
  198. break;
  199. case 'c':
  200. class = optarg;
  201. break;
  202. case 'p':
  203. perm = optarg;
  204. break;
  205. case 'P':
  206. policy = optarg;
  207. break;
  208. case 'o':
  209. outfile = optarg;
  210. break;
  211. case 'Z':
  212. permissive = optarg;
  213. break;
  214. case 'l':
  215. load = 1;
  216. break;
  217. case 'R':
  218. reload = 1;
  219. break;
  220. default:
  221. usage(argv[0]);
  222. }
  223. }
  224.  
  225. if ((!source || !target || !class || !perm) && !permissive && !reload)
  226. usage(argv[0]);
  227.  
  228. if (reload)
  229. policy = "/sepolicy";
  230. else if (!policy)
  231. policy = "/sys/fs/selinux/policy";
  232.  
  233. sepol_set_policydb(&policydb);
  234. sepol_set_sidtab(&sidtab);
  235.  
  236. if (load_policy(policy, &policydb, &pf)) {
  237. fprintf(stderr, "Could not load policy\n");
  238. return 1;
  239. }
  240.  
  241. if (policydb_load_isids(&policydb, &sidtab))
  242. return 1;
  243.  
  244. if (!reload)
  245. if (permissive) {
  246. type_datum_t *type;
  247. type = hashtab_search(policydb.p_types.table, permissive);
  248. if (type == NULL) {
  249. fprintf(stderr, "type %s does not exist\n", permissive);
  250. return 2;
  251. }
  252. if (ebitmap_set_bit(&policydb.permissive_map, type->s.value, 1)) {
  253. fprintf(stderr, "Could not set bit in permissive map\n");
  254. return 1;
  255. }
  256. } else {
  257. perm_token = strtok_r(perm, ",", &perm_saveptr);
  258. while (perm_token) {
  259. if (ret_add_rule = add_rule(source, target, class, perm_token, &policydb)) {
  260. fprintf(stderr, "Could not add rule for perm: %s\n", perm_token);
  261. return ret_add_rule;
  262. }
  263. perm_token = strtok_r(NULL, ",", &perm_saveptr);
  264. }
  265. }
  266.  
  267. if (outfile && !reload) {
  268. fp = fopen(outfile, "w");
  269. if (!fp) {
  270. fprintf(stderr, "Could not open outfile\n");
  271. return 1;
  272. }
  273.  
  274. policy_file_init(&outpf);
  275. outpf.type = PF_USE_STDIO;
  276. outpf.fp = fp;
  277.  
  278. if (policydb_write(&policydb, &outpf)) {
  279. fprintf(stderr, "Could not write policy\n");
  280. return 1;
  281. }
  282.  
  283. fclose(fp);
  284. }
  285.  
  286. if (load || reload) {
  287. if (load_policy_into_kernel(&policydb)) {
  288. fprintf(stderr, "Could not load new policy into kernel\n");
  289. return 1;
  290. }
  291. }
  292.  
  293. policydb_destroy(&policydb);
  294.  
  295. fprintf(stdout, "Success\n");
  296. return 0;
  297. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement