file.c 38 KB

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