2 * security/tomoyo/audit.c
4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
8 #include <linux/slab.h>
11 * tomoyo_print_bprm - Print "struct linux_binprm" for auditing.
13 * @bprm: Pointer to "struct linux_binprm".
14 * @dump: Pointer to "struct tomoyo_page_dump".
16 * Returns the contents of @bprm on success, NULL otherwise.
18 * This function uses kzalloc(), so caller must kfree() if this function
21 static char *tomoyo_print_bprm(struct linux_binprm
*bprm
,
22 struct tomoyo_page_dump
*dump
)
24 static const int tomoyo_buffer_len
= 4096 * 2;
25 char *buffer
= kzalloc(tomoyo_buffer_len
, GFP_NOFS
);
29 unsigned long pos
= bprm
->p
;
30 int offset
= pos
% PAGE_SIZE
;
31 int argv_count
= bprm
->argc
;
32 int envp_count
= bprm
->envc
;
33 bool truncated
= false;
36 len
= snprintf(buffer
, tomoyo_buffer_len
- 1, "argv[]={ ");
39 memmove(cp
, "} envp[]={ ", 11);
43 while (argv_count
|| envp_count
) {
44 if (!tomoyo_dump_page(bprm
, pos
, dump
))
46 pos
+= PAGE_SIZE
- offset
;
48 while (offset
< PAGE_SIZE
) {
49 const char *kaddr
= dump
->data
;
50 const unsigned char c
= kaddr
[offset
++];
53 if (cp
>= buffer
+ tomoyo_buffer_len
- 32) {
54 /* Reserve some room for "..." string. */
56 } else if (c
== '\\') {
59 } else if (c
> ' ' && c
< 127) {
67 *cp
++ = (c
>> 6) + '0';
68 *cp
++ = ((c
>> 3) & 7) + '0';
69 *cp
++ = (c
& 7) + '0';
74 if (--argv_count
== 0) {
77 memmove(cp
, "... ", 4);
80 memmove(cp
, "} envp[]={ ", 11);
85 } else if (envp_count
) {
86 if (--envp_count
== 0) {
89 memmove(cp
, "... ", 4);
94 if (!argv_count
&& !envp_count
)
103 snprintf(buffer
, tomoyo_buffer_len
- 1,
104 "argv[]={ ... } envp[]= { ... }");
109 * tomoyo_filetype - Get string representation of file type.
111 * @mode: Mode value for stat().
113 * Returns file type string.
115 static inline const char *tomoyo_filetype(const umode_t mode
)
117 switch (mode
& S_IFMT
) {
120 return tomoyo_condition_keyword
[TOMOYO_TYPE_IS_FILE
];
122 return tomoyo_condition_keyword
[TOMOYO_TYPE_IS_DIRECTORY
];
124 return tomoyo_condition_keyword
[TOMOYO_TYPE_IS_SYMLINK
];
126 return tomoyo_condition_keyword
[TOMOYO_TYPE_IS_FIFO
];
128 return tomoyo_condition_keyword
[TOMOYO_TYPE_IS_SOCKET
];
130 return tomoyo_condition_keyword
[TOMOYO_TYPE_IS_BLOCK_DEV
];
132 return tomoyo_condition_keyword
[TOMOYO_TYPE_IS_CHAR_DEV
];
134 return "unknown"; /* This should not happen. */
138 * tomoyo_print_header - Get header line of audit log.
140 * @r: Pointer to "struct tomoyo_request_info".
142 * Returns string representation.
144 * This function uses kmalloc(), so caller must kfree() if this function
145 * didn't return NULL.
147 static char *tomoyo_print_header(struct tomoyo_request_info
*r
)
149 struct tomoyo_time stamp
;
150 const pid_t gpid
= task_pid_nr(current
);
151 struct tomoyo_obj_info
*obj
= r
->obj
;
152 static const int tomoyo_buffer_len
= 4096;
153 char *buffer
= kmalloc(tomoyo_buffer_len
, GFP_NOFS
);
159 tomoyo_convert_time(get_seconds(), &stamp
);
161 pos
= snprintf(buffer
, tomoyo_buffer_len
- 1,
162 "#%04u/%02u/%02u %02u:%02u:%02u# profile=%u mode=%s "
163 "granted=%s (global-pid=%u) task={ pid=%u ppid=%u "
164 "uid=%u gid=%u euid=%u egid=%u suid=%u sgid=%u "
165 "fsuid=%u fsgid=%u }", stamp
.year
, stamp
.month
,
166 stamp
.day
, stamp
.hour
, stamp
.min
, stamp
.sec
, r
->profile
,
167 tomoyo_mode
[r
->mode
], tomoyo_yesno(r
->granted
), gpid
,
168 tomoyo_sys_getpid(), tomoyo_sys_getppid(),
169 from_kuid(&init_user_ns
, current_uid()),
170 from_kgid(&init_user_ns
, current_gid()),
171 from_kuid(&init_user_ns
, current_euid()),
172 from_kgid(&init_user_ns
, current_egid()),
173 from_kuid(&init_user_ns
, current_suid()),
174 from_kgid(&init_user_ns
, current_sgid()),
175 from_kuid(&init_user_ns
, current_fsuid()),
176 from_kgid(&init_user_ns
, current_fsgid()));
179 if (!obj
->validate_done
) {
180 tomoyo_get_attributes(obj
);
181 obj
->validate_done
= true;
183 for (i
= 0; i
< TOMOYO_MAX_PATH_STAT
; i
++) {
184 struct tomoyo_mini_stat
*stat
;
187 if (!obj
->stat_valid
[i
])
189 stat
= &obj
->stat
[i
];
193 pos
+= snprintf(buffer
+ pos
,
194 tomoyo_buffer_len
- 1 - pos
,
195 " path%u.parent={ uid=%u gid=%u "
196 "ino=%lu perm=0%o }", (i
>> 1) + 1,
197 from_kuid(&init_user_ns
, stat
->uid
),
198 from_kgid(&init_user_ns
, stat
->gid
),
199 (unsigned long)stat
->ino
,
200 stat
->mode
& S_IALLUGO
);
203 pos
+= snprintf(buffer
+ pos
, tomoyo_buffer_len
- 1 - pos
,
204 " path%u={ uid=%u gid=%u ino=%lu major=%u"
205 " minor=%u perm=0%o type=%s", (i
>> 1) + 1,
206 from_kuid(&init_user_ns
, stat
->uid
),
207 from_kgid(&init_user_ns
, stat
->gid
),
208 (unsigned long)stat
->ino
,
209 MAJOR(dev
), MINOR(dev
),
210 mode
& S_IALLUGO
, tomoyo_filetype(mode
));
211 if (S_ISCHR(mode
) || S_ISBLK(mode
)) {
213 pos
+= snprintf(buffer
+ pos
,
214 tomoyo_buffer_len
- 1 - pos
,
215 " dev_major=%u dev_minor=%u",
216 MAJOR(dev
), MINOR(dev
));
218 pos
+= snprintf(buffer
+ pos
, tomoyo_buffer_len
- 1 - pos
,
222 if (pos
< tomoyo_buffer_len
- 1)
229 * tomoyo_init_log - Allocate buffer for audit logs.
231 * @r: Pointer to "struct tomoyo_request_info".
232 * @len: Buffer size needed for @fmt and @args.
233 * @fmt: The printf()'s format string.
234 * @args: va_list structure for @fmt.
236 * Returns pointer to allocated memory.
238 * This function uses kzalloc(), so caller must kfree() if this function
239 * didn't return NULL.
241 char *tomoyo_init_log(struct tomoyo_request_info
*r
, int len
, const char *fmt
,
245 char *bprm_info
= NULL
;
246 const char *header
= NULL
;
247 char *realpath
= NULL
;
248 const char *symlink
= NULL
;
250 const char *domainname
= r
->domain
->domainname
->name
;
251 header
= tomoyo_print_header(r
);
254 /* +10 is for '\n' etc. and '\0'. */
255 len
+= strlen(domainname
) + strlen(header
) + 10;
257 struct file
*file
= r
->ee
->bprm
->file
;
258 realpath
= tomoyo_realpath_from_path(&file
->f_path
);
259 bprm_info
= tomoyo_print_bprm(r
->ee
->bprm
, &r
->ee
->dump
);
260 if (!realpath
|| !bprm_info
)
262 /* +80 is for " exec={ realpath=\"%s\" argc=%d envc=%d %s }" */
263 len
+= strlen(realpath
) + 80 + strlen(bprm_info
);
264 } else if (r
->obj
&& r
->obj
->symlink_target
) {
265 symlink
= r
->obj
->symlink_target
->name
;
266 /* +18 is for " symlink.target=\"%s\"" */
267 len
+= 18 + strlen(symlink
);
269 len
= tomoyo_round2(len
);
270 buf
= kzalloc(len
, GFP_NOFS
);
274 pos
= snprintf(buf
, len
, "%s", header
);
276 struct linux_binprm
*bprm
= r
->ee
->bprm
;
277 pos
+= snprintf(buf
+ pos
, len
- pos
,
278 " exec={ realpath=\"%s\" argc=%d envc=%d %s }",
279 realpath
, bprm
->argc
, bprm
->envc
, bprm_info
);
281 pos
+= snprintf(buf
+ pos
, len
- pos
, " symlink.target=\"%s\"",
283 pos
+= snprintf(buf
+ pos
, len
- pos
, "\n%s\n", domainname
);
284 vsnprintf(buf
+ pos
, len
- pos
, fmt
, args
);
292 /* Wait queue for /sys/kernel/security/tomoyo/audit. */
293 static DECLARE_WAIT_QUEUE_HEAD(tomoyo_log_wait
);
295 /* Structure for audit log. */
297 struct list_head list
;
302 /* The list for "struct tomoyo_log". */
303 static LIST_HEAD(tomoyo_log
);
305 /* Lock for "struct list_head tomoyo_log". */
306 static DEFINE_SPINLOCK(tomoyo_log_lock
);
308 /* Length of "stuct list_head tomoyo_log". */
309 static unsigned int tomoyo_log_count
;
312 * tomoyo_get_audit - Get audit mode.
314 * @ns: Pointer to "struct tomoyo_policy_namespace".
315 * @profile: Profile number.
316 * @index: Index number of functionality.
317 * @is_granted: True if granted log, false otherwise.
319 * Returns true if this request should be audited, false otherwise.
321 static bool tomoyo_get_audit(const struct tomoyo_policy_namespace
*ns
,
322 const u8 profile
, const u8 index
,
323 const struct tomoyo_acl_info
*matched_acl
,
324 const bool is_granted
)
327 const u8 category
= tomoyo_index2category
[index
] +
328 TOMOYO_MAX_MAC_INDEX
;
329 struct tomoyo_profile
*p
;
330 if (!tomoyo_policy_loaded
)
332 p
= tomoyo_profile(ns
, profile
);
333 if (tomoyo_log_count
>= p
->pref
[TOMOYO_PREF_MAX_AUDIT_LOG
])
335 if (is_granted
&& matched_acl
&& matched_acl
->cond
&&
336 matched_acl
->cond
->grant_log
!= TOMOYO_GRANTLOG_AUTO
)
337 return matched_acl
->cond
->grant_log
== TOMOYO_GRANTLOG_YES
;
338 mode
= p
->config
[index
];
339 if (mode
== TOMOYO_CONFIG_USE_DEFAULT
)
340 mode
= p
->config
[category
];
341 if (mode
== TOMOYO_CONFIG_USE_DEFAULT
)
342 mode
= p
->default_config
;
344 return mode
& TOMOYO_CONFIG_WANT_GRANT_LOG
;
345 return mode
& TOMOYO_CONFIG_WANT_REJECT_LOG
;
349 * tomoyo_write_log2 - Write an audit log.
351 * @r: Pointer to "struct tomoyo_request_info".
352 * @len: Buffer size needed for @fmt and @args.
353 * @fmt: The printf()'s format string.
354 * @args: va_list structure for @fmt.
358 void tomoyo_write_log2(struct tomoyo_request_info
*r
, int len
, const char *fmt
,
362 struct tomoyo_log
*entry
;
363 bool quota_exceeded
= false;
364 if (!tomoyo_get_audit(r
->domain
->ns
, r
->profile
, r
->type
,
365 r
->matched_acl
, r
->granted
))
367 buf
= tomoyo_init_log(r
, len
, fmt
, args
);
370 entry
= kzalloc(sizeof(*entry
), GFP_NOFS
);
376 len
= tomoyo_round2(strlen(buf
) + 1);
378 * The entry->size is used for memory quota checks.
379 * Don't go beyond strlen(entry->log).
381 entry
->size
= len
+ tomoyo_round2(sizeof(*entry
));
382 spin_lock(&tomoyo_log_lock
);
383 if (tomoyo_memory_quota
[TOMOYO_MEMORY_AUDIT
] &&
384 tomoyo_memory_used
[TOMOYO_MEMORY_AUDIT
] + entry
->size
>=
385 tomoyo_memory_quota
[TOMOYO_MEMORY_AUDIT
]) {
386 quota_exceeded
= true;
388 tomoyo_memory_used
[TOMOYO_MEMORY_AUDIT
] += entry
->size
;
389 list_add_tail(&entry
->list
, &tomoyo_log
);
392 spin_unlock(&tomoyo_log_lock
);
393 if (quota_exceeded
) {
398 wake_up(&tomoyo_log_wait
);
404 * tomoyo_write_log - Write an audit log.
406 * @r: Pointer to "struct tomoyo_request_info".
407 * @fmt: The printf()'s format string, followed by parameters.
411 void tomoyo_write_log(struct tomoyo_request_info
*r
, const char *fmt
, ...)
416 len
= vsnprintf((char *) &len
, 1, fmt
, args
) + 1;
419 tomoyo_write_log2(r
, len
, fmt
, args
);
424 * tomoyo_read_log - Read an audit log.
426 * @head: Pointer to "struct tomoyo_io_buffer".
430 void tomoyo_read_log(struct tomoyo_io_buffer
*head
)
432 struct tomoyo_log
*ptr
= NULL
;
435 kfree(head
->read_buf
);
436 head
->read_buf
= NULL
;
437 spin_lock(&tomoyo_log_lock
);
438 if (!list_empty(&tomoyo_log
)) {
439 ptr
= list_entry(tomoyo_log
.next
, typeof(*ptr
), list
);
440 list_del(&ptr
->list
);
442 tomoyo_memory_used
[TOMOYO_MEMORY_AUDIT
] -= ptr
->size
;
444 spin_unlock(&tomoyo_log_lock
);
446 head
->read_buf
= ptr
->log
;
447 head
->r
.w
[head
->r
.w_pos
++] = head
->read_buf
;
453 * tomoyo_poll_log - Wait for an audit log.
455 * @file: Pointer to "struct file".
456 * @wait: Pointer to "poll_table". Maybe NULL.
458 * Returns POLLIN | POLLRDNORM when ready to read an audit log.
460 unsigned int tomoyo_poll_log(struct file
*file
, poll_table
*wait
)
462 if (tomoyo_log_count
)
463 return POLLIN
| POLLRDNORM
;
464 poll_wait(file
, &tomoyo_log_wait
, wait
);
465 if (tomoyo_log_count
)
466 return POLLIN
| POLLRDNORM
;