audit.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. /*
  2. * security/tomoyo/audit.c
  3. *
  4. * Pathname restriction functions.
  5. *
  6. * Copyright (C) 2005-2010 NTT DATA CORPORATION
  7. */
  8. #include "common.h"
  9. #include <linux/slab.h>
  10. /**
  11. * tomoyo_filetype - Get string representation of file type.
  12. *
  13. * @mode: Mode value for stat().
  14. *
  15. * Returns file type string.
  16. */
  17. static inline const char *tomoyo_filetype(const mode_t mode)
  18. {
  19. switch (mode & S_IFMT) {
  20. case S_IFREG:
  21. case 0:
  22. return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FILE];
  23. case S_IFDIR:
  24. return tomoyo_condition_keyword[TOMOYO_TYPE_IS_DIRECTORY];
  25. case S_IFLNK:
  26. return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SYMLINK];
  27. case S_IFIFO:
  28. return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FIFO];
  29. case S_IFSOCK:
  30. return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SOCKET];
  31. case S_IFBLK:
  32. return tomoyo_condition_keyword[TOMOYO_TYPE_IS_BLOCK_DEV];
  33. case S_IFCHR:
  34. return tomoyo_condition_keyword[TOMOYO_TYPE_IS_CHAR_DEV];
  35. }
  36. return "unknown"; /* This should not happen. */
  37. }
  38. /**
  39. * tomoyo_print_header - Get header line of audit log.
  40. *
  41. * @r: Pointer to "struct tomoyo_request_info".
  42. *
  43. * Returns string representation.
  44. *
  45. * This function uses kmalloc(), so caller must kfree() if this function
  46. * didn't return NULL.
  47. */
  48. static char *tomoyo_print_header(struct tomoyo_request_info *r)
  49. {
  50. struct tomoyo_time stamp;
  51. const pid_t gpid = task_pid_nr(current);
  52. struct tomoyo_obj_info *obj = r->obj;
  53. static const int tomoyo_buffer_len = 4096;
  54. char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS);
  55. int pos;
  56. u8 i;
  57. if (!buffer)
  58. return NULL;
  59. {
  60. struct timeval tv;
  61. do_gettimeofday(&tv);
  62. tomoyo_convert_time(tv.tv_sec, &stamp);
  63. }
  64. pos = snprintf(buffer, tomoyo_buffer_len - 1,
  65. "#%04u/%02u/%02u %02u:%02u:%02u# profile=%u mode=%s "
  66. "granted=%s (global-pid=%u) task={ pid=%u ppid=%u "
  67. "uid=%u gid=%u euid=%u egid=%u suid=%u sgid=%u "
  68. "fsuid=%u fsgid=%u }", stamp.year, stamp.month,
  69. stamp.day, stamp.hour, stamp.min, stamp.sec, r->profile,
  70. tomoyo_mode[r->mode], tomoyo_yesno(r->granted), gpid,
  71. tomoyo_sys_getpid(), tomoyo_sys_getppid(),
  72. current_uid(), current_gid(), current_euid(),
  73. current_egid(), current_suid(), current_sgid(),
  74. current_fsuid(), current_fsgid());
  75. if (!obj)
  76. goto no_obj_info;
  77. if (!obj->validate_done) {
  78. tomoyo_get_attributes(obj);
  79. obj->validate_done = true;
  80. }
  81. for (i = 0; i < TOMOYO_MAX_PATH_STAT; i++) {
  82. struct tomoyo_mini_stat *stat;
  83. unsigned int dev;
  84. mode_t mode;
  85. if (!obj->stat_valid[i])
  86. continue;
  87. stat = &obj->stat[i];
  88. dev = stat->dev;
  89. mode = stat->mode;
  90. if (i & 1) {
  91. pos += snprintf(buffer + pos,
  92. tomoyo_buffer_len - 1 - pos,
  93. " path%u.parent={ uid=%u gid=%u "
  94. "ino=%lu perm=0%o }", (i >> 1) + 1,
  95. stat->uid, stat->gid, (unsigned long)
  96. stat->ino, stat->mode & S_IALLUGO);
  97. continue;
  98. }
  99. pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos,
  100. " path%u={ uid=%u gid=%u ino=%lu major=%u"
  101. " minor=%u perm=0%o type=%s", (i >> 1) + 1,
  102. stat->uid, stat->gid, (unsigned long)
  103. stat->ino, MAJOR(dev), MINOR(dev),
  104. mode & S_IALLUGO, tomoyo_filetype(mode));
  105. if (S_ISCHR(mode) || S_ISBLK(mode)) {
  106. dev = stat->rdev;
  107. pos += snprintf(buffer + pos,
  108. tomoyo_buffer_len - 1 - pos,
  109. " dev_major=%u dev_minor=%u",
  110. MAJOR(dev), MINOR(dev));
  111. }
  112. pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos,
  113. " }");
  114. }
  115. no_obj_info:
  116. if (pos < tomoyo_buffer_len - 1)
  117. return buffer;
  118. kfree(buffer);
  119. return NULL;
  120. }
  121. /**
  122. * tomoyo_init_log - Allocate buffer for audit logs.
  123. *
  124. * @r: Pointer to "struct tomoyo_request_info".
  125. * @len: Buffer size needed for @fmt and @args.
  126. * @fmt: The printf()'s format string.
  127. * @args: va_list structure for @fmt.
  128. *
  129. * Returns pointer to allocated memory.
  130. *
  131. * This function uses kzalloc(), so caller must kfree() if this function
  132. * didn't return NULL.
  133. */
  134. char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt,
  135. va_list args)
  136. {
  137. char *buf = NULL;
  138. const char *header = NULL;
  139. char *realpath = NULL;
  140. const char *symlink = NULL;
  141. int pos;
  142. const char *domainname = r->domain->domainname->name;
  143. header = tomoyo_print_header(r);
  144. if (!header)
  145. return NULL;
  146. /* +10 is for '\n' etc. and '\0'. */
  147. len += strlen(domainname) + strlen(header) + 10;
  148. if (r->ee) {
  149. struct file *file = r->ee->bprm->file;
  150. realpath = tomoyo_realpath_from_path(&file->f_path);
  151. if (!realpath)
  152. goto out;
  153. /* +80 is for " exec={ realpath=\"%s\" }" */
  154. len += strlen(realpath) + 80;
  155. } else if (r->obj && r->obj->symlink_target) {
  156. symlink = r->obj->symlink_target->name;
  157. /* +18 is for " symlink.target=\"%s\"" */
  158. len += 18 + strlen(symlink);
  159. }
  160. len = tomoyo_round2(len);
  161. buf = kzalloc(len, GFP_NOFS);
  162. if (!buf)
  163. goto out;
  164. len--;
  165. pos = snprintf(buf, len, "%s", header);
  166. if (realpath) {
  167. pos += snprintf(buf + pos, len - pos,
  168. " exec={ realpath=\"%s\" }", realpath);
  169. } else if (symlink)
  170. pos += snprintf(buf + pos, len - pos, " symlink.target=\"%s\"",
  171. symlink);
  172. pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname);
  173. vsnprintf(buf + pos, len - pos, fmt, args);
  174. out:
  175. kfree(realpath);
  176. kfree(header);
  177. return buf;
  178. }
  179. /* Wait queue for /sys/kernel/security/tomoyo/audit. */
  180. static DECLARE_WAIT_QUEUE_HEAD(tomoyo_log_wait);
  181. /* Structure for audit log. */
  182. struct tomoyo_log {
  183. struct list_head list;
  184. char *log;
  185. int size;
  186. };
  187. /* The list for "struct tomoyo_log". */
  188. static LIST_HEAD(tomoyo_log);
  189. /* Lock for "struct list_head tomoyo_log". */
  190. static DEFINE_SPINLOCK(tomoyo_log_lock);
  191. /* Length of "stuct list_head tomoyo_log". */
  192. static unsigned int tomoyo_log_count;
  193. /**
  194. * tomoyo_get_audit - Get audit mode.
  195. *
  196. * @ns: Pointer to "struct tomoyo_policy_namespace".
  197. * @profile: Profile number.
  198. * @index: Index number of functionality.
  199. * @is_granted: True if granted log, false otherwise.
  200. *
  201. * Returns true if this request should be audited, false otherwise.
  202. */
  203. static bool tomoyo_get_audit(const struct tomoyo_policy_namespace *ns,
  204. const u8 profile, const u8 index,
  205. const bool is_granted)
  206. {
  207. u8 mode;
  208. const u8 category = tomoyo_index2category[index] +
  209. TOMOYO_MAX_MAC_INDEX;
  210. struct tomoyo_profile *p;
  211. if (!tomoyo_policy_loaded)
  212. return false;
  213. p = tomoyo_profile(ns, profile);
  214. if (tomoyo_log_count >= p->pref[TOMOYO_PREF_MAX_AUDIT_LOG])
  215. return false;
  216. mode = p->config[index];
  217. if (mode == TOMOYO_CONFIG_USE_DEFAULT)
  218. mode = p->config[category];
  219. if (mode == TOMOYO_CONFIG_USE_DEFAULT)
  220. mode = p->default_config;
  221. if (is_granted)
  222. return mode & TOMOYO_CONFIG_WANT_GRANT_LOG;
  223. return mode & TOMOYO_CONFIG_WANT_REJECT_LOG;
  224. }
  225. /**
  226. * tomoyo_write_log2 - Write an audit log.
  227. *
  228. * @r: Pointer to "struct tomoyo_request_info".
  229. * @len: Buffer size needed for @fmt and @args.
  230. * @fmt: The printf()'s format string.
  231. * @args: va_list structure for @fmt.
  232. *
  233. * Returns nothing.
  234. */
  235. void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt,
  236. va_list args)
  237. {
  238. char *buf;
  239. struct tomoyo_log *entry;
  240. bool quota_exceeded = false;
  241. if (!tomoyo_get_audit(r->domain->ns, r->profile, r->type, r->granted))
  242. goto out;
  243. buf = tomoyo_init_log(r, len, fmt, args);
  244. if (!buf)
  245. goto out;
  246. entry = kzalloc(sizeof(*entry), GFP_NOFS);
  247. if (!entry) {
  248. kfree(buf);
  249. goto out;
  250. }
  251. entry->log = buf;
  252. len = tomoyo_round2(strlen(buf) + 1);
  253. /*
  254. * The entry->size is used for memory quota checks.
  255. * Don't go beyond strlen(entry->log).
  256. */
  257. entry->size = len + tomoyo_round2(sizeof(*entry));
  258. spin_lock(&tomoyo_log_lock);
  259. if (tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT] &&
  260. tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] + entry->size >=
  261. tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT]) {
  262. quota_exceeded = true;
  263. } else {
  264. tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] += entry->size;
  265. list_add_tail(&entry->list, &tomoyo_log);
  266. tomoyo_log_count++;
  267. }
  268. spin_unlock(&tomoyo_log_lock);
  269. if (quota_exceeded) {
  270. kfree(buf);
  271. kfree(entry);
  272. goto out;
  273. }
  274. wake_up(&tomoyo_log_wait);
  275. out:
  276. return;
  277. }
  278. /**
  279. * tomoyo_write_log - Write an audit log.
  280. *
  281. * @r: Pointer to "struct tomoyo_request_info".
  282. * @fmt: The printf()'s format string, followed by parameters.
  283. *
  284. * Returns nothing.
  285. */
  286. void tomoyo_write_log(struct tomoyo_request_info *r, const char *fmt, ...)
  287. {
  288. va_list args;
  289. int len;
  290. va_start(args, fmt);
  291. len = vsnprintf((char *) &len, 1, fmt, args) + 1;
  292. va_end(args);
  293. va_start(args, fmt);
  294. tomoyo_write_log2(r, len, fmt, args);
  295. va_end(args);
  296. }
  297. /**
  298. * tomoyo_read_log - Read an audit log.
  299. *
  300. * @head: Pointer to "struct tomoyo_io_buffer".
  301. *
  302. * Returns nothing.
  303. */
  304. void tomoyo_read_log(struct tomoyo_io_buffer *head)
  305. {
  306. struct tomoyo_log *ptr = NULL;
  307. if (head->r.w_pos)
  308. return;
  309. kfree(head->read_buf);
  310. head->read_buf = NULL;
  311. spin_lock(&tomoyo_log_lock);
  312. if (!list_empty(&tomoyo_log)) {
  313. ptr = list_entry(tomoyo_log.next, typeof(*ptr), list);
  314. list_del(&ptr->list);
  315. tomoyo_log_count--;
  316. tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] -= ptr->size;
  317. }
  318. spin_unlock(&tomoyo_log_lock);
  319. if (ptr) {
  320. head->read_buf = ptr->log;
  321. head->r.w[head->r.w_pos++] = head->read_buf;
  322. kfree(ptr);
  323. }
  324. }
  325. /**
  326. * tomoyo_poll_log - Wait for an audit log.
  327. *
  328. * @file: Pointer to "struct file".
  329. * @wait: Pointer to "poll_table".
  330. *
  331. * Returns POLLIN | POLLRDNORM when ready to read an audit log.
  332. */
  333. int tomoyo_poll_log(struct file *file, poll_table *wait)
  334. {
  335. if (tomoyo_log_count)
  336. return POLLIN | POLLRDNORM;
  337. poll_wait(file, &tomoyo_log_wait, wait);
  338. if (tomoyo_log_count)
  339. return POLLIN | POLLRDNORM;
  340. return 0;
  341. }