aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
author <dwmw2@shinybook.infradead.org>2005-04-29 16:08:28 +0100
committer <dwmw2@shinybook.infradead.org>2005-04-29 16:08:28 +0100
commit2fd6f58ba6efc82ea2c9c2630f7ff5ed9eeaf34a (patch)
tree87cf236a78ad242ae01f1b71c289131e6d1c0662 /arch
parentnamei: add audit_inode to all branches in path_lookup (diff)
downloadlinux-dev-2fd6f58ba6efc82ea2c9c2630f7ff5ed9eeaf34a.tar.xz
linux-dev-2fd6f58ba6efc82ea2c9c2630f7ff5ed9eeaf34a.zip
[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 'arch')
-rw-r--r--arch/i386/kernel/ptrace.c19
-rw-r--r--arch/ia64/kernel/ptrace.c21
-rw-r--r--arch/mips/kernel/ptrace.c38
-rw-r--r--arch/ppc64/kernel/ptrace.c15
-rw-r--r--arch/s390/kernel/ptrace.c21
-rw-r--r--arch/x86_64/kernel/ptrace.c13
6 files changed, 79 insertions, 48 deletions
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index b2f17640ceff..5606ec7a5c2b 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -682,24 +682,18 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
/* do the secure computing check first */
secure_computing(regs->orig_eax);
- if (unlikely(current->audit_context)) {
- if (!entryexit)
- audit_syscall_entry(current, regs->orig_eax,
- regs->ebx, regs->ecx,
- regs->edx, regs->esi);
- else
- audit_syscall_exit(current, regs->eax);
- }
+ if (unlikely(current->audit_context) && entryexit)
+ audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax);
if (!(current->ptrace & PT_PTRACED))
- return;
+ goto out;
/* Fake a debug trap */
if (test_thread_flag(TIF_SINGLESTEP))
send_sigtrap(current, regs, 0);
if (!test_thread_flag(TIF_SYSCALL_TRACE))
- return;
+ goto out;
/* the 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
@@ -714,4 +708,9 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
send_sig(current->exit_code, current, 1);
current->exit_code = 0;
}
+ out:
+ if (unlikely(current->audit_context) && !entryexit)
+ audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax,
+ regs->ebx, regs->ecx, regs->edx, regs->esi);
+
}
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 55789fcd7210..8dde0b16d4c8 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -1595,20 +1595,25 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
long arg4, long arg5, long arg6, long arg7,
struct pt_regs regs)
{
- long syscall;
+ if (test_thread_flag(TIF_SYSCALL_TRACE)
+ && (current->ptrace & PT_PTRACED))
+ syscall_trace();
if (unlikely(current->audit_context)) {
- if (IS_IA32_PROCESS(&regs))
+ long syscall;
+ int arch;
+
+ if (IS_IA32_PROCESS(&regs)) {
syscall = regs.r1;
- else
+ arch = AUDIT_ARCH_I386;
+ } else {
syscall = regs.r15;
+ arch = AUDIT_ARCH_IA64;
+ }
- audit_syscall_entry(current, syscall, arg0, arg1, arg2, arg3);
+ audit_syscall_entry(current, arch, syscall, arg0, arg1, arg2, arg3);
}
- if (test_thread_flag(TIF_SYSCALL_TRACE)
- && (current->ptrace & PT_PTRACED))
- syscall_trace();
}
/* "asmlinkage" so the input arguments are preserved... */
@@ -1619,7 +1624,7 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
struct pt_regs regs)
{
if (unlikely(current->audit_context))
- audit_syscall_exit(current, regs.r8);
+ audit_syscall_exit(current, AUDITSC_RESULT(regs.r10), regs.r8);
if (test_thread_flag(TIF_SYSCALL_TRACE)
&& (current->ptrace & PT_PTRACED))
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 92f2c39afe27..eaf7be9d0b0a 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -300,25 +300,38 @@ out:
return ret;
}
+static inline int audit_arch()
+{
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#ifdef CONFIG_MIPS64
+ if (!(current->thread.mflags & MF_32BIT_REGS))
+ return AUDIT_ARCH_MIPSEL64;
+#endif /* MIPS64 */
+ return AUDIT_ARCH_MIPSEL;
+
+#else /* big endian... */
+#ifdef CONFIG_MIPS64
+ if (!(current->thread.mflags & MF_32BIT_REGS))
+ return AUDIT_ARCH_MIPS64;
+#endif /* MIPS64 */
+ return AUDIT_ARCH_MIPS;
+
+#endif /* endian */
+}
+
/*
* Notification of system call entry/exit
* - triggered by current->work.syscall_trace
*/
asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
{
- if (unlikely(current->audit_context)) {
- if (!entryexit)
- audit_syscall_entry(current, regs->regs[2],
- regs->regs[4], regs->regs[5],
- regs->regs[6], regs->regs[7]);
- else
- audit_syscall_exit(current, regs->regs[2]);
- }
+ if (unlikely(current->audit_context) && entryexit)
+ audit_syscall_exit(current, AUDITSC_RESULT(regs->regs[2]), regs->regs[2]);
if (!test_thread_flag(TIF_SYSCALL_TRACE))
- return;
+ goto out;
if (!(current->ptrace & PT_PTRACED))
- return;
+ goto out;
/* The 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
@@ -334,4 +347,9 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
send_sig(current->exit_code, current, 1);
current->exit_code = 0;
}
+ out:
+ if (unlikely(current->audit_context) && !entryexit)
+ audit_syscall_entry(current, audit_arch(), regs->regs[2],
+ regs->regs[4], regs->regs[5],
+ regs->regs[6], regs->regs[7]);
}
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
index 354a287c67eb..3c76333ec3a9 100644
--- a/arch/ppc64/kernel/ptrace.c
+++ b/arch/ppc64/kernel/ptrace.c
@@ -304,14 +304,17 @@ static void do_syscall_trace(void)
void do_syscall_trace_enter(struct pt_regs *regs)
{
+ if (test_thread_flag(TIF_SYSCALL_TRACE)
+ && (current->ptrace & PT_PTRACED))
+ do_syscall_trace();
+
if (unlikely(current->audit_context))
- audit_syscall_entry(current, regs->gpr[0],
+ audit_syscall_entry(current,
+ test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64,
+ regs->gpr[0],
regs->gpr[3], regs->gpr[4],
regs->gpr[5], regs->gpr[6]);
- if (test_thread_flag(TIF_SYSCALL_TRACE)
- && (current->ptrace & PT_PTRACED))
- do_syscall_trace();
}
void do_syscall_trace_leave(struct pt_regs *regs)
@@ -319,7 +322,9 @@ void do_syscall_trace_leave(struct pt_regs *regs)
secure_computing(regs->gpr[0]);
if (unlikely(current->audit_context))
- audit_syscall_exit(current, regs->result);
+ audit_syscall_exit(current,
+ (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
+ regs->result);
if ((test_thread_flag(TIF_SYSCALL_TRACE)
|| test_thread_flag(TIF_SINGLESTEP))
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 647233c02fc8..2d546c67f7c3 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -711,18 +711,13 @@ out:
asmlinkage void
syscall_trace(struct pt_regs *regs, int entryexit)
{
- if (unlikely(current->audit_context)) {
- if (!entryexit)
- audit_syscall_entry(current, regs->gprs[2],
- regs->orig_gpr2, regs->gprs[3],
- regs->gprs[4], regs->gprs[5]);
- else
- audit_syscall_exit(current, regs->gprs[2]);
- }
+ if (unlikely(current->audit_context) && entryexit)
+ audit_syscall_exit(current, AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]);
+
if (!test_thread_flag(TIF_SYSCALL_TRACE))
- return;
+ goto out;
if (!(current->ptrace & PT_PTRACED))
- return;
+ goto out;
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0));
@@ -735,4 +730,10 @@ syscall_trace(struct pt_regs *regs, int entryexit)
send_sig(current->exit_code, current, 1);
current->exit_code = 0;
}
+ out:
+ if (unlikely(current->audit_context) && !entryexit)
+ audit_syscall_entry(current,
+ test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X,
+ regs->gprs[2], regs->orig_gpr2, regs->gprs[3],
+ regs->gprs[4], regs->gprs[5]);
}
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index c7011675007d..ecbccbbf5c2a 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -629,25 +629,28 @@ static void syscall_trace(struct pt_regs *regs)
}
}
+#define audit_arch() (test_thread_flag(TIF_IA32) ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64)
+
asmlinkage void syscall_trace_enter(struct pt_regs *regs)
{
/* do the secure computing check first */
secure_computing(regs->orig_rax);
+ if (test_thread_flag(TIF_SYSCALL_TRACE)
+ && (current->ptrace & PT_PTRACED))
+ syscall_trace(regs);
+
if (unlikely(current->audit_context))
- audit_syscall_entry(current, regs->orig_rax,
+ audit_syscall_entry(current, audit_arch(), regs->orig_rax,
regs->rdi, regs->rsi,
regs->rdx, regs->r10);
- if (test_thread_flag(TIF_SYSCALL_TRACE)
- && (current->ptrace & PT_PTRACED))
- syscall_trace(regs);
}
asmlinkage void syscall_trace_leave(struct pt_regs *regs)
{
if (unlikely(current->audit_context))
- audit_syscall_exit(current, regs->rax);
+ audit_syscall_exit(current, AUDITSC_RESULT(regs->rax), regs->rax);
if ((test_thread_flag(TIF_SYSCALL_TRACE)
|| test_thread_flag(TIF_SINGLESTEP))