提交 2fd6f58b 编写于 作者:

[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: NDavid Woodhouse <dwmw2@infradead.org>
上级 ea3834d9
...@@ -682,24 +682,18 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit) ...@@ -682,24 +682,18 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
/* do the secure computing check first */ /* do the secure computing check first */
secure_computing(regs->orig_eax); secure_computing(regs->orig_eax);
if (unlikely(current->audit_context)) { if (unlikely(current->audit_context) && entryexit)
if (!entryexit) audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax);
audit_syscall_entry(current, regs->orig_eax,
regs->ebx, regs->ecx,
regs->edx, regs->esi);
else
audit_syscall_exit(current, regs->eax);
}
if (!(current->ptrace & PT_PTRACED)) if (!(current->ptrace & PT_PTRACED))
return; goto out;
/* Fake a debug trap */ /* Fake a debug trap */
if (test_thread_flag(TIF_SINGLESTEP)) if (test_thread_flag(TIF_SINGLESTEP))
send_sigtrap(current, regs, 0); send_sigtrap(current, regs, 0);
if (!test_thread_flag(TIF_SYSCALL_TRACE)) if (!test_thread_flag(TIF_SYSCALL_TRACE))
return; goto out;
/* the 0x80 provides a way for the tracing parent to distinguish /* the 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */ between a syscall stop and SIGTRAP delivery */
...@@ -714,4 +708,9 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit) ...@@ -714,4 +708,9 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
send_sig(current->exit_code, current, 1); send_sig(current->exit_code, current, 1);
current->exit_code = 0; 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);
} }
...@@ -1595,20 +1595,25 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3, ...@@ -1595,20 +1595,25 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
long arg4, long arg5, long arg6, long arg7, long arg4, long arg5, long arg6, long arg7,
struct pt_regs regs) 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 (unlikely(current->audit_context)) {
if (IS_IA32_PROCESS(&regs)) long syscall;
int arch;
if (IS_IA32_PROCESS(&regs)) {
syscall = regs.r1; syscall = regs.r1;
else arch = AUDIT_ARCH_I386;
} else {
syscall = regs.r15; 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... */ /* "asmlinkage" so the input arguments are preserved... */
...@@ -1619,7 +1624,7 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3, ...@@ -1619,7 +1624,7 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
struct pt_regs regs) struct pt_regs regs)
{ {
if (unlikely(current->audit_context)) 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) if (test_thread_flag(TIF_SYSCALL_TRACE)
&& (current->ptrace & PT_PTRACED)) && (current->ptrace & PT_PTRACED))
......
...@@ -300,25 +300,38 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -300,25 +300,38 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
return ret; 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 * Notification of system call entry/exit
* - triggered by current->work.syscall_trace * - triggered by current->work.syscall_trace
*/ */
asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
{ {
if (unlikely(current->audit_context)) { if (unlikely(current->audit_context) && entryexit)
if (!entryexit) audit_syscall_exit(current, AUDITSC_RESULT(regs->regs[2]), regs->regs[2]);
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 (!test_thread_flag(TIF_SYSCALL_TRACE)) if (!test_thread_flag(TIF_SYSCALL_TRACE))
return; goto out;
if (!(current->ptrace & PT_PTRACED)) if (!(current->ptrace & PT_PTRACED))
return; goto out;
/* The 0x80 provides a way for the tracing parent to distinguish /* The 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */ between a syscall stop and SIGTRAP delivery */
...@@ -334,4 +347,9 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) ...@@ -334,4 +347,9 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
send_sig(current->exit_code, current, 1); send_sig(current->exit_code, current, 1);
current->exit_code = 0; 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]);
} }
...@@ -304,14 +304,17 @@ static void do_syscall_trace(void) ...@@ -304,14 +304,17 @@ static void do_syscall_trace(void)
void do_syscall_trace_enter(struct pt_regs *regs) 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)) 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[3], regs->gpr[4],
regs->gpr[5], regs->gpr[6]); 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) void do_syscall_trace_leave(struct pt_regs *regs)
...@@ -319,7 +322,9 @@ 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]); secure_computing(regs->gpr[0]);
if (unlikely(current->audit_context)) 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) if ((test_thread_flag(TIF_SYSCALL_TRACE)
|| test_thread_flag(TIF_SINGLESTEP)) || test_thread_flag(TIF_SINGLESTEP))
......
...@@ -711,18 +711,13 @@ sys_ptrace(long request, long pid, long addr, long data) ...@@ -711,18 +711,13 @@ sys_ptrace(long request, long pid, long addr, long data)
asmlinkage void asmlinkage void
syscall_trace(struct pt_regs *regs, int entryexit) syscall_trace(struct pt_regs *regs, int entryexit)
{ {
if (unlikely(current->audit_context)) { if (unlikely(current->audit_context) && entryexit)
if (!entryexit) audit_syscall_exit(current, AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]);
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 (!test_thread_flag(TIF_SYSCALL_TRACE)) if (!test_thread_flag(TIF_SYSCALL_TRACE))
return; goto out;
if (!(current->ptrace & PT_PTRACED)) if (!(current->ptrace & PT_PTRACED))
return; goto out;
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0)); ? 0x80 : 0));
...@@ -735,4 +730,10 @@ syscall_trace(struct pt_regs *regs, int entryexit) ...@@ -735,4 +730,10 @@ syscall_trace(struct pt_regs *regs, int entryexit)
send_sig(current->exit_code, current, 1); send_sig(current->exit_code, current, 1);
current->exit_code = 0; 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]);
} }
...@@ -629,25 +629,28 @@ static void syscall_trace(struct pt_regs *regs) ...@@ -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) asmlinkage void syscall_trace_enter(struct pt_regs *regs)
{ {
/* do the secure computing check first */ /* do the secure computing check first */
secure_computing(regs->orig_rax); secure_computing(regs->orig_rax);
if (test_thread_flag(TIF_SYSCALL_TRACE)
&& (current->ptrace & PT_PTRACED))
syscall_trace(regs);
if (unlikely(current->audit_context)) 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->rdi, regs->rsi,
regs->rdx, regs->r10); 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) asmlinkage void syscall_trace_leave(struct pt_regs *regs)
{ {
if (unlikely(current->audit_context)) 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) if ((test_thread_flag(TIF_SYSCALL_TRACE)
|| test_thread_flag(TIF_SINGLESTEP)) || test_thread_flag(TIF_SINGLESTEP))
......
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
#ifndef _LINUX_AUDIT_H_ #ifndef _LINUX_AUDIT_H_
#define _LINUX_AUDIT_H_ #define _LINUX_AUDIT_H_
#include <linux/sched.h>
#include <linux/elf.h>
/* Request and reply types */ /* Request and reply types */
#define AUDIT_GET 1000 /* Get status */ #define AUDIT_GET 1000 /* Get status */
#define AUDIT_SET 1001 /* Set status (enable/disable/auditd) */ #define AUDIT_SET 1001 /* Set status (enable/disable/auditd) */
...@@ -67,6 +70,7 @@ ...@@ -67,6 +70,7 @@
#define AUDIT_FSGID 8 #define AUDIT_FSGID 8
#define AUDIT_LOGINUID 9 #define AUDIT_LOGINUID 9
#define AUDIT_PERS 10 #define AUDIT_PERS 10
#define AUDIT_ARCH 11
/* These are ONLY useful when checking /* These are ONLY useful when checking
* at syscall exit time (AUDIT_AT_EXIT). */ * at syscall exit time (AUDIT_AT_EXIT). */
...@@ -96,6 +100,38 @@ ...@@ -96,6 +100,38 @@
#define AUDIT_FAIL_PRINTK 1 #define AUDIT_FAIL_PRINTK 1
#define AUDIT_FAIL_PANIC 2 #define AUDIT_FAIL_PANIC 2
/* distinguish syscall tables */
#define __AUDIT_ARCH_64BIT 0x80000000
#define __AUDIT_ARCH_LE 0x40000000
#define AUDIT_ARCH_ALPHA (EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_ARMEB (EM_ARM)
#define AUDIT_ARCH_CRIS (EM_CRIS|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_FRV (EM_FRV)
#define AUDIT_ARCH_H8300 (EM_H8_300)
#define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_IA64 (EM_IA_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_M32R (EM_M32R)
#define AUDIT_ARCH_M68K (EM_68K)
#define AUDIT_ARCH_MIPS (EM_MIPS)
#define AUDIT_ARCH_MIPSEL (EM_MIPS|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_MIPS64 (EM_MIPS|__AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_MIPSEL64 (EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_PARISC (EM_PARISC)
#define AUDIT_ARCH_PARISC64 (EM_PARISC|__AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_PPC (EM_PPC)
#define AUDIT_ARCH_PPC64 (EM_PPC64|__AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_S390 (EM_S390)
#define AUDIT_ARCH_S390X (EM_S390|__AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_SH (EM_SH)
#define AUDIT_ARCH_SHEL (EM_SH|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_SH64 (EM_SH|__AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_SHEL64 (EM_SH|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_SPARC (EM_SPARC)
#define AUDIT_ARCH_SPARC64 (EM_SPARC64|__AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_V850 (EM_V850|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_X86_64 (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#ifndef __KERNEL__ #ifndef __KERNEL__
struct audit_message { struct audit_message {
struct nlmsghdr nlh; struct nlmsghdr nlh;
...@@ -129,15 +165,19 @@ struct audit_buffer; ...@@ -129,15 +165,19 @@ struct audit_buffer;
struct audit_context; struct audit_context;
struct inode; struct inode;
#define AUDITSC_INVALID 0
#define AUDITSC_SUCCESS 1
#define AUDITSC_FAILURE 2
#define AUDITSC_RESULT(x) ( ((long)(x))<0?AUDITSC_FAILURE:AUDITSC_SUCCESS )
#ifdef CONFIG_AUDITSYSCALL #ifdef CONFIG_AUDITSYSCALL
/* These are defined in auditsc.c */ /* These are defined in auditsc.c */
/* Public API */ /* Public API */
extern int audit_alloc(struct task_struct *task); extern int audit_alloc(struct task_struct *task);
extern void audit_free(struct task_struct *task); extern void audit_free(struct task_struct *task);
extern void audit_syscall_entry(struct task_struct *task, extern void audit_syscall_entry(struct task_struct *task, int arch,
int major, unsigned long a0, unsigned long a1, int major, unsigned long a0, unsigned long a1,
unsigned long a2, unsigned long a3); unsigned long a2, unsigned long a3);
extern void audit_syscall_exit(struct task_struct *task, int return_code); extern void audit_syscall_exit(struct task_struct *task, int failed, long return_code);
extern void audit_getname(const char *name); extern void audit_getname(const char *name);
extern void audit_putname(const char *name); extern void audit_putname(const char *name);
extern void audit_inode(const char *name, const struct inode *inode); extern void audit_inode(const char *name, const struct inode *inode);
...@@ -153,8 +193,8 @@ extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mo ...@@ -153,8 +193,8 @@ extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mo
#else #else
#define audit_alloc(t) ({ 0; }) #define audit_alloc(t) ({ 0; })
#define audit_free(t) do { ; } while (0) #define audit_free(t) do { ; } while (0)
#define audit_syscall_entry(t,a,b,c,d,e) do { ; } while (0) #define audit_syscall_entry(t,ta,a,b,c,d,e) do { ; } while (0)
#define audit_syscall_exit(t,r) do { ; } while (0) #define audit_syscall_exit(t,f,r) do { ; } while (0)
#define audit_getname(n) do { ; } while (0) #define audit_getname(n) do { ; } while (0)
#define audit_putname(n) do { ; } while (0) #define audit_putname(n) do { ; } while (0)
#define audit_inode(n,i) do { ; } while (0) #define audit_inode(n,i) do { ; } while (0)
......
...@@ -123,7 +123,7 @@ struct audit_context { ...@@ -123,7 +123,7 @@ struct audit_context {
int major; /* syscall number */ int major; /* syscall number */
unsigned long argv[4]; /* syscall arguments */ unsigned long argv[4]; /* syscall arguments */
int return_valid; /* return code is valid */ int return_valid; /* return code is valid */
int return_code;/* syscall return code */ long return_code;/* syscall return code */
int auditable; /* 1 if record should be written */ int auditable; /* 1 if record should be written */
int name_count; int name_count;
struct audit_names names[AUDIT_NAMES]; struct audit_names names[AUDIT_NAMES];
...@@ -135,6 +135,7 @@ struct audit_context { ...@@ -135,6 +135,7 @@ struct audit_context {
uid_t uid, euid, suid, fsuid; uid_t uid, euid, suid, fsuid;
gid_t gid, egid, sgid, fsgid; gid_t gid, egid, sgid, fsgid;
unsigned long personality; unsigned long personality;
int arch;
#if AUDIT_DEBUG #if AUDIT_DEBUG
int put_count; int put_count;
...@@ -348,6 +349,10 @@ static int audit_filter_rules(struct task_struct *tsk, ...@@ -348,6 +349,10 @@ static int audit_filter_rules(struct task_struct *tsk,
case AUDIT_PERS: case AUDIT_PERS:
result = (tsk->personality == value); result = (tsk->personality == value);
break; break;
case AUDIT_ARCH:
if (ctx)
result = (ctx->arch == value);
break;
case AUDIT_EXIT: case AUDIT_EXIT:
if (ctx && ctx->return_valid) if (ctx && ctx->return_valid)
...@@ -355,7 +360,7 @@ static int audit_filter_rules(struct task_struct *tsk, ...@@ -355,7 +360,7 @@ static int audit_filter_rules(struct task_struct *tsk,
break; break;
case AUDIT_SUCCESS: case AUDIT_SUCCESS:
if (ctx && ctx->return_valid) if (ctx && ctx->return_valid)
result = (ctx->return_code >= 0); result = (ctx->return_valid == AUDITSC_SUCCESS);
break; break;
case AUDIT_DEVMAJOR: case AUDIT_DEVMAJOR:
if (ctx) { if (ctx) {
...@@ -648,8 +653,11 @@ static void audit_log_exit(struct audit_context *context) ...@@ -648,8 +653,11 @@ static void audit_log_exit(struct audit_context *context)
audit_log_format(ab, "syscall=%d", context->major); audit_log_format(ab, "syscall=%d", context->major);
if (context->personality != PER_LINUX) if (context->personality != PER_LINUX)
audit_log_format(ab, " per=%lx", context->personality); audit_log_format(ab, " per=%lx", context->personality);
audit_log_format(ab, " arch=%x", context->arch);
if (context->return_valid) if (context->return_valid)
audit_log_format(ab, " exit=%d", context->return_code); audit_log_format(ab, " success=%s exit=%ld",
(context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
context->return_code);
audit_log_format(ab, audit_log_format(ab,
" a0=%lx a1=%lx a2=%lx a3=%lx items=%d" " a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
" pid=%d loginuid=%d uid=%d gid=%d" " pid=%d loginuid=%d uid=%d gid=%d"
...@@ -773,7 +781,7 @@ static inline unsigned int audit_serial(void) ...@@ -773,7 +781,7 @@ static inline unsigned int audit_serial(void)
* then the record will be written at syscall exit time (otherwise, it * then the record will be written at syscall exit time (otherwise, it
* will only be written if another part of the kernel requests that it * will only be written if another part of the kernel requests that it
* be written). */ * be written). */
void audit_syscall_entry(struct task_struct *tsk, int major, void audit_syscall_entry(struct task_struct *tsk, int arch, int major,
unsigned long a1, unsigned long a2, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4) unsigned long a3, unsigned long a4)
{ {
...@@ -827,6 +835,7 @@ void audit_syscall_entry(struct task_struct *tsk, int major, ...@@ -827,6 +835,7 @@ void audit_syscall_entry(struct task_struct *tsk, int major,
if (!audit_enabled) if (!audit_enabled)
return; return;
context->arch = arch;
context->major = major; context->major = major;
context->argv[0] = a1; context->argv[0] = a1;
context->argv[1] = a2; context->argv[1] = a2;
...@@ -850,13 +859,13 @@ void audit_syscall_entry(struct task_struct *tsk, int major, ...@@ -850,13 +859,13 @@ void audit_syscall_entry(struct task_struct *tsk, int major,
* filtering, or because some other part of the kernel write an audit * filtering, or because some other part of the kernel write an audit
* message), then write out the syscall information. In call cases, * message), then write out the syscall information. In call cases,
* free the names stored from getname(). */ * free the names stored from getname(). */
void audit_syscall_exit(struct task_struct *tsk, int return_code) void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code)
{ {
struct audit_context *context; struct audit_context *context;
get_task_struct(tsk); get_task_struct(tsk);
task_lock(tsk); task_lock(tsk);
context = audit_get_context(tsk, 1, return_code); context = audit_get_context(tsk, valid, return_code);
task_unlock(tsk); task_unlock(tsk);
/* Not having a context here is ok, since the parent may have /* 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,6 +878,7 @@ void audit_syscall_exit(struct task_struct *tsk, int return_code)
context->in_syscall = 0; context->in_syscall = 0;
context->auditable = 0; context->auditable = 0;
if (context->previous) { if (context->previous) {
struct audit_context *new_context = context->previous; struct audit_context *new_context = context->previous;
context->previous = NULL; context->previous = NULL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册