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
);
160 do_gettimeofday(&tv
);
161 tomoyo_convert_time(tv
.tv_sec
, &stamp
);
163 pos
= snprintf(buffer
, tomoyo_buffer_len
- 1,
164 "#%04u/%02u/%02u %02u:%02u:%02u# profile=%u mode=%s "
165 "granted=%s (global-pid=%u) task={ pid=%u ppid=%u "
166 "uid=%u gid=%u euid=%u egid=%u suid=%u sgid=%u "
167 "fsuid=%u fsgid=%u }", stamp
.year
, stamp
.month
,
168 stamp
.day
, stamp
.hour
, stamp
.min
, stamp
.sec
, r
->profile
,
169 tomoyo_mode
[r
->mode
], tomoyo_yesno(r
->granted
), gpid
,
170 tomoyo_sys_getpid(), tomoyo_sys_getppid(),
171 from_kuid(&init_user_ns
, current_uid()),
172 from_kgid(&init_user_ns
, current_gid()),
173 from_kuid(&init_user_ns
, current_euid()),
174 from_kgid(&init_user_ns
, current_egid()),
175 from_kuid(&init_user_ns
, current_suid()),
176 from_kgid(&init_user_ns
, current_sgid()),
177 from_kuid(&init_user_ns
, current_fsuid()),
178 from_kgid(&init_user_ns
, current_fsgid()));
181 if (!obj
->validate_done
) {
182 tomoyo_get_attributes(obj
);
183 obj
->validate_done
= true;
185 for (i
= 0; i
< TOMOYO_MAX_PATH_STAT
; i
++) {
186 struct tomoyo_mini_stat
*stat
;
189 if (!obj
->stat_valid
[i
])
191 stat
= &obj
->stat
[i
];
195 pos
+= snprintf(buffer
+ pos
,
196 tomoyo_buffer_len
- 1 - pos
,
197 " path%u.parent={ uid=%u gid=%u "
198 "ino=%lu perm=0%o }", (i
>> 1) + 1,
199 from_kuid(&init_user_ns
, stat
->uid
),
200 from_kgid(&init_user_ns
, stat
->gid
),
201 (unsigned long)stat
->ino
,
202 stat
->mode
& S_IALLUGO
);
205 pos
+= snprintf(buffer
+ pos
, tomoyo_buffer_len
- 1 - pos
,
206 " path%u={ uid=%u gid=%u ino=%lu major=%u"
207 " minor=%u perm=0%o type=%s", (i
>> 1) + 1,
208 from_kuid(&init_user_ns
, stat
->uid
),
209 from_kgid(&init_user_ns
, stat
->gid
),
210 (unsigned long)stat
->ino
,
211 MAJOR(dev
), MINOR(dev
),
212 mode
& S_IALLUGO
, tomoyo_filetype(mode
));
213 if (S_ISCHR(mode
) || S_ISBLK(mode
)) {
215 pos
+= snprintf(buffer
+ pos
,
216 tomoyo_buffer_len
- 1 - pos
,
217 " dev_major=%u dev_minor=%u",
218 MAJOR(dev
), MINOR(dev
));
220 pos
+= snprintf(buffer
+ pos
, tomoyo_buffer_len
- 1 - pos
,
224 if (pos
< tomoyo_buffer_len
- 1)
231 * tomoyo_init_log - Allocate buffer for audit logs.
233 * @r: Pointer to "struct tomoyo_request_info".
234 * @len: Buffer size needed for @fmt and @args.
235 * @fmt: The printf()'s format string.
236 * @args: va_list structure for @fmt.
238 * Returns pointer to allocated memory.
240 * This function uses kzalloc(), so caller must kfree() if this function
241 * didn't return NULL.
243 char *tomoyo_init_log(struct tomoyo_request_info
*r
, int len
, const char *fmt
,
247 char *bprm_info
= NULL
;
248 const char *header
= NULL
;
249 char *realpath
= NULL
;
250 const char *symlink
= NULL
;
252 const char *domainname
= r
->domain
->domainname
->name
;
253 header
= tomoyo_print_header(r
);
256 /* +10 is for '\n' etc. and '\0'. */
257 len
+= strlen(domainname
) + strlen(header
) + 10;
259 struct file
*file
= r
->ee
->bprm
->file
;
260 realpath
= tomoyo_realpath_from_path(&file
->f_path
);
261 bprm_info
= tomoyo_print_bprm(r
->ee
->bprm
, &r
->ee
->dump
);
262 if (!realpath
|| !bprm_info
)
264 /* +80 is for " exec={ realpath=\"%s\" argc=%d envc=%d %s }" */
265 len
+= strlen(realpath
) + 80 + strlen(bprm_info
);
266 } else if (r
->obj
&& r
->obj
->symlink_target
) {
267 symlink
= r
->obj
->symlink_target
->name
;
268 /* +18 is for " symlink.target=\"%s\"" */
269 len
+= 18 + strlen(symlink
);
271 len
= tomoyo_round2(len
);
272 buf
= kzalloc(len
, GFP_NOFS
);
276 pos
= snprintf(buf
, len
, "%s", header
);
278 struct linux_binprm
*bprm
= r
->ee
->bprm
;
279 pos
+= snprintf(buf
+ pos
, len
- pos
,
280 " exec={ realpath=\"%s\" argc=%d envc=%d %s }",
281 realpath
, bprm
->argc
, bprm
->envc
, bprm_info
);
283 pos
+= snprintf(buf
+ pos
, len
- pos
, " symlink.target=\"%s\"",
285 pos
+= snprintf(buf
+ pos
, len
- pos
, "\n%s\n", domainname
);
286 vsnprintf(buf
+ pos
, len
- pos
, fmt
, args
);
294 /* Wait queue for /sys/kernel/security/tomoyo/audit. */
295 static DECLARE_WAIT_QUEUE_HEAD(tomoyo_log_wait
);
297 /* Structure for audit log. */
299 struct list_head list
;
304 /* The list for "struct tomoyo_log". */
305 static LIST_HEAD(tomoyo_log
);
307 /* Lock for "struct list_head tomoyo_log". */
308 static DEFINE_SPINLOCK(tomoyo_log_lock
);
310 /* Length of "stuct list_head tomoyo_log". */
311 static unsigned int tomoyo_log_count
;
314 * tomoyo_get_audit - Get audit mode.
316 * @ns: Pointer to "struct tomoyo_policy_namespace".
317 * @profile: Profile number.
318 * @index: Index number of functionality.
319 * @is_granted: True if granted log, false otherwise.
321 * Returns true if this request should be audited, false otherwise.
323 static bool tomoyo_get_audit(const struct tomoyo_policy_namespace
*ns
,
324 const u8 profile
, const u8 index
,
325 const struct tomoyo_acl_info
*matched_acl
,
326 const bool is_granted
)
329 const u8 category
= tomoyo_index2category
[index
] +
330 TOMOYO_MAX_MAC_INDEX
;
331 struct tomoyo_profile
*p
;
332 if (!tomoyo_policy_loaded
)
334 p
= tomoyo_profile(ns
, profile
);
335 if (tomoyo_log_count
>= p
->pref
[TOMOYO_PREF_MAX_AUDIT_LOG
])
337 if (is_granted
&& matched_acl
&& matched_acl
->cond
&&
338 matched_acl
->cond
->grant_log
!= TOMOYO_GRANTLOG_AUTO
)
339 return matched_acl
->cond
->grant_log
== TOMOYO_GRANTLOG_YES
;
340 mode
= p
->config
[index
];
341 if (mode
== TOMOYO_CONFIG_USE_DEFAULT
)
342 mode
= p
->config
[category
];
343 if (mode
== TOMOYO_CONFIG_USE_DEFAULT
)
344 mode
= p
->default_config
;
346 return mode
& TOMOYO_CONFIG_WANT_GRANT_LOG
;
347 return mode
& TOMOYO_CONFIG_WANT_REJECT_LOG
;
351 * tomoyo_write_log2 - Write an audit log.
353 * @r: Pointer to "struct tomoyo_request_info".
354 * @len: Buffer size needed for @fmt and @args.
355 * @fmt: The printf()'s format string.
356 * @args: va_list structure for @fmt.
360 void tomoyo_write_log2(struct tomoyo_request_info
*r
, int len
, const char *fmt
,
364 struct tomoyo_log
*entry
;
365 bool quota_exceeded
= false;
366 if (!tomoyo_get_audit(r
->domain
->ns
, r
->profile
, r
->type
,
367 r
->matched_acl
, r
->granted
))
369 buf
= tomoyo_init_log(r
, len
, fmt
, args
);
372 entry
= kzalloc(sizeof(*entry
), GFP_NOFS
);
378 len
= tomoyo_round2(strlen(buf
) + 1);
380 * The entry->size is used for memory quota checks.
381 * Don't go beyond strlen(entry->log).
383 entry
->size
= len
+ tomoyo_round2(sizeof(*entry
));
384 spin_lock(&tomoyo_log_lock
);
385 if (tomoyo_memory_quota
[TOMOYO_MEMORY_AUDIT
] &&
386 tomoyo_memory_used
[TOMOYO_MEMORY_AUDIT
] + entry
->size
>=
387 tomoyo_memory_quota
[TOMOYO_MEMORY_AUDIT
]) {
388 quota_exceeded
= true;
390 tomoyo_memory_used
[TOMOYO_MEMORY_AUDIT
] += entry
->size
;
391 list_add_tail(&entry
->list
, &tomoyo_log
);
394 spin_unlock(&tomoyo_log_lock
);
395 if (quota_exceeded
) {
400 wake_up(&tomoyo_log_wait
);
406 * tomoyo_write_log - Write an audit log.
408 * @r: Pointer to "struct tomoyo_request_info".
409 * @fmt: The printf()'s format string, followed by parameters.
413 void tomoyo_write_log(struct tomoyo_request_info
*r
, const char *fmt
, ...)
418 len
= vsnprintf((char *) &len
, 1, fmt
, args
) + 1;
421 tomoyo_write_log2(r
, len
, fmt
, args
);
426 * tomoyo_read_log - Read an audit log.
428 * @head: Pointer to "struct tomoyo_io_buffer".
432 void tomoyo_read_log(struct tomoyo_io_buffer
*head
)
434 struct tomoyo_log
*ptr
= NULL
;
437 kfree(head
->read_buf
);
438 head
->read_buf
= NULL
;
439 spin_lock(&tomoyo_log_lock
);
440 if (!list_empty(&tomoyo_log
)) {
441 ptr
= list_entry(tomoyo_log
.next
, typeof(*ptr
), list
);
442 list_del(&ptr
->list
);
444 tomoyo_memory_used
[TOMOYO_MEMORY_AUDIT
] -= ptr
->size
;
446 spin_unlock(&tomoyo_log_lock
);
448 head
->read_buf
= ptr
->log
;
449 head
->r
.w
[head
->r
.w_pos
++] = head
->read_buf
;
455 * tomoyo_poll_log - Wait for an audit log.
457 * @file: Pointer to "struct file".
458 * @wait: Pointer to "poll_table". Maybe NULL.
460 * Returns POLLIN | POLLRDNORM when ready to read an audit log.
462 unsigned int tomoyo_poll_log(struct file
*file
, poll_table
*wait
)
464 if (tomoyo_log_count
)
465 return POLLIN
| POLLRDNORM
;
466 poll_wait(file
, &tomoyo_log_wait
, wait
);
467 if (tomoyo_log_count
)
468 return POLLIN
| POLLRDNORM
;