audit.c revision 8761afd49ebff8ae04c1a7888af090177441d07d
1eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/*
2eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * security/tomoyo/audit.c
3eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
4eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Pathname restriction functions.
5eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
6eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Copyright (C) 2005-2010  NTT DATA CORPORATION
7eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */
8eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa
9eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa#include "common.h"
10eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa#include <linux/slab.h>
11eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa
12eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/**
138761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa * tomoyo_filetype - Get string representation of file type.
148761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa *
158761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa * @mode: Mode value for stat().
168761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa *
178761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa * Returns file type string.
188761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa */
198761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handastatic inline const char *tomoyo_filetype(const mode_t mode)
208761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa{
218761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	switch (mode & S_IFMT) {
228761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	case S_IFREG:
238761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	case 0:
248761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FILE];
258761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	case S_IFDIR:
268761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		return tomoyo_condition_keyword[TOMOYO_TYPE_IS_DIRECTORY];
278761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	case S_IFLNK:
288761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SYMLINK];
298761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	case S_IFIFO:
308761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FIFO];
318761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	case S_IFSOCK:
328761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SOCKET];
338761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	case S_IFBLK:
348761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		return tomoyo_condition_keyword[TOMOYO_TYPE_IS_BLOCK_DEV];
358761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	case S_IFCHR:
368761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		return tomoyo_condition_keyword[TOMOYO_TYPE_IS_CHAR_DEV];
378761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	}
388761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	return "unknown"; /* This should not happen. */
398761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa}
408761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa
418761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa/**
42eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * tomoyo_print_header - Get header line of audit log.
43eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
44eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @r: Pointer to "struct tomoyo_request_info".
45eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
46eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Returns string representation.
47eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
48eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * This function uses kmalloc(), so caller must kfree() if this function
49eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * didn't return NULL.
50eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */
51eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handastatic char *tomoyo_print_header(struct tomoyo_request_info *r)
52eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa{
53eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	struct tomoyo_time stamp;
54eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	const pid_t gpid = task_pid_nr(current);
558761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	struct tomoyo_obj_info *obj = r->obj;
56eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	static const int tomoyo_buffer_len = 4096;
57eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS);
582066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa	int pos;
598761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	u8 i;
60eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (!buffer)
61eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		return NULL;
62eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	{
63eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		struct timeval tv;
64eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		do_gettimeofday(&tv);
65eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		tomoyo_convert_time(tv.tv_sec, &stamp);
66eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	}
672066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa	pos = snprintf(buffer, tomoyo_buffer_len - 1,
682066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa		       "#%04u/%02u/%02u %02u:%02u:%02u# profile=%u mode=%s "
692066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa		       "granted=%s (global-pid=%u) task={ pid=%u ppid=%u "
702066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa		       "uid=%u gid=%u euid=%u egid=%u suid=%u sgid=%u "
712066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa		       "fsuid=%u fsgid=%u }", stamp.year, stamp.month,
722066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa		       stamp.day, stamp.hour, stamp.min, stamp.sec, r->profile,
732066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa		       tomoyo_mode[r->mode], tomoyo_yesno(r->granted), gpid,
742066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa		       tomoyo_sys_getpid(), tomoyo_sys_getppid(),
752066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa		       current_uid(), current_gid(), current_euid(),
762066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa		       current_egid(), current_suid(), current_sgid(),
772066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa		       current_fsuid(), current_fsgid());
788761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	if (!obj)
798761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		goto no_obj_info;
808761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	if (!obj->validate_done) {
818761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		tomoyo_get_attributes(obj);
828761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		obj->validate_done = true;
838761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	}
848761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	for (i = 0; i < TOMOYO_MAX_PATH_STAT; i++) {
858761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		struct tomoyo_mini_stat *stat;
868761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		unsigned int dev;
878761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		mode_t mode;
888761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		if (!obj->stat_valid[i])
898761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa			continue;
908761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		stat = &obj->stat[i];
918761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		dev = stat->dev;
928761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		mode = stat->mode;
938761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		if (i & 1) {
948761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa			pos += snprintf(buffer + pos,
958761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa					tomoyo_buffer_len - 1 - pos,
968761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa					" path%u.parent={ uid=%u gid=%u "
978761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa					"ino=%lu perm=0%o }", (i >> 1) + 1,
988761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa					stat->uid, stat->gid, (unsigned long)
998761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa					stat->ino, stat->mode & S_IALLUGO);
1008761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa			continue;
1018761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		}
1028761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos,
1038761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa				" path%u={ uid=%u gid=%u ino=%lu major=%u"
1048761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa				" minor=%u perm=0%o type=%s", (i >> 1) + 1,
1058761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa				stat->uid, stat->gid, (unsigned long)
1068761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa				stat->ino, MAJOR(dev), MINOR(dev),
1078761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa				mode & S_IALLUGO, tomoyo_filetype(mode));
1088761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		if (S_ISCHR(mode) || S_ISBLK(mode)) {
1098761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa			dev = stat->rdev;
1108761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa			pos += snprintf(buffer + pos,
1118761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa					tomoyo_buffer_len - 1 - pos,
1128761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa					" dev_major=%u dev_minor=%u",
1138761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa					MAJOR(dev), MINOR(dev));
1148761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		}
1158761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa		pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos,
1168761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa				" }");
1178761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handa	}
1188761afd49ebff8ae04c1a7888af090177441d07dTetsuo Handano_obj_info:
1192066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa	if (pos < tomoyo_buffer_len - 1)
1202066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa		return buffer;
1212066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa	kfree(buffer);
1222066a36125fcbf5220990173b9d8e8bc49ad7538Tetsuo Handa	return NULL;
123eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa}
124eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa
125eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/**
126eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * tomoyo_init_log - Allocate buffer for audit logs.
127eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
128eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @r:    Pointer to "struct tomoyo_request_info".
129eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @len:  Buffer size needed for @fmt and @args.
130eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @fmt:  The printf()'s format string.
131eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @args: va_list structure for @fmt.
132eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
133eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Returns pointer to allocated memory.
134eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
135eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * This function uses kzalloc(), so caller must kfree() if this function
136eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * didn't return NULL.
137eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */
138eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handachar *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt,
139eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		      va_list args)
140eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa{
141eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	char *buf = NULL;
142eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	const char *header = NULL;
143eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	int pos;
144ea504819122a76a236f8b95d1556f807a0a41397Tetsuo Handa	const char *domainname = r->domain->domainname->name;
145eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	header = tomoyo_print_header(r);
146eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (!header)
147eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		return NULL;
148eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	/* +10 is for '\n' etc. and '\0'. */
149eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	len += strlen(domainname) + strlen(header) + 10;
150eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	len = tomoyo_round2(len);
151eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	buf = kzalloc(len, GFP_NOFS);
152eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (!buf)
153eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		goto out;
154eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	len--;
155eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	pos = snprintf(buf, len, "%s", header);
156eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname);
157eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	vsnprintf(buf + pos, len - pos, fmt, args);
158eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handaout:
159eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	kfree(header);
160eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	return buf;
161eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa}
162eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa
163eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/* Wait queue for /sys/kernel/security/tomoyo/audit. */
164eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handastatic DECLARE_WAIT_QUEUE_HEAD(tomoyo_log_wait);
165eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa
166eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/* Structure for audit log. */
167eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handastruct tomoyo_log {
168eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	struct list_head list;
169eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	char *log;
170eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	int size;
171eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa};
172eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa
173eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/* The list for "struct tomoyo_log". */
174eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handastatic LIST_HEAD(tomoyo_log);
175eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa
176eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/* Lock for "struct list_head tomoyo_log". */
177eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handastatic DEFINE_SPINLOCK(tomoyo_log_lock);
178eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa
179eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/* Length of "stuct list_head tomoyo_log". */
180eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handastatic unsigned int tomoyo_log_count;
181eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa
182eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/**
183eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * tomoyo_get_audit - Get audit mode.
184eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
185bd03a3e4c9a9df0c6b007045fa7fc8889111a478Tetsuo Handa * @ns:          Pointer to "struct tomoyo_policy_namespace".
186eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @profile:     Profile number.
187eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @index:       Index number of functionality.
188eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @is_granted:  True if granted log, false otherwise.
189eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
190eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Returns true if this request should be audited, false otherwise.
191eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */
192bd03a3e4c9a9df0c6b007045fa7fc8889111a478Tetsuo Handastatic bool tomoyo_get_audit(const struct tomoyo_policy_namespace *ns,
193bd03a3e4c9a9df0c6b007045fa7fc8889111a478Tetsuo Handa			     const u8 profile, const u8 index,
194eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa			     const bool is_granted)
195eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa{
196eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	u8 mode;
1972c47ab9353242b0f061959318f83c55360b88fa4Tetsuo Handa	const u8 category = tomoyo_index2category[index] +
1982c47ab9353242b0f061959318f83c55360b88fa4Tetsuo Handa		TOMOYO_MAX_MAC_INDEX;
199eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	struct tomoyo_profile *p;
200eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (!tomoyo_policy_loaded)
201eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		return false;
202bd03a3e4c9a9df0c6b007045fa7fc8889111a478Tetsuo Handa	p = tomoyo_profile(ns, profile);
203eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (tomoyo_log_count >= p->pref[TOMOYO_PREF_MAX_AUDIT_LOG])
204eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		return false;
205eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	mode = p->config[index];
206eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (mode == TOMOYO_CONFIG_USE_DEFAULT)
207eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		mode = p->config[category];
208eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (mode == TOMOYO_CONFIG_USE_DEFAULT)
209eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		mode = p->default_config;
210eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (is_granted)
211eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		return mode & TOMOYO_CONFIG_WANT_GRANT_LOG;
212eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	return mode & TOMOYO_CONFIG_WANT_REJECT_LOG;
213eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa}
214eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa
215eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/**
216eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * tomoyo_write_log2 - Write an audit log.
217eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
218eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @r:    Pointer to "struct tomoyo_request_info".
219eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @len:  Buffer size needed for @fmt and @args.
220eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @fmt:  The printf()'s format string.
221eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @args: va_list structure for @fmt.
222eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
223eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Returns nothing.
224eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */
225eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handavoid tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt,
226eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		       va_list args)
227eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa{
228eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	char *buf;
229eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	struct tomoyo_log *entry;
230eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	bool quota_exceeded = false;
231bd03a3e4c9a9df0c6b007045fa7fc8889111a478Tetsuo Handa	if (!tomoyo_get_audit(r->domain->ns, r->profile, r->type, r->granted))
232eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		goto out;
233eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	buf = tomoyo_init_log(r, len, fmt, args);
234eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (!buf)
235eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		goto out;
236eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	entry = kzalloc(sizeof(*entry), GFP_NOFS);
237eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (!entry) {
238eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		kfree(buf);
239eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		goto out;
240eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	}
241eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	entry->log = buf;
242eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	len = tomoyo_round2(strlen(buf) + 1);
243eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	/*
244eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	 * The entry->size is used for memory quota checks.
245eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	 * Don't go beyond strlen(entry->log).
246eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	 */
247eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	entry->size = len + tomoyo_round2(sizeof(*entry));
248eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	spin_lock(&tomoyo_log_lock);
249eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT] &&
250eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	    tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] + entry->size >=
251eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	    tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT]) {
252eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		quota_exceeded = true;
253eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	} else {
254eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] += entry->size;
255eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		list_add_tail(&entry->list, &tomoyo_log);
256eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		tomoyo_log_count++;
257eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	}
258eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	spin_unlock(&tomoyo_log_lock);
259eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (quota_exceeded) {
260eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		kfree(buf);
261eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		kfree(entry);
262eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		goto out;
263eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	}
264eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	wake_up(&tomoyo_log_wait);
265eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handaout:
266eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	return;
267eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa}
268eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa
269eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/**
270eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * tomoyo_write_log - Write an audit log.
271eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
272eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @r:   Pointer to "struct tomoyo_request_info".
273eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @fmt: The printf()'s format string, followed by parameters.
274eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
275eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Returns nothing.
276eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */
277eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handavoid tomoyo_write_log(struct tomoyo_request_info *r, const char *fmt, ...)
278eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa{
279eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	va_list args;
280eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	int len;
281eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	va_start(args, fmt);
282eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	len = vsnprintf((char *) &len, 1, fmt, args) + 1;
283eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	va_end(args);
284eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	va_start(args, fmt);
285eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	tomoyo_write_log2(r, len, fmt, args);
286eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	va_end(args);
287eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa}
288eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa
289eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/**
290eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * tomoyo_read_log - Read an audit log.
291eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
292eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @head: Pointer to "struct tomoyo_io_buffer".
293eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
294eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Returns nothing.
295eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */
296eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handavoid tomoyo_read_log(struct tomoyo_io_buffer *head)
297eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa{
298eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	struct tomoyo_log *ptr = NULL;
299eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (head->r.w_pos)
300eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		return;
301eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	kfree(head->read_buf);
302eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	head->read_buf = NULL;
303eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	spin_lock(&tomoyo_log_lock);
304eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (!list_empty(&tomoyo_log)) {
305eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		ptr = list_entry(tomoyo_log.next, typeof(*ptr), list);
306eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		list_del(&ptr->list);
307eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		tomoyo_log_count--;
308eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] -= ptr->size;
309eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	}
310eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	spin_unlock(&tomoyo_log_lock);
311eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (ptr) {
312eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		head->read_buf = ptr->log;
313eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		head->r.w[head->r.w_pos++] = head->read_buf;
314eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		kfree(ptr);
315eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	}
316eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa}
317eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa
318eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa/**
319eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * tomoyo_poll_log - Wait for an audit log.
320eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
321eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @file: Pointer to "struct file".
322eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * @wait: Pointer to "poll_table".
323eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa *
324eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa * Returns POLLIN | POLLRDNORM when ready to read an audit log.
325eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa */
326eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handaint tomoyo_poll_log(struct file *file, poll_table *wait)
327eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa{
328eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (tomoyo_log_count)
329eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		return POLLIN | POLLRDNORM;
330eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	poll_wait(file, &tomoyo_log_wait, wait);
331eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	if (tomoyo_log_count)
332eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa		return POLLIN | POLLRDNORM;
333eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa	return 0;
334eadd99cc85347b4f9eb10122ac90032eb4971b02Tetsuo Handa}
335