file.c 29 KB

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