aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/audit.h7
-rw-r--r--kernel/audit.c46
-rw-r--r--kernel/auditsc.c46
3 files changed, 52 insertions, 47 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 4b7caf0c6e10..3278ddf41ce6 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -219,8 +219,9 @@ extern void audit_inode(const char *name, const struct inode *inode);
219 /* Private API (for audit.c only) */ 219 /* Private API (for audit.c only) */
220extern int audit_receive_filter(int type, int pid, int uid, int seq, 220extern int audit_receive_filter(int type, int pid, int uid, int seq,
221 void *data, uid_t loginuid); 221 void *data, uid_t loginuid);
222extern int audit_get_stamp(struct audit_context *ctx, 222extern unsigned int audit_serial(void);
223 struct timespec *t, unsigned int *serial); 223extern void auditsc_get_stamp(struct audit_context *ctx,
224 struct timespec *t, unsigned int *serial);
224extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); 225extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
225extern uid_t audit_get_loginuid(struct audit_context *ctx); 226extern uid_t audit_get_loginuid(struct audit_context *ctx);
226extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode); 227extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
@@ -237,7 +238,7 @@ extern void audit_signal_info(int sig, struct task_struct *t);
237#define audit_putname(n) do { ; } while (0) 238#define audit_putname(n) do { ; } while (0)
238#define audit_inode(n,i) do { ; } while (0) 239#define audit_inode(n,i) do { ; } while (0)
239#define audit_receive_filter(t,p,u,s,d,l) ({ -EOPNOTSUPP; }) 240#define audit_receive_filter(t,p,u,s,d,l) ({ -EOPNOTSUPP; })
240#define audit_get_stamp(c,t,s) ({ 0; }) 241#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
241#define audit_get_loginuid(c) ({ -1; }) 242#define audit_get_loginuid(c) ({ -1; })
242#define audit_ipc_perms(q,u,g,m) ({ 0; }) 243#define audit_ipc_perms(q,u,g,m) ({ 0; })
243#define audit_socketcall(n,a) ({ 0; }) 244#define audit_socketcall(n,a) ({ 0; })
diff --git a/kernel/audit.c b/kernel/audit.c
index f0a003acf621..35306f4369e7 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -597,6 +597,47 @@ err:
597 return NULL; 597 return NULL;
598} 598}
599 599
600/* Compute a serial number for the audit record. Audit records are
601 * written to user-space as soon as they are generated, so a complete
602 * audit record may be written in several pieces. The timestamp of the
603 * record and this serial number are used by the user-space tools to
604 * determine which pieces belong to the same audit record. The
605 * (timestamp,serial) tuple is unique for each syscall and is live from
606 * syscall entry to syscall exit.
607 *
608 * Atomic values are only guaranteed to be 24-bit, so we count down.
609 *
610 * NOTE: Another possibility is to store the formatted records off the
611 * audit context (for those records that have a context), and emit them
612 * all at syscall exit. However, this could delay the reporting of
613 * significant errors until syscall exit (or never, if the system
614 * halts). */
615unsigned int audit_serial(void)
616{
617 static atomic_t serial = ATOMIC_INIT(0xffffff);
618 unsigned int a, b;
619
620 do {
621 a = atomic_read(&serial);
622 if (atomic_dec_and_test(&serial))
623 atomic_set(&serial, 0xffffff);
624 b = atomic_read(&serial);
625 } while (b != a - 1);
626
627 return 0xffffff - b;
628}
629
630static inline void audit_get_stamp(struct audit_context *ctx,
631 struct timespec *t, unsigned int *serial)
632{
633 if (ctx)
634 auditsc_get_stamp(ctx, t, serial);
635 else {
636 *t = CURRENT_TIME;
637 *serial = audit_serial();
638 }
639}
640
600/* Obtain an audit buffer. This routine does locking to obtain the 641/* Obtain an audit buffer. This routine does locking to obtain the
601 * audit buffer, but then no locking is required for calls to 642 * audit buffer, but then no locking is required for calls to
602 * audit_log_*format. If the tsk is a task that is currently in a 643 * audit_log_*format. If the tsk is a task that is currently in a
@@ -630,10 +671,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int type)
630 return NULL; 671 return NULL;
631 } 672 }
632 673
633 if (!audit_get_stamp(ab->ctx, &t, &serial)) { 674 audit_get_stamp(ab->ctx, &t, &serial);
634 t = CURRENT_TIME;
635 serial = 0;
636 }
637 675
638 audit_log_format(ab, "audit(%lu.%03lu:%u): ", 676 audit_log_format(ab, "audit(%lu.%03lu:%u): ",
639 t.tv_sec, t.tv_nsec/1000000, serial); 677 t.tv_sec, t.tv_nsec/1000000, serial);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 4193811d4fe1..74c2ae804ca8 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -795,36 +795,6 @@ void audit_free(struct task_struct *tsk)
795 audit_free_context(context); 795 audit_free_context(context);
796} 796}
797 797
798/* Compute a serial number for the audit record. Audit records are
799 * written to user-space as soon as they are generated, so a complete
800 * audit record may be written in several pieces. The timestamp of the
801 * record and this serial number are used by the user-space tools to
802 * determine which pieces belong to the same audit record. The
803 * (timestamp,serial) tuple is unique for each syscall and is live from
804 * syscall entry to syscall exit.
805 *
806 * Atomic values are only guaranteed to be 24-bit, so we count down.
807 *
808 * NOTE: Another possibility is to store the formatted records off the
809 * audit context (for those records that have a context), and emit them
810 * all at syscall exit. However, this could delay the reporting of
811 * significant errors until syscall exit (or never, if the system
812 * halts). */
813static inline unsigned int audit_serial(void)
814{
815 static atomic_t serial = ATOMIC_INIT(0xffffff);
816 unsigned int a, b;
817
818 do {
819 a = atomic_read(&serial);
820 if (atomic_dec_and_test(&serial))
821 atomic_set(&serial, 0xffffff);
822 b = atomic_read(&serial);
823 } while (b != a - 1);
824
825 return 0xffffff - b;
826}
827
828/* Fill in audit context at syscall entry. This only happens if the 798/* Fill in audit context at syscall entry. This only happens if the
829 * audit context was created when the task was created and the state or 799 * audit context was created when the task was created and the state or
830 * filters demand the audit context be built. If the state from the 800 * filters demand the audit context be built. If the state from the
@@ -1042,17 +1012,13 @@ void audit_inode(const char *name, const struct inode *inode)
1042 context->names[idx].rdev = inode->i_rdev; 1012 context->names[idx].rdev = inode->i_rdev;
1043} 1013}
1044 1014
1045int audit_get_stamp(struct audit_context *ctx, 1015void auditsc_get_stamp(struct audit_context *ctx,
1046 struct timespec *t, unsigned int *serial) 1016 struct timespec *t, unsigned int *serial)
1047{ 1017{
1048 if (ctx) { 1018 t->tv_sec = ctx->ctime.tv_sec;
1049 t->tv_sec = ctx->ctime.tv_sec; 1019 t->tv_nsec = ctx->ctime.tv_nsec;
1050 t->tv_nsec = ctx->ctime.tv_nsec; 1020 *serial = ctx->serial;
1051 *serial = ctx->serial; 1021 ctx->auditable = 1;
1052 ctx->auditable = 1;
1053 return 1;
1054 }
1055 return 0;
1056} 1022}
1057 1023
1058int audit_set_loginuid(struct task_struct *task, uid_t loginuid) 1024int audit_set_loginuid(struct task_struct *task, uid_t loginuid)