Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit: (29 commits) audit: no leading space in audit_log_d_path prefix audit: treat s_id as an untrusted string audit: fix signedness bug in audit_log_execve_info() audit: comparison on interprocess fields audit: implement all object interfield comparisons audit: allow interfield comparison between gid and ogid audit: complex interfield comparison helper audit: allow interfield comparison in audit rules Kernel: Audit Support For The ARM Platform audit: do not call audit_getname on error audit: only allow tasks to set their loginuid if it is -1 audit: remove task argument to audit_set_loginuid audit: allow audit matching on inode gid audit: allow matching on obj_uid audit: remove audit_finish_fork as it can't be called audit: reject entry,always rules audit: inline audit_free to simplify the look of generic code audit: drop audit_set_macxattr as it doesn't do anything audit: inline checks for not needing to collect aux records audit: drop some potentially inadvisable likely notations ... Use evil merge to fix up grammar mistakes in Kconfig file. Bad speling and horrible grammar (and copious swearing) is to be expected, but let's keep it to commit messages and comments, rather than expose it to users in config help texts or printouts.
This commit is contained in:
commit
f429ee3b80
43 changed files with 808 additions and 498 deletions
|
@ -24,7 +24,6 @@
|
|||
#define MAX_INSN_SIZE 2
|
||||
#define MAX_STACK_SIZE 64 /* 32 would probably be OK */
|
||||
|
||||
#define regs_return_value(regs) ((regs)->ARM_r0)
|
||||
#define flush_insn_slot(p) do { } while (0)
|
||||
#define kretprobe_blacklist_size 0
|
||||
|
||||
|
|
|
@ -189,6 +189,11 @@ static inline int valid_user_regs(struct pt_regs *regs)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline long regs_return_value(struct pt_regs *regs)
|
||||
{
|
||||
return regs->ARM_r0;
|
||||
}
|
||||
|
||||
#define instruction_pointer(regs) (regs)->ARM_pc
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
|
|
@ -129,6 +129,7 @@ extern void vfp_flush_hwstate(struct thread_info *);
|
|||
/*
|
||||
* thread information flags:
|
||||
* TIF_SYSCALL_TRACE - syscall trace active
|
||||
* TIF_SYSCAL_AUDIT - syscall auditing active
|
||||
* TIF_SIGPENDING - signal pending
|
||||
* TIF_NEED_RESCHED - rescheduling necessary
|
||||
* TIF_NOTIFY_RESUME - callback before returning to user
|
||||
|
@ -139,6 +140,7 @@ extern void vfp_flush_hwstate(struct thread_info *);
|
|||
#define TIF_NEED_RESCHED 1
|
||||
#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
|
||||
#define TIF_SYSCALL_TRACE 8
|
||||
#define TIF_SYSCALL_AUDIT 9
|
||||
#define TIF_POLLING_NRFLAG 16
|
||||
#define TIF_USING_IWMMXT 17
|
||||
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
|
||||
|
@ -149,11 +151,15 @@ extern void vfp_flush_hwstate(struct thread_info *);
|
|||
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
|
||||
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
|
||||
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
|
||||
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
|
||||
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
|
||||
#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
|
||||
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
|
||||
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
|
||||
|
||||
/* Checks for any syscall work in entry-common.S */
|
||||
#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT)
|
||||
|
||||
/*
|
||||
* Change these and you break ASM code in entry-common.S
|
||||
*/
|
||||
|
|
|
@ -87,7 +87,7 @@ ENTRY(ret_from_fork)
|
|||
get_thread_info tsk
|
||||
ldr r1, [tsk, #TI_FLAGS] @ check for syscall tracing
|
||||
mov why, #1
|
||||
tst r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
|
||||
tst r1, #_TIF_SYSCALL_WORK @ are we tracing syscalls?
|
||||
beq ret_slow_syscall
|
||||
mov r1, sp
|
||||
mov r0, #1 @ trace exit [IP = 1]
|
||||
|
@ -443,7 +443,7 @@ ENTRY(vector_swi)
|
|||
1:
|
||||
#endif
|
||||
|
||||
tst r10, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
|
||||
tst r10, #_TIF_SYSCALL_WORK @ are we tracing syscalls?
|
||||
bne __sys_trace
|
||||
|
||||
cmp scno, #NR_syscalls @ check upper syscall limit
|
||||
|
|
|
@ -906,11 +906,6 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
|
|||
{
|
||||
unsigned long ip;
|
||||
|
||||
if (!test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
return scno;
|
||||
if (!(current->ptrace & PT_PTRACED))
|
||||
return scno;
|
||||
|
||||
/*
|
||||
* Save IP. IP is used to denote syscall entry/exit:
|
||||
* IP = 0 -> entry, = 1 -> exit
|
||||
|
@ -918,6 +913,17 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
|
|||
ip = regs->ARM_ip;
|
||||
regs->ARM_ip = why;
|
||||
|
||||
if (!ip)
|
||||
audit_syscall_exit(regs);
|
||||
else
|
||||
audit_syscall_entry(AUDIT_ARCH_ARMEB, scno, regs->ARM_r0,
|
||||
regs->ARM_r1, regs->ARM_r2, regs->ARM_r3);
|
||||
|
||||
if (!test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
return scno;
|
||||
if (!(current->ptrace & PT_PTRACED))
|
||||
return scno;
|
||||
|
||||
current_thread_info()->syscall = scno;
|
||||
|
||||
/* the 0x80 provides a way for the tracing parent to distinguish
|
||||
|
|
|
@ -246,7 +246,18 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs)
|
|||
return regs->ar_bspstore;
|
||||
}
|
||||
|
||||
#define regs_return_value(regs) ((regs)->r8)
|
||||
static inline int is_syscall_success(struct pt_regs *regs)
|
||||
{
|
||||
return regs->r10 != -1;
|
||||
}
|
||||
|
||||
static inline long regs_return_value(struct pt_regs *regs)
|
||||
{
|
||||
if (is_syscall_success(regs))
|
||||
return regs->r8;
|
||||
else
|
||||
return -regs->r8;
|
||||
}
|
||||
|
||||
/* Conserve space in histogram by encoding slot bits in address
|
||||
* bits 2 and 3 rather than bits 0 and 1.
|
||||
|
|
|
@ -1246,15 +1246,8 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
|
|||
if (test_thread_flag(TIF_RESTORE_RSE))
|
||||
ia64_sync_krbs();
|
||||
|
||||
if (unlikely(current->audit_context)) {
|
||||
long syscall;
|
||||
int arch;
|
||||
|
||||
syscall = regs.r15;
|
||||
arch = AUDIT_ARCH_IA64;
|
||||
|
||||
audit_syscall_entry(arch, syscall, arg0, arg1, arg2, arg3);
|
||||
}
|
||||
audit_syscall_entry(AUDIT_ARCH_IA64, regs.r15, arg0, arg1, arg2, arg3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1268,14 +1261,7 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
|
|||
{
|
||||
int step;
|
||||
|
||||
if (unlikely(current->audit_context)) {
|
||||
int success = AUDITSC_RESULT(regs.r10);
|
||||
long result = regs.r8;
|
||||
|
||||
if (success != AUDITSC_SUCCESS)
|
||||
result = -result;
|
||||
audit_syscall_exit(success, result);
|
||||
}
|
||||
audit_syscall_exit(®s);
|
||||
|
||||
step = test_thread_flag(TIF_SINGLESTEP);
|
||||
if (step || test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
|
|
|
@ -61,6 +61,11 @@ struct pt_regs {
|
|||
#define instruction_pointer(regs) ((regs)->pc)
|
||||
#define profile_pc(regs) instruction_pointer(regs)
|
||||
|
||||
static inline long regs_return_value(struct pt_regs *regs)
|
||||
{
|
||||
return regs->r3;
|
||||
}
|
||||
|
||||
#else /* __KERNEL__ */
|
||||
|
||||
/* pt_regs offsets used by gdbserver etc in ptrace syscalls */
|
||||
|
|
|
@ -147,10 +147,8 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
|
|||
*/
|
||||
ret = -1L;
|
||||
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_entry(EM_MICROBLAZE, regs->r12,
|
||||
regs->r5, regs->r6,
|
||||
regs->r7, regs->r8);
|
||||
audit_syscall_entry(EM_MICROBLAZE, regs->r12, regs->r5, regs->r6,
|
||||
regs->r7, regs->r8);
|
||||
|
||||
return ret ?: regs->r12;
|
||||
}
|
||||
|
@ -159,8 +157,7 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
|
|||
{
|
||||
int step;
|
||||
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_exit(AUDITSC_RESULT(regs->r3), regs->r3);
|
||||
audit_syscall_exit(regs);
|
||||
|
||||
step = test_thread_flag(TIF_SINGLESTEP);
|
||||
if (step || test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
|
|
|
@ -137,7 +137,19 @@ extern int ptrace_set_watch_regs(struct task_struct *child,
|
|||
*/
|
||||
#define user_mode(regs) (((regs)->cp0_status & KU_MASK) == KU_USER)
|
||||
|
||||
#define regs_return_value(_regs) ((_regs)->regs[2])
|
||||
static inline int is_syscall_success(struct pt_regs *regs)
|
||||
{
|
||||
return !regs->regs[7];
|
||||
}
|
||||
|
||||
static inline long regs_return_value(struct pt_regs *regs)
|
||||
{
|
||||
if (is_syscall_success(regs))
|
||||
return regs->regs[2];
|
||||
else
|
||||
return -regs->regs[2];
|
||||
}
|
||||
|
||||
#define instruction_pointer(regs) ((regs)->cp0_epc)
|
||||
#define profile_pc(regs) instruction_pointer(regs)
|
||||
|
||||
|
|
|
@ -560,10 +560,9 @@ asmlinkage void syscall_trace_enter(struct pt_regs *regs)
|
|||
}
|
||||
|
||||
out:
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_entry(audit_arch(), regs->regs[2],
|
||||
regs->regs[4], regs->regs[5],
|
||||
regs->regs[6], regs->regs[7]);
|
||||
audit_syscall_entry(audit_arch(), regs->regs[2],
|
||||
regs->regs[4], regs->regs[5],
|
||||
regs->regs[6], regs->regs[7]);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -572,9 +571,7 @@ asmlinkage void syscall_trace_enter(struct pt_regs *regs)
|
|||
*/
|
||||
asmlinkage void syscall_trace_leave(struct pt_regs *regs)
|
||||
{
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_exit(AUDITSC_RESULT(regs->regs[7]),
|
||||
-regs->regs[2]);
|
||||
audit_syscall_exit(regs);
|
||||
|
||||
if (!(current->ptrace & PT_PTRACED))
|
||||
return;
|
||||
|
|
|
@ -86,7 +86,18 @@ struct pt_regs {
|
|||
#define instruction_pointer(regs) ((regs)->nip)
|
||||
#define user_stack_pointer(regs) ((regs)->gpr[1])
|
||||
#define kernel_stack_pointer(regs) ((regs)->gpr[1])
|
||||
#define regs_return_value(regs) ((regs)->gpr[3])
|
||||
static inline int is_syscall_success(struct pt_regs *regs)
|
||||
{
|
||||
return !(regs->ccr & 0x10000000);
|
||||
}
|
||||
|
||||
static inline long regs_return_value(struct pt_regs *regs)
|
||||
{
|
||||
if (is_syscall_success(regs))
|
||||
return regs->gpr[3];
|
||||
else
|
||||
return -regs->gpr[3];
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
extern unsigned long profile_pc(struct pt_regs *regs);
|
||||
|
|
|
@ -1724,22 +1724,20 @@ long do_syscall_trace_enter(struct pt_regs *regs)
|
|||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
trace_sys_enter(regs, regs->gpr[0]);
|
||||
|
||||
if (unlikely(current->audit_context)) {
|
||||
#ifdef CONFIG_PPC64
|
||||
if (!is_32bit_task())
|
||||
audit_syscall_entry(AUDIT_ARCH_PPC64,
|
||||
regs->gpr[0],
|
||||
regs->gpr[3], regs->gpr[4],
|
||||
regs->gpr[5], regs->gpr[6]);
|
||||
else
|
||||
if (!is_32bit_task())
|
||||
audit_syscall_entry(AUDIT_ARCH_PPC64,
|
||||
regs->gpr[0],
|
||||
regs->gpr[3], regs->gpr[4],
|
||||
regs->gpr[5], regs->gpr[6]);
|
||||
else
|
||||
#endif
|
||||
audit_syscall_entry(AUDIT_ARCH_PPC,
|
||||
regs->gpr[0],
|
||||
regs->gpr[3] & 0xffffffff,
|
||||
regs->gpr[4] & 0xffffffff,
|
||||
regs->gpr[5] & 0xffffffff,
|
||||
regs->gpr[6] & 0xffffffff);
|
||||
}
|
||||
audit_syscall_entry(AUDIT_ARCH_PPC,
|
||||
regs->gpr[0],
|
||||
regs->gpr[3] & 0xffffffff,
|
||||
regs->gpr[4] & 0xffffffff,
|
||||
regs->gpr[5] & 0xffffffff,
|
||||
regs->gpr[6] & 0xffffffff);
|
||||
|
||||
return ret ?: regs->gpr[0];
|
||||
}
|
||||
|
@ -1748,9 +1746,7 @@ void do_syscall_trace_leave(struct pt_regs *regs)
|
|||
{
|
||||
int step;
|
||||
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
|
||||
regs->result);
|
||||
audit_syscall_exit(regs);
|
||||
|
||||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
trace_sys_exit(regs, regs->result);
|
||||
|
|
|
@ -541,9 +541,13 @@ struct user_regs_struct
|
|||
#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
|
||||
#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
|
||||
#define user_stack_pointer(regs)((regs)->gprs[15])
|
||||
#define regs_return_value(regs)((regs)->gprs[2])
|
||||
#define profile_pc(regs) instruction_pointer(regs)
|
||||
|
||||
static inline long regs_return_value(struct pt_regs *regs)
|
||||
{
|
||||
return regs->gprs[2];
|
||||
}
|
||||
|
||||
int regs_query_register_offset(const char *name);
|
||||
const char *regs_query_register_name(unsigned int offset);
|
||||
unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset);
|
||||
|
|
|
@ -740,20 +740,17 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
|
|||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
trace_sys_enter(regs, regs->gprs[2]);
|
||||
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_entry(is_compat_task() ?
|
||||
AUDIT_ARCH_S390 : AUDIT_ARCH_S390X,
|
||||
regs->gprs[2], regs->orig_gpr2,
|
||||
regs->gprs[3], regs->gprs[4],
|
||||
regs->gprs[5]);
|
||||
audit_syscall_entry(is_compat_task() ?
|
||||
AUDIT_ARCH_S390 : AUDIT_ARCH_S390X,
|
||||
regs->gprs[2], regs->orig_gpr2,
|
||||
regs->gprs[3], regs->gprs[4],
|
||||
regs->gprs[5]);
|
||||
return ret ?: regs->gprs[2];
|
||||
}
|
||||
|
||||
asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
|
||||
{
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]),
|
||||
regs->gprs[2]);
|
||||
audit_syscall_exit(regs);
|
||||
|
||||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
trace_sys_exit(regs, regs->gprs[2]);
|
||||
|
|
|
@ -76,7 +76,10 @@ struct pt_dspregs {
|
|||
#ifdef __KERNEL__
|
||||
|
||||
#define MAX_REG_OFFSET offsetof(struct pt_regs, tra)
|
||||
#define regs_return_value(_regs) ((_regs)->regs[0])
|
||||
static inline long regs_return_value(struct pt_regs *regs)
|
||||
{
|
||||
return regs->regs[0];
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
|
|
@ -13,7 +13,10 @@ struct pt_regs {
|
|||
#ifdef __KERNEL__
|
||||
|
||||
#define MAX_REG_OFFSET offsetof(struct pt_regs, tregs[7])
|
||||
#define regs_return_value(_regs) ((_regs)->regs[3])
|
||||
static inline long regs_return_value(struct pt_regs *regs)
|
||||
{
|
||||
return regs->regs[3];
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
|
|
@ -518,10 +518,9 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
|
|||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
trace_sys_enter(regs, regs->regs[0]);
|
||||
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_entry(audit_arch(), regs->regs[3],
|
||||
regs->regs[4], regs->regs[5],
|
||||
regs->regs[6], regs->regs[7]);
|
||||
audit_syscall_entry(audit_arch(), regs->regs[3],
|
||||
regs->regs[4], regs->regs[5],
|
||||
regs->regs[6], regs->regs[7]);
|
||||
|
||||
return ret ?: regs->regs[0];
|
||||
}
|
||||
|
@ -530,9 +529,7 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
|
|||
{
|
||||
int step;
|
||||
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]),
|
||||
regs->regs[0]);
|
||||
audit_syscall_exit(regs);
|
||||
|
||||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
trace_sys_exit(regs, regs->regs[0]);
|
||||
|
|
|
@ -536,10 +536,9 @@ asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs)
|
|||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
trace_sys_enter(regs, regs->regs[9]);
|
||||
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_entry(audit_arch(), regs->regs[1],
|
||||
regs->regs[2], regs->regs[3],
|
||||
regs->regs[4], regs->regs[5]);
|
||||
audit_syscall_entry(audit_arch(), regs->regs[1],
|
||||
regs->regs[2], regs->regs[3],
|
||||
regs->regs[4], regs->regs[5]);
|
||||
|
||||
return ret ?: regs->regs[9];
|
||||
}
|
||||
|
@ -548,9 +547,7 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
|
|||
{
|
||||
int step;
|
||||
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]),
|
||||
regs->regs[9]);
|
||||
audit_syscall_exit(regs);
|
||||
|
||||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
trace_sys_exit(regs, regs->regs[9]);
|
||||
|
|
|
@ -207,7 +207,15 @@ do { current_thread_info()->syscall_noerror = 1; \
|
|||
#define instruction_pointer(regs) ((regs)->tpc)
|
||||
#define instruction_pointer_set(regs, val) ((regs)->tpc = (val))
|
||||
#define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP])
|
||||
#define regs_return_value(regs) ((regs)->u_regs[UREG_I0])
|
||||
static inline int is_syscall_success(struct pt_regs *regs)
|
||||
{
|
||||
return !(regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY));
|
||||
}
|
||||
|
||||
static inline long regs_return_value(struct pt_regs *regs)
|
||||
{
|
||||
return regs->u_regs[UREG_I0];
|
||||
}
|
||||
#ifdef CONFIG_SMP
|
||||
extern unsigned long profile_pc(struct pt_regs *);
|
||||
#else
|
||||
|
|
|
@ -1071,32 +1071,22 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
|
|||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
trace_sys_enter(regs, regs->u_regs[UREG_G1]);
|
||||
|
||||
if (unlikely(current->audit_context) && !ret)
|
||||
audit_syscall_entry((test_thread_flag(TIF_32BIT) ?
|
||||
AUDIT_ARCH_SPARC :
|
||||
AUDIT_ARCH_SPARC64),
|
||||
regs->u_regs[UREG_G1],
|
||||
regs->u_regs[UREG_I0],
|
||||
regs->u_regs[UREG_I1],
|
||||
regs->u_regs[UREG_I2],
|
||||
regs->u_regs[UREG_I3]);
|
||||
audit_syscall_entry((test_thread_flag(TIF_32BIT) ?
|
||||
AUDIT_ARCH_SPARC :
|
||||
AUDIT_ARCH_SPARC64),
|
||||
regs->u_regs[UREG_G1],
|
||||
regs->u_regs[UREG_I0],
|
||||
regs->u_regs[UREG_I1],
|
||||
regs->u_regs[UREG_I2],
|
||||
regs->u_regs[UREG_I3]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
asmlinkage void syscall_trace_leave(struct pt_regs *regs)
|
||||
{
|
||||
#ifdef CONFIG_AUDITSYSCALL
|
||||
if (unlikely(current->audit_context)) {
|
||||
unsigned long tstate = regs->tstate;
|
||||
int result = AUDITSC_SUCCESS;
|
||||
audit_syscall_exit(regs);
|
||||
|
||||
if (unlikely(tstate & (TSTATE_XCARRY | TSTATE_ICARRY)))
|
||||
result = AUDITSC_FAILURE;
|
||||
|
||||
audit_syscall_exit(result, regs->u_regs[UREG_I0]);
|
||||
}
|
||||
#endif
|
||||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
trace_sys_exit(regs, regs->u_regs[UREG_G1]);
|
||||
|
||||
|
|
|
@ -167,17 +167,15 @@ void syscall_trace(struct uml_pt_regs *regs, int entryexit)
|
|||
int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit;
|
||||
int tracesysgood;
|
||||
|
||||
if (unlikely(current->audit_context)) {
|
||||
if (!entryexit)
|
||||
audit_syscall_entry(HOST_AUDIT_ARCH,
|
||||
UPT_SYSCALL_NR(regs),
|
||||
UPT_SYSCALL_ARG1(regs),
|
||||
UPT_SYSCALL_ARG2(regs),
|
||||
UPT_SYSCALL_ARG3(regs),
|
||||
UPT_SYSCALL_ARG4(regs));
|
||||
else audit_syscall_exit(AUDITSC_RESULT(UPT_SYSCALL_RET(regs)),
|
||||
UPT_SYSCALL_RET(regs));
|
||||
}
|
||||
if (!entryexit)
|
||||
audit_syscall_entry(HOST_AUDIT_ARCH,
|
||||
UPT_SYSCALL_NR(regs),
|
||||
UPT_SYSCALL_ARG1(regs),
|
||||
UPT_SYSCALL_ARG2(regs),
|
||||
UPT_SYSCALL_ARG3(regs),
|
||||
UPT_SYSCALL_ARG4(regs));
|
||||
else
|
||||
audit_syscall_exit(regs);
|
||||
|
||||
/* Fake a debug trap */
|
||||
if (is_singlestep)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <asm/segment.h>
|
||||
#include <asm/irqflags.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
|
||||
#include <linux/elf-em.h>
|
||||
|
@ -189,7 +190,7 @@ sysexit_from_sys_call:
|
|||
movl %ebx,%edx /* 3rd arg: 1st syscall arg */
|
||||
movl %eax,%esi /* 2nd arg: syscall number */
|
||||
movl $AUDIT_ARCH_I386,%edi /* 1st arg: audit arch */
|
||||
call audit_syscall_entry
|
||||
call __audit_syscall_entry
|
||||
movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall number */
|
||||
cmpq $(IA32_NR_syscalls-1),%rax
|
||||
ja ia32_badsys
|
||||
|
@ -206,12 +207,13 @@ sysexit_from_sys_call:
|
|||
TRACE_IRQS_ON
|
||||
sti
|
||||
movl %eax,%esi /* second arg, syscall return value */
|
||||
cmpl $0,%eax /* is it < 0? */
|
||||
setl %al /* 1 if so, 0 if not */
|
||||
cmpl $-MAX_ERRNO,%eax /* is it an error ? */
|
||||
jbe 1f
|
||||
movslq %eax, %rsi /* if error sign extend to 64 bits */
|
||||
1: setbe %al /* 1 if error, 0 if not */
|
||||
movzbl %al,%edi /* zero-extend that into %edi */
|
||||
inc %edi /* first arg, 0->1(AUDITSC_SUCCESS), 1->2(AUDITSC_FAILURE) */
|
||||
call audit_syscall_exit
|
||||
movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall return value */
|
||||
call __audit_syscall_exit
|
||||
movq RAX-ARGOFFSET(%rsp),%rax /* reload syscall return value */
|
||||
movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi
|
||||
cli
|
||||
TRACE_IRQS_OFF
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/err.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/irqflags.h>
|
||||
#include <asm/errno.h>
|
||||
|
@ -453,7 +454,7 @@ sysenter_audit:
|
|||
movl %ebx,%ecx /* 3rd arg: 1st syscall arg */
|
||||
movl %eax,%edx /* 2nd arg: syscall number */
|
||||
movl $AUDIT_ARCH_I386,%eax /* 1st arg: audit arch */
|
||||
call audit_syscall_entry
|
||||
call __audit_syscall_entry
|
||||
pushl_cfi %ebx
|
||||
movl PT_EAX(%esp),%eax /* reload syscall number */
|
||||
jmp sysenter_do_call
|
||||
|
@ -464,11 +465,10 @@ sysexit_audit:
|
|||
TRACE_IRQS_ON
|
||||
ENABLE_INTERRUPTS(CLBR_ANY)
|
||||
movl %eax,%edx /* second arg, syscall return value */
|
||||
cmpl $0,%eax /* is it < 0? */
|
||||
setl %al /* 1 if so, 0 if not */
|
||||
cmpl $-MAX_ERRNO,%eax /* is it an error ? */
|
||||
setbe %al /* 1 if so, 0 if not */
|
||||
movzbl %al,%eax /* zero-extend that */
|
||||
inc %eax /* first arg, 0->1(AUDITSC_SUCCESS), 1->2(AUDITSC_FAILURE) */
|
||||
call audit_syscall_exit
|
||||
call __audit_syscall_exit
|
||||
DISABLE_INTERRUPTS(CLBR_ANY)
|
||||
TRACE_IRQS_OFF
|
||||
movl TI_flags(%ebp), %ecx
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include <asm/paravirt.h>
|
||||
#include <asm/ftrace.h>
|
||||
#include <asm/percpu.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
|
||||
#include <linux/elf-em.h>
|
||||
|
@ -548,7 +549,7 @@ badsys:
|
|||
#ifdef CONFIG_AUDITSYSCALL
|
||||
/*
|
||||
* Fast path for syscall audit without full syscall trace.
|
||||
* We just call audit_syscall_entry() directly, and then
|
||||
* We just call __audit_syscall_entry() directly, and then
|
||||
* jump back to the normal fast path.
|
||||
*/
|
||||
auditsys:
|
||||
|
@ -558,22 +559,21 @@ auditsys:
|
|||
movq %rdi,%rdx /* 3rd arg: 1st syscall arg */
|
||||
movq %rax,%rsi /* 2nd arg: syscall number */
|
||||
movl $AUDIT_ARCH_X86_64,%edi /* 1st arg: audit arch */
|
||||
call audit_syscall_entry
|
||||
call __audit_syscall_entry
|
||||
LOAD_ARGS 0 /* reload call-clobbered registers */
|
||||
jmp system_call_fastpath
|
||||
|
||||
/*
|
||||
* Return fast path for syscall audit. Call audit_syscall_exit()
|
||||
* Return fast path for syscall audit. Call __audit_syscall_exit()
|
||||
* directly and then jump back to the fast path with TIF_SYSCALL_AUDIT
|
||||
* masked off.
|
||||
*/
|
||||
sysret_audit:
|
||||
movq RAX-ARGOFFSET(%rsp),%rsi /* second arg, syscall return value */
|
||||
cmpq $0,%rsi /* is it < 0? */
|
||||
setl %al /* 1 if so, 0 if not */
|
||||
cmpq $-MAX_ERRNO,%rsi /* is it < -MAX_ERRNO? */
|
||||
setbe %al /* 1 if so, 0 if not */
|
||||
movzbl %al,%edi /* zero-extend that into %edi */
|
||||
inc %edi /* first arg, 0->1(AUDITSC_SUCCESS), 1->2(AUDITSC_FAILURE) */
|
||||
call audit_syscall_exit
|
||||
call __audit_syscall_exit
|
||||
movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi
|
||||
jmp sysret_check
|
||||
#endif /* CONFIG_AUDITSYSCALL */
|
||||
|
|
|
@ -1392,20 +1392,18 @@ long syscall_trace_enter(struct pt_regs *regs)
|
|||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
trace_sys_enter(regs, regs->orig_ax);
|
||||
|
||||
if (unlikely(current->audit_context)) {
|
||||
if (IS_IA32)
|
||||
audit_syscall_entry(AUDIT_ARCH_I386,
|
||||
regs->orig_ax,
|
||||
regs->bx, regs->cx,
|
||||
regs->dx, regs->si);
|
||||
if (IS_IA32)
|
||||
audit_syscall_entry(AUDIT_ARCH_I386,
|
||||
regs->orig_ax,
|
||||
regs->bx, regs->cx,
|
||||
regs->dx, regs->si);
|
||||
#ifdef CONFIG_X86_64
|
||||
else
|
||||
audit_syscall_entry(AUDIT_ARCH_X86_64,
|
||||
regs->orig_ax,
|
||||
regs->di, regs->si,
|
||||
regs->dx, regs->r10);
|
||||
else
|
||||
audit_syscall_entry(AUDIT_ARCH_X86_64,
|
||||
regs->orig_ax,
|
||||
regs->di, regs->si,
|
||||
regs->dx, regs->r10);
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret ?: regs->orig_ax;
|
||||
}
|
||||
|
@ -1414,8 +1412,7 @@ void syscall_trace_leave(struct pt_regs *regs)
|
|||
{
|
||||
bool step;
|
||||
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
|
||||
audit_syscall_exit(regs);
|
||||
|
||||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
trace_sys_exit(regs, regs->ax);
|
||||
|
|
|
@ -335,9 +335,9 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
|
|||
if (info->flags & VM86_SCREEN_BITMAP)
|
||||
mark_screen_rdonly(tsk->mm);
|
||||
|
||||
/*call audit_syscall_exit since we do not exit via the normal paths */
|
||||
/*call __audit_syscall_exit since we do not exit via the normal paths */
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_exit(AUDITSC_RESULT(0), 0);
|
||||
__audit_syscall_exit(1, 0);
|
||||
|
||||
__asm__ __volatile__(
|
||||
"movl %0,%%esp\n\t"
|
||||
|
|
|
@ -3,3 +3,8 @@
|
|||
#else
|
||||
#include "ptrace_64.h"
|
||||
#endif
|
||||
|
||||
static inline long regs_return_value(struct uml_pt_regs *regs)
|
||||
{
|
||||
return UPT_SYSCALL_RET(regs);
|
||||
}
|
||||
|
|
|
@ -334,8 +334,7 @@ void do_syscall_trace_enter(struct pt_regs *regs)
|
|||
do_syscall_trace();
|
||||
|
||||
#if 0
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_entry(current, AUDIT_ARCH_XTENSA..);
|
||||
audit_syscall_entry(current, AUDIT_ARCH_XTENSA..);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
24
fs/namei.c
24
fs/namei.c
|
@ -140,21 +140,19 @@ static int do_getname(const char __user *filename, char *page)
|
|||
|
||||
static char *getname_flags(const char __user *filename, int flags, int *empty)
|
||||
{
|
||||
char *tmp, *result;
|
||||
char *result = __getname();
|
||||
int retval;
|
||||
|
||||
result = ERR_PTR(-ENOMEM);
|
||||
tmp = __getname();
|
||||
if (tmp) {
|
||||
int retval = do_getname(filename, tmp);
|
||||
if (!result)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
result = tmp;
|
||||
if (retval < 0) {
|
||||
if (retval == -ENOENT && empty)
|
||||
*empty = 1;
|
||||
if (retval != -ENOENT || !(flags & LOOKUP_EMPTY)) {
|
||||
__putname(tmp);
|
||||
result = ERR_PTR(retval);
|
||||
}
|
||||
retval = do_getname(filename, result);
|
||||
if (retval < 0) {
|
||||
if (retval == -ENOENT && empty)
|
||||
*empty = 1;
|
||||
if (retval != -ENOENT || !(flags & LOOKUP_EMPTY)) {
|
||||
__putname(result);
|
||||
return ERR_PTR(retval);
|
||||
}
|
||||
}
|
||||
audit_getname(result);
|
||||
|
|
|
@ -1132,9 +1132,6 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
|
|||
ssize_t length;
|
||||
uid_t loginuid;
|
||||
|
||||
if (!capable(CAP_AUDIT_CONTROL))
|
||||
return -EPERM;
|
||||
|
||||
rcu_read_lock();
|
||||
if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) {
|
||||
rcu_read_unlock();
|
||||
|
@ -1163,7 +1160,7 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
|
|||
goto out_free_page;
|
||||
|
||||
}
|
||||
length = audit_set_loginuid(current, loginuid);
|
||||
length = audit_set_loginuid(loginuid);
|
||||
if (likely(length == 0))
|
||||
length = count;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
#include <linux/elf-em.h>
|
||||
#include <linux/ptrace.h>
|
||||
|
||||
/* The netlink messages for the audit system is divided into blocks:
|
||||
* 1000 - 1099 are for commanding the audit system
|
||||
|
@ -181,6 +182,40 @@
|
|||
* AUDIT_UNUSED_BITS is updated if need be. */
|
||||
#define AUDIT_UNUSED_BITS 0x07FFFC00
|
||||
|
||||
/* AUDIT_FIELD_COMPARE rule list */
|
||||
#define AUDIT_COMPARE_UID_TO_OBJ_UID 1
|
||||
#define AUDIT_COMPARE_GID_TO_OBJ_GID 2
|
||||
#define AUDIT_COMPARE_EUID_TO_OBJ_UID 3
|
||||
#define AUDIT_COMPARE_EGID_TO_OBJ_GID 4
|
||||
#define AUDIT_COMPARE_AUID_TO_OBJ_UID 5
|
||||
#define AUDIT_COMPARE_SUID_TO_OBJ_UID 6
|
||||
#define AUDIT_COMPARE_SGID_TO_OBJ_GID 7
|
||||
#define AUDIT_COMPARE_FSUID_TO_OBJ_UID 8
|
||||
#define AUDIT_COMPARE_FSGID_TO_OBJ_GID 9
|
||||
|
||||
#define AUDIT_COMPARE_UID_TO_AUID 10
|
||||
#define AUDIT_COMPARE_UID_TO_EUID 11
|
||||
#define AUDIT_COMPARE_UID_TO_FSUID 12
|
||||
#define AUDIT_COMPARE_UID_TO_SUID 13
|
||||
|
||||
#define AUDIT_COMPARE_AUID_TO_FSUID 14
|
||||
#define AUDIT_COMPARE_AUID_TO_SUID 15
|
||||
#define AUDIT_COMPARE_AUID_TO_EUID 16
|
||||
|
||||
#define AUDIT_COMPARE_EUID_TO_SUID 17
|
||||
#define AUDIT_COMPARE_EUID_TO_FSUID 18
|
||||
|
||||
#define AUDIT_COMPARE_SUID_TO_FSUID 19
|
||||
|
||||
#define AUDIT_COMPARE_GID_TO_EGID 20
|
||||
#define AUDIT_COMPARE_GID_TO_FSGID 21
|
||||
#define AUDIT_COMPARE_GID_TO_SGID 22
|
||||
|
||||
#define AUDIT_COMPARE_EGID_TO_FSGID 23
|
||||
#define AUDIT_COMPARE_EGID_TO_SGID 24
|
||||
#define AUDIT_COMPARE_SGID_TO_FSGID 25
|
||||
|
||||
#define AUDIT_MAX_FIELD_COMPARE AUDIT_COMPARE_SGID_TO_FSGID
|
||||
|
||||
/* Rule fields */
|
||||
/* These are useful when checking the
|
||||
|
@ -222,6 +257,9 @@
|
|||
#define AUDIT_PERM 106
|
||||
#define AUDIT_DIR 107
|
||||
#define AUDIT_FILETYPE 108
|
||||
#define AUDIT_OBJ_UID 109
|
||||
#define AUDIT_OBJ_GID 110
|
||||
#define AUDIT_FIELD_COMPARE 111
|
||||
|
||||
#define AUDIT_ARG0 200
|
||||
#define AUDIT_ARG1 (AUDIT_ARG0+1)
|
||||
|
@ -408,28 +446,24 @@ struct audit_field {
|
|||
void *lsm_rule;
|
||||
};
|
||||
|
||||
#define AUDITSC_INVALID 0
|
||||
#define AUDITSC_SUCCESS 1
|
||||
#define AUDITSC_FAILURE 2
|
||||
#define AUDITSC_RESULT(x) ( ((long)(x))<0?AUDITSC_FAILURE:AUDITSC_SUCCESS )
|
||||
extern int __init audit_register_class(int class, unsigned *list);
|
||||
extern int audit_classify_syscall(int abi, unsigned syscall);
|
||||
extern int audit_classify_arch(int arch);
|
||||
#ifdef CONFIG_AUDITSYSCALL
|
||||
/* These are defined in auditsc.c */
|
||||
/* Public API */
|
||||
extern void audit_finish_fork(struct task_struct *child);
|
||||
extern int audit_alloc(struct task_struct *task);
|
||||
extern void audit_free(struct task_struct *task);
|
||||
extern void audit_syscall_entry(int arch,
|
||||
int major, unsigned long a0, unsigned long a1,
|
||||
unsigned long a2, unsigned long a3);
|
||||
extern void audit_syscall_exit(int failed, long return_code);
|
||||
extern void __audit_free(struct task_struct *task);
|
||||
extern void __audit_syscall_entry(int arch,
|
||||
int major, unsigned long a0, unsigned long a1,
|
||||
unsigned long a2, unsigned long a3);
|
||||
extern void __audit_syscall_exit(int ret_success, long ret_value);
|
||||
extern void __audit_getname(const char *name);
|
||||
extern void audit_putname(const char *name);
|
||||
extern void __audit_inode(const char *name, const struct dentry *dentry);
|
||||
extern void __audit_inode_child(const struct dentry *dentry,
|
||||
const struct inode *parent);
|
||||
extern void __audit_seccomp(unsigned long syscall);
|
||||
extern void __audit_ptrace(struct task_struct *t);
|
||||
|
||||
static inline int audit_dummy_context(void)
|
||||
|
@ -437,6 +471,27 @@ static inline int audit_dummy_context(void)
|
|||
void *p = current->audit_context;
|
||||
return !p || *(int *)p;
|
||||
}
|
||||
static inline void audit_free(struct task_struct *task)
|
||||
{
|
||||
if (unlikely(task->audit_context))
|
||||
__audit_free(task);
|
||||
}
|
||||
static inline void audit_syscall_entry(int arch, int major, unsigned long a0,
|
||||
unsigned long a1, unsigned long a2,
|
||||
unsigned long a3)
|
||||
{
|
||||
if (unlikely(!audit_dummy_context()))
|
||||
__audit_syscall_entry(arch, major, a0, a1, a2, a3);
|
||||
}
|
||||
static inline void audit_syscall_exit(void *pt_regs)
|
||||
{
|
||||
if (unlikely(current->audit_context)) {
|
||||
int success = is_syscall_success(pt_regs);
|
||||
int return_code = regs_return_value(pt_regs);
|
||||
|
||||
__audit_syscall_exit(success, return_code);
|
||||
}
|
||||
}
|
||||
static inline void audit_getname(const char *name)
|
||||
{
|
||||
if (unlikely(!audit_dummy_context()))
|
||||
|
@ -453,6 +508,12 @@ static inline void audit_inode_child(const struct dentry *dentry,
|
|||
}
|
||||
void audit_core_dumps(long signr);
|
||||
|
||||
static inline void audit_seccomp(unsigned long syscall)
|
||||
{
|
||||
if (unlikely(!audit_dummy_context()))
|
||||
__audit_seccomp(syscall);
|
||||
}
|
||||
|
||||
static inline void audit_ptrace(struct task_struct *t)
|
||||
{
|
||||
if (unlikely(!audit_dummy_context()))
|
||||
|
@ -463,17 +524,16 @@ static inline void audit_ptrace(struct task_struct *t)
|
|||
extern unsigned int audit_serial(void);
|
||||
extern int auditsc_get_stamp(struct audit_context *ctx,
|
||||
struct timespec *t, unsigned int *serial);
|
||||
extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
|
||||
extern int audit_set_loginuid(uid_t loginuid);
|
||||
#define audit_get_loginuid(t) ((t)->loginuid)
|
||||
#define audit_get_sessionid(t) ((t)->sessionid)
|
||||
extern void audit_log_task_context(struct audit_buffer *ab);
|
||||
extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp);
|
||||
extern void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mode);
|
||||
extern int audit_bprm(struct linux_binprm *bprm);
|
||||
extern void audit_socketcall(int nargs, unsigned long *args);
|
||||
extern int audit_sockaddr(int len, void *addr);
|
||||
extern int __audit_bprm(struct linux_binprm *bprm);
|
||||
extern void __audit_socketcall(int nargs, unsigned long *args);
|
||||
extern int __audit_sockaddr(int len, void *addr);
|
||||
extern void __audit_fd_pair(int fd1, int fd2);
|
||||
extern int audit_set_macxattr(const char *name);
|
||||
extern void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr);
|
||||
extern void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout);
|
||||
extern void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification);
|
||||
|
@ -499,6 +559,23 @@ static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid
|
|||
if (unlikely(!audit_dummy_context()))
|
||||
__audit_ipc_set_perm(qbytes, uid, gid, mode);
|
||||
}
|
||||
static inline int audit_bprm(struct linux_binprm *bprm)
|
||||
{
|
||||
if (unlikely(!audit_dummy_context()))
|
||||
return __audit_bprm(bprm);
|
||||
return 0;
|
||||
}
|
||||
static inline void audit_socketcall(int nargs, unsigned long *args)
|
||||
{
|
||||
if (unlikely(!audit_dummy_context()))
|
||||
__audit_socketcall(nargs, args);
|
||||
}
|
||||
static inline int audit_sockaddr(int len, void *addr)
|
||||
{
|
||||
if (unlikely(!audit_dummy_context()))
|
||||
return __audit_sockaddr(len, addr);
|
||||
return 0;
|
||||
}
|
||||
static inline void audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
|
||||
{
|
||||
if (unlikely(!audit_dummy_context()))
|
||||
|
@ -544,12 +621,11 @@ static inline void audit_mmap_fd(int fd, int flags)
|
|||
|
||||
extern int audit_n_rules;
|
||||
extern int audit_signals;
|
||||
#else
|
||||
#define audit_finish_fork(t)
|
||||
#else /* CONFIG_AUDITSYSCALL */
|
||||
#define audit_alloc(t) ({ 0; })
|
||||
#define audit_free(t) do { ; } while (0)
|
||||
#define audit_syscall_entry(ta,a,b,c,d,e) do { ; } while (0)
|
||||
#define audit_syscall_exit(f,r) do { ; } while (0)
|
||||
#define audit_syscall_exit(r) do { ; } while (0)
|
||||
#define audit_dummy_context() 1
|
||||
#define audit_getname(n) do { ; } while (0)
|
||||
#define audit_putname(n) do { ; } while (0)
|
||||
|
@ -558,6 +634,7 @@ extern int audit_signals;
|
|||
#define audit_inode(n,d) do { (void)(d); } while (0)
|
||||
#define audit_inode_child(i,p) do { ; } while (0)
|
||||
#define audit_core_dumps(i) do { ; } while (0)
|
||||
#define audit_seccomp(i) do { ; } while (0)
|
||||
#define auditsc_get_stamp(c,t,s) (0)
|
||||
#define audit_get_loginuid(t) (-1)
|
||||
#define audit_get_sessionid(t) (-1)
|
||||
|
@ -568,7 +645,6 @@ extern int audit_signals;
|
|||
#define audit_socketcall(n,a) ((void)0)
|
||||
#define audit_fd_pair(n,a) ((void)0)
|
||||
#define audit_sockaddr(len, addr) ({ 0; })
|
||||
#define audit_set_macxattr(n) do { ; } while (0)
|
||||
#define audit_mq_open(o,m,a) ((void)0)
|
||||
#define audit_mq_sendrecv(d,l,p,t) ((void)0)
|
||||
#define audit_mq_notify(d,n) ((void)0)
|
||||
|
@ -579,7 +655,7 @@ extern int audit_signals;
|
|||
#define audit_ptrace(t) ((void)0)
|
||||
#define audit_n_rules 0
|
||||
#define audit_signals 0
|
||||
#endif
|
||||
#endif /* CONFIG_AUDITSYSCALL */
|
||||
|
||||
#ifdef CONFIG_AUDIT
|
||||
/* These are defined in audit.c */
|
||||
|
|
|
@ -112,6 +112,7 @@
|
|||
|
||||
#include <linux/compiler.h> /* For unlikely. */
|
||||
#include <linux/sched.h> /* For struct task_struct. */
|
||||
#include <linux/err.h> /* for IS_ERR_VALUE */
|
||||
|
||||
|
||||
extern long arch_ptrace(struct task_struct *child, long request,
|
||||
|
@ -266,6 +267,15 @@ static inline void ptrace_release_task(struct task_struct *task)
|
|||
#define force_successful_syscall_return() do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifndef is_syscall_success
|
||||
/*
|
||||
* On most systems we can tell if a syscall is a success based on if the retval
|
||||
* is an error value. On some systems like ia64 and powerpc they have different
|
||||
* indicators of success/failure and must define their own.
|
||||
*/
|
||||
#define is_syscall_success(regs) (!IS_ERR_VALUE((unsigned long)(regs_return_value(regs))))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* <asm/ptrace.h> should define the following things inside #ifdef __KERNEL__.
|
||||
*
|
||||
|
|
16
init/Kconfig
16
init/Kconfig
|
@ -355,7 +355,7 @@ config AUDIT
|
|||
|
||||
config AUDITSYSCALL
|
||||
bool "Enable system-call auditing support"
|
||||
depends on AUDIT && (X86 || PPC || S390 || IA64 || UML || SPARC64 || SUPERH)
|
||||
depends on AUDIT && (X86 || PPC || S390 || IA64 || UML || SPARC64 || SUPERH || ARM)
|
||||
default y if SECURITY_SELINUX
|
||||
help
|
||||
Enable low-overhead system-call auditing infrastructure that
|
||||
|
@ -372,6 +372,20 @@ config AUDIT_TREE
|
|||
depends on AUDITSYSCALL
|
||||
select FSNOTIFY
|
||||
|
||||
config AUDIT_LOGINUID_IMMUTABLE
|
||||
bool "Make audit loginuid immutable"
|
||||
depends on AUDIT
|
||||
help
|
||||
The config option toggles if a task setting its loginuid requires
|
||||
CAP_SYS_AUDITCONTROL or if that task should require no special permissions
|
||||
but should instead only allow setting its loginuid if it was never
|
||||
previously set. On systems which use systemd or a similar central
|
||||
process to restart login services this should be set to true. On older
|
||||
systems in which an admin would typically have to directly stop and
|
||||
start processes this should be set to false. Setting this to true allows
|
||||
one to drop potentially dangerous capabilites from the login tasks,
|
||||
but may not be backwards compatible with older init systems.
|
||||
|
||||
source "kernel/irq/Kconfig"
|
||||
|
||||
menu "RCU Subsystem"
|
||||
|
|
|
@ -631,7 +631,7 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type,
|
|||
}
|
||||
|
||||
*ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
|
||||
audit_log_format(*ab, "user pid=%d uid=%u auid=%u ses=%u",
|
||||
audit_log_format(*ab, "pid=%d uid=%u auid=%u ses=%u",
|
||||
pid, uid, auid, ses);
|
||||
if (sid) {
|
||||
rc = security_secid_to_secctx(sid, &ctx, &len);
|
||||
|
@ -1423,7 +1423,7 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
|
|||
char *p, *pathname;
|
||||
|
||||
if (prefix)
|
||||
audit_log_format(ab, " %s", prefix);
|
||||
audit_log_format(ab, "%s", prefix);
|
||||
|
||||
/* We will allow 11 spaces for ' (deleted)' to be appended */
|
||||
pathname = kmalloc(PATH_MAX+11, ab->gfp_mask);
|
||||
|
|
|
@ -36,12 +36,8 @@ enum audit_state {
|
|||
AUDIT_DISABLED, /* Do not create per-task audit_context.
|
||||
* No syscall-specific audit records can
|
||||
* be generated. */
|
||||
AUDIT_SETUP_CONTEXT, /* Create the per-task audit_context,
|
||||
* but don't necessarily fill it in at
|
||||
* syscall entry time (i.e., filter
|
||||
* instead). */
|
||||
AUDIT_BUILD_CONTEXT, /* Create the per-task audit_context,
|
||||
* and always fill it in at syscall
|
||||
* and fill it in at syscall
|
||||
* entry time. This makes a full
|
||||
* syscall record available if some
|
||||
* other part of the kernel decides it
|
||||
|
|
|
@ -235,13 +235,15 @@ static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule)
|
|||
switch(listnr) {
|
||||
default:
|
||||
goto exit_err;
|
||||
case AUDIT_FILTER_USER:
|
||||
case AUDIT_FILTER_TYPE:
|
||||
#ifdef CONFIG_AUDITSYSCALL
|
||||
case AUDIT_FILTER_ENTRY:
|
||||
if (rule->action == AUDIT_ALWAYS)
|
||||
goto exit_err;
|
||||
case AUDIT_FILTER_EXIT:
|
||||
case AUDIT_FILTER_TASK:
|
||||
#endif
|
||||
case AUDIT_FILTER_USER:
|
||||
case AUDIT_FILTER_TYPE:
|
||||
;
|
||||
}
|
||||
if (unlikely(rule->action == AUDIT_POSSIBLE)) {
|
||||
|
@ -385,7 +387,7 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
|
|||
goto exit_free;
|
||||
break;
|
||||
case AUDIT_FILETYPE:
|
||||
if ((f->val & ~S_IFMT) > S_IFMT)
|
||||
if (f->val & ~S_IFMT)
|
||||
goto exit_free;
|
||||
break;
|
||||
case AUDIT_INODE:
|
||||
|
@ -459,6 +461,8 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
|
|||
case AUDIT_ARG1:
|
||||
case AUDIT_ARG2:
|
||||
case AUDIT_ARG3:
|
||||
case AUDIT_OBJ_UID:
|
||||
case AUDIT_OBJ_GID:
|
||||
break;
|
||||
case AUDIT_ARCH:
|
||||
entry->rule.arch_f = f;
|
||||
|
@ -522,7 +526,6 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
|
|||
goto exit_free;
|
||||
break;
|
||||
case AUDIT_FILTERKEY:
|
||||
err = -EINVAL;
|
||||
if (entry->rule.filterkey || f->val > AUDIT_MAX_KEY_LEN)
|
||||
goto exit_free;
|
||||
str = audit_unpack_string(&bufp, &remain, f->val);
|
||||
|
@ -536,7 +539,11 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
|
|||
goto exit_free;
|
||||
break;
|
||||
case AUDIT_FILETYPE:
|
||||
if ((f->val & ~S_IFMT) > S_IFMT)
|
||||
if (f->val & ~S_IFMT)
|
||||
goto exit_free;
|
||||
break;
|
||||
case AUDIT_FIELD_COMPARE:
|
||||
if (f->val > AUDIT_MAX_FIELD_COMPARE)
|
||||
goto exit_free;
|
||||
break;
|
||||
default:
|
||||
|
|
735
kernel/auditsc.c
735
kernel/auditsc.c
File diff suppressed because it is too large
Load diff
|
@ -964,8 +964,7 @@ void do_exit(long code)
|
|||
acct_collect(code, group_dead);
|
||||
if (group_dead)
|
||||
tty_audit_exit();
|
||||
if (unlikely(tsk->audit_context))
|
||||
audit_free(tsk);
|
||||
audit_free(tsk);
|
||||
|
||||
tsk->exit_code = code;
|
||||
taskstats_exit(tsk, group_dead);
|
||||
|
|
|
@ -1527,8 +1527,6 @@ long do_fork(unsigned long clone_flags,
|
|||
init_completion(&vfork);
|
||||
}
|
||||
|
||||
audit_finish_fork(p);
|
||||
|
||||
/*
|
||||
* We set PF_STARTING at creation in case tracing wants to
|
||||
* use this to distinguish a fully live task from one that
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* This defines a simple but solid secure-computing mode.
|
||||
*/
|
||||
|
||||
#include <linux/audit.h>
|
||||
#include <linux/seccomp.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/compat.h>
|
||||
|
@ -54,6 +55,7 @@ void __secure_computing(int this_syscall)
|
|||
#ifdef SECCOMP_DEBUG
|
||||
dump_stack();
|
||||
#endif
|
||||
audit_seccomp(this_syscall);
|
||||
do_exit(SIGKILL);
|
||||
}
|
||||
|
||||
|
|
|
@ -56,9 +56,11 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
|
|||
audit_log_format(ab, " name=");
|
||||
audit_log_untrustedstring(ab, fname);
|
||||
}
|
||||
if (inode)
|
||||
audit_log_format(ab, " dev=%s ino=%lu",
|
||||
inode->i_sb->s_id, inode->i_ino);
|
||||
if (inode) {
|
||||
audit_log_format(ab, " dev=");
|
||||
audit_log_untrustedstring(ab, inode->i_sb->s_id);
|
||||
audit_log_format(ab, " ino=%lu", inode->i_ino);
|
||||
}
|
||||
audit_log_format(ab, " res=%d", !result ? 0 : 1);
|
||||
audit_log_end(ab);
|
||||
}
|
||||
|
|
|
@ -232,13 +232,14 @@ static void dump_common_audit_data(struct audit_buffer *ab,
|
|||
case LSM_AUDIT_DATA_PATH: {
|
||||
struct inode *inode;
|
||||
|
||||
audit_log_d_path(ab, "path=", &a->u.path);
|
||||
audit_log_d_path(ab, " path=", &a->u.path);
|
||||
|
||||
inode = a->u.path.dentry->d_inode;
|
||||
if (inode)
|
||||
audit_log_format(ab, " dev=%s ino=%lu",
|
||||
inode->i_sb->s_id,
|
||||
inode->i_ino);
|
||||
if (inode) {
|
||||
audit_log_format(ab, " dev=");
|
||||
audit_log_untrustedstring(ab, inode->i_sb->s_id);
|
||||
audit_log_format(ab, " ino=%lu", inode->i_ino);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LSM_AUDIT_DATA_DENTRY: {
|
||||
|
@ -248,10 +249,11 @@ static void dump_common_audit_data(struct audit_buffer *ab,
|
|||
audit_log_untrustedstring(ab, a->u.dentry->d_name.name);
|
||||
|
||||
inode = a->u.dentry->d_inode;
|
||||
if (inode)
|
||||
audit_log_format(ab, " dev=%s ino=%lu",
|
||||
inode->i_sb->s_id,
|
||||
inode->i_ino);
|
||||
if (inode) {
|
||||
audit_log_format(ab, " dev=");
|
||||
audit_log_untrustedstring(ab, inode->i_sb->s_id);
|
||||
audit_log_format(ab, " ino=%lu", inode->i_ino);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LSM_AUDIT_DATA_INODE: {
|
||||
|
@ -266,8 +268,9 @@ static void dump_common_audit_data(struct audit_buffer *ab,
|
|||
dentry->d_name.name);
|
||||
dput(dentry);
|
||||
}
|
||||
audit_log_format(ab, " dev=%s ino=%lu", inode->i_sb->s_id,
|
||||
inode->i_ino);
|
||||
audit_log_format(ab, " dev=");
|
||||
audit_log_untrustedstring(ab, inode->i_sb->s_id);
|
||||
audit_log_format(ab, " ino=%lu", inode->i_ino);
|
||||
break;
|
||||
}
|
||||
case LSM_AUDIT_DATA_TASK:
|
||||
|
@ -315,7 +318,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
|
|||
.dentry = u->dentry,
|
||||
.mnt = u->mnt
|
||||
};
|
||||
audit_log_d_path(ab, "path=", &path);
|
||||
audit_log_d_path(ab, " path=", &path);
|
||||
break;
|
||||
}
|
||||
if (!u->addr)
|
||||
|
|
Loading…
Reference in a new issue