file.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969
  1. /*
  2. * security/tomoyo/file.c
  3. *
  4. * Pathname restriction functions.
  5. *
  6. * Copyright (C) 2005-2010 NTT DATA CORPORATION
  7. */
  8. #include "common.h"
  9. #include <linux/slab.h>
  10. /*
  11. * Mapping table from "enum tomoyo_path_acl_index" to "enum tomoyo_mac_index".
  12. */
  13. static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = {
  14. [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE,
  15. [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN,
  16. [TOMOYO_TYPE_WRITE] = TOMOYO_MAC_FILE_OPEN,
  17. [TOMOYO_TYPE_APPEND] = TOMOYO_MAC_FILE_OPEN,
  18. [TOMOYO_TYPE_UNLINK] = TOMOYO_MAC_FILE_UNLINK,
  19. [TOMOYO_TYPE_GETATTR] = TOMOYO_MAC_FILE_GETATTR,
  20. [TOMOYO_TYPE_RMDIR] = TOMOYO_MAC_FILE_RMDIR,
  21. [TOMOYO_TYPE_TRUNCATE] = TOMOYO_MAC_FILE_TRUNCATE,
  22. [TOMOYO_TYPE_SYMLINK] = TOMOYO_MAC_FILE_SYMLINK,
  23. [TOMOYO_TYPE_CHROOT] = TOMOYO_MAC_FILE_CHROOT,
  24. [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT,
  25. };
  26. /*
  27. * Mapping table from "enum tomoyo_mkdev_acl_index" to "enum tomoyo_mac_index".
  28. */
  29. const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION] = {
  30. [TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK,
  31. [TOMOYO_TYPE_MKCHAR] = TOMOYO_MAC_FILE_MKCHAR,
  32. };
  33. /*
  34. * Mapping table from "enum tomoyo_path2_acl_index" to "enum tomoyo_mac_index".
  35. */
  36. const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = {
  37. [TOMOYO_TYPE_LINK] = TOMOYO_MAC_FILE_LINK,
  38. [TOMOYO_TYPE_RENAME] = TOMOYO_MAC_FILE_RENAME,
  39. [TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT,
  40. };
  41. /*
  42. * Mapping table from "enum tomoyo_path_number_acl_index" to
  43. * "enum tomoyo_mac_index".
  44. */
  45. const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
  46. [TOMOYO_TYPE_CREATE] = TOMOYO_MAC_FILE_CREATE,
  47. [TOMOYO_TYPE_MKDIR] = TOMOYO_MAC_FILE_MKDIR,
  48. [TOMOYO_TYPE_MKFIFO] = TOMOYO_MAC_FILE_MKFIFO,
  49. [TOMOYO_TYPE_MKSOCK] = TOMOYO_MAC_FILE_MKSOCK,
  50. [TOMOYO_TYPE_IOCTL] = TOMOYO_MAC_FILE_IOCTL,
  51. [TOMOYO_TYPE_CHMOD] = TOMOYO_MAC_FILE_CHMOD,
  52. [TOMOYO_TYPE_CHOWN] = TOMOYO_MAC_FILE_CHOWN,
  53. [TOMOYO_TYPE_CHGRP] = TOMOYO_MAC_FILE_CHGRP,
  54. };
  55. /**
  56. * tomoyo_put_name_union - Drop reference on "struct tomoyo_name_union".
  57. *
  58. * @ptr: Pointer to "struct tomoyo_name_union".
  59. *
  60. * Returns nothing.
  61. */
  62. void tomoyo_put_name_union(struct tomoyo_name_union *ptr)
  63. {
  64. tomoyo_put_group(ptr->group);
  65. tomoyo_put_name(ptr->filename);
  66. }
  67. /**
  68. * tomoyo_compare_name_union - Check whether a name matches "struct tomoyo_name_union" or not.
  69. *
  70. * @name: Pointer to "struct tomoyo_path_info".
  71. * @ptr: Pointer to "struct tomoyo_name_union".
  72. *
  73. * Returns "struct tomoyo_path_info" if @name matches @ptr, NULL otherwise.
  74. */
  75. const struct tomoyo_path_info *
  76. tomoyo_compare_name_union(const struct tomoyo_path_info *name,
  77. const struct tomoyo_name_union *ptr)
  78. {
  79. if (ptr->group)
  80. return tomoyo_path_matches_group(name, ptr->group);
  81. if (tomoyo_path_matches_pattern(name, ptr->filename))
  82. return ptr->filename;
  83. return NULL;
  84. }
  85. /**
  86. * tomoyo_put_number_union - Drop reference on "struct tomoyo_number_union".
  87. *
  88. * @ptr: Pointer to "struct tomoyo_number_union".
  89. *
  90. * Returns nothing.
  91. */
  92. void tomoyo_put_number_union(struct tomoyo_number_union *ptr)
  93. {
  94. tomoyo_put_group(ptr->group);
  95. }
  96. /**
  97. * tomoyo_compare_number_union - Check whether a value matches "struct tomoyo_number_union" or not.
  98. *
  99. * @value: Number to check.
  100. * @ptr: Pointer to "struct tomoyo_number_union".
  101. *
  102. * Returns true if @value matches @ptr, false otherwise.
  103. */
  104. bool tomoyo_compare_number_union(const unsigned long value,
  105. const struct tomoyo_number_union *ptr)
  106. {
  107. if (ptr->group)
  108. return tomoyo_number_matches_group(value, value, ptr->group);
  109. return value >= ptr->values[0] && value <= ptr->values[1];
  110. }
  111. /**
  112. * tomoyo_add_slash - Add trailing '/' if needed.
  113. *
  114. * @buf: Pointer to "struct tomoyo_path_info".
  115. *
  116. * Returns nothing.
  117. *
  118. * @buf must be generated by tomoyo_encode() because this function does not
  119. * allocate memory for adding '/'.
  120. */
  121. static void tomoyo_add_slash(struct tomoyo_path_info *buf)
  122. {
  123. if (buf->is_dir)
  124. return;
  125. /*
  126. * This is OK because tomoyo_encode() reserves space for appending "/".
  127. */
  128. strcat((char *) buf->name, "/");
  129. tomoyo_fill_path_info(buf);
  130. }
  131. /**
  132. * tomoyo_get_realpath - Get realpath.
  133. *
  134. * @buf: Pointer to "struct tomoyo_path_info".
  135. * @path: Pointer to "struct path".
  136. *
  137. * Returns true on success, false otherwise.
  138. */
  139. static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, struct path *path)
  140. {
  141. buf->name = tomoyo_realpath_from_path(path);
  142. if (buf->name) {
  143. tomoyo_fill_path_info(buf);
  144. return true;
  145. }
  146. return false;
  147. }
  148. /**
  149. * tomoyo_audit_path_log - Audit path request log.
  150. *
  151. * @r: Pointer to "struct tomoyo_request_info".
  152. *
  153. * Returns 0 on success, negative value otherwise.
  154. */
  155. static int tomoyo_audit_path_log(struct tomoyo_request_info *r)
  156. {
  157. return tomoyo_supervisor(r, "file %s %s\n", tomoyo_path_keyword
  158. [r->param.path.operation],
  159. r->param.path.filename->name);
  160. }
  161. /**
  162. * tomoyo_audit_path2_log - Audit path/path request log.
  163. *
  164. * @r: Pointer to "struct tomoyo_request_info".
  165. *
  166. * Returns 0 on success, negative value otherwise.
  167. */
  168. static int tomoyo_audit_path2_log(struct tomoyo_request_info *r)
  169. {
  170. return tomoyo_supervisor(r, "file %s %s %s\n", tomoyo_mac_keywords
  171. [tomoyo_pp2mac[r->param.path2.operation]],
  172. r->param.path2.filename1->name,
  173. r->param.path2.filename2->name);
  174. }
  175. /**
  176. * tomoyo_audit_mkdev_log - Audit path/number/number/number request log.
  177. *
  178. * @r: Pointer to "struct tomoyo_request_info".
  179. *
  180. * Returns 0 on success, negative value otherwise.
  181. */
  182. static int tomoyo_audit_mkdev_log(struct tomoyo_request_info *r)
  183. {
  184. return tomoyo_supervisor(r, "file %s %s 0%o %u %u\n",
  185. tomoyo_mac_keywords
  186. [tomoyo_pnnn2mac[r->param.mkdev.operation]],
  187. r->param.mkdev.filename->name,
  188. r->param.mkdev.mode, r->param.mkdev.major,
  189. r->param.mkdev.minor);
  190. }
  191. /**
  192. * tomoyo_audit_path_number_log - Audit path/number request log.
  193. *
  194. * @r: Pointer to "struct tomoyo_request_info".
  195. *
  196. * Returns 0 on success, negative value otherwise.
  197. */
  198. static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r)
  199. {
  200. const u8 type = r->param.path_number.operation;
  201. u8 radix;
  202. char buffer[64];
  203. switch (type) {
  204. case TOMOYO_TYPE_CREATE:
  205. case TOMOYO_TYPE_MKDIR:
  206. case TOMOYO_TYPE_MKFIFO:
  207. case TOMOYO_TYPE_MKSOCK:
  208. case TOMOYO_TYPE_CHMOD:
  209. radix = TOMOYO_VALUE_TYPE_OCTAL;
  210. break;
  211. case TOMOYO_TYPE_IOCTL:
  212. radix = TOMOYO_VALUE_TYPE_HEXADECIMAL;
  213. break;
  214. default:
  215. radix = TOMOYO_VALUE_TYPE_DECIMAL;
  216. break;
  217. }
  218. tomoyo_print_ulong(buffer, sizeof(buffer), r->param.path_number.number,
  219. radix);
  220. return tomoyo_supervisor(r, "file %s %s %s\n", tomoyo_mac_keywords
  221. [tomoyo_pn2mac[type]],
  222. r->param.path_number.filename->name, buffer);
  223. }
  224. /**
  225. * tomoyo_check_path_acl - Check permission for path operation.
  226. *
  227. * @r: Pointer to "struct tomoyo_request_info".
  228. * @ptr: Pointer to "struct tomoyo_acl_info".
  229. *
  230. * Returns true if granted, false otherwise.
  231. *
  232. * To be able to use wildcard for domain transition, this function sets
  233. * matching entry on success. Since the caller holds tomoyo_read_lock(),
  234. * it is safe to set matching entry.
  235. */
  236. static bool tomoyo_check_path_acl(struct tomoyo_request_info *r,
  237. const struct tomoyo_acl_info *ptr)
  238. {
  239. const struct tomoyo_path_acl *acl = container_of(ptr, typeof(*acl),
  240. head);
  241. if (acl->perm & (1 << r->param.path.operation)) {
  242. r->param.path.matched_path =
  243. tomoyo_compare_name_union(r->param.path.filename,
  244. &acl->name);
  245. return r->param.path.matched_path != NULL;
  246. }
  247. return false;
  248. }
  249. /**
  250. * tomoyo_check_path_number_acl - Check permission for path number operation.
  251. *
  252. * @r: Pointer to "struct tomoyo_request_info".
  253. * @ptr: Pointer to "struct tomoyo_acl_info".
  254. *
  255. * Returns true if granted, false otherwise.
  256. */
  257. static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r,
  258. const struct tomoyo_acl_info *ptr)
  259. {
  260. const struct tomoyo_path_number_acl *acl =
  261. container_of(ptr, typeof(*acl), head);
  262. return (acl->perm & (1 << r->param.path_number.operation)) &&
  263. tomoyo_compare_number_union(r->param.path_number.number,
  264. &acl->number) &&
  265. tomoyo_compare_name_union(r->param.path_number.filename,
  266. &acl->name);
  267. }
  268. /**
  269. * tomoyo_check_path2_acl - Check permission for path path operation.
  270. *
  271. * @r: Pointer to "struct tomoyo_request_info".
  272. * @ptr: Pointer to "struct tomoyo_acl_info".
  273. *
  274. * Returns true if granted, false otherwise.
  275. */
  276. static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r,
  277. const struct tomoyo_acl_info *ptr)
  278. {
  279. const struct tomoyo_path2_acl *acl =
  280. container_of(ptr, typeof(*acl), head);
  281. return (acl->perm & (1 << r->param.path2.operation)) &&
  282. tomoyo_compare_name_union(r->param.path2.filename1, &acl->name1)
  283. && tomoyo_compare_name_union(r->param.path2.filename2,
  284. &acl->name2);
  285. }
  286. /**
  287. * tomoyo_check_mkdev_acl - Check permission for path number number number operation.
  288. *
  289. * @r: Pointer to "struct tomoyo_request_info".
  290. * @ptr: Pointer to "struct tomoyo_acl_info".
  291. *
  292. * Returns true if granted, false otherwise.
  293. */
  294. static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r,
  295. const struct tomoyo_acl_info *ptr)
  296. {
  297. const struct tomoyo_mkdev_acl *acl =
  298. container_of(ptr, typeof(*acl), head);
  299. return (acl->perm & (1 << r->param.mkdev.operation)) &&
  300. tomoyo_compare_number_union(r->param.mkdev.mode,
  301. &acl->mode) &&
  302. tomoyo_compare_number_union(r->param.mkdev.major,
  303. &acl->major) &&
  304. tomoyo_compare_number_union(r->param.mkdev.minor,
  305. &acl->minor) &&
  306. tomoyo_compare_name_union(r->param.mkdev.filename,
  307. &acl->name);
  308. }
  309. /**
  310. * tomoyo_same_path_acl - Check for duplicated "struct tomoyo_path_acl" entry.
  311. *
  312. * @a: Pointer to "struct tomoyo_acl_info".
  313. * @b: Pointer to "struct tomoyo_acl_info".
  314. *
  315. * Returns true if @a == @b except permission bits, false otherwise.
  316. */
  317. static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a,
  318. const struct tomoyo_acl_info *b)
  319. {
  320. const struct tomoyo_path_acl *p1 = container_of(a, typeof(*p1), head);
  321. const struct tomoyo_path_acl *p2 = container_of(b, typeof(*p2), head);
  322. return tomoyo_same_name_union(&p1->name, &p2->name);
  323. }
  324. /**
  325. * tomoyo_merge_path_acl - Merge duplicated "struct tomoyo_path_acl" entry.
  326. *
  327. * @a: Pointer to "struct tomoyo_acl_info".
  328. * @b: Pointer to "struct tomoyo_acl_info".
  329. * @is_delete: True for @a &= ~@b, false for @a |= @b.
  330. *
  331. * Returns true if @a is empty, false otherwise.
  332. */
  333. static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a,
  334. struct tomoyo_acl_info *b,
  335. const bool is_delete)
  336. {
  337. u16 * const a_perm = &container_of(a, struct tomoyo_path_acl, head)
  338. ->perm;
  339. u16 perm = *a_perm;
  340. const u16 b_perm = container_of(b, struct tomoyo_path_acl, head)->perm;
  341. if (is_delete)
  342. perm &= ~b_perm;
  343. else
  344. perm |= b_perm;
  345. *a_perm = perm;
  346. return !perm;
  347. }
  348. /**
  349. * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list.
  350. *
  351. * @perm: Permission.
  352. * @param: Pointer to "struct tomoyo_acl_param".
  353. *
  354. * Returns 0 on success, negative value otherwise.
  355. *
  356. * Caller holds tomoyo_read_lock().
  357. */
  358. static int tomoyo_update_path_acl(const u16 perm,
  359. struct tomoyo_acl_param *param)
  360. {
  361. struct tomoyo_path_acl e = {
  362. .head.type = TOMOYO_TYPE_PATH_ACL,
  363. .perm = perm
  364. };
  365. int error;
  366. if (!tomoyo_parse_name_union(param, &e.name))
  367. error = -EINVAL;
  368. else
  369. error = tomoyo_update_domain(&e.head, sizeof(e), param,
  370. tomoyo_same_path_acl,
  371. tomoyo_merge_path_acl);
  372. tomoyo_put_name_union(&e.name);
  373. return error;
  374. }
  375. /**
  376. * tomoyo_same_mkdev_acl - Check for duplicated "struct tomoyo_mkdev_acl" entry.
  377. *
  378. * @a: Pointer to "struct tomoyo_acl_info".
  379. * @b: Pointer to "struct tomoyo_acl_info".
  380. *
  381. * Returns true if @a == @b except permission bits, false otherwise.
  382. */
  383. static bool tomoyo_same_mkdev_acl(const struct tomoyo_acl_info *a,
  384. const struct tomoyo_acl_info *b)
  385. {
  386. const struct tomoyo_mkdev_acl *p1 = container_of(a, typeof(*p1), head);
  387. const struct tomoyo_mkdev_acl *p2 = container_of(b, typeof(*p2), head);
  388. return tomoyo_same_name_union(&p1->name, &p2->name) &&
  389. tomoyo_same_number_union(&p1->mode, &p2->mode) &&
  390. tomoyo_same_number_union(&p1->major, &p2->major) &&
  391. tomoyo_same_number_union(&p1->minor, &p2->minor);
  392. }
  393. /**
  394. * tomoyo_merge_mkdev_acl - Merge duplicated "struct tomoyo_mkdev_acl" entry.
  395. *
  396. * @a: Pointer to "struct tomoyo_acl_info".
  397. * @b: Pointer to "struct tomoyo_acl_info".
  398. * @is_delete: True for @a &= ~@b, false for @a |= @b.
  399. *
  400. * Returns true if @a is empty, false otherwise.
  401. */
  402. static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a,
  403. struct tomoyo_acl_info *b,
  404. const bool is_delete)
  405. {
  406. u8 *const a_perm = &container_of(a, struct tomoyo_mkdev_acl,
  407. head)->perm;
  408. u8 perm = *a_perm;
  409. const u8 b_perm = container_of(b, struct tomoyo_mkdev_acl, head)
  410. ->perm;
  411. if (is_delete)
  412. perm &= ~b_perm;
  413. else
  414. perm |= b_perm;
  415. *a_perm = perm;
  416. return !perm;
  417. }
  418. /**
  419. * tomoyo_update_mkdev_acl - Update "struct tomoyo_mkdev_acl" list.
  420. *
  421. * @perm: Permission.
  422. * @param: Pointer to "struct tomoyo_acl_param".
  423. *
  424. * Returns 0 on success, negative value otherwise.
  425. *
  426. * Caller holds tomoyo_read_lock().
  427. */
  428. static int tomoyo_update_mkdev_acl(const u8 perm,
  429. struct tomoyo_acl_param *param)
  430. {
  431. struct tomoyo_mkdev_acl e = {
  432. .head.type = TOMOYO_TYPE_MKDEV_ACL,
  433. .perm = perm
  434. };
  435. int error;
  436. if (!tomoyo_parse_name_union(param, &e.name) ||
  437. !tomoyo_parse_number_union(param, &e.mode) ||
  438. !tomoyo_parse_number_union(param, &e.major) ||
  439. !tomoyo_parse_number_union(param, &e.minor))
  440. error = -EINVAL;
  441. else
  442. error = tomoyo_update_domain(&e.head, sizeof(e), param,
  443. tomoyo_same_mkdev_acl,
  444. tomoyo_merge_mkdev_acl);
  445. tomoyo_put_name_union(&e.name);
  446. tomoyo_put_number_union(&e.mode);
  447. tomoyo_put_number_union(&e.major);
  448. tomoyo_put_number_union(&e.minor);
  449. return error;
  450. }
  451. /**
  452. * tomoyo_same_path2_acl - Check for duplicated "struct tomoyo_path2_acl" entry.
  453. *
  454. * @a: Pointer to "struct tomoyo_acl_info".
  455. * @b: Pointer to "struct tomoyo_acl_info".
  456. *
  457. * Returns true if @a == @b except permission bits, false otherwise.
  458. */
  459. static bool tomoyo_same_path2_acl(const struct tomoyo_acl_info *a,
  460. const struct tomoyo_acl_info *b)
  461. {
  462. const struct tomoyo_path2_acl *p1 = container_of(a, typeof(*p1), head);
  463. const struct tomoyo_path2_acl *p2 = container_of(b, typeof(*p2), head);
  464. return tomoyo_same_name_union(&p1->name1, &p2->name1) &&
  465. tomoyo_same_name_union(&p1->name2, &p2->name2);
  466. }
  467. /**
  468. * tomoyo_merge_path2_acl - Merge duplicated "struct tomoyo_path2_acl" entry.
  469. *
  470. * @a: Pointer to "struct tomoyo_acl_info".
  471. * @b: Pointer to "struct tomoyo_acl_info".
  472. * @is_delete: True for @a &= ~@b, false for @a |= @b.
  473. *
  474. * Returns true if @a is empty, false otherwise.
  475. */
  476. static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a,
  477. struct tomoyo_acl_info *b,
  478. const bool is_delete)
  479. {
  480. u8 * const a_perm = &container_of(a, struct tomoyo_path2_acl, head)
  481. ->perm;
  482. u8 perm = *a_perm;
  483. const u8 b_perm = container_of(b, struct tomoyo_path2_acl, head)->perm;
  484. if (is_delete)
  485. perm &= ~b_perm;
  486. else
  487. perm |= b_perm;
  488. *a_perm = perm;
  489. return !perm;
  490. }
  491. /**
  492. * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list.
  493. *
  494. * @perm: Permission.
  495. * @param: Pointer to "struct tomoyo_acl_param".
  496. *
  497. * Returns 0 on success, negative value otherwise.
  498. *
  499. * Caller holds tomoyo_read_lock().
  500. */
  501. static int tomoyo_update_path2_acl(const u8 perm,
  502. struct tomoyo_acl_param *param)
  503. {
  504. struct tomoyo_path2_acl e = {
  505. .head.type = TOMOYO_TYPE_PATH2_ACL,
  506. .perm = perm
  507. };
  508. int error;
  509. if (!tomoyo_parse_name_union(param, &e.name1) ||
  510. !tomoyo_parse_name_union(param, &e.name2))
  511. error = -EINVAL;
  512. else
  513. error = tomoyo_update_domain(&e.head, sizeof(e), param,
  514. tomoyo_same_path2_acl,
  515. tomoyo_merge_path2_acl);
  516. tomoyo_put_name_union(&e.name1);
  517. tomoyo_put_name_union(&e.name2);
  518. return error;
  519. }
  520. /**
  521. * tomoyo_path_permission - Check permission for single path operation.
  522. *
  523. * @r: Pointer to "struct tomoyo_request_info".
  524. * @operation: Type of operation.
  525. * @filename: Filename to check.
  526. *
  527. * Returns 0 on success, negative value otherwise.
  528. *
  529. * Caller holds tomoyo_read_lock().
  530. */
  531. int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
  532. const struct tomoyo_path_info *filename)
  533. {
  534. int error;
  535. r->type = tomoyo_p2mac[operation];
  536. r->mode = tomoyo_get_mode(r->domain->ns, r->profile, r->type);
  537. if (r->mode == TOMOYO_CONFIG_DISABLED)
  538. return 0;
  539. r->param_type = TOMOYO_TYPE_PATH_ACL;
  540. r->param.path.filename = filename;
  541. r->param.path.operation = operation;
  542. do {
  543. tomoyo_check_acl(r, tomoyo_check_path_acl);
  544. error = tomoyo_audit_path_log(r);
  545. /*
  546. * Do not retry for execute request, for alias may have
  547. * changed.
  548. */
  549. } while (error == TOMOYO_RETRY_REQUEST &&
  550. operation != TOMOYO_TYPE_EXECUTE);
  551. return error;
  552. }
  553. /**
  554. * tomoyo_same_path_number_acl - Check for duplicated "struct tomoyo_path_number_acl" entry.
  555. *
  556. * @a: Pointer to "struct tomoyo_acl_info".
  557. * @b: Pointer to "struct tomoyo_acl_info".
  558. *
  559. * Returns true if @a == @b except permission bits, false otherwise.
  560. */
  561. static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a,
  562. const struct tomoyo_acl_info *b)
  563. {
  564. const struct tomoyo_path_number_acl *p1 = container_of(a, typeof(*p1),
  565. head);
  566. const struct tomoyo_path_number_acl *p2 = container_of(b, typeof(*p2),
  567. head);
  568. return tomoyo_same_name_union(&p1->name, &p2->name) &&
  569. tomoyo_same_number_union(&p1->number, &p2->number);
  570. }
  571. /**
  572. * tomoyo_merge_path_number_acl - Merge duplicated "struct tomoyo_path_number_acl" entry.
  573. *
  574. * @a: Pointer to "struct tomoyo_acl_info".
  575. * @b: Pointer to "struct tomoyo_acl_info".
  576. * @is_delete: True for @a &= ~@b, false for @a |= @b.
  577. *
  578. * Returns true if @a is empty, false otherwise.
  579. */
  580. static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a,
  581. struct tomoyo_acl_info *b,
  582. const bool is_delete)
  583. {
  584. u8 * const a_perm = &container_of(a, struct tomoyo_path_number_acl,
  585. head)->perm;
  586. u8 perm = *a_perm;
  587. const u8 b_perm = container_of(b, struct tomoyo_path_number_acl, head)
  588. ->perm;
  589. if (is_delete)
  590. perm &= ~b_perm;
  591. else
  592. perm |= b_perm;
  593. *a_perm = perm;
  594. return !perm;
  595. }
  596. /**
  597. * tomoyo_update_path_number_acl - Update ioctl/chmod/chown/chgrp ACL.
  598. *
  599. * @perm: Permission.
  600. * @param: Pointer to "struct tomoyo_acl_param".
  601. *
  602. * Returns 0 on success, negative value otherwise.
  603. */
  604. static int tomoyo_update_path_number_acl(const u8 perm,
  605. struct tomoyo_acl_param *param)
  606. {
  607. struct tomoyo_path_number_acl e = {
  608. .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL,
  609. .perm = perm
  610. };
  611. int error;
  612. if (!tomoyo_parse_name_union(param, &e.name) ||
  613. !tomoyo_parse_number_union(param, &e.number))
  614. error = -EINVAL;
  615. else
  616. error = tomoyo_update_domain(&e.head, sizeof(e), param,
  617. tomoyo_same_path_number_acl,
  618. tomoyo_merge_path_number_acl);
  619. tomoyo_put_name_union(&e.name);
  620. tomoyo_put_number_union(&e.number);
  621. return error;
  622. }
  623. /**
  624. * tomoyo_path_number_perm - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp".
  625. *
  626. * @type: Type of operation.
  627. * @path: Pointer to "struct path".
  628. * @number: Number.
  629. *
  630. * Returns 0 on success, negative value otherwise.
  631. */
  632. int tomoyo_path_number_perm(const u8 type, struct path *path,
  633. unsigned long number)
  634. {
  635. struct tomoyo_request_info r;
  636. int error = -ENOMEM;
  637. struct tomoyo_path_info buf;
  638. int idx;
  639. if (tomoyo_init_request_info(&r, NULL, tomoyo_pn2mac[type])
  640. == TOMOYO_CONFIG_DISABLED || !path->dentry)
  641. return 0;
  642. idx = tomoyo_read_lock();
  643. if (!tomoyo_get_realpath(&buf, path))
  644. goto out;
  645. if (type == TOMOYO_TYPE_MKDIR)
  646. tomoyo_add_slash(&buf);
  647. r.param_type = TOMOYO_TYPE_PATH_NUMBER_ACL;
  648. r.param.path_number.operation = type;
  649. r.param.path_number.filename = &buf;
  650. r.param.path_number.number = number;
  651. do {
  652. tomoyo_check_acl(&r, tomoyo_check_path_number_acl);
  653. error = tomoyo_audit_path_number_log(&r);
  654. } while (error == TOMOYO_RETRY_REQUEST);
  655. kfree(buf.name);
  656. out:
  657. tomoyo_read_unlock(idx);
  658. if (r.mode != TOMOYO_CONFIG_ENFORCING)
  659. error = 0;
  660. return error;
  661. }
  662. /**
  663. * tomoyo_check_open_permission - Check permission for "read" and "write".
  664. *
  665. * @domain: Pointer to "struct tomoyo_domain_info".
  666. * @path: Pointer to "struct path".
  667. * @flag: Flags for open().
  668. *
  669. * Returns 0 on success, negative value otherwise.
  670. */
  671. int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
  672. struct path *path, const int flag)
  673. {
  674. const u8 acc_mode = ACC_MODE(flag);
  675. int error = 0;
  676. struct tomoyo_path_info buf;
  677. struct tomoyo_request_info r;
  678. int idx;
  679. buf.name = NULL;
  680. r.mode = TOMOYO_CONFIG_DISABLED;
  681. idx = tomoyo_read_lock();
  682. if (acc_mode &&
  683. tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN)
  684. != TOMOYO_CONFIG_DISABLED) {
  685. if (!tomoyo_get_realpath(&buf, path)) {
  686. error = -ENOMEM;
  687. goto out;
  688. }
  689. if (acc_mode & MAY_READ)
  690. error = tomoyo_path_permission(&r, TOMOYO_TYPE_READ,
  691. &buf);
  692. if (!error && (acc_mode & MAY_WRITE))
  693. error = tomoyo_path_permission(&r, (flag & O_APPEND) ?
  694. TOMOYO_TYPE_APPEND :
  695. TOMOYO_TYPE_WRITE,
  696. &buf);
  697. }
  698. out:
  699. kfree(buf.name);
  700. tomoyo_read_unlock(idx);
  701. if (r.mode != TOMOYO_CONFIG_ENFORCING)
  702. error = 0;
  703. return error;
  704. }
  705. /**
  706. * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "append", "chroot" and "unmount".
  707. *
  708. * @operation: Type of operation.
  709. * @path: Pointer to "struct path".
  710. *
  711. * Returns 0 on success, negative value otherwise.
  712. */
  713. int tomoyo_path_perm(const u8 operation, struct path *path)
  714. {
  715. struct tomoyo_request_info r;
  716. int error;
  717. struct tomoyo_path_info buf;
  718. bool is_enforce;
  719. int idx;
  720. if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation])
  721. == TOMOYO_CONFIG_DISABLED)
  722. return 0;
  723. is_enforce = (r.mode == TOMOYO_CONFIG_ENFORCING);
  724. error = -ENOMEM;
  725. buf.name = NULL;
  726. idx = tomoyo_read_lock();
  727. if (!tomoyo_get_realpath(&buf, path))
  728. goto out;
  729. switch (operation) {
  730. case TOMOYO_TYPE_RMDIR:
  731. case TOMOYO_TYPE_CHROOT:
  732. tomoyo_add_slash(&buf);
  733. break;
  734. }
  735. error = tomoyo_path_permission(&r, operation, &buf);
  736. out:
  737. kfree(buf.name);
  738. tomoyo_read_unlock(idx);
  739. if (!is_enforce)
  740. error = 0;
  741. return error;
  742. }
  743. /**
  744. * tomoyo_mkdev_perm - Check permission for "mkblock" and "mkchar".
  745. *
  746. * @operation: Type of operation. (TOMOYO_TYPE_MKCHAR or TOMOYO_TYPE_MKBLOCK)
  747. * @path: Pointer to "struct path".
  748. * @mode: Create mode.
  749. * @dev: Device number.
  750. *
  751. * Returns 0 on success, negative value otherwise.
  752. */
  753. int tomoyo_mkdev_perm(const u8 operation, struct path *path,
  754. const unsigned int mode, unsigned int dev)
  755. {
  756. struct tomoyo_request_info r;
  757. int error = -ENOMEM;
  758. struct tomoyo_path_info buf;
  759. int idx;
  760. if (tomoyo_init_request_info(&r, NULL, tomoyo_pnnn2mac[operation])
  761. == TOMOYO_CONFIG_DISABLED)
  762. return 0;
  763. idx = tomoyo_read_lock();
  764. error = -ENOMEM;
  765. if (tomoyo_get_realpath(&buf, path)) {
  766. dev = new_decode_dev(dev);
  767. r.param_type = TOMOYO_TYPE_MKDEV_ACL;
  768. r.param.mkdev.filename = &buf;
  769. r.param.mkdev.operation = operation;
  770. r.param.mkdev.mode = mode;
  771. r.param.mkdev.major = MAJOR(dev);
  772. r.param.mkdev.minor = MINOR(dev);
  773. tomoyo_check_acl(&r, tomoyo_check_mkdev_acl);
  774. error = tomoyo_audit_mkdev_log(&r);
  775. kfree(buf.name);
  776. }
  777. tomoyo_read_unlock(idx);
  778. if (r.mode != TOMOYO_CONFIG_ENFORCING)
  779. error = 0;
  780. return error;
  781. }
  782. /**
  783. * tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root".
  784. *
  785. * @operation: Type of operation.
  786. * @path1: Pointer to "struct path".
  787. * @path2: Pointer to "struct path".
  788. *
  789. * Returns 0 on success, negative value otherwise.
  790. */
  791. int tomoyo_path2_perm(const u8 operation, struct path *path1,
  792. struct path *path2)
  793. {
  794. int error = -ENOMEM;
  795. struct tomoyo_path_info buf1;
  796. struct tomoyo_path_info buf2;
  797. struct tomoyo_request_info r;
  798. int idx;
  799. if (tomoyo_init_request_info(&r, NULL, tomoyo_pp2mac[operation])
  800. == TOMOYO_CONFIG_DISABLED)
  801. return 0;
  802. buf1.name = NULL;
  803. buf2.name = NULL;
  804. idx = tomoyo_read_lock();
  805. if (!tomoyo_get_realpath(&buf1, path1) ||
  806. !tomoyo_get_realpath(&buf2, path2))
  807. goto out;
  808. switch (operation) {
  809. struct dentry *dentry;
  810. case TOMOYO_TYPE_RENAME:
  811. case TOMOYO_TYPE_LINK:
  812. dentry = path1->dentry;
  813. if (!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode))
  814. break;
  815. /* fall through */
  816. case TOMOYO_TYPE_PIVOT_ROOT:
  817. tomoyo_add_slash(&buf1);
  818. tomoyo_add_slash(&buf2);
  819. break;
  820. }
  821. r.param_type = TOMOYO_TYPE_PATH2_ACL;
  822. r.param.path2.operation = operation;
  823. r.param.path2.filename1 = &buf1;
  824. r.param.path2.filename2 = &buf2;
  825. do {
  826. tomoyo_check_acl(&r, tomoyo_check_path2_acl);
  827. error = tomoyo_audit_path2_log(&r);
  828. } while (error == TOMOYO_RETRY_REQUEST);
  829. out:
  830. kfree(buf1.name);
  831. kfree(buf2.name);
  832. tomoyo_read_unlock(idx);
  833. if (r.mode != TOMOYO_CONFIG_ENFORCING)
  834. error = 0;
  835. return error;
  836. }
  837. /**
  838. * tomoyo_same_mount_acl - Check for duplicated "struct tomoyo_mount_acl" entry.
  839. *
  840. * @a: Pointer to "struct tomoyo_acl_info".
  841. * @b: Pointer to "struct tomoyo_acl_info".
  842. *
  843. * Returns true if @a == @b, false otherwise.
  844. */
  845. static bool tomoyo_same_mount_acl(const struct tomoyo_acl_info *a,
  846. const struct tomoyo_acl_info *b)
  847. {
  848. const struct tomoyo_mount_acl *p1 = container_of(a, typeof(*p1), head);
  849. const struct tomoyo_mount_acl *p2 = container_of(b, typeof(*p2), head);
  850. return tomoyo_same_name_union(&p1->dev_name, &p2->dev_name) &&
  851. tomoyo_same_name_union(&p1->dir_name, &p2->dir_name) &&
  852. tomoyo_same_name_union(&p1->fs_type, &p2->fs_type) &&
  853. tomoyo_same_number_union(&p1->flags, &p2->flags);
  854. }
  855. /**
  856. * tomoyo_update_mount_acl - Write "struct tomoyo_mount_acl" list.
  857. *
  858. * @param: Pointer to "struct tomoyo_acl_param".
  859. *
  860. * Returns 0 on success, negative value otherwise.
  861. *
  862. * Caller holds tomoyo_read_lock().
  863. */
  864. static int tomoyo_update_mount_acl(struct tomoyo_acl_param *param)
  865. {
  866. struct tomoyo_mount_acl e = { .head.type = TOMOYO_TYPE_MOUNT_ACL };
  867. int error;
  868. if (!tomoyo_parse_name_union(param, &e.dev_name) ||
  869. !tomoyo_parse_name_union(param, &e.dir_name) ||
  870. !tomoyo_parse_name_union(param, &e.fs_type) ||
  871. !tomoyo_parse_number_union(param, &e.flags))
  872. error = -EINVAL;
  873. else
  874. error = tomoyo_update_domain(&e.head, sizeof(e), param,
  875. tomoyo_same_mount_acl, NULL);
  876. tomoyo_put_name_union(&e.dev_name);
  877. tomoyo_put_name_union(&e.dir_name);
  878. tomoyo_put_name_union(&e.fs_type);
  879. tomoyo_put_number_union(&e.flags);
  880. return error;
  881. }
  882. /**
  883. * tomoyo_write_file - Update file related list.
  884. *
  885. * @param: Pointer to "struct tomoyo_acl_param".
  886. *
  887. * Returns 0 on success, negative value otherwise.
  888. *
  889. * Caller holds tomoyo_read_lock().
  890. */
  891. int tomoyo_write_file(struct tomoyo_acl_param *param)
  892. {
  893. u16 perm = 0;
  894. u8 type;
  895. const char *operation = tomoyo_read_token(param);
  896. for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++)
  897. if (tomoyo_permstr(operation, tomoyo_path_keyword[type]))
  898. perm |= 1 << type;
  899. if (perm)
  900. return tomoyo_update_path_acl(perm, param);
  901. for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++)
  902. if (tomoyo_permstr(operation,
  903. tomoyo_mac_keywords[tomoyo_pp2mac[type]]))
  904. perm |= 1 << type;
  905. if (perm)
  906. return tomoyo_update_path2_acl(perm, param);
  907. for (type = 0; type < TOMOYO_MAX_PATH_NUMBER_OPERATION; type++)
  908. if (tomoyo_permstr(operation,
  909. tomoyo_mac_keywords[tomoyo_pn2mac[type]]))
  910. perm |= 1 << type;
  911. if (perm)
  912. return tomoyo_update_path_number_acl(perm, param);
  913. for (type = 0; type < TOMOYO_MAX_MKDEV_OPERATION; type++)
  914. if (tomoyo_permstr(operation,
  915. tomoyo_mac_keywords[tomoyo_pnnn2mac[type]]))
  916. perm |= 1 << type;
  917. if (perm)
  918. return tomoyo_update_mkdev_acl(perm, param);
  919. if (tomoyo_permstr(operation,
  920. tomoyo_mac_keywords[TOMOYO_MAC_FILE_MOUNT]))
  921. return tomoyo_update_mount_acl(param);
  922. return -EINVAL;
  923. }