conditional.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* Authors: Karl MacMillan <[email protected]>
  3. * Frank Mayer <[email protected]>
  4. *
  5. * Copyright (C) 2003 - 2004 Tresys Technology, LLC
  6. */
  7. #include <linux/kernel.h>
  8. #include <linux/errno.h>
  9. #include <linux/string.h>
  10. #include <linux/spinlock.h>
  11. #include <linux/slab.h>
  12. #include "security.h"
  13. #include "conditional.h"
  14. #include "services.h"
  15. /*
  16. * cond_evaluate_expr evaluates a conditional expr
  17. * in reverse polish notation. It returns true (1), false (0),
  18. * or undefined (-1). Undefined occurs when the expression
  19. * exceeds the stack depth of COND_EXPR_MAXDEPTH.
  20. */
  21. static int cond_evaluate_expr(struct policydb *p, struct cond_expr *expr)
  22. {
  23. u32 i;
  24. int s[COND_EXPR_MAXDEPTH];
  25. int sp = -1;
  26. if (expr->len == 0)
  27. return -1;
  28. for (i = 0; i < expr->len; i++) {
  29. struct cond_expr_node *node = &expr->nodes[i];
  30. switch (node->expr_type) {
  31. case COND_BOOL:
  32. if (sp == (COND_EXPR_MAXDEPTH - 1))
  33. return -1;
  34. sp++;
  35. s[sp] = p->bool_val_to_struct[node->bool - 1]->state;
  36. break;
  37. case COND_NOT:
  38. if (sp < 0)
  39. return -1;
  40. s[sp] = !s[sp];
  41. break;
  42. case COND_OR:
  43. if (sp < 1)
  44. return -1;
  45. sp--;
  46. s[sp] |= s[sp + 1];
  47. break;
  48. case COND_AND:
  49. if (sp < 1)
  50. return -1;
  51. sp--;
  52. s[sp] &= s[sp + 1];
  53. break;
  54. case COND_XOR:
  55. if (sp < 1)
  56. return -1;
  57. sp--;
  58. s[sp] ^= s[sp + 1];
  59. break;
  60. case COND_EQ:
  61. if (sp < 1)
  62. return -1;
  63. sp--;
  64. s[sp] = (s[sp] == s[sp + 1]);
  65. break;
  66. case COND_NEQ:
  67. if (sp < 1)
  68. return -1;
  69. sp--;
  70. s[sp] = (s[sp] != s[sp + 1]);
  71. break;
  72. default:
  73. return -1;
  74. }
  75. }
  76. return s[0];
  77. }
  78. /*
  79. * evaluate_cond_node evaluates the conditional stored in
  80. * a struct cond_node and if the result is different than the
  81. * current state of the node it sets the rules in the true/false
  82. * list appropriately. If the result of the expression is undefined
  83. * all of the rules are disabled for safety.
  84. */
  85. static void evaluate_cond_node(struct policydb *p, struct cond_node *node)
  86. {
  87. struct avtab_node *avnode;
  88. int new_state;
  89. u32 i;
  90. new_state = cond_evaluate_expr(p, &node->expr);
  91. if (new_state != node->cur_state) {
  92. node->cur_state = new_state;
  93. if (new_state == -1)
  94. pr_err("SELinux: expression result was undefined - disabling all rules.\n");
  95. /* turn the rules on or off */
  96. for (i = 0; i < node->true_list.len; i++) {
  97. avnode = node->true_list.nodes[i];
  98. if (new_state <= 0)
  99. avnode->key.specified &= ~AVTAB_ENABLED;
  100. else
  101. avnode->key.specified |= AVTAB_ENABLED;
  102. }
  103. for (i = 0; i < node->false_list.len; i++) {
  104. avnode = node->false_list.nodes[i];
  105. /* -1 or 1 */
  106. if (new_state)
  107. avnode->key.specified &= ~AVTAB_ENABLED;
  108. else
  109. avnode->key.specified |= AVTAB_ENABLED;
  110. }
  111. }
  112. }
  113. void evaluate_cond_nodes(struct policydb *p)
  114. {
  115. u32 i;
  116. for (i = 0; i < p->cond_list_len; i++)
  117. evaluate_cond_node(p, &p->cond_list[i]);
  118. }
  119. void cond_policydb_init(struct policydb *p)
  120. {
  121. p->bool_val_to_struct = NULL;
  122. p->cond_list = NULL;
  123. p->cond_list_len = 0;
  124. avtab_init(&p->te_cond_avtab);
  125. }
  126. static void cond_node_destroy(struct cond_node *node)
  127. {
  128. kfree(node->expr.nodes);
  129. /* the avtab_ptr_t nodes are destroyed by the avtab */
  130. kfree(node->true_list.nodes);
  131. kfree(node->false_list.nodes);
  132. }
  133. static void cond_list_destroy(struct policydb *p)
  134. {
  135. u32 i;
  136. for (i = 0; i < p->cond_list_len; i++)
  137. cond_node_destroy(&p->cond_list[i]);
  138. kfree(p->cond_list);
  139. p->cond_list = NULL;
  140. p->cond_list_len = 0;
  141. }
  142. void cond_policydb_destroy(struct policydb *p)
  143. {
  144. kfree(p->bool_val_to_struct);
  145. avtab_destroy(&p->te_cond_avtab);
  146. cond_list_destroy(p);
  147. }
  148. int cond_init_bool_indexes(struct policydb *p)
  149. {
  150. kfree(p->bool_val_to_struct);
  151. p->bool_val_to_struct = kmalloc_array(p->p_bools.nprim,
  152. sizeof(*p->bool_val_to_struct),
  153. GFP_KERNEL);
  154. if (!p->bool_val_to_struct)
  155. return -ENOMEM;
  156. return 0;
  157. }
  158. int cond_destroy_bool(void *key, void *datum, void *p)
  159. {
  160. kfree(key);
  161. kfree(datum);
  162. return 0;
  163. }
  164. int cond_index_bool(void *key, void *datum, void *datap)
  165. {
  166. struct policydb *p;
  167. struct cond_bool_datum *booldatum;
  168. booldatum = datum;
  169. p = datap;
  170. if (!booldatum->value || booldatum->value > p->p_bools.nprim)
  171. return -EINVAL;
  172. p->sym_val_to_name[SYM_BOOLS][booldatum->value - 1] = key;
  173. p->bool_val_to_struct[booldatum->value - 1] = booldatum;
  174. return 0;
  175. }
  176. static int bool_isvalid(struct cond_bool_datum *b)
  177. {
  178. if (!(b->state == 0 || b->state == 1))
  179. return 0;
  180. return 1;
  181. }
  182. int cond_read_bool(struct policydb *p, struct symtab *s, void *fp)
  183. {
  184. char *key = NULL;
  185. struct cond_bool_datum *booldatum;
  186. __le32 buf[3];
  187. u32 len;
  188. int rc;
  189. booldatum = kzalloc(sizeof(*booldatum), GFP_KERNEL);
  190. if (!booldatum)
  191. return -ENOMEM;
  192. rc = next_entry(buf, fp, sizeof(buf));
  193. if (rc)
  194. goto err;
  195. booldatum->value = le32_to_cpu(buf[0]);
  196. booldatum->state = le32_to_cpu(buf[1]);
  197. rc = -EINVAL;
  198. if (!bool_isvalid(booldatum))
  199. goto err;
  200. len = le32_to_cpu(buf[2]);
  201. if (((len == 0) || (len == (u32)-1)))
  202. goto err;
  203. rc = -ENOMEM;
  204. key = kmalloc(len + 1, GFP_KERNEL);
  205. if (!key)
  206. goto err;
  207. rc = next_entry(key, fp, len);
  208. if (rc)
  209. goto err;
  210. key[len] = '\0';
  211. rc = symtab_insert(s, key, booldatum);
  212. if (rc)
  213. goto err;
  214. return 0;
  215. err:
  216. cond_destroy_bool(key, booldatum, NULL);
  217. return rc;
  218. }
  219. struct cond_insertf_data {
  220. struct policydb *p;
  221. struct avtab_node **dst;
  222. struct cond_av_list *other;
  223. };
  224. static int cond_insertf(struct avtab *a, const struct avtab_key *k,
  225. const struct avtab_datum *d, void *ptr)
  226. {
  227. struct cond_insertf_data *data = ptr;
  228. struct policydb *p = data->p;
  229. struct cond_av_list *other = data->other;
  230. struct avtab_node *node_ptr;
  231. u32 i;
  232. bool found;
  233. /*
  234. * For type rules we have to make certain there aren't any
  235. * conflicting rules by searching the te_avtab and the
  236. * cond_te_avtab.
  237. */
  238. if (k->specified & AVTAB_TYPE) {
  239. if (avtab_search(&p->te_avtab, k)) {
  240. pr_err("SELinux: type rule already exists outside of a conditional.\n");
  241. return -EINVAL;
  242. }
  243. /*
  244. * If we are reading the false list other will be a pointer to
  245. * the true list. We can have duplicate entries if there is only
  246. * 1 other entry and it is in our true list.
  247. *
  248. * If we are reading the true list (other == NULL) there shouldn't
  249. * be any other entries.
  250. */
  251. if (other) {
  252. node_ptr = avtab_search_node(&p->te_cond_avtab, k);
  253. if (node_ptr) {
  254. if (avtab_search_node_next(node_ptr, k->specified)) {
  255. pr_err("SELinux: too many conflicting type rules.\n");
  256. return -EINVAL;
  257. }
  258. found = false;
  259. for (i = 0; i < other->len; i++) {
  260. if (other->nodes[i] == node_ptr) {
  261. found = true;
  262. break;
  263. }
  264. }
  265. if (!found) {
  266. pr_err("SELinux: conflicting type rules.\n");
  267. return -EINVAL;
  268. }
  269. }
  270. } else {
  271. if (avtab_search(&p->te_cond_avtab, k)) {
  272. pr_err("SELinux: conflicting type rules when adding type rule for true.\n");
  273. return -EINVAL;
  274. }
  275. }
  276. }
  277. node_ptr = avtab_insert_nonunique(&p->te_cond_avtab, k, d);
  278. if (!node_ptr) {
  279. pr_err("SELinux: could not insert rule.\n");
  280. return -ENOMEM;
  281. }
  282. *data->dst = node_ptr;
  283. return 0;
  284. }
  285. static int cond_read_av_list(struct policydb *p, void *fp,
  286. struct cond_av_list *list,
  287. struct cond_av_list *other)
  288. {
  289. int rc;
  290. __le32 buf[1];
  291. u32 i, len;
  292. struct cond_insertf_data data;
  293. rc = next_entry(buf, fp, sizeof(u32));
  294. if (rc)
  295. return rc;
  296. len = le32_to_cpu(buf[0]);
  297. if (len == 0)
  298. return 0;
  299. list->nodes = kcalloc(len, sizeof(*list->nodes), GFP_KERNEL);
  300. if (!list->nodes)
  301. return -ENOMEM;
  302. data.p = p;
  303. data.other = other;
  304. for (i = 0; i < len; i++) {
  305. data.dst = &list->nodes[i];
  306. rc = avtab_read_item(&p->te_cond_avtab, fp, p, cond_insertf,
  307. &data);
  308. if (rc) {
  309. kfree(list->nodes);
  310. list->nodes = NULL;
  311. return rc;
  312. }
  313. }
  314. list->len = len;
  315. return 0;
  316. }
  317. static int expr_node_isvalid(struct policydb *p, struct cond_expr_node *expr)
  318. {
  319. if (expr->expr_type <= 0 || expr->expr_type > COND_LAST) {
  320. pr_err("SELinux: conditional expressions uses unknown operator.\n");
  321. return 0;
  322. }
  323. if (expr->bool > p->p_bools.nprim) {
  324. pr_err("SELinux: conditional expressions uses unknown bool.\n");
  325. return 0;
  326. }
  327. return 1;
  328. }
  329. static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
  330. {
  331. __le32 buf[2];
  332. u32 i, len;
  333. int rc;
  334. rc = next_entry(buf, fp, sizeof(u32) * 2);
  335. if (rc)
  336. return rc;
  337. node->cur_state = le32_to_cpu(buf[0]);
  338. /* expr */
  339. len = le32_to_cpu(buf[1]);
  340. node->expr.nodes = kcalloc(len, sizeof(*node->expr.nodes), GFP_KERNEL);
  341. if (!node->expr.nodes)
  342. return -ENOMEM;
  343. node->expr.len = len;
  344. for (i = 0; i < len; i++) {
  345. struct cond_expr_node *expr = &node->expr.nodes[i];
  346. rc = next_entry(buf, fp, sizeof(u32) * 2);
  347. if (rc)
  348. return rc;
  349. expr->expr_type = le32_to_cpu(buf[0]);
  350. expr->bool = le32_to_cpu(buf[1]);
  351. if (!expr_node_isvalid(p, expr))
  352. return -EINVAL;
  353. }
  354. rc = cond_read_av_list(p, fp, &node->true_list, NULL);
  355. if (rc)
  356. return rc;
  357. return cond_read_av_list(p, fp, &node->false_list, &node->true_list);
  358. }
  359. int cond_read_list(struct policydb *p, void *fp)
  360. {
  361. __le32 buf[1];
  362. u32 i, len;
  363. int rc;
  364. rc = next_entry(buf, fp, sizeof(buf));
  365. if (rc)
  366. return rc;
  367. len = le32_to_cpu(buf[0]);
  368. p->cond_list = kcalloc(len, sizeof(*p->cond_list), GFP_KERNEL);
  369. if (!p->cond_list)
  370. return -ENOMEM;
  371. rc = avtab_alloc(&(p->te_cond_avtab), p->te_avtab.nel);
  372. if (rc)
  373. goto err;
  374. p->cond_list_len = len;
  375. for (i = 0; i < len; i++) {
  376. rc = cond_read_node(p, &p->cond_list[i], fp);
  377. if (rc)
  378. goto err;
  379. }
  380. return 0;
  381. err:
  382. cond_list_destroy(p);
  383. return rc;
  384. }
  385. int cond_write_bool(void *vkey, void *datum, void *ptr)
  386. {
  387. char *key = vkey;
  388. struct cond_bool_datum *booldatum = datum;
  389. struct policy_data *pd = ptr;
  390. void *fp = pd->fp;
  391. __le32 buf[3];
  392. u32 len;
  393. int rc;
  394. len = strlen(key);
  395. buf[0] = cpu_to_le32(booldatum->value);
  396. buf[1] = cpu_to_le32(booldatum->state);
  397. buf[2] = cpu_to_le32(len);
  398. rc = put_entry(buf, sizeof(u32), 3, fp);
  399. if (rc)
  400. return rc;
  401. rc = put_entry(key, 1, len, fp);
  402. if (rc)
  403. return rc;
  404. return 0;
  405. }
  406. /*
  407. * cond_write_cond_av_list doesn't write out the av_list nodes.
  408. * Instead it writes out the key/value pairs from the avtab. This
  409. * is necessary because there is no way to uniquely identifying rules
  410. * in the avtab so it is not possible to associate individual rules
  411. * in the avtab with a conditional without saving them as part of
  412. * the conditional. This means that the avtab with the conditional
  413. * rules will not be saved but will be rebuilt on policy load.
  414. */
  415. static int cond_write_av_list(struct policydb *p,
  416. struct cond_av_list *list, struct policy_file *fp)
  417. {
  418. __le32 buf[1];
  419. u32 i;
  420. int rc;
  421. buf[0] = cpu_to_le32(list->len);
  422. rc = put_entry(buf, sizeof(u32), 1, fp);
  423. if (rc)
  424. return rc;
  425. for (i = 0; i < list->len; i++) {
  426. rc = avtab_write_item(p, list->nodes[i], fp);
  427. if (rc)
  428. return rc;
  429. }
  430. return 0;
  431. }
  432. static int cond_write_node(struct policydb *p, struct cond_node *node,
  433. struct policy_file *fp)
  434. {
  435. __le32 buf[2];
  436. int rc;
  437. u32 i;
  438. buf[0] = cpu_to_le32(node->cur_state);
  439. rc = put_entry(buf, sizeof(u32), 1, fp);
  440. if (rc)
  441. return rc;
  442. buf[0] = cpu_to_le32(node->expr.len);
  443. rc = put_entry(buf, sizeof(u32), 1, fp);
  444. if (rc)
  445. return rc;
  446. for (i = 0; i < node->expr.len; i++) {
  447. buf[0] = cpu_to_le32(node->expr.nodes[i].expr_type);
  448. buf[1] = cpu_to_le32(node->expr.nodes[i].bool);
  449. rc = put_entry(buf, sizeof(u32), 2, fp);
  450. if (rc)
  451. return rc;
  452. }
  453. rc = cond_write_av_list(p, &node->true_list, fp);
  454. if (rc)
  455. return rc;
  456. rc = cond_write_av_list(p, &node->false_list, fp);
  457. if (rc)
  458. return rc;
  459. return 0;
  460. }
  461. int cond_write_list(struct policydb *p, void *fp)
  462. {
  463. u32 i;
  464. __le32 buf[1];
  465. int rc;
  466. buf[0] = cpu_to_le32(p->cond_list_len);
  467. rc = put_entry(buf, sizeof(u32), 1, fp);
  468. if (rc)
  469. return rc;
  470. for (i = 0; i < p->cond_list_len; i++) {
  471. rc = cond_write_node(p, &p->cond_list[i], fp);
  472. if (rc)
  473. return rc;
  474. }
  475. return 0;
  476. }
  477. void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key,
  478. struct extended_perms_decision *xpermd)
  479. {
  480. struct avtab_node *node;
  481. if (!ctab || !key || !xpermd)
  482. return;
  483. for (node = avtab_search_node(ctab, key); node;
  484. node = avtab_search_node_next(node, key->specified)) {
  485. if (node->key.specified & AVTAB_ENABLED)
  486. services_compute_xperms_decision(xpermd, node);
  487. }
  488. }
  489. /* Determine whether additional permissions are granted by the conditional
  490. * av table, and if so, add them to the result
  491. */
  492. void cond_compute_av(struct avtab *ctab, struct avtab_key *key,
  493. struct av_decision *avd, struct extended_perms *xperms)
  494. {
  495. struct avtab_node *node;
  496. if (!ctab || !key || !avd)
  497. return;
  498. for (node = avtab_search_node(ctab, key); node;
  499. node = avtab_search_node_next(node, key->specified)) {
  500. if ((u16)(AVTAB_ALLOWED|AVTAB_ENABLED) ==
  501. (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED)))
  502. avd->allowed |= node->datum.u.data;
  503. if ((u16)(AVTAB_AUDITDENY|AVTAB_ENABLED) ==
  504. (node->key.specified & (AVTAB_AUDITDENY|AVTAB_ENABLED)))
  505. /* Since a '0' in an auditdeny mask represents a
  506. * permission we do NOT want to audit (dontaudit), we use
  507. * the '&' operand to ensure that all '0's in the mask
  508. * are retained (much unlike the allow and auditallow cases).
  509. */
  510. avd->auditdeny &= node->datum.u.data;
  511. if ((u16)(AVTAB_AUDITALLOW|AVTAB_ENABLED) ==
  512. (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED)))
  513. avd->auditallow |= node->datum.u.data;
  514. if (xperms && (node->key.specified & AVTAB_ENABLED) &&
  515. (node->key.specified & AVTAB_XPERMS))
  516. services_compute_xperms_drivers(xperms, node);
  517. }
  518. }
  519. static int cond_dup_av_list(struct cond_av_list *new,
  520. struct cond_av_list *orig,
  521. struct avtab *avtab)
  522. {
  523. u32 i;
  524. memset(new, 0, sizeof(*new));
  525. new->nodes = kcalloc(orig->len, sizeof(*new->nodes), GFP_KERNEL);
  526. if (!new->nodes)
  527. return -ENOMEM;
  528. for (i = 0; i < orig->len; i++) {
  529. new->nodes[i] = avtab_insert_nonunique(avtab,
  530. &orig->nodes[i]->key,
  531. &orig->nodes[i]->datum);
  532. if (!new->nodes[i])
  533. return -ENOMEM;
  534. new->len++;
  535. }
  536. return 0;
  537. }
  538. static int duplicate_policydb_cond_list(struct policydb *newp,
  539. struct policydb *origp)
  540. {
  541. int rc;
  542. u32 i;
  543. rc = avtab_alloc_dup(&newp->te_cond_avtab, &origp->te_cond_avtab);
  544. if (rc)
  545. return rc;
  546. newp->cond_list_len = 0;
  547. newp->cond_list = kcalloc(origp->cond_list_len,
  548. sizeof(*newp->cond_list),
  549. GFP_KERNEL);
  550. if (!newp->cond_list)
  551. goto error;
  552. for (i = 0; i < origp->cond_list_len; i++) {
  553. struct cond_node *newn = &newp->cond_list[i];
  554. struct cond_node *orign = &origp->cond_list[i];
  555. newp->cond_list_len++;
  556. newn->cur_state = orign->cur_state;
  557. newn->expr.nodes = kmemdup(orign->expr.nodes,
  558. orign->expr.len * sizeof(*orign->expr.nodes),
  559. GFP_KERNEL);
  560. if (!newn->expr.nodes)
  561. goto error;
  562. newn->expr.len = orign->expr.len;
  563. rc = cond_dup_av_list(&newn->true_list, &orign->true_list,
  564. &newp->te_cond_avtab);
  565. if (rc)
  566. goto error;
  567. rc = cond_dup_av_list(&newn->false_list, &orign->false_list,
  568. &newp->te_cond_avtab);
  569. if (rc)
  570. goto error;
  571. }
  572. return 0;
  573. error:
  574. avtab_destroy(&newp->te_cond_avtab);
  575. cond_list_destroy(newp);
  576. return -ENOMEM;
  577. }
  578. static int cond_bools_destroy(void *key, void *datum, void *args)
  579. {
  580. /* key was not copied so no need to free here */
  581. kfree(datum);
  582. return 0;
  583. }
  584. static int cond_bools_copy(struct hashtab_node *new, struct hashtab_node *orig, void *args)
  585. {
  586. struct cond_bool_datum *datum;
  587. datum = kmemdup(orig->datum, sizeof(struct cond_bool_datum),
  588. GFP_KERNEL);
  589. if (!datum)
  590. return -ENOMEM;
  591. new->key = orig->key; /* No need to copy, never modified */
  592. new->datum = datum;
  593. return 0;
  594. }
  595. static int cond_bools_index(void *key, void *datum, void *args)
  596. {
  597. struct cond_bool_datum *booldatum, **cond_bool_array;
  598. booldatum = datum;
  599. cond_bool_array = args;
  600. cond_bool_array[booldatum->value - 1] = booldatum;
  601. return 0;
  602. }
  603. static int duplicate_policydb_bools(struct policydb *newdb,
  604. struct policydb *orig)
  605. {
  606. struct cond_bool_datum **cond_bool_array;
  607. int rc;
  608. cond_bool_array = kmalloc_array(orig->p_bools.nprim,
  609. sizeof(*orig->bool_val_to_struct),
  610. GFP_KERNEL);
  611. if (!cond_bool_array)
  612. return -ENOMEM;
  613. rc = hashtab_duplicate(&newdb->p_bools.table, &orig->p_bools.table,
  614. cond_bools_copy, cond_bools_destroy, NULL);
  615. if (rc) {
  616. kfree(cond_bool_array);
  617. return -ENOMEM;
  618. }
  619. hashtab_map(&newdb->p_bools.table, cond_bools_index, cond_bool_array);
  620. newdb->bool_val_to_struct = cond_bool_array;
  621. newdb->p_bools.nprim = orig->p_bools.nprim;
  622. return 0;
  623. }
  624. void cond_policydb_destroy_dup(struct policydb *p)
  625. {
  626. hashtab_map(&p->p_bools.table, cond_bools_destroy, NULL);
  627. hashtab_destroy(&p->p_bools.table);
  628. cond_policydb_destroy(p);
  629. }
  630. int cond_policydb_dup(struct policydb *new, struct policydb *orig)
  631. {
  632. cond_policydb_init(new);
  633. if (duplicate_policydb_bools(new, orig))
  634. return -ENOMEM;
  635. if (duplicate_policydb_cond_list(new, orig)) {
  636. cond_policydb_destroy_dup(new);
  637. return -ENOMEM;
  638. }
  639. return 0;
  640. }