file.c 35 KB

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