file.c 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274
  1. /*
  2. * security/tomoyo/file.c
  3. *
  4. * Implementation of the Domain-Based Mandatory Access Control.
  5. *
  6. * Copyright (C) 2005-2009 NTT DATA CORPORATION
  7. *
  8. * Version: 2.2.0 2009/04/01
  9. *
  10. */
  11. #include "common.h"
  12. #include <linux/slab.h>
  13. /* Keyword array for single path operations. */
  14. static const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = {
  15. [TOMOYO_TYPE_READ_WRITE] = "read/write",
  16. [TOMOYO_TYPE_EXECUTE] = "execute",
  17. [TOMOYO_TYPE_READ] = "read",
  18. [TOMOYO_TYPE_WRITE] = "write",
  19. [TOMOYO_TYPE_CREATE] = "create",
  20. [TOMOYO_TYPE_UNLINK] = "unlink",
  21. [TOMOYO_TYPE_MKDIR] = "mkdir",
  22. [TOMOYO_TYPE_RMDIR] = "rmdir",
  23. [TOMOYO_TYPE_MKFIFO] = "mkfifo",
  24. [TOMOYO_TYPE_MKSOCK] = "mksock",
  25. [TOMOYO_TYPE_MKBLOCK] = "mkblock",
  26. [TOMOYO_TYPE_MKCHAR] = "mkchar",
  27. [TOMOYO_TYPE_TRUNCATE] = "truncate",
  28. [TOMOYO_TYPE_SYMLINK] = "symlink",
  29. [TOMOYO_TYPE_REWRITE] = "rewrite",
  30. [TOMOYO_TYPE_IOCTL] = "ioctl",
  31. [TOMOYO_TYPE_CHMOD] = "chmod",
  32. [TOMOYO_TYPE_CHOWN] = "chown",
  33. [TOMOYO_TYPE_CHGRP] = "chgrp",
  34. [TOMOYO_TYPE_CHROOT] = "chroot",
  35. [TOMOYO_TYPE_MOUNT] = "mount",
  36. [TOMOYO_TYPE_UMOUNT] = "unmount",
  37. };
  38. /* Keyword array for double path operations. */
  39. static const char *tomoyo_path2_keyword[TOMOYO_MAX_PATH2_OPERATION] = {
  40. [TOMOYO_TYPE_LINK] = "link",
  41. [TOMOYO_TYPE_RENAME] = "rename",
  42. [TOMOYO_TYPE_PIVOT_ROOT] = "pivot_root",
  43. };
  44. /**
  45. * tomoyo_path2keyword - Get the name of single path operation.
  46. *
  47. * @operation: Type of operation.
  48. *
  49. * Returns the name of single path operation.
  50. */
  51. const char *tomoyo_path2keyword(const u8 operation)
  52. {
  53. return (operation < TOMOYO_MAX_PATH_OPERATION)
  54. ? tomoyo_path_keyword[operation] : NULL;
  55. }
  56. /**
  57. * tomoyo_path22keyword - Get the name of double path operation.
  58. *
  59. * @operation: Type of operation.
  60. *
  61. * Returns the name of double path operation.
  62. */
  63. const char *tomoyo_path22keyword(const u8 operation)
  64. {
  65. return (operation < TOMOYO_MAX_PATH2_OPERATION)
  66. ? tomoyo_path2_keyword[operation] : NULL;
  67. }
  68. /**
  69. * tomoyo_strendswith - Check whether the token ends with the given token.
  70. *
  71. * @name: The token to check.
  72. * @tail: The token to find.
  73. *
  74. * Returns true if @name ends with @tail, false otherwise.
  75. */
  76. static bool tomoyo_strendswith(const char *name, const char *tail)
  77. {
  78. int len;
  79. if (!name || !tail)
  80. return false;
  81. len = strlen(name) - strlen(tail);
  82. return len >= 0 && !strcmp(name + len, tail);
  83. }
  84. /**
  85. * tomoyo_get_path - Get realpath.
  86. *
  87. * @path: Pointer to "struct path".
  88. *
  89. * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
  90. */
  91. static struct tomoyo_path_info *tomoyo_get_path(struct path *path)
  92. {
  93. int error;
  94. struct tomoyo_path_info_with_data *buf = kzalloc(sizeof(*buf),
  95. GFP_NOFS);
  96. if (!buf)
  97. return NULL;
  98. /* Reserve one byte for appending "/". */
  99. error = tomoyo_realpath_from_path2(path, buf->body,
  100. sizeof(buf->body) - 2);
  101. if (!error) {
  102. buf->head.name = buf->body;
  103. tomoyo_fill_path_info(&buf->head);
  104. return &buf->head;
  105. }
  106. kfree(buf);
  107. return NULL;
  108. }
  109. static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
  110. const char *filename2,
  111. struct tomoyo_domain_info *const domain,
  112. const bool is_delete);
  113. static int tomoyo_update_path_acl(const u8 type, const char *filename,
  114. struct tomoyo_domain_info *const domain,
  115. const bool is_delete);
  116. /*
  117. * tomoyo_globally_readable_list is used for holding list of pathnames which
  118. * are by default allowed to be open()ed for reading by any process.
  119. *
  120. * An entry is added by
  121. *
  122. * # echo 'allow_read /lib/libc-2.5.so' > \
  123. * /sys/kernel/security/tomoyo/exception_policy
  124. *
  125. * and is deleted by
  126. *
  127. * # echo 'delete allow_read /lib/libc-2.5.so' > \
  128. * /sys/kernel/security/tomoyo/exception_policy
  129. *
  130. * and all entries are retrieved by
  131. *
  132. * # grep ^allow_read /sys/kernel/security/tomoyo/exception_policy
  133. *
  134. * In the example above, any process is allowed to
  135. * open("/lib/libc-2.5.so", O_RDONLY).
  136. * One exception is, if the domain which current process belongs to is marked
  137. * as "ignore_global_allow_read", current process can't do so unless explicitly
  138. * given "allow_read /lib/libc-2.5.so" to the domain which current process
  139. * belongs to.
  140. */
  141. LIST_HEAD(tomoyo_globally_readable_list);
  142. /**
  143. * tomoyo_update_globally_readable_entry - Update "struct tomoyo_globally_readable_file_entry" list.
  144. *
  145. * @filename: Filename unconditionally permitted to open() for reading.
  146. * @is_delete: True if it is a delete request.
  147. *
  148. * Returns 0 on success, negative value otherwise.
  149. *
  150. * Caller holds tomoyo_read_lock().
  151. */
  152. static int tomoyo_update_globally_readable_entry(const char *filename,
  153. const bool is_delete)
  154. {
  155. struct tomoyo_globally_readable_file_entry *ptr;
  156. struct tomoyo_globally_readable_file_entry e = { };
  157. int error = is_delete ? -ENOENT : -ENOMEM;
  158. if (!tomoyo_is_correct_path(filename, 1, 0, -1))
  159. return -EINVAL;
  160. e.filename = tomoyo_get_name(filename);
  161. if (!e.filename)
  162. return -ENOMEM;
  163. if (mutex_lock_interruptible(&tomoyo_policy_lock))
  164. goto out;
  165. list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
  166. if (ptr->filename != e.filename)
  167. continue;
  168. ptr->is_deleted = is_delete;
  169. error = 0;
  170. break;
  171. }
  172. if (!is_delete && error) {
  173. struct tomoyo_globally_readable_file_entry *entry =
  174. tomoyo_commit_ok(&e, sizeof(e));
  175. if (entry) {
  176. list_add_tail_rcu(&entry->list,
  177. &tomoyo_globally_readable_list);
  178. error = 0;
  179. }
  180. }
  181. mutex_unlock(&tomoyo_policy_lock);
  182. out:
  183. tomoyo_put_name(e.filename);
  184. return error;
  185. }
  186. /**
  187. * tomoyo_is_globally_readable_file - Check if the file is unconditionnaly permitted to be open()ed for reading.
  188. *
  189. * @filename: The filename to check.
  190. *
  191. * Returns true if any domain can open @filename for reading, false otherwise.
  192. *
  193. * Caller holds tomoyo_read_lock().
  194. */
  195. static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info *
  196. filename)
  197. {
  198. struct tomoyo_globally_readable_file_entry *ptr;
  199. bool found = false;
  200. list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
  201. if (!ptr->is_deleted &&
  202. tomoyo_path_matches_pattern(filename, ptr->filename)) {
  203. found = true;
  204. break;
  205. }
  206. }
  207. return found;
  208. }
  209. /**
  210. * tomoyo_write_globally_readable_policy - Write "struct tomoyo_globally_readable_file_entry" list.
  211. *
  212. * @data: String to parse.
  213. * @is_delete: True if it is a delete request.
  214. *
  215. * Returns 0 on success, negative value otherwise.
  216. *
  217. * Caller holds tomoyo_read_lock().
  218. */
  219. int tomoyo_write_globally_readable_policy(char *data, const bool is_delete)
  220. {
  221. return tomoyo_update_globally_readable_entry(data, is_delete);
  222. }
  223. /**
  224. * tomoyo_read_globally_readable_policy - Read "struct tomoyo_globally_readable_file_entry" list.
  225. *
  226. * @head: Pointer to "struct tomoyo_io_buffer".
  227. *
  228. * Returns true on success, false otherwise.
  229. *
  230. * Caller holds tomoyo_read_lock().
  231. */
  232. bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
  233. {
  234. struct list_head *pos;
  235. bool done = true;
  236. list_for_each_cookie(pos, head->read_var2,
  237. &tomoyo_globally_readable_list) {
  238. struct tomoyo_globally_readable_file_entry *ptr;
  239. ptr = list_entry(pos,
  240. struct tomoyo_globally_readable_file_entry,
  241. list);
  242. if (ptr->is_deleted)
  243. continue;
  244. done = tomoyo_io_printf(head, TOMOYO_KEYWORD_ALLOW_READ "%s\n",
  245. ptr->filename->name);
  246. if (!done)
  247. break;
  248. }
  249. return done;
  250. }
  251. /* tomoyo_pattern_list is used for holding list of pathnames which are used for
  252. * converting pathnames to pathname patterns during learning mode.
  253. *
  254. * An entry is added by
  255. *
  256. * # echo 'file_pattern /proc/\$/mounts' > \
  257. * /sys/kernel/security/tomoyo/exception_policy
  258. *
  259. * and is deleted by
  260. *
  261. * # echo 'delete file_pattern /proc/\$/mounts' > \
  262. * /sys/kernel/security/tomoyo/exception_policy
  263. *
  264. * and all entries are retrieved by
  265. *
  266. * # grep ^file_pattern /sys/kernel/security/tomoyo/exception_policy
  267. *
  268. * In the example above, if a process which belongs to a domain which is in
  269. * learning mode requested open("/proc/1/mounts", O_RDONLY),
  270. * "allow_read /proc/\$/mounts" is automatically added to the domain which that
  271. * process belongs to.
  272. *
  273. * It is not a desirable behavior that we have to use /proc/\$/ instead of
  274. * /proc/self/ when current process needs to access only current process's
  275. * information. As of now, LSM version of TOMOYO is using __d_path() for
  276. * calculating pathname. Non LSM version of TOMOYO is using its own function
  277. * which pretends as if /proc/self/ is not a symlink; so that we can forbid
  278. * current process from accessing other process's information.
  279. */
  280. LIST_HEAD(tomoyo_pattern_list);
  281. /**
  282. * tomoyo_update_file_pattern_entry - Update "struct tomoyo_pattern_entry" list.
  283. *
  284. * @pattern: Pathname pattern.
  285. * @is_delete: True if it is a delete request.
  286. *
  287. * Returns 0 on success, negative value otherwise.
  288. *
  289. * Caller holds tomoyo_read_lock().
  290. */
  291. static int tomoyo_update_file_pattern_entry(const char *pattern,
  292. const bool is_delete)
  293. {
  294. struct tomoyo_pattern_entry *ptr;
  295. struct tomoyo_pattern_entry e = { .pattern = tomoyo_get_name(pattern) };
  296. int error = is_delete ? -ENOENT : -ENOMEM;
  297. if (!e.pattern)
  298. return error;
  299. if (!e.pattern->is_patterned)
  300. goto out;
  301. if (mutex_lock_interruptible(&tomoyo_policy_lock))
  302. goto out;
  303. list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
  304. if (e.pattern != ptr->pattern)
  305. continue;
  306. ptr->is_deleted = is_delete;
  307. error = 0;
  308. break;
  309. }
  310. if (!is_delete && error) {
  311. struct tomoyo_pattern_entry *entry =
  312. tomoyo_commit_ok(&e, sizeof(e));
  313. if (entry) {
  314. list_add_tail_rcu(&entry->list, &tomoyo_pattern_list);
  315. error = 0;
  316. }
  317. }
  318. mutex_unlock(&tomoyo_policy_lock);
  319. out:
  320. tomoyo_put_name(e.pattern);
  321. return error;
  322. }
  323. /**
  324. * tomoyo_get_file_pattern - Get patterned pathname.
  325. *
  326. * @filename: The filename to find patterned pathname.
  327. *
  328. * Returns pointer to pathname pattern if matched, @filename otherwise.
  329. *
  330. * Caller holds tomoyo_read_lock().
  331. */
  332. static const struct tomoyo_path_info *
  333. tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
  334. {
  335. struct tomoyo_pattern_entry *ptr;
  336. const struct tomoyo_path_info *pattern = NULL;
  337. list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
  338. if (ptr->is_deleted)
  339. continue;
  340. if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
  341. continue;
  342. pattern = ptr->pattern;
  343. if (tomoyo_strendswith(pattern->name, "/\\*")) {
  344. /* Do nothing. Try to find the better match. */
  345. } else {
  346. /* This would be the better match. Use this. */
  347. break;
  348. }
  349. }
  350. if (pattern)
  351. filename = pattern;
  352. return filename;
  353. }
  354. /**
  355. * tomoyo_write_pattern_policy - Write "struct tomoyo_pattern_entry" list.
  356. *
  357. * @data: String to parse.
  358. * @is_delete: True if it is a delete request.
  359. *
  360. * Returns 0 on success, negative value otherwise.
  361. *
  362. * Caller holds tomoyo_read_lock().
  363. */
  364. int tomoyo_write_pattern_policy(char *data, const bool is_delete)
  365. {
  366. return tomoyo_update_file_pattern_entry(data, is_delete);
  367. }
  368. /**
  369. * tomoyo_read_file_pattern - Read "struct tomoyo_pattern_entry" list.
  370. *
  371. * @head: Pointer to "struct tomoyo_io_buffer".
  372. *
  373. * Returns true on success, false otherwise.
  374. *
  375. * Caller holds tomoyo_read_lock().
  376. */
  377. bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
  378. {
  379. struct list_head *pos;
  380. bool done = true;
  381. list_for_each_cookie(pos, head->read_var2, &tomoyo_pattern_list) {
  382. struct tomoyo_pattern_entry *ptr;
  383. ptr = list_entry(pos, struct tomoyo_pattern_entry, list);
  384. if (ptr->is_deleted)
  385. continue;
  386. done = tomoyo_io_printf(head, TOMOYO_KEYWORD_FILE_PATTERN
  387. "%s\n", ptr->pattern->name);
  388. if (!done)
  389. break;
  390. }
  391. return done;
  392. }
  393. /*
  394. * tomoyo_no_rewrite_list is used for holding list of pathnames which are by
  395. * default forbidden to modify already written content of a file.
  396. *
  397. * An entry is added by
  398. *
  399. * # echo 'deny_rewrite /var/log/messages' > \
  400. * /sys/kernel/security/tomoyo/exception_policy
  401. *
  402. * and is deleted by
  403. *
  404. * # echo 'delete deny_rewrite /var/log/messages' > \
  405. * /sys/kernel/security/tomoyo/exception_policy
  406. *
  407. * and all entries are retrieved by
  408. *
  409. * # grep ^deny_rewrite /sys/kernel/security/tomoyo/exception_policy
  410. *
  411. * In the example above, if a process requested to rewrite /var/log/messages ,
  412. * the process can't rewrite unless the domain which that process belongs to
  413. * has "allow_rewrite /var/log/messages" entry.
  414. *
  415. * It is not a desirable behavior that we have to add "\040(deleted)" suffix
  416. * when we want to allow rewriting already unlink()ed file. As of now,
  417. * LSM version of TOMOYO is using __d_path() for calculating pathname.
  418. * Non LSM version of TOMOYO is using its own function which doesn't append
  419. * " (deleted)" suffix if the file is already unlink()ed; so that we don't
  420. * need to worry whether the file is already unlink()ed or not.
  421. */
  422. LIST_HEAD(tomoyo_no_rewrite_list);
  423. /**
  424. * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite_entry" list.
  425. *
  426. * @pattern: Pathname pattern that are not rewritable by default.
  427. * @is_delete: True if it is a delete request.
  428. *
  429. * Returns 0 on success, negative value otherwise.
  430. *
  431. * Caller holds tomoyo_read_lock().
  432. */
  433. static int tomoyo_update_no_rewrite_entry(const char *pattern,
  434. const bool is_delete)
  435. {
  436. struct tomoyo_no_rewrite_entry *ptr;
  437. struct tomoyo_no_rewrite_entry e = { };
  438. int error = is_delete ? -ENOENT : -ENOMEM;
  439. if (!tomoyo_is_correct_path(pattern, 0, 0, 0))
  440. return -EINVAL;
  441. e.pattern = tomoyo_get_name(pattern);
  442. if (!e.pattern)
  443. return error;
  444. if (mutex_lock_interruptible(&tomoyo_policy_lock))
  445. goto out;
  446. list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
  447. if (ptr->pattern != e.pattern)
  448. continue;
  449. ptr->is_deleted = is_delete;
  450. error = 0;
  451. break;
  452. }
  453. if (!is_delete && error) {
  454. struct tomoyo_no_rewrite_entry *entry =
  455. tomoyo_commit_ok(&e, sizeof(e));
  456. if (entry) {
  457. list_add_tail_rcu(&entry->list,
  458. &tomoyo_no_rewrite_list);
  459. error = 0;
  460. }
  461. }
  462. mutex_unlock(&tomoyo_policy_lock);
  463. out:
  464. tomoyo_put_name(e.pattern);
  465. return error;
  466. }
  467. /**
  468. * tomoyo_is_no_rewrite_file - Check if the given pathname is not permitted to be rewrited.
  469. *
  470. * @filename: Filename to check.
  471. *
  472. * Returns true if @filename is specified by "deny_rewrite" directive,
  473. * false otherwise.
  474. *
  475. * Caller holds tomoyo_read_lock().
  476. */
  477. static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
  478. {
  479. struct tomoyo_no_rewrite_entry *ptr;
  480. bool found = false;
  481. list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
  482. if (ptr->is_deleted)
  483. continue;
  484. if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
  485. continue;
  486. found = true;
  487. break;
  488. }
  489. return found;
  490. }
  491. /**
  492. * tomoyo_write_no_rewrite_policy - Write "struct tomoyo_no_rewrite_entry" list.
  493. *
  494. * @data: String to parse.
  495. * @is_delete: True if it is a delete request.
  496. *
  497. * Returns 0 on success, negative value otherwise.
  498. *
  499. * Caller holds tomoyo_read_lock().
  500. */
  501. int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete)
  502. {
  503. return tomoyo_update_no_rewrite_entry(data, is_delete);
  504. }
  505. /**
  506. * tomoyo_read_no_rewrite_policy - Read "struct tomoyo_no_rewrite_entry" list.
  507. *
  508. * @head: Pointer to "struct tomoyo_io_buffer".
  509. *
  510. * Returns true on success, false otherwise.
  511. *
  512. * Caller holds tomoyo_read_lock().
  513. */
  514. bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
  515. {
  516. struct list_head *pos;
  517. bool done = true;
  518. list_for_each_cookie(pos, head->read_var2, &tomoyo_no_rewrite_list) {
  519. struct tomoyo_no_rewrite_entry *ptr;
  520. ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list);
  521. if (ptr->is_deleted)
  522. continue;
  523. done = tomoyo_io_printf(head, TOMOYO_KEYWORD_DENY_REWRITE
  524. "%s\n", ptr->pattern->name);
  525. if (!done)
  526. break;
  527. }
  528. return done;
  529. }
  530. /**
  531. * tomoyo_update_file_acl - Update file's read/write/execute ACL.
  532. *
  533. * @filename: Filename.
  534. * @perm: Permission (between 1 to 7).
  535. * @domain: Pointer to "struct tomoyo_domain_info".
  536. * @is_delete: True if it is a delete request.
  537. *
  538. * Returns 0 on success, negative value otherwise.
  539. *
  540. * This is legacy support interface for older policy syntax.
  541. * Current policy syntax uses "allow_read/write" instead of "6",
  542. * "allow_read" instead of "4", "allow_write" instead of "2",
  543. * "allow_execute" instead of "1".
  544. *
  545. * Caller holds tomoyo_read_lock().
  546. */
  547. static int tomoyo_update_file_acl(const char *filename, u8 perm,
  548. struct tomoyo_domain_info * const domain,
  549. const bool is_delete)
  550. {
  551. if (perm > 7 || !perm) {
  552. printk(KERN_DEBUG "%s: Invalid permission '%d %s'\n",
  553. __func__, perm, filename);
  554. return -EINVAL;
  555. }
  556. if (filename[0] != '@' && tomoyo_strendswith(filename, "/"))
  557. /*
  558. * Only 'allow_mkdir' and 'allow_rmdir' are valid for
  559. * directory permissions.
  560. */
  561. return 0;
  562. if (perm & 4)
  563. tomoyo_update_path_acl(TOMOYO_TYPE_READ, filename, domain,
  564. is_delete);
  565. if (perm & 2)
  566. tomoyo_update_path_acl(TOMOYO_TYPE_WRITE, filename, domain,
  567. is_delete);
  568. if (perm & 1)
  569. tomoyo_update_path_acl(TOMOYO_TYPE_EXECUTE, filename, domain,
  570. is_delete);
  571. return 0;
  572. }
  573. /**
  574. * tomoyo_path_acl2 - Check permission for single path operation.
  575. *
  576. * @domain: Pointer to "struct tomoyo_domain_info".
  577. * @filename: Filename to check.
  578. * @perm: Permission.
  579. * @may_use_pattern: True if patterned ACL is permitted.
  580. *
  581. * Returns 0 on success, -EPERM otherwise.
  582. *
  583. * Caller holds tomoyo_read_lock().
  584. */
  585. static int tomoyo_path_acl2(const struct tomoyo_domain_info *domain,
  586. const struct tomoyo_path_info *filename,
  587. const u32 perm, const bool may_use_pattern)
  588. {
  589. struct tomoyo_acl_info *ptr;
  590. int error = -EPERM;
  591. list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
  592. struct tomoyo_path_acl *acl;
  593. if (ptr->type != TOMOYO_TYPE_PATH_ACL)
  594. continue;
  595. acl = container_of(ptr, struct tomoyo_path_acl, head);
  596. if (perm <= 0xFFFF) {
  597. if (!(acl->perm & perm))
  598. continue;
  599. } else {
  600. if (!(acl->perm_high & (perm >> 16)))
  601. continue;
  602. }
  603. if (may_use_pattern || !acl->filename->is_patterned) {
  604. if (!tomoyo_path_matches_pattern(filename,
  605. acl->filename))
  606. continue;
  607. } else {
  608. continue;
  609. }
  610. error = 0;
  611. break;
  612. }
  613. return error;
  614. }
  615. /**
  616. * tomoyo_check_file_acl - Check permission for opening files.
  617. *
  618. * @domain: Pointer to "struct tomoyo_domain_info".
  619. * @filename: Filename to check.
  620. * @operation: Mode ("read" or "write" or "read/write" or "execute").
  621. *
  622. * Returns 0 on success, -EPERM otherwise.
  623. *
  624. * Caller holds tomoyo_read_lock().
  625. */
  626. static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain,
  627. const struct tomoyo_path_info *filename,
  628. const u8 operation)
  629. {
  630. u32 perm = 0;
  631. if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
  632. return 0;
  633. if (operation == 6)
  634. perm = 1 << TOMOYO_TYPE_READ_WRITE;
  635. else if (operation == 4)
  636. perm = 1 << TOMOYO_TYPE_READ;
  637. else if (operation == 2)
  638. perm = 1 << TOMOYO_TYPE_WRITE;
  639. else if (operation == 1)
  640. perm = 1 << TOMOYO_TYPE_EXECUTE;
  641. else
  642. BUG();
  643. return tomoyo_path_acl2(domain, filename, perm, operation != 1);
  644. }
  645. /**
  646. * tomoyo_check_file_perm2 - Check permission for opening files.
  647. *
  648. * @domain: Pointer to "struct tomoyo_domain_info".
  649. * @filename: Filename to check.
  650. * @perm: Mode ("read" or "write" or "read/write" or "execute").
  651. * @operation: Operation name passed used for verbose mode.
  652. * @mode: Access control mode.
  653. *
  654. * Returns 0 on success, negative value otherwise.
  655. *
  656. * Caller holds tomoyo_read_lock().
  657. */
  658. static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain,
  659. const struct tomoyo_path_info *filename,
  660. const u8 perm, const char *operation,
  661. const u8 mode)
  662. {
  663. const bool is_enforce = (mode == 3);
  664. const char *msg = "<unknown>";
  665. int error = 0;
  666. if (!filename)
  667. return 0;
  668. error = tomoyo_check_file_acl(domain, filename, perm);
  669. if (error && perm == 4 && !domain->ignore_global_allow_read
  670. && tomoyo_is_globally_readable_file(filename))
  671. error = 0;
  672. if (perm == 6)
  673. msg = tomoyo_path2keyword(TOMOYO_TYPE_READ_WRITE);
  674. else if (perm == 4)
  675. msg = tomoyo_path2keyword(TOMOYO_TYPE_READ);
  676. else if (perm == 2)
  677. msg = tomoyo_path2keyword(TOMOYO_TYPE_WRITE);
  678. else if (perm == 1)
  679. msg = tomoyo_path2keyword(TOMOYO_TYPE_EXECUTE);
  680. else
  681. BUG();
  682. if (!error)
  683. return 0;
  684. if (tomoyo_verbose_mode(domain))
  685. printk(KERN_WARNING "TOMOYO-%s: Access '%s(%s) %s' denied "
  686. "for %s\n", tomoyo_get_msg(is_enforce), msg, operation,
  687. filename->name, tomoyo_get_last_name(domain));
  688. if (is_enforce)
  689. return error;
  690. if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) {
  691. /* Don't use patterns for execute permission. */
  692. const struct tomoyo_path_info *patterned_file = (perm != 1) ?
  693. tomoyo_get_file_pattern(filename) : filename;
  694. tomoyo_update_file_acl(patterned_file->name, perm,
  695. domain, false);
  696. }
  697. return 0;
  698. }
  699. /**
  700. * tomoyo_write_file_policy - Update file related list.
  701. *
  702. * @data: String to parse.
  703. * @domain: Pointer to "struct tomoyo_domain_info".
  704. * @is_delete: True if it is a delete request.
  705. *
  706. * Returns 0 on success, negative value otherwise.
  707. *
  708. * Caller holds tomoyo_read_lock().
  709. */
  710. int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
  711. const bool is_delete)
  712. {
  713. char *filename = strchr(data, ' ');
  714. char *filename2;
  715. unsigned int perm;
  716. u8 type;
  717. if (!filename)
  718. return -EINVAL;
  719. *filename++ = '\0';
  720. if (sscanf(data, "%u", &perm) == 1)
  721. return tomoyo_update_file_acl(filename, (u8) perm, domain,
  722. is_delete);
  723. if (strncmp(data, "allow_", 6))
  724. goto out;
  725. data += 6;
  726. for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++) {
  727. if (strcmp(data, tomoyo_path_keyword[type]))
  728. continue;
  729. return tomoyo_update_path_acl(type, filename, domain,
  730. is_delete);
  731. }
  732. filename2 = strchr(filename, ' ');
  733. if (!filename2)
  734. goto out;
  735. *filename2++ = '\0';
  736. for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++) {
  737. if (strcmp(data, tomoyo_path2_keyword[type]))
  738. continue;
  739. return tomoyo_update_path2_acl(type, filename, filename2,
  740. domain, is_delete);
  741. }
  742. out:
  743. return -EINVAL;
  744. }
  745. /**
  746. * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list.
  747. *
  748. * @type: Type of operation.
  749. * @filename: Filename.
  750. * @domain: Pointer to "struct tomoyo_domain_info".
  751. * @is_delete: True if it is a delete request.
  752. *
  753. * Returns 0 on success, negative value otherwise.
  754. *
  755. * Caller holds tomoyo_read_lock().
  756. */
  757. static int tomoyo_update_path_acl(const u8 type, const char *filename,
  758. struct tomoyo_domain_info *const domain,
  759. const bool is_delete)
  760. {
  761. static const u32 tomoyo_rw_mask =
  762. (1 << TOMOYO_TYPE_READ) | (1 << TOMOYO_TYPE_WRITE);
  763. const u32 perm = 1 << type;
  764. struct tomoyo_acl_info *ptr;
  765. struct tomoyo_path_acl e = {
  766. .head.type = TOMOYO_TYPE_PATH_ACL,
  767. .perm_high = perm >> 16,
  768. .perm = perm
  769. };
  770. int error = is_delete ? -ENOENT : -ENOMEM;
  771. if (type == TOMOYO_TYPE_READ_WRITE)
  772. e.perm |= tomoyo_rw_mask;
  773. if (!domain)
  774. return -EINVAL;
  775. if (!tomoyo_is_correct_path(filename, 0, 0, 0))
  776. return -EINVAL;
  777. e.filename = tomoyo_get_name(filename);
  778. if (!e.filename)
  779. return -ENOMEM;
  780. if (mutex_lock_interruptible(&tomoyo_policy_lock))
  781. goto out;
  782. list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
  783. struct tomoyo_path_acl *acl =
  784. container_of(ptr, struct tomoyo_path_acl, head);
  785. if (ptr->type != TOMOYO_TYPE_PATH_ACL)
  786. continue;
  787. if (acl->filename != e.filename)
  788. continue;
  789. if (is_delete) {
  790. if (perm <= 0xFFFF)
  791. acl->perm &= ~perm;
  792. else
  793. acl->perm_high &= ~(perm >> 16);
  794. if ((acl->perm & tomoyo_rw_mask) != tomoyo_rw_mask)
  795. acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE);
  796. else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE)))
  797. acl->perm &= ~tomoyo_rw_mask;
  798. } else {
  799. if (perm <= 0xFFFF)
  800. acl->perm |= perm;
  801. else
  802. acl->perm_high |= (perm >> 16);
  803. if ((acl->perm & tomoyo_rw_mask) == tomoyo_rw_mask)
  804. acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE;
  805. else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE))
  806. acl->perm |= tomoyo_rw_mask;
  807. }
  808. error = 0;
  809. break;
  810. }
  811. if (!is_delete && error) {
  812. struct tomoyo_path_acl *entry =
  813. tomoyo_commit_ok(&e, sizeof(e));
  814. if (entry) {
  815. list_add_tail_rcu(&entry->head.list,
  816. &domain->acl_info_list);
  817. error = 0;
  818. }
  819. }
  820. mutex_unlock(&tomoyo_policy_lock);
  821. out:
  822. tomoyo_put_name(e.filename);
  823. return error;
  824. }
  825. /**
  826. * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list.
  827. *
  828. * @type: Type of operation.
  829. * @filename1: First filename.
  830. * @filename2: Second filename.
  831. * @domain: Pointer to "struct tomoyo_domain_info".
  832. * @is_delete: True if it is a delete request.
  833. *
  834. * Returns 0 on success, negative value otherwise.
  835. *
  836. * Caller holds tomoyo_read_lock().
  837. */
  838. static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
  839. const char *filename2,
  840. struct tomoyo_domain_info *const domain,
  841. const bool is_delete)
  842. {
  843. const u8 perm = 1 << type;
  844. struct tomoyo_path2_acl e = {
  845. .head.type = TOMOYO_TYPE_PATH2_ACL,
  846. .perm = perm
  847. };
  848. struct tomoyo_acl_info *ptr;
  849. int error = is_delete ? -ENOENT : -ENOMEM;
  850. if (!domain)
  851. return -EINVAL;
  852. if (!tomoyo_is_correct_path(filename1, 0, 0, 0) ||
  853. !tomoyo_is_correct_path(filename2, 0, 0, 0))
  854. return -EINVAL;
  855. e.filename1 = tomoyo_get_name(filename1);
  856. e.filename2 = tomoyo_get_name(filename2);
  857. if (!e.filename1 || !e.filename2)
  858. goto out;
  859. if (mutex_lock_interruptible(&tomoyo_policy_lock))
  860. goto out;
  861. list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
  862. struct tomoyo_path2_acl *acl =
  863. container_of(ptr, struct tomoyo_path2_acl, head);
  864. if (ptr->type != TOMOYO_TYPE_PATH2_ACL)
  865. continue;
  866. if (acl->filename1 != e.filename1 ||
  867. acl->filename2 != e.filename2)
  868. continue;
  869. if (is_delete)
  870. acl->perm &= ~perm;
  871. else
  872. acl->perm |= perm;
  873. error = 0;
  874. break;
  875. }
  876. if (!is_delete && error) {
  877. struct tomoyo_path2_acl *entry =
  878. tomoyo_commit_ok(&e, sizeof(e));
  879. if (entry) {
  880. list_add_tail_rcu(&entry->head.list,
  881. &domain->acl_info_list);
  882. error = 0;
  883. }
  884. }
  885. mutex_unlock(&tomoyo_policy_lock);
  886. out:
  887. tomoyo_put_name(e.filename1);
  888. tomoyo_put_name(e.filename2);
  889. return error;
  890. }
  891. /**
  892. * tomoyo_path_acl - Check permission for single path operation.
  893. *
  894. * @domain: Pointer to "struct tomoyo_domain_info".
  895. * @type: Type of operation.
  896. * @filename: Filename to check.
  897. *
  898. * Returns 0 on success, negative value otherwise.
  899. *
  900. * Caller holds tomoyo_read_lock().
  901. */
  902. static int tomoyo_path_acl(struct tomoyo_domain_info *domain, const u8 type,
  903. const struct tomoyo_path_info *filename)
  904. {
  905. if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
  906. return 0;
  907. return tomoyo_path_acl2(domain, filename, 1 << type, 1);
  908. }
  909. /**
  910. * tomoyo_path2_acl - Check permission for double path operation.
  911. *
  912. * @domain: Pointer to "struct tomoyo_domain_info".
  913. * @type: Type of operation.
  914. * @filename1: First filename to check.
  915. * @filename2: Second filename to check.
  916. *
  917. * Returns 0 on success, -EPERM otherwise.
  918. *
  919. * Caller holds tomoyo_read_lock().
  920. */
  921. static int tomoyo_path2_acl(const struct tomoyo_domain_info *domain,
  922. const u8 type,
  923. const struct tomoyo_path_info *filename1,
  924. const struct tomoyo_path_info *filename2)
  925. {
  926. struct tomoyo_acl_info *ptr;
  927. const u8 perm = 1 << type;
  928. int error = -EPERM;
  929. if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
  930. return 0;
  931. list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
  932. struct tomoyo_path2_acl *acl;
  933. if (ptr->type != TOMOYO_TYPE_PATH2_ACL)
  934. continue;
  935. acl = container_of(ptr, struct tomoyo_path2_acl, head);
  936. if (!(acl->perm & perm))
  937. continue;
  938. if (!tomoyo_path_matches_pattern(filename1, acl->filename1))
  939. continue;
  940. if (!tomoyo_path_matches_pattern(filename2, acl->filename2))
  941. continue;
  942. error = 0;
  943. break;
  944. }
  945. return error;
  946. }
  947. /**
  948. * tomoyo_path_permission2 - Check permission for single path operation.
  949. *
  950. * @domain: Pointer to "struct tomoyo_domain_info".
  951. * @operation: Type of operation.
  952. * @filename: Filename to check.
  953. * @mode: Access control mode.
  954. *
  955. * Returns 0 on success, negative value otherwise.
  956. *
  957. * Caller holds tomoyo_read_lock().
  958. */
  959. static int tomoyo_path_permission2(struct tomoyo_domain_info *const domain,
  960. u8 operation,
  961. const struct tomoyo_path_info *filename,
  962. const u8 mode)
  963. {
  964. const char *msg;
  965. int error;
  966. const bool is_enforce = (mode == 3);
  967. if (!mode)
  968. return 0;
  969. next:
  970. error = tomoyo_path_acl(domain, operation, filename);
  971. msg = tomoyo_path2keyword(operation);
  972. if (!error)
  973. goto ok;
  974. if (tomoyo_verbose_mode(domain))
  975. printk(KERN_WARNING "TOMOYO-%s: Access '%s %s' denied for %s\n",
  976. tomoyo_get_msg(is_enforce), msg, filename->name,
  977. tomoyo_get_last_name(domain));
  978. if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) {
  979. const char *name = tomoyo_get_file_pattern(filename)->name;
  980. tomoyo_update_path_acl(operation, name, domain, false);
  981. }
  982. if (!is_enforce)
  983. error = 0;
  984. ok:
  985. /*
  986. * Since "allow_truncate" doesn't imply "allow_rewrite" permission,
  987. * we need to check "allow_rewrite" permission if the filename is
  988. * specified by "deny_rewrite" keyword.
  989. */
  990. if (!error && operation == TOMOYO_TYPE_TRUNCATE &&
  991. tomoyo_is_no_rewrite_file(filename)) {
  992. operation = TOMOYO_TYPE_REWRITE;
  993. goto next;
  994. }
  995. return error;
  996. }
  997. /**
  998. * tomoyo_check_exec_perm - Check permission for "execute".
  999. *
  1000. * @domain: Pointer to "struct tomoyo_domain_info".
  1001. * @filename: Check permission for "execute".
  1002. *
  1003. * Returns 0 on success, negativevalue otherwise.
  1004. *
  1005. * Caller holds tomoyo_read_lock().
  1006. */
  1007. int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain,
  1008. const struct tomoyo_path_info *filename)
  1009. {
  1010. const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
  1011. if (!mode)
  1012. return 0;
  1013. return tomoyo_check_file_perm2(domain, filename, 1, "do_execve", mode);
  1014. }
  1015. /**
  1016. * tomoyo_check_open_permission - Check permission for "read" and "write".
  1017. *
  1018. * @domain: Pointer to "struct tomoyo_domain_info".
  1019. * @path: Pointer to "struct path".
  1020. * @flag: Flags for open().
  1021. *
  1022. * Returns 0 on success, negative value otherwise.
  1023. */
  1024. int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
  1025. struct path *path, const int flag)
  1026. {
  1027. const u8 acc_mode = ACC_MODE(flag);
  1028. int error = -ENOMEM;
  1029. struct tomoyo_path_info *buf;
  1030. const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
  1031. const bool is_enforce = (mode == 3);
  1032. int idx;
  1033. if (!mode || !path->mnt)
  1034. return 0;
  1035. if (acc_mode == 0)
  1036. return 0;
  1037. if (path->dentry->d_inode && S_ISDIR(path->dentry->d_inode->i_mode))
  1038. /*
  1039. * I don't check directories here because mkdir() and rmdir()
  1040. * don't call me.
  1041. */
  1042. return 0;
  1043. idx = tomoyo_read_lock();
  1044. buf = tomoyo_get_path(path);
  1045. if (!buf)
  1046. goto out;
  1047. error = 0;
  1048. /*
  1049. * If the filename is specified by "deny_rewrite" keyword,
  1050. * we need to check "allow_rewrite" permission when the filename is not
  1051. * opened for append mode or the filename is truncated at open time.
  1052. */
  1053. if ((acc_mode & MAY_WRITE) &&
  1054. ((flag & O_TRUNC) || !(flag & O_APPEND)) &&
  1055. (tomoyo_is_no_rewrite_file(buf))) {
  1056. error = tomoyo_path_permission2(domain, TOMOYO_TYPE_REWRITE,
  1057. buf, mode);
  1058. }
  1059. if (!error)
  1060. error = tomoyo_check_file_perm2(domain, buf, acc_mode, "open",
  1061. mode);
  1062. if (!error && (flag & O_TRUNC))
  1063. error = tomoyo_path_permission2(domain, TOMOYO_TYPE_TRUNCATE,
  1064. buf, mode);
  1065. out:
  1066. kfree(buf);
  1067. tomoyo_read_unlock(idx);
  1068. if (!is_enforce)
  1069. error = 0;
  1070. return error;
  1071. }
  1072. /**
  1073. * tomoyo_path_perm - Check permission for "create", "unlink", "mkdir", "rmdir", "mkfifo", "mksock", "mkblock", "mkchar", "truncate", "symlink", "ioctl", "chmod", "chown", "chgrp", "chroot", "mount" and "unmount".
  1074. *
  1075. * @operation: Type of operation.
  1076. * @path: Pointer to "struct path".
  1077. *
  1078. * Returns 0 on success, negative value otherwise.
  1079. */
  1080. int tomoyo_path_perm(const u8 operation, struct path *path)
  1081. {
  1082. int error = -ENOMEM;
  1083. struct tomoyo_path_info *buf;
  1084. struct tomoyo_domain_info *domain = tomoyo_domain();
  1085. const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
  1086. const bool is_enforce = (mode == 3);
  1087. int idx;
  1088. if (!mode || !path->mnt)
  1089. return 0;
  1090. idx = tomoyo_read_lock();
  1091. buf = tomoyo_get_path(path);
  1092. if (!buf)
  1093. goto out;
  1094. switch (operation) {
  1095. case TOMOYO_TYPE_MKDIR:
  1096. case TOMOYO_TYPE_RMDIR:
  1097. case TOMOYO_TYPE_CHROOT:
  1098. if (!buf->is_dir) {
  1099. /*
  1100. * tomoyo_get_path() reserves space for appending "/."
  1101. */
  1102. strcat((char *) buf->name, "/");
  1103. tomoyo_fill_path_info(buf);
  1104. }
  1105. }
  1106. error = tomoyo_path_permission2(domain, operation, buf, mode);
  1107. out:
  1108. kfree(buf);
  1109. tomoyo_read_unlock(idx);
  1110. if (!is_enforce)
  1111. error = 0;
  1112. return error;
  1113. }
  1114. /**
  1115. * tomoyo_check_rewrite_permission - Check permission for "rewrite".
  1116. *
  1117. * @filp: Pointer to "struct file".
  1118. *
  1119. * Returns 0 on success, negative value otherwise.
  1120. */
  1121. int tomoyo_check_rewrite_permission(struct file *filp)
  1122. {
  1123. int error = -ENOMEM;
  1124. struct tomoyo_domain_info *domain = tomoyo_domain();
  1125. const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
  1126. const bool is_enforce = (mode == 3);
  1127. struct tomoyo_path_info *buf;
  1128. int idx;
  1129. if (!mode || !filp->f_path.mnt)
  1130. return 0;
  1131. idx = tomoyo_read_lock();
  1132. buf = tomoyo_get_path(&filp->f_path);
  1133. if (!buf)
  1134. goto out;
  1135. if (!tomoyo_is_no_rewrite_file(buf)) {
  1136. error = 0;
  1137. goto out;
  1138. }
  1139. error = tomoyo_path_permission2(domain, TOMOYO_TYPE_REWRITE, buf, mode);
  1140. out:
  1141. kfree(buf);
  1142. tomoyo_read_unlock(idx);
  1143. if (!is_enforce)
  1144. error = 0;
  1145. return error;
  1146. }
  1147. /**
  1148. * tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root".
  1149. *
  1150. * @operation: Type of operation.
  1151. * @path1: Pointer to "struct path".
  1152. * @path2: Pointer to "struct path".
  1153. *
  1154. * Returns 0 on success, negative value otherwise.
  1155. */
  1156. int tomoyo_path2_perm(const u8 operation, struct path *path1,
  1157. struct path *path2)
  1158. {
  1159. int error = -ENOMEM;
  1160. struct tomoyo_path_info *buf1, *buf2;
  1161. struct tomoyo_domain_info *domain = tomoyo_domain();
  1162. const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
  1163. const bool is_enforce = (mode == 3);
  1164. const char *msg;
  1165. int idx;
  1166. if (!mode || !path1->mnt || !path2->mnt)
  1167. return 0;
  1168. idx = tomoyo_read_lock();
  1169. buf1 = tomoyo_get_path(path1);
  1170. buf2 = tomoyo_get_path(path2);
  1171. if (!buf1 || !buf2)
  1172. goto out;
  1173. {
  1174. struct dentry *dentry = path1->dentry;
  1175. if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) {
  1176. /*
  1177. * tomoyo_get_path() reserves space for appending "/."
  1178. */
  1179. if (!buf1->is_dir) {
  1180. strcat((char *) buf1->name, "/");
  1181. tomoyo_fill_path_info(buf1);
  1182. }
  1183. if (!buf2->is_dir) {
  1184. strcat((char *) buf2->name, "/");
  1185. tomoyo_fill_path_info(buf2);
  1186. }
  1187. }
  1188. }
  1189. error = tomoyo_path2_acl(domain, operation, buf1, buf2);
  1190. msg = tomoyo_path22keyword(operation);
  1191. if (!error)
  1192. goto out;
  1193. if (tomoyo_verbose_mode(domain))
  1194. printk(KERN_WARNING "TOMOYO-%s: Access '%s %s %s' "
  1195. "denied for %s\n", tomoyo_get_msg(is_enforce),
  1196. msg, buf1->name, buf2->name,
  1197. tomoyo_get_last_name(domain));
  1198. if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) {
  1199. const char *name1 = tomoyo_get_file_pattern(buf1)->name;
  1200. const char *name2 = tomoyo_get_file_pattern(buf2)->name;
  1201. tomoyo_update_path2_acl(operation, name1, name2, domain,
  1202. false);
  1203. }
  1204. out:
  1205. kfree(buf1);
  1206. kfree(buf2);
  1207. tomoyo_read_unlock(idx);
  1208. if (!is_enforce)
  1209. error = 0;
  1210. return error;
  1211. }