aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/audit.h16
-rw-r--r--kernel/audit.c48
-rw-r--r--kernel/auditsc.c23
-rw-r--r--security/selinux/avc.c2
4 files changed, 33 insertions, 56 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 58c5589b531f..405332ebf3c6 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -216,11 +216,14 @@ extern void audit_signal_info(int sig, struct task_struct *t);
216#ifdef CONFIG_AUDIT 216#ifdef CONFIG_AUDIT
217/* These are defined in audit.c */ 217/* These are defined in audit.c */
218 /* Public API */ 218 /* Public API */
219extern void audit_log(struct audit_context *ctx, 219#define audit_log(ctx, fmt, args...) \
220 const char *fmt, ...) 220 audit_log_type(ctx, AUDIT_KERNEL, 0, fmt, ##args)
221 __attribute__((format(printf,2,3))); 221extern void audit_log_type(struct audit_context *ctx, int type,
222 int pid, const char *fmt, ...)
223 __attribute__((format(printf,4,5)));
222 224
223extern struct audit_buffer *audit_log_start(struct audit_context *ctx); 225extern struct audit_buffer *audit_log_start(struct audit_context *ctx, int type,
226 int pid);
224extern void audit_log_format(struct audit_buffer *ab, 227extern void audit_log_format(struct audit_buffer *ab,
225 const char *fmt, ...) 228 const char *fmt, ...)
226 __attribute__((format(printf,2,3))); 229 __attribute__((format(printf,2,3)));
@@ -240,8 +243,9 @@ extern void audit_send_reply(int pid, int seq, int type,
240 void *payload, int size); 243 void *payload, int size);
241extern void audit_log_lost(const char *message); 244extern void audit_log_lost(const char *message);
242#else 245#else
243#define audit_log(t,f,...) do { ; } while (0) 246#define audit_log(c,f,...) do { ; } while (0)
244#define audit_log_start(t) ({ NULL; }) 247#define audit_log_type(c,t,p,f,...) do { ; } while (0)
248#define audit_log_start(c,t,p) ({ NULL; })
245#define audit_log_vformat(b,f,a) do { ; } while (0) 249#define audit_log_vformat(b,f,a) do { ; } while (0)
246#define audit_log_format(b,f,...) do { ; } while (0) 250#define audit_log_format(b,f,...) do { ; } while (0)
247#define audit_log_end(b) do { ; } while (0) 251#define audit_log_end(b) do { ; } while (0)
diff --git a/kernel/audit.c b/kernel/audit.c
index c18b769e23a2..060b554f481e 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -140,18 +140,6 @@ struct audit_buffer {
140 struct audit_context *ctx; /* NULL or associated context */ 140 struct audit_context *ctx; /* NULL or associated context */
141}; 141};
142 142
143void audit_set_type(struct audit_buffer *ab, int type)
144{
145 struct nlmsghdr *nlh = (struct nlmsghdr *)ab->skb->data;
146 nlh->nlmsg_type = type;
147}
148
149static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
150{
151 struct nlmsghdr *nlh = (struct nlmsghdr *)ab->skb->data;
152 nlh->nlmsg_pid = pid;
153}
154
155struct audit_entry { 143struct audit_entry {
156 struct list_head list; 144 struct list_head list;
157 struct audit_rule rule; 145 struct audit_rule rule;
@@ -344,7 +332,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
344 void *data; 332 void *data;
345 struct audit_status *status_get, status_set; 333 struct audit_status *status_get, status_set;
346 int err; 334 int err;
347 struct audit_buffer *ab;
348 u16 msg_type = nlh->nlmsg_type; 335 u16 msg_type = nlh->nlmsg_type;
349 uid_t loginuid; /* loginuid of sender */ 336 uid_t loginuid; /* loginuid of sender */
350 struct audit_sig_info sig_data; 337 struct audit_sig_info sig_data;
@@ -396,19 +383,13 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
396 loginuid); 383 loginuid);
397 break; 384 break;
398 case AUDIT_USER: 385 case AUDIT_USER:
399 ab = audit_log_start(NULL); 386 audit_log_type(NULL, AUDIT_USER, pid,
400 if (!ab)
401 break; /* audit_panic has been called */
402 audit_log_format(ab,
403 "user pid=%d uid=%d length=%d loginuid=%u" 387 "user pid=%d uid=%d length=%d loginuid=%u"
404 " msg='%.1024s'", 388 " msg='%.1024s'",
405 pid, uid, 389 pid, uid,
406 (int)(nlh->nlmsg_len 390 (int)(nlh->nlmsg_len
407 - ((char *)data - (char *)nlh)), 391 - ((char *)data - (char *)nlh)),
408 loginuid, (char *)data); 392 loginuid, (char *)data);
409 audit_set_type(ab, AUDIT_USER);
410 audit_set_pid(ab, pid);
411 audit_log_end(ab);
412 break; 393 break;
413 case AUDIT_ADD: 394 case AUDIT_ADD:
414 case AUDIT_DEL: 395 case AUDIT_DEL:
@@ -560,12 +541,10 @@ static void audit_buffer_free(struct audit_buffer *ab)
560 spin_unlock_irqrestore(&audit_freelist_lock, flags); 541 spin_unlock_irqrestore(&audit_freelist_lock, flags);
561} 542}
562 543
563static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx, 544static struct audit_buffer * audit_buffer_alloc(int gfp_mask)
564 int gfp_mask)
565{ 545{
566 unsigned long flags; 546 unsigned long flags;
567 struct audit_buffer *ab = NULL; 547 struct audit_buffer *ab = NULL;
568 struct nlmsghdr *nlh;
569 548
570 spin_lock_irqsave(&audit_freelist_lock, flags); 549 spin_lock_irqsave(&audit_freelist_lock, flags);
571 if (!list_empty(&audit_freelist)) { 550 if (!list_empty(&audit_freelist)) {
@@ -587,12 +566,6 @@ static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
587 if (!ab->skb) 566 if (!ab->skb)
588 goto err; 567 goto err;
589 568
590 ab->ctx = ctx;
591 nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));
592 nlh->nlmsg_type = AUDIT_KERNEL;
593 nlh->nlmsg_flags = 0;
594 nlh->nlmsg_pid = 0;
595 nlh->nlmsg_seq = 0;
596 return ab; 569 return ab;
597err: 570err:
598 audit_buffer_free(ab); 571 audit_buffer_free(ab);
@@ -605,11 +578,12 @@ err:
605 * syscall, then the syscall is marked as auditable and an audit record 578 * syscall, then the syscall is marked as auditable and an audit record
606 * will be written at syscall exit. If there is no associated task, tsk 579 * will be written at syscall exit. If there is no associated task, tsk
607 * should be NULL. */ 580 * should be NULL. */
608struct audit_buffer *audit_log_start(struct audit_context *ctx) 581struct audit_buffer *audit_log_start(struct audit_context *ctx, int type, int pid)
609{ 582{
610 struct audit_buffer *ab = NULL; 583 struct audit_buffer *ab = NULL;
611 struct timespec t; 584 struct timespec t;
612 unsigned int serial; 585 unsigned int serial;
586 struct nlmsghdr *nlh;
613 587
614 if (!audit_initialized) 588 if (!audit_initialized)
615 return NULL; 589 return NULL;
@@ -626,12 +600,19 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx)
626 return NULL; 600 return NULL;
627 } 601 }
628 602
629 ab = audit_buffer_alloc(ctx, GFP_ATOMIC); 603 ab = audit_buffer_alloc(GFP_ATOMIC);
630 if (!ab) { 604 if (!ab) {
631 audit_log_lost("out of memory in audit_log_start"); 605 audit_log_lost("out of memory in audit_log_start");
632 return NULL; 606 return NULL;
633 } 607 }
634 608
609 ab->ctx = ctx;
610 nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));
611 nlh->nlmsg_type = type;
612 nlh->nlmsg_flags = 0;
613 nlh->nlmsg_pid = pid;
614 nlh->nlmsg_seq = 0;
615
635 if (!audit_get_stamp(ab->ctx, &t, &serial)) { 616 if (!audit_get_stamp(ab->ctx, &t, &serial)) {
636 t = CURRENT_TIME; 617 t = CURRENT_TIME;
637 serial = 0; 618 serial = 0;
@@ -828,12 +809,13 @@ void audit_log_end(struct audit_buffer *ab)
828/* Log an audit record. This is a convenience function that calls 809/* Log an audit record. This is a convenience function that calls
829 * audit_log_start, audit_log_vformat, and audit_log_end. It may be 810 * audit_log_start, audit_log_vformat, and audit_log_end. It may be
830 * called in any context. */ 811 * called in any context. */
831void audit_log(struct audit_context *ctx, const char *fmt, ...) 812void audit_log_type(struct audit_context *ctx, int type, int pid,
813 const char *fmt, ...)
832{ 814{
833 struct audit_buffer *ab; 815 struct audit_buffer *ab;
834 va_list args; 816 va_list args;
835 817
836 ab = audit_log_start(ctx); 818 ab = audit_log_start(ctx, type, pid);
837 if (ab) { 819 if (ab) {
838 va_start(args, fmt); 820 va_start(args, fmt);
839 audit_log_vformat(ab, fmt, args); 821 audit_log_vformat(ab, fmt, args);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 94338abf76f5..d089263253a7 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -648,7 +648,7 @@ static void audit_log_exit(struct audit_context *context)
648 int i; 648 int i;
649 struct audit_buffer *ab; 649 struct audit_buffer *ab;
650 650
651 ab = audit_log_start(context); 651 ab = audit_log_start(context, AUDIT_KERNEL, 0);
652 if (!ab) 652 if (!ab)
653 return; /* audit_panic has been called */ 653 return; /* audit_panic has been called */
654 audit_log_format(ab, "syscall=%d", context->major); 654 audit_log_format(ab, "syscall=%d", context->major);
@@ -680,7 +680,7 @@ static void audit_log_exit(struct audit_context *context)
680 while (context->aux) { 680 while (context->aux) {
681 struct audit_aux_data *aux; 681 struct audit_aux_data *aux;
682 682
683 ab = audit_log_start(context); 683 ab = audit_log_start(context, AUDIT_KERNEL, 0);
684 if (!ab) 684 if (!ab)
685 continue; /* audit_panic has been called */ 685 continue; /* audit_panic has been called */
686 686
@@ -701,7 +701,7 @@ static void audit_log_exit(struct audit_context *context)
701 } 701 }
702 702
703 for (i = 0; i < context->name_count; i++) { 703 for (i = 0; i < context->name_count; i++) {
704 ab = audit_log_start(context); 704 ab = audit_log_start(context, AUDIT_KERNEL, 0);
705 if (!ab) 705 if (!ab)
706 continue; /* audit_panic has been called */ 706 continue; /* audit_panic has been called */
707 audit_log_format(ab, "item=%d", i); 707 audit_log_format(ab, "item=%d", i);
@@ -1005,22 +1005,13 @@ int audit_get_stamp(struct audit_context *ctx,
1005 return 0; 1005 return 0;
1006} 1006}
1007 1007
1008extern int audit_set_type(struct audit_buffer *ab, int type);
1009
1010int audit_set_loginuid(struct task_struct *task, uid_t loginuid) 1008int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
1011{ 1009{
1012 if (task->audit_context) { 1010 if (task->audit_context) {
1013 struct audit_buffer *ab; 1011 audit_log_type(NULL, AUDIT_LOGIN, 0,
1014 1012 "login pid=%d uid=%u old loginuid=%u new loginuid=%u",
1015 ab = audit_log_start(NULL); 1013 task->pid, task->uid, task->audit_context->loginuid,
1016 if (ab) { 1014 loginuid);
1017 audit_log_format(ab, "login pid=%d uid=%u "
1018 "old loginuid=%u new loginuid=%u",
1019 task->pid, task->uid,
1020 task->audit_context->loginuid, loginuid);
1021 audit_set_type(ab, AUDIT_LOGIN);
1022 audit_log_end(ab);
1023 }
1024 task->audit_context->loginuid = loginuid; 1015 task->audit_context->loginuid = loginuid;
1025 } 1016 }
1026 return 0; 1017 return 0;
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 85a6f66a873f..9e71a1bbe011 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -549,7 +549,7 @@ void avc_audit(u32 ssid, u32 tsid,
549 return; 549 return;
550 } 550 }
551 551
552 ab = audit_log_start(current->audit_context); 552 ab = audit_log_start(current->audit_context, AUDIT_KERNEL, 0);
553 if (!ab) 553 if (!ab)
554 return; /* audit_panic has been called */ 554 return; /* audit_panic has been called */
555 audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted"); 555 audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted");