aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/audit.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/audit.c')
-rw-r--r--kernel/audit.c112
1 files changed, 68 insertions, 44 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index 0f84dd7af2c8..9c4f1af0c794 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1,4 +1,4 @@
1/* audit.c -- Auditing support -*- linux-c -*- 1/* audit.c -- Auditing support
2 * Gateway between the kernel (e.g., selinux) and the user-space audit daemon. 2 * Gateway between the kernel (e.g., selinux) and the user-space audit daemon.
3 * System-call specific features have moved to auditsc.c 3 * System-call specific features have moved to auditsc.c
4 * 4 *
@@ -38,7 +38,7 @@
38 * 6) Support low-overhead kernel-based filtering to minimize the 38 * 6) Support low-overhead kernel-based filtering to minimize the
39 * information that must be passed to user-space. 39 * information that must be passed to user-space.
40 * 40 *
41 * Example user-space utilities: http://people.redhat.com/faith/audit/ 41 * Example user-space utilities: http://people.redhat.com/sgrubb/audit/
42 */ 42 */
43 43
44#include <linux/init.h> 44#include <linux/init.h>
@@ -142,7 +142,6 @@ struct audit_buffer {
142 int total; 142 int total;
143 int type; 143 int type;
144 int pid; 144 int pid;
145 int count; /* Times requeued */
146}; 145};
147 146
148void audit_set_type(struct audit_buffer *ab, int type) 147void audit_set_type(struct audit_buffer *ab, int type)
@@ -239,36 +238,36 @@ void audit_log_lost(const char *message)
239 238
240} 239}
241 240
242static int audit_set_rate_limit(int limit) 241static int audit_set_rate_limit(int limit, uid_t loginuid)
243{ 242{
244 int old = audit_rate_limit; 243 int old = audit_rate_limit;
245 audit_rate_limit = limit; 244 audit_rate_limit = limit;
246 audit_log(current->audit_context, "audit_rate_limit=%d old=%d", 245 audit_log(NULL, "audit_rate_limit=%d old=%d by auid %u",
247 audit_rate_limit, old); 246 audit_rate_limit, old, loginuid);
248 return old; 247 return old;
249} 248}
250 249
251static int audit_set_backlog_limit(int limit) 250static int audit_set_backlog_limit(int limit, uid_t loginuid)
252{ 251{
253 int old = audit_backlog_limit; 252 int old = audit_backlog_limit;
254 audit_backlog_limit = limit; 253 audit_backlog_limit = limit;
255 audit_log(current->audit_context, "audit_backlog_limit=%d old=%d", 254 audit_log(NULL, "audit_backlog_limit=%d old=%d by auid %u",
256 audit_backlog_limit, old); 255 audit_backlog_limit, old, loginuid);
257 return old; 256 return old;
258} 257}
259 258
260static int audit_set_enabled(int state) 259static int audit_set_enabled(int state, uid_t loginuid)
261{ 260{
262 int old = audit_enabled; 261 int old = audit_enabled;
263 if (state != 0 && state != 1) 262 if (state != 0 && state != 1)
264 return -EINVAL; 263 return -EINVAL;
265 audit_enabled = state; 264 audit_enabled = state;
266 audit_log(current->audit_context, "audit_enabled=%d old=%d", 265 audit_log(NULL, "audit_enabled=%d old=%d by auid %u",
267 audit_enabled, old); 266 audit_enabled, old, loginuid);
268 return old; 267 return old;
269} 268}
270 269
271static int audit_set_failure(int state) 270static int audit_set_failure(int state, uid_t loginuid)
272{ 271{
273 int old = audit_failure; 272 int old = audit_failure;
274 if (state != AUDIT_FAIL_SILENT 273 if (state != AUDIT_FAIL_SILENT
@@ -276,8 +275,8 @@ static int audit_set_failure(int state)
276 && state != AUDIT_FAIL_PANIC) 275 && state != AUDIT_FAIL_PANIC)
277 return -EINVAL; 276 return -EINVAL;
278 audit_failure = state; 277 audit_failure = state;
279 audit_log(current->audit_context, "audit_failure=%d old=%d", 278 audit_log(NULL, "audit_failure=%d old=%d by auid %u",
280 audit_failure, old); 279 audit_failure, old, loginuid);
281 return old; 280 return old;
282} 281}
283 282
@@ -344,6 +343,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
344 int err; 343 int err;
345 struct audit_buffer *ab; 344 struct audit_buffer *ab;
346 u16 msg_type = nlh->nlmsg_type; 345 u16 msg_type = nlh->nlmsg_type;
346 uid_t loginuid; /* loginuid of sender */
347 347
348 err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type); 348 err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
349 if (err) 349 if (err)
@@ -351,6 +351,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
351 351
352 pid = NETLINK_CREDS(skb)->pid; 352 pid = NETLINK_CREDS(skb)->pid;
353 uid = NETLINK_CREDS(skb)->uid; 353 uid = NETLINK_CREDS(skb)->uid;
354 loginuid = NETLINK_CB(skb).loginuid;
354 seq = nlh->nlmsg_seq; 355 seq = nlh->nlmsg_seq;
355 data = NLMSG_DATA(nlh); 356 data = NLMSG_DATA(nlh);
356 357
@@ -371,34 +372,36 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
371 return -EINVAL; 372 return -EINVAL;
372 status_get = (struct audit_status *)data; 373 status_get = (struct audit_status *)data;
373 if (status_get->mask & AUDIT_STATUS_ENABLED) { 374 if (status_get->mask & AUDIT_STATUS_ENABLED) {
374 err = audit_set_enabled(status_get->enabled); 375 err = audit_set_enabled(status_get->enabled, loginuid);
375 if (err < 0) return err; 376 if (err < 0) return err;
376 } 377 }
377 if (status_get->mask & AUDIT_STATUS_FAILURE) { 378 if (status_get->mask & AUDIT_STATUS_FAILURE) {
378 err = audit_set_failure(status_get->failure); 379 err = audit_set_failure(status_get->failure, loginuid);
379 if (err < 0) return err; 380 if (err < 0) return err;
380 } 381 }
381 if (status_get->mask & AUDIT_STATUS_PID) { 382 if (status_get->mask & AUDIT_STATUS_PID) {
382 int old = audit_pid; 383 int old = audit_pid;
383 audit_pid = status_get->pid; 384 audit_pid = status_get->pid;
384 audit_log(current->audit_context, 385 audit_log(NULL, "audit_pid=%d old=%d by auid %u",
385 "audit_pid=%d old=%d", audit_pid, old); 386 audit_pid, old, loginuid);
386 } 387 }
387 if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) 388 if (status_get->mask & AUDIT_STATUS_RATE_LIMIT)
388 audit_set_rate_limit(status_get->rate_limit); 389 audit_set_rate_limit(status_get->rate_limit, loginuid);
389 if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) 390 if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT)
390 audit_set_backlog_limit(status_get->backlog_limit); 391 audit_set_backlog_limit(status_get->backlog_limit,
392 loginuid);
391 break; 393 break;
392 case AUDIT_USER: 394 case AUDIT_USER:
393 ab = audit_log_start(NULL); 395 ab = audit_log_start(NULL);
394 if (!ab) 396 if (!ab)
395 break; /* audit_panic has been called */ 397 break; /* audit_panic has been called */
396 audit_log_format(ab, 398 audit_log_format(ab,
397 "user pid=%d uid=%d length=%d msg='%.1024s'", 399 "user pid=%d uid=%d length=%d loginuid=%u"
400 " msg='%.1024s'",
398 pid, uid, 401 pid, uid,
399 (int)(nlh->nlmsg_len 402 (int)(nlh->nlmsg_len
400 - ((char *)data - (char *)nlh)), 403 - ((char *)data - (char *)nlh)),
401 (char *)data); 404 loginuid, (char *)data);
402 ab->type = AUDIT_USER; 405 ab->type = AUDIT_USER;
403 ab->pid = pid; 406 ab->pid = pid;
404 audit_log_end(ab); 407 audit_log_end(ab);
@@ -411,7 +414,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
411 case AUDIT_LIST: 414 case AUDIT_LIST:
412#ifdef CONFIG_AUDITSYSCALL 415#ifdef CONFIG_AUDITSYSCALL
413 err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, 416 err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
414 uid, seq, data); 417 uid, seq, data, loginuid);
415#else 418#else
416 err = -EOPNOTSUPP; 419 err = -EOPNOTSUPP;
417#endif 420#endif
@@ -427,7 +430,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
427/* Get message from skb (based on rtnetlink_rcv_skb). Each message is 430/* Get message from skb (based on rtnetlink_rcv_skb). Each message is
428 * processed by audit_receive_msg. Malformed skbs with wrong length are 431 * processed by audit_receive_msg. Malformed skbs with wrong length are
429 * discarded silently. */ 432 * discarded silently. */
430static int audit_receive_skb(struct sk_buff *skb) 433static void audit_receive_skb(struct sk_buff *skb)
431{ 434{
432 int err; 435 int err;
433 struct nlmsghdr *nlh; 436 struct nlmsghdr *nlh;
@@ -436,7 +439,7 @@ static int audit_receive_skb(struct sk_buff *skb)
436 while (skb->len >= NLMSG_SPACE(0)) { 439 while (skb->len >= NLMSG_SPACE(0)) {
437 nlh = (struct nlmsghdr *)skb->data; 440 nlh = (struct nlmsghdr *)skb->data;
438 if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) 441 if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
439 return 0; 442 return;
440 rlen = NLMSG_ALIGN(nlh->nlmsg_len); 443 rlen = NLMSG_ALIGN(nlh->nlmsg_len);
441 if (rlen > skb->len) 444 if (rlen > skb->len)
442 rlen = skb->len; 445 rlen = skb->len;
@@ -446,23 +449,20 @@ static int audit_receive_skb(struct sk_buff *skb)
446 netlink_ack(skb, nlh, 0); 449 netlink_ack(skb, nlh, 0);
447 skb_pull(skb, rlen); 450 skb_pull(skb, rlen);
448 } 451 }
449 return 0;
450} 452}
451 453
452/* Receive messages from netlink socket. */ 454/* Receive messages from netlink socket. */
453static void audit_receive(struct sock *sk, int length) 455static void audit_receive(struct sock *sk, int length)
454{ 456{
455 struct sk_buff *skb; 457 struct sk_buff *skb;
458 unsigned int qlen;
456 459
457 if (down_trylock(&audit_netlink_sem)) 460 down(&audit_netlink_sem);
458 return;
459 461
460 /* FIXME: this must not cause starvation */ 462 for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) {
461 while ((skb = skb_dequeue(&sk->sk_receive_queue))) { 463 skb = skb_dequeue(&sk->sk_receive_queue);
462 if (audit_receive_skb(skb) && skb->len) 464 audit_receive_skb(skb);
463 skb_queue_head(&sk->sk_receive_queue, skb); 465 kfree_skb(skb);
464 else
465 kfree_skb(skb);
466 } 466 }
467 up(&audit_netlink_sem); 467 up(&audit_netlink_sem);
468} 468}
@@ -483,7 +483,7 @@ static void audit_log_move(struct audit_buffer *ab)
483 if (ab->len == 0) 483 if (ab->len == 0)
484 return; 484 return;
485 485
486 skb = skb_peek(&ab->sklist); 486 skb = skb_peek_tail(&ab->sklist);
487 if (!skb || skb_tailroom(skb) <= ab->len + extra) { 487 if (!skb || skb_tailroom(skb) <= ab->len + extra) {
488 skb = alloc_skb(2 * ab->len + extra, GFP_ATOMIC); 488 skb = alloc_skb(2 * ab->len + extra, GFP_ATOMIC);
489 if (!skb) { 489 if (!skb) {
@@ -522,9 +522,9 @@ static inline int audit_log_drain(struct audit_buffer *ab)
522 retval = netlink_unicast(audit_sock, skb, audit_pid, 522 retval = netlink_unicast(audit_sock, skb, audit_pid,
523 MSG_DONTWAIT); 523 MSG_DONTWAIT);
524 } 524 }
525 if (retval == -EAGAIN && ab->count < 5) { 525 if (retval == -EAGAIN &&
526 ++ab->count; 526 (atomic_read(&audit_backlog)) < audit_backlog_limit) {
527 skb_queue_tail(&ab->sklist, skb); 527 skb_queue_head(&ab->sklist, skb);
528 audit_log_end_irq(ab); 528 audit_log_end_irq(ab);
529 return 1; 529 return 1;
530 } 530 }
@@ -540,8 +540,8 @@ static inline int audit_log_drain(struct audit_buffer *ab)
540 if (!audit_pid) { /* No daemon */ 540 if (!audit_pid) { /* No daemon */
541 int offset = ab->nlh ? NLMSG_SPACE(0) : 0; 541 int offset = ab->nlh ? NLMSG_SPACE(0) : 0;
542 int len = skb->len - offset; 542 int len = skb->len - offset;
543 printk(KERN_ERR "%*.*s\n", 543 skb->data[offset + len] = '\0';
544 len, len, skb->data + offset); 544 printk(KERN_ERR "%s\n", skb->data + offset);
545 } 545 }
546 kfree_skb(skb); 546 kfree_skb(skb);
547 ab->nlh = NULL; 547 ab->nlh = NULL;
@@ -620,7 +620,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx)
620 struct audit_buffer *ab = NULL; 620 struct audit_buffer *ab = NULL;
621 unsigned long flags; 621 unsigned long flags;
622 struct timespec t; 622 struct timespec t;
623 int serial = 0; 623 unsigned int serial;
624 624
625 if (!audit_initialized) 625 if (!audit_initialized)
626 return NULL; 626 return NULL;
@@ -662,15 +662,16 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx)
662 ab->total = 0; 662 ab->total = 0;
663 ab->type = AUDIT_KERNEL; 663 ab->type = AUDIT_KERNEL;
664 ab->pid = 0; 664 ab->pid = 0;
665 ab->count = 0;
666 665
667#ifdef CONFIG_AUDITSYSCALL 666#ifdef CONFIG_AUDITSYSCALL
668 if (ab->ctx) 667 if (ab->ctx)
669 audit_get_stamp(ab->ctx, &t, &serial); 668 audit_get_stamp(ab->ctx, &t, &serial);
670 else 669 else
671#endif 670#endif
671 {
672 t = CURRENT_TIME; 672 t = CURRENT_TIME;
673 673 serial = 0;
674 }
674 audit_log_format(ab, "audit(%lu.%03lu:%u): ", 675 audit_log_format(ab, "audit(%lu.%03lu:%u): ",
675 t.tv_sec, t.tv_nsec/1000000, serial); 676 t.tv_sec, t.tv_nsec/1000000, serial);
676 return ab; 677 return ab;
@@ -720,6 +721,29 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
720 va_end(args); 721 va_end(args);
721} 722}
722 723
724void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, size_t len)
725{
726 int i;
727
728 for (i=0; i<len; i++)
729 audit_log_format(ab, "%02x", buf[i]);
730}
731
732void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
733{
734 const unsigned char *p = string;
735
736 while (*p) {
737 if (*p == '"' || *p == ' ' || *p < 0x20 || *p > 0x7f) {
738 audit_log_hex(ab, string, strlen(string));
739 return;
740 }
741 p++;
742 }
743 audit_log_format(ab, "\"%s\"", string);
744}
745
746
723/* This is a helper-function to print the d_path without using a static 747/* This is a helper-function to print the d_path without using a static
724 * buffer or allocating another buffer in addition to the one in 748 * buffer or allocating another buffer in addition to the one in
725 * audit_buffer. */ 749 * audit_buffer. */