aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
author <dwmw2@shinybook.infradead.org>2005-04-29 11:08:28 -0400
committer <dwmw2@shinybook.infradead.org>2005-04-29 11:08:28 -0400
commit2fd6f58ba6efc82ea2c9c2630f7ff5ed9eeaf34a (patch)
tree87cf236a78ad242ae01f1b71c289131e6d1c0662 /kernel
parentea3834d9fb348fb1144ad3affea22df933eaf62e (diff)
[AUDIT] Don't allow ptrace to fool auditing, log arch of audited syscalls.
We were calling ptrace_notify() after auditing the syscall and arguments, but the debugger could have _changed_ them before the syscall was actually invoked. Reorder the calls to fix that. While we're touching ever call to audit_syscall_entry(), we also make it take an extra argument: the architecture of the syscall which was made, because some architectures allow more than one type of syscall. Also add an explicit success/failure flag to audit_syscall_exit(), for the benefit of architectures which return that in a condition register rather than only returning a single register. Change type of syscall return value to 'long' not 'int'. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/auditsc.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 00e87ffff13b..77e92592de57 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -123,7 +123,7 @@ struct audit_context {
123 int major; /* syscall number */ 123 int major; /* syscall number */
124 unsigned long argv[4]; /* syscall arguments */ 124 unsigned long argv[4]; /* syscall arguments */
125 int return_valid; /* return code is valid */ 125 int return_valid; /* return code is valid */
126 int return_code;/* syscall return code */ 126 long return_code;/* syscall return code */
127 int auditable; /* 1 if record should be written */ 127 int auditable; /* 1 if record should be written */
128 int name_count; 128 int name_count;
129 struct audit_names names[AUDIT_NAMES]; 129 struct audit_names names[AUDIT_NAMES];
@@ -135,6 +135,7 @@ struct audit_context {
135 uid_t uid, euid, suid, fsuid; 135 uid_t uid, euid, suid, fsuid;
136 gid_t gid, egid, sgid, fsgid; 136 gid_t gid, egid, sgid, fsgid;
137 unsigned long personality; 137 unsigned long personality;
138 int arch;
138 139
139#if AUDIT_DEBUG 140#if AUDIT_DEBUG
140 int put_count; 141 int put_count;
@@ -348,6 +349,10 @@ static int audit_filter_rules(struct task_struct *tsk,
348 case AUDIT_PERS: 349 case AUDIT_PERS:
349 result = (tsk->personality == value); 350 result = (tsk->personality == value);
350 break; 351 break;
352 case AUDIT_ARCH:
353 if (ctx)
354 result = (ctx->arch == value);
355 break;
351 356
352 case AUDIT_EXIT: 357 case AUDIT_EXIT:
353 if (ctx && ctx->return_valid) 358 if (ctx && ctx->return_valid)
@@ -355,7 +360,7 @@ static int audit_filter_rules(struct task_struct *tsk,
355 break; 360 break;
356 case AUDIT_SUCCESS: 361 case AUDIT_SUCCESS:
357 if (ctx && ctx->return_valid) 362 if (ctx && ctx->return_valid)
358 result = (ctx->return_code >= 0); 363 result = (ctx->return_valid == AUDITSC_SUCCESS);
359 break; 364 break;
360 case AUDIT_DEVMAJOR: 365 case AUDIT_DEVMAJOR:
361 if (ctx) { 366 if (ctx) {
@@ -648,8 +653,11 @@ static void audit_log_exit(struct audit_context *context)
648 audit_log_format(ab, "syscall=%d", context->major); 653 audit_log_format(ab, "syscall=%d", context->major);
649 if (context->personality != PER_LINUX) 654 if (context->personality != PER_LINUX)
650 audit_log_format(ab, " per=%lx", context->personality); 655 audit_log_format(ab, " per=%lx", context->personality);
656 audit_log_format(ab, " arch=%x", context->arch);
651 if (context->return_valid) 657 if (context->return_valid)
652 audit_log_format(ab, " exit=%d", context->return_code); 658 audit_log_format(ab, " success=%s exit=%ld",
659 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
660 context->return_code);
653 audit_log_format(ab, 661 audit_log_format(ab,
654 " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" 662 " a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
655 " pid=%d loginuid=%d uid=%d gid=%d" 663 " pid=%d loginuid=%d uid=%d gid=%d"
@@ -773,7 +781,7 @@ static inline unsigned int audit_serial(void)
773 * then the record will be written at syscall exit time (otherwise, it 781 * then the record will be written at syscall exit time (otherwise, it
774 * will only be written if another part of the kernel requests that it 782 * will only be written if another part of the kernel requests that it
775 * be written). */ 783 * be written). */
776void audit_syscall_entry(struct task_struct *tsk, int major, 784void audit_syscall_entry(struct task_struct *tsk, int arch, int major,
777 unsigned long a1, unsigned long a2, 785 unsigned long a1, unsigned long a2,
778 unsigned long a3, unsigned long a4) 786 unsigned long a3, unsigned long a4)
779{ 787{
@@ -827,6 +835,7 @@ void audit_syscall_entry(struct task_struct *tsk, int major,
827 if (!audit_enabled) 835 if (!audit_enabled)
828 return; 836 return;
829 837
838 context->arch = arch;
830 context->major = major; 839 context->major = major;
831 context->argv[0] = a1; 840 context->argv[0] = a1;
832 context->argv[1] = a2; 841 context->argv[1] = a2;
@@ -850,13 +859,13 @@ void audit_syscall_entry(struct task_struct *tsk, int major,
850 * filtering, or because some other part of the kernel write an audit 859 * filtering, or because some other part of the kernel write an audit
851 * message), then write out the syscall information. In call cases, 860 * message), then write out the syscall information. In call cases,
852 * free the names stored from getname(). */ 861 * free the names stored from getname(). */
853void audit_syscall_exit(struct task_struct *tsk, int return_code) 862void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code)
854{ 863{
855 struct audit_context *context; 864 struct audit_context *context;
856 865
857 get_task_struct(tsk); 866 get_task_struct(tsk);
858 task_lock(tsk); 867 task_lock(tsk);
859 context = audit_get_context(tsk, 1, return_code); 868 context = audit_get_context(tsk, valid, return_code);
860 task_unlock(tsk); 869 task_unlock(tsk);
861 870
862 /* Not having a context here is ok, since the parent may have 871 /* Not having a context here is ok, since the parent may have
@@ -869,6 +878,7 @@ void audit_syscall_exit(struct task_struct *tsk, int return_code)
869 878
870 context->in_syscall = 0; 879 context->in_syscall = 0;
871 context->auditable = 0; 880 context->auditable = 0;
881
872 if (context->previous) { 882 if (context->previous) {
873 struct audit_context *new_context = context->previous; 883 struct audit_context *new_context = context->previous;
874 context->previous = NULL; 884 context->previous = NULL;