file.c 30 KB

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