Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
19fa95e9
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
19fa95e9
编写于
6月 18, 2005
作者:
L
Linus Torvalds
浏览文件
操作
浏览文件
下载
差异文件
Merge master.kernel.org:/pub/scm/linux/kernel/git/dwmw2/audit-2.6
上级
ba483d57
0107b3cf
变更
16
展开全部
隐藏空白更改
内联
并排
Showing
16 changed file
with
674 addition
and
433 deletion
+674
-433
arch/ppc/Kconfig
arch/ppc/Kconfig
+17
-0
arch/ppc/kernel/entry.S
arch/ppc/kernel/entry.S
+9
-7
arch/ppc/kernel/ppc_ksyms.c
arch/ppc/kernel/ppc_ksyms.c
+0
-2
arch/ppc/kernel/ptrace.c
arch/ppc/kernel/ptrace.c
+36
-4
include/asm-ppc/seccomp.h
include/asm-ppc/seccomp.h
+10
-0
include/asm-ppc/thread_info.h
include/asm-ppc/thread_info.h
+7
-0
include/linux/audit.h
include/linux/audit.h
+70
-24
init/Kconfig
init/Kconfig
+2
-1
kernel/audit.c
kernel/audit.c
+294
-293
kernel/auditsc.c
kernel/auditsc.c
+184
-75
kernel/signal.c
kernel/signal.c
+6
-1
net/socket.c
net/socket.c
+7
-2
security/selinux/avc.c
security/selinux/avc.c
+21
-19
security/selinux/hooks.c
security/selinux/hooks.c
+1
-1
security/selinux/nlmsgtab.c
security/selinux/nlmsgtab.c
+8
-2
security/selinux/ss/services.c
security/selinux/ss/services.c
+2
-2
未找到文件。
arch/ppc/Kconfig
浏览文件 @
19fa95e9
...
@@ -1083,6 +1083,23 @@ source "drivers/zorro/Kconfig"
...
@@ -1083,6 +1083,23 @@ source "drivers/zorro/Kconfig"
source kernel/power/Kconfig
source kernel/power/Kconfig
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
depends on PROC_FS
default y
help
This kernel feature is useful for number crunching applications
that may need to compute untrusted bytecode during their
execution. By using pipes or other transports made available to
the process as file descriptors supporting the read/write
syscalls, it's possible to isolate those applications in
their own address space using seccomp. Once seccomp is
enabled via /proc/<pid>/seccomp, it cannot be disabled
and the task is only allowed to execute a few safe syscalls
defined by each seccomp mode.
If unsure, say Y. Only embedded should say N here.
endmenu
endmenu
config ISA_DMA_API
config ISA_DMA_API
...
...
arch/ppc/kernel/entry.S
浏览文件 @
19fa95e9
...
@@ -202,7 +202,7 @@ _GLOBAL(DoSyscall)
...
@@ -202,7 +202,7 @@ _GLOBAL(DoSyscall)
rlwinm
r11
,
r11
,
0
,
~
_TIFL_FORCE_NOERROR
rlwinm
r11
,
r11
,
0
,
~
_TIFL_FORCE_NOERROR
stw
r11
,
TI_LOCAL_FLAGS
(
r10
)
stw
r11
,
TI_LOCAL_FLAGS
(
r10
)
lwz
r11
,
TI_FLAGS
(
r10
)
lwz
r11
,
TI_FLAGS
(
r10
)
andi
.
r11
,
r11
,
_TIF_SYSCALL_T
RACE
andi
.
r11
,
r11
,
_TIF_SYSCALL_T
_OR_A
bne
-
syscall_dotrace
bne
-
syscall_dotrace
syscall_dotrace_cont
:
syscall_dotrace_cont
:
cmplwi
0
,
r0
,
NR_syscalls
cmplwi
0
,
r0
,
NR_syscalls
...
@@ -237,7 +237,7 @@ ret_from_syscall:
...
@@ -237,7 +237,7 @@ ret_from_syscall:
SYNC
SYNC
MTMSRD
(
r10
)
MTMSRD
(
r10
)
lwz
r9
,
TI_FLAGS
(
r12
)
lwz
r9
,
TI_FLAGS
(
r12
)
andi
.
r0
,
r9
,(
_TIF_SYSCALL_T
RACE
|_TIF_SIGPENDING|_TIF_NEED_RESCHED
)
andi
.
r0
,
r9
,(
_TIF_SYSCALL_T
_OR_A
|_TIF_SIGPENDING|_TIF_NEED_RESCHED
)
bne
-
syscall_exit_work
bne
-
syscall_exit_work
syscall_exit_cont
:
syscall_exit_cont
:
#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
...
@@ -277,7 +277,8 @@ syscall_dotrace:
...
@@ -277,7 +277,8 @@ syscall_dotrace:
SAVE_NVGPRS
(
r1
)
SAVE_NVGPRS
(
r1
)
li
r0
,
0xc00
li
r0
,
0xc00
stw
r0
,
TRAP
(
r1
)
stw
r0
,
TRAP
(
r1
)
bl
do_syscall_trace
addi
r3
,
r1
,
STACK_FRAME_OVERHEAD
bl
do_syscall_trace_enter
lwz
r0
,
GPR0
(
r1
)
/*
Restore
original
registers
*/
lwz
r0
,
GPR0
(
r1
)
/*
Restore
original
registers
*/
lwz
r3
,
GPR3
(
r1
)
lwz
r3
,
GPR3
(
r1
)
lwz
r4
,
GPR4
(
r1
)
lwz
r4
,
GPR4
(
r1
)
...
@@ -291,7 +292,7 @@ syscall_dotrace:
...
@@ -291,7 +292,7 @@ syscall_dotrace:
syscall_exit_work
:
syscall_exit_work
:
stw
r6
,
RESULT
(
r1
)
/*
Save
result
*/
stw
r6
,
RESULT
(
r1
)
/*
Save
result
*/
stw
r3
,
GPR3
(
r1
)
/*
Update
return
value
*/
stw
r3
,
GPR3
(
r1
)
/*
Update
return
value
*/
andi
.
r0
,
r9
,
_TIF_SYSCALL_T
RACE
andi
.
r0
,
r9
,
_TIF_SYSCALL_T
_OR_A
beq
5
f
beq
5
f
ori
r10
,
r10
,
MSR_EE
ori
r10
,
r10
,
MSR_EE
SYNC
SYNC
...
@@ -303,7 +304,8 @@ syscall_exit_work:
...
@@ -303,7 +304,8 @@ syscall_exit_work:
li
r4
,
0xc00
li
r4
,
0xc00
stw
r4
,
TRAP
(
r1
)
stw
r4
,
TRAP
(
r1
)
4
:
4
:
bl
do_syscall_trace
addi
r3
,
r1
,
STACK_FRAME_OVERHEAD
bl
do_syscall_trace_leave
REST_NVGPRS
(
r1
)
REST_NVGPRS
(
r1
)
2
:
2
:
lwz
r3
,
GPR3
(
r1
)
lwz
r3
,
GPR3
(
r1
)
...
@@ -627,8 +629,8 @@ sigreturn_exit:
...
@@ -627,8 +629,8 @@ sigreturn_exit:
subi
r1
,
r3
,
STACK_FRAME_OVERHEAD
subi
r1
,
r3
,
STACK_FRAME_OVERHEAD
rlwinm
r12
,
r1
,
0
,
0
,
18
/*
current_thread_info
()
*/
rlwinm
r12
,
r1
,
0
,
0
,
18
/*
current_thread_info
()
*/
lwz
r9
,
TI_FLAGS
(
r12
)
lwz
r9
,
TI_FLAGS
(
r12
)
andi
.
r0
,
r9
,
_TIF_SYSCALL_T
RACE
andi
.
r0
,
r9
,
_TIF_SYSCALL_T
_OR_A
bnel
-
do_syscall_trace
bnel
-
do_syscall_trace
_leave
/
*
fall
through
*/
/
*
fall
through
*/
.
globl
ret_from_except_full
.
globl
ret_from_except_full
...
...
arch/ppc/kernel/ppc_ksyms.c
浏览文件 @
19fa95e9
...
@@ -55,7 +55,6 @@
...
@@ -55,7 +55,6 @@
#define EXPORT_SYMTAB_STROPS
#define EXPORT_SYMTAB_STROPS
extern
void
transfer_to_handler
(
void
);
extern
void
transfer_to_handler
(
void
);
extern
void
do_syscall_trace
(
void
);
extern
void
do_IRQ
(
struct
pt_regs
*
regs
);
extern
void
do_IRQ
(
struct
pt_regs
*
regs
);
extern
void
MachineCheckException
(
struct
pt_regs
*
regs
);
extern
void
MachineCheckException
(
struct
pt_regs
*
regs
);
extern
void
AlignmentException
(
struct
pt_regs
*
regs
);
extern
void
AlignmentException
(
struct
pt_regs
*
regs
);
...
@@ -74,7 +73,6 @@ extern unsigned long mm_ptov (unsigned long paddr);
...
@@ -74,7 +73,6 @@ extern unsigned long mm_ptov (unsigned long paddr);
EXPORT_SYMBOL
(
clear_pages
);
EXPORT_SYMBOL
(
clear_pages
);
EXPORT_SYMBOL
(
clear_user_page
);
EXPORT_SYMBOL
(
clear_user_page
);
EXPORT_SYMBOL
(
do_signal
);
EXPORT_SYMBOL
(
do_signal
);
EXPORT_SYMBOL
(
do_syscall_trace
);
EXPORT_SYMBOL
(
transfer_to_handler
);
EXPORT_SYMBOL
(
transfer_to_handler
);
EXPORT_SYMBOL
(
do_IRQ
);
EXPORT_SYMBOL
(
do_IRQ
);
EXPORT_SYMBOL
(
MachineCheckException
);
EXPORT_SYMBOL
(
MachineCheckException
);
...
...
arch/ppc/kernel/ptrace.c
浏览文件 @
19fa95e9
...
@@ -27,6 +27,9 @@
...
@@ -27,6 +27,9 @@
#include <linux/user.h>
#include <linux/user.h>
#include <linux/security.h>
#include <linux/security.h>
#include <linux/signal.h>
#include <linux/signal.h>
#include <linux/seccomp.h>
#include <linux/audit.h>
#include <linux/module.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <asm/page.h>
#include <asm/page.h>
...
@@ -455,11 +458,10 @@ int sys_ptrace(long request, long pid, long addr, long data)
...
@@ -455,11 +458,10 @@ int sys_ptrace(long request, long pid, long addr, long data)
return
ret
;
return
ret
;
}
}
void
do_syscall_trace
(
void
)
static
void
do_syscall_trace
(
void
)
{
{
if
(
!
test_thread_flag
(
TIF_SYSCALL_TRACE
)
/* the 0x80 provides a way for the tracing parent to distinguish
||
!
(
current
->
ptrace
&
PT_PTRACED
))
between a syscall stop and SIGTRAP delivery */
return
;
ptrace_notify
(
SIGTRAP
|
((
current
->
ptrace
&
PT_TRACESYSGOOD
)
ptrace_notify
(
SIGTRAP
|
((
current
->
ptrace
&
PT_TRACESYSGOOD
)
?
0x80
:
0
));
?
0x80
:
0
));
...
@@ -473,3 +475,33 @@ void do_syscall_trace(void)
...
@@ -473,3 +475,33 @@ void do_syscall_trace(void)
current
->
exit_code
=
0
;
current
->
exit_code
=
0
;
}
}
}
}
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
,
AUDIT_ARCH_PPC
,
regs
->
gpr
[
0
],
regs
->
gpr
[
3
],
regs
->
gpr
[
4
],
regs
->
gpr
[
5
],
regs
->
gpr
[
6
]);
}
void
do_syscall_trace_leave
(
struct
pt_regs
*
regs
)
{
secure_computing
(
regs
->
gpr
[
0
]);
if
(
unlikely
(
current
->
audit_context
))
audit_syscall_exit
(
current
,
(
regs
->
ccr
&
0x1000
)
?
AUDITSC_FAILURE
:
AUDITSC_SUCCESS
,
regs
->
result
);
if
((
test_thread_flag
(
TIF_SYSCALL_TRACE
))
&&
(
current
->
ptrace
&
PT_PTRACED
))
do_syscall_trace
();
}
EXPORT_SYMBOL
(
do_syscall_trace_enter
);
EXPORT_SYMBOL
(
do_syscall_trace_leave
);
include/asm-ppc/seccomp.h
0 → 100644
浏览文件 @
19fa95e9
#ifndef _ASM_SECCOMP_H
#include <linux/unistd.h>
#define __NR_seccomp_read __NR_read
#define __NR_seccomp_write __NR_write
#define __NR_seccomp_exit __NR_exit
#define __NR_seccomp_sigreturn __NR_rt_sigreturn
#endif
/* _ASM_SECCOMP_H */
include/asm-ppc/thread_info.h
浏览文件 @
19fa95e9
...
@@ -77,12 +77,19 @@ static inline struct thread_info *current_thread_info(void)
...
@@ -77,12 +77,19 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_POLLING_NRFLAG 4
/* true if poll_idle() is polling
#define TIF_POLLING_NRFLAG 4
/* true if poll_idle() is polling
TIF_NEED_RESCHED */
TIF_NEED_RESCHED */
#define TIF_MEMDIE 5
#define TIF_MEMDIE 5
#define TIF_SYSCALL_AUDIT 6
/* syscall auditing active */
#define TIF_SECCOMP 7
/* secure computing */
/* as above, but as bit values */
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
/*
/*
* Non racy (local) flags bit numbers
* Non racy (local) flags bit numbers
...
...
include/linux/audit.h
浏览文件 @
19fa95e9
...
@@ -27,15 +27,52 @@
...
@@ -27,15 +27,52 @@
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/elf.h>
#include <linux/elf.h>
/* Request and reply types */
/* The netlink messages for the audit system is divided into blocks:
#define AUDIT_GET 1000
/* Get status */
* 1000 - 1099 are for commanding the audit system
#define AUDIT_SET 1001
/* Set status (enable/disable/auditd) */
* 1100 - 1199 user space trusted application messages
#define AUDIT_LIST 1002
/* List filtering rules */
* 1200 - 1299 messages internal to the audit daemon
#define AUDIT_ADD 1003
/* Add filtering rule */
* 1300 - 1399 audit event messages
#define AUDIT_DEL 1004
/* Delete filtering rule */
* 1400 - 1499 SE Linux use
#define AUDIT_USER 1005
/* Send a message from user-space */
* 1500 - 1999 future use
#define AUDIT_LOGIN 1006
/* Define the login id and informaiton */
* 2000 is for otherwise unclassified kernel audit messages
#define AUDIT_KERNEL 2000
/* Asynchronous audit record. NOT A REQUEST. */
*
* Messages from 1000-1199 are bi-directional. 1200-1299 are exclusively user
* space. Anything over that is kernel --> user space communication.
*/
#define AUDIT_GET 1000
/* Get status */
#define AUDIT_SET 1001
/* Set status (enable/disable/auditd) */
#define AUDIT_LIST 1002
/* List syscall filtering rules */
#define AUDIT_ADD 1003
/* Add syscall filtering rule */
#define AUDIT_DEL 1004
/* Delete syscall filtering rule */
#define AUDIT_USER 1005
/* Message from userspace -- deprecated */
#define AUDIT_LOGIN 1006
/* Define the login id and information */
#define AUDIT_WATCH_INS 1007
/* Insert file/dir watch entry */
#define AUDIT_WATCH_REM 1008
/* Remove file/dir watch entry */
#define AUDIT_WATCH_LIST 1009
/* List all file/dir watches */
#define AUDIT_SIGNAL_INFO 1010
/* Get info about sender of signal to auditd */
#define AUDIT_FIRST_USER_MSG 1100
/* Userspace messages uninteresting to kernel */
#define AUDIT_LAST_USER_MSG 1199
#define AUDIT_DAEMON_START 1200
/* Daemon startup record */
#define AUDIT_DAEMON_END 1201
/* Daemon normal stop record */
#define AUDIT_DAEMON_ABORT 1202
/* Daemon error stop record */
#define AUDIT_DAEMON_CONFIG 1203
/* Daemon config change */
#define AUDIT_SYSCALL 1300
/* Syscall event */
#define AUDIT_FS_WATCH 1301
/* Filesystem watch event */
#define AUDIT_PATH 1302
/* Filename path information */
#define AUDIT_IPC 1303
/* IPC record */
#define AUDIT_SOCKETCALL 1304
/* sys_socketcall arguments */
#define AUDIT_CONFIG_CHANGE 1305
/* Audit system configuration change */
#define AUDIT_SOCKADDR 1306
/* sockaddr copied as syscall arg */
#define AUDIT_CWD 1307
/* Current working directory */
#define AUDIT_AVC 1400
/* SE Linux avc denial or grant */
#define AUDIT_SELINUX_ERR 1401
/* Internal SE Linux Errors */
#define AUDIT_AVC_PATH 1402
/* dentry, vfsmount pair from avc */
#define AUDIT_KERNEL 2000
/* Asynchronous audit record. NOT A REQUEST. */
/* Rule flags */
/* Rule flags */
#define AUDIT_PER_TASK 0x01
/* Apply rule at task creation (not syscall) */
#define AUDIT_PER_TASK 0x01
/* Apply rule at task creation (not syscall) */
...
@@ -132,16 +169,9 @@
...
@@ -132,16 +169,9 @@
#define AUDIT_ARCH_V850 (EM_V850|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_V850 (EM_V850|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_X86_64 (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_X86_64 (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#ifndef __KERNEL__
struct
audit_message
{
struct
nlmsghdr
nlh
;
char
data
[
1200
];
};
#endif
struct
audit_status
{
struct
audit_status
{
__u32
mask
;
/* Bit mask for valid entries */
__u32
mask
;
/* Bit mask for valid entries */
__u32
enabled
;
/* 1 = enabled, 0 = dis
ba
led */
__u32
enabled
;
/* 1 = enabled, 0 = dis
ab
led */
__u32
failure
;
/* Failure-to-log action */
__u32
failure
;
/* Failure-to-log action */
__u32
pid
;
/* pid of auditd process */
__u32
pid
;
/* pid of auditd process */
__u32
rate_limit
;
/* messages rate limit (per second) */
__u32
rate_limit
;
/* messages rate limit (per second) */
...
@@ -161,6 +191,11 @@ struct audit_rule { /* for AUDIT_LIST, AUDIT_ADD, and AUDIT_DEL */
...
@@ -161,6 +191,11 @@ struct audit_rule { /* for AUDIT_LIST, AUDIT_ADD, and AUDIT_DEL */
#ifdef __KERNEL__
#ifdef __KERNEL__
struct
audit_sig_info
{
uid_t
uid
;
pid_t
pid
;
};
struct
audit_buffer
;
struct
audit_buffer
;
struct
audit_context
;
struct
audit_context
;
struct
inode
;
struct
inode
;
...
@@ -185,11 +220,16 @@ extern void audit_inode(const char *name, const struct inode *inode);
...
@@ -185,11 +220,16 @@ extern void audit_inode(const char *name, const struct inode *inode);
/* Private API (for audit.c only) */
/* Private API (for audit.c only) */
extern
int
audit_receive_filter
(
int
type
,
int
pid
,
int
uid
,
int
seq
,
extern
int
audit_receive_filter
(
int
type
,
int
pid
,
int
uid
,
int
seq
,
void
*
data
,
uid_t
loginuid
);
void
*
data
,
uid_t
loginuid
);
extern
void
audit_get_stamp
(
struct
audit_context
*
ctx
,
extern
unsigned
int
audit_serial
(
void
);
struct
timespec
*
t
,
unsigned
int
*
serial
);
extern
void
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
(
struct
task_struct
*
task
,
uid_t
loginuid
);
extern
uid_t
audit_get_loginuid
(
struct
audit_context
*
ctx
);
extern
uid_t
audit_get_loginuid
(
struct
audit_context
*
ctx
);
extern
int
audit_ipc_perms
(
unsigned
long
qbytes
,
uid_t
uid
,
gid_t
gid
,
mode_t
mode
);
extern
int
audit_ipc_perms
(
unsigned
long
qbytes
,
uid_t
uid
,
gid_t
gid
,
mode_t
mode
);
extern
int
audit_socketcall
(
int
nargs
,
unsigned
long
*
args
);
extern
int
audit_sockaddr
(
int
len
,
void
*
addr
);
extern
int
audit_avc_path
(
struct
dentry
*
dentry
,
struct
vfsmount
*
mnt
);
extern
void
audit_signal_info
(
int
sig
,
struct
task_struct
*
t
);
#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)
...
@@ -198,18 +238,24 @@ extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mo
...
@@ -198,18 +238,24 @@ extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mo
#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)
#define audit_receive_filter(t,p,u,s,d,l) ({ -EOPNOTSUPP; })
#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
#define audit_get_loginuid(c) ({ -1; })
#define audit_get_loginuid(c) ({ -1; })
#define audit_ipc_perms(q,u,g,m) ({ 0; })
#define audit_ipc_perms(q,u,g,m) ({ 0; })
#define audit_socketcall(n,a) ({ 0; })
#define audit_sockaddr(len, addr) ({ 0; })
#define audit_avc_path(dentry, mnt) ({ 0; })
#define audit_signal_info(s,t) do { ; } while (0)
#endif
#endif
#ifdef CONFIG_AUDIT
#ifdef CONFIG_AUDIT
/* These are defined in audit.c */
/* These are defined in audit.c */
/* Public API */
/* Public API */
extern
void
audit_log
(
struct
audit_context
*
ctx
,
extern
void
audit_log
(
struct
audit_context
*
ctx
,
int
type
,
const
char
*
fmt
,
...)
const
char
*
fmt
,
...)
__attribute__
((
format
(
printf
,
2
,
3
)));
__attribute__
((
format
(
printf
,
3
,
4
)));
extern
struct
audit_buffer
*
audit_log_start
(
struct
audit_context
*
ctx
);
extern
struct
audit_buffer
*
audit_log_start
(
struct
audit_context
*
ctx
,
int
type
);
extern
void
audit_log_format
(
struct
audit_buffer
*
ab
,
extern
void
audit_log_format
(
struct
audit_buffer
*
ab
,
const
char
*
fmt
,
...)
const
char
*
fmt
,
...)
__attribute__
((
format
(
printf
,
2
,
3
)));
__attribute__
((
format
(
printf
,
2
,
3
)));
...
@@ -229,8 +275,8 @@ extern void audit_send_reply(int pid, int seq, int type,
...
@@ -229,8 +275,8 @@ extern void audit_send_reply(int pid, int seq, int type,
void
*
payload
,
int
size
);
void
*
payload
,
int
size
);
extern
void
audit_log_lost
(
const
char
*
message
);
extern
void
audit_log_lost
(
const
char
*
message
);
#else
#else
#define audit_log(t,f,...) do { ; } while (0)
#define audit_log(
c,
t,f,...) do { ; } while (0)
#define audit_log_start(t) ({ NULL; })
#define audit_log_start(
c,
t) ({ NULL; })
#define audit_log_vformat(b,f,a) do { ; } while (0)
#define audit_log_vformat(b,f,a) do { ; } while (0)
#define audit_log_format(b,f,...) do { ; } while (0)
#define audit_log_format(b,f,...) do { ; } while (0)
#define audit_log_end(b) do { ; } while (0)
#define audit_log_end(b) do { ; } while (0)
...
...
init/Kconfig
浏览文件 @
19fa95e9
...
@@ -164,6 +164,7 @@ config SYSCTL
...
@@ -164,6 +164,7 @@ config SYSCTL
config AUDIT
config AUDIT
bool "Auditing support"
bool "Auditing support"
depends on NET
default y if SECURITY_SELINUX
default y if SECURITY_SELINUX
help
help
Enable auditing infrastructure that can be used with another
Enable auditing infrastructure that can be used with another
...
@@ -173,7 +174,7 @@ config AUDIT
...
@@ -173,7 +174,7 @@ config AUDIT
config AUDITSYSCALL
config AUDITSYSCALL
bool "Enable system-call auditing support"
bool "Enable system-call auditing support"
depends on AUDIT && (X86 || PPC64 || ARCH_S390 || IA64 || UML)
depends on AUDIT && (X86 || PPC
|| PPC
64 || ARCH_S390 || IA64 || UML)
default y if SECURITY_SELINUX
default y if SECURITY_SELINUX
help
help
Enable low-overhead system-call auditing infrastructure that
Enable low-overhead system-call auditing infrastructure that
...
...
kernel/audit.c
浏览文件 @
19fa95e9
此差异已折叠。
点击以展开。
kernel/auditsc.c
浏览文件 @
19fa95e9
...
@@ -34,7 +34,8 @@
...
@@ -34,7 +34,8 @@
#include <asm/types.h>
#include <asm/types.h>
#include <linux/mm.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/mount.h>
#include <linux/socket.h>
#include <linux/audit.h>
#include <linux/audit.h>
#include <linux/personality.h>
#include <linux/personality.h>
#include <linux/time.h>
#include <linux/time.h>
...
@@ -112,6 +113,23 @@ struct audit_aux_data_ipcctl {
...
@@ -112,6 +113,23 @@ struct audit_aux_data_ipcctl {
mode_t
mode
;
mode_t
mode
;
};
};
struct
audit_aux_data_socketcall
{
struct
audit_aux_data
d
;
int
nargs
;
unsigned
long
args
[
0
];
};
struct
audit_aux_data_sockaddr
{
struct
audit_aux_data
d
;
int
len
;
char
a
[
0
];
};
struct
audit_aux_data_path
{
struct
audit_aux_data
d
;
struct
dentry
*
dentry
;
struct
vfsmount
*
mnt
;
};
/* The per-task audit context. */
/* The per-task audit context. */
struct
audit_context
{
struct
audit_context
{
...
@@ -127,6 +145,8 @@ struct audit_context {
...
@@ -127,6 +145,8 @@ struct audit_context {
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
];
struct
dentry
*
pwd
;
struct
vfsmount
*
pwdmnt
;
struct
audit_context
*
previous
;
/* For nested syscalls */
struct
audit_context
*
previous
;
/* For nested syscalls */
struct
audit_aux_data
*
aux
;
struct
audit_aux_data
*
aux
;
...
@@ -157,6 +177,8 @@ struct audit_entry {
...
@@ -157,6 +177,8 @@ struct audit_entry {
struct
audit_rule
rule
;
struct
audit_rule
rule
;
};
};
extern
int
audit_pid
;
/* Check to see if two rules are identical. It is called from
/* Check to see if two rules are identical. It is called from
* audit_del_rule during AUDIT_DEL. */
* audit_del_rule during AUDIT_DEL. */
static
int
audit_compare_rule
(
struct
audit_rule
*
a
,
struct
audit_rule
*
b
)
static
int
audit_compare_rule
(
struct
audit_rule
*
a
,
struct
audit_rule
*
b
)
...
@@ -226,7 +248,6 @@ static inline int audit_del_rule(struct audit_rule *rule,
...
@@ -226,7 +248,6 @@ static inline int audit_del_rule(struct audit_rule *rule,
return
-
EFAULT
;
/* No matching rule */
return
-
EFAULT
;
/* No matching rule */
}
}
#ifdef CONFIG_NET
/* Copy rule from user-space to kernel-space. Called during
/* Copy rule from user-space to kernel-space. Called during
* AUDIT_ADD. */
* AUDIT_ADD. */
static
int
audit_copy_rule
(
struct
audit_rule
*
d
,
struct
audit_rule
*
s
)
static
int
audit_copy_rule
(
struct
audit_rule
*
d
,
struct
audit_rule
*
s
)
...
@@ -287,7 +308,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
...
@@ -287,7 +308,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
err
=
audit_add_rule
(
entry
,
&
audit_entlist
);
err
=
audit_add_rule
(
entry
,
&
audit_entlist
);
if
(
!
err
&&
(
flags
&
AUDIT_AT_EXIT
))
if
(
!
err
&&
(
flags
&
AUDIT_AT_EXIT
))
err
=
audit_add_rule
(
entry
,
&
audit_extlist
);
err
=
audit_add_rule
(
entry
,
&
audit_extlist
);
audit_log
(
NULL
,
"auid %u added an audit rule
\n
"
,
loginuid
);
audit_log
(
NULL
,
AUDIT_CONFIG_CHANGE
,
"auid=%u added an audit rule
\n
"
,
loginuid
);
break
;
break
;
case
AUDIT_DEL
:
case
AUDIT_DEL
:
flags
=
((
struct
audit_rule
*
)
data
)
->
flags
;
flags
=
((
struct
audit_rule
*
)
data
)
->
flags
;
...
@@ -297,7 +319,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
...
@@ -297,7 +319,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
err
=
audit_del_rule
(
data
,
&
audit_entlist
);
err
=
audit_del_rule
(
data
,
&
audit_entlist
);
if
(
!
err
&&
(
flags
&
AUDIT_AT_EXIT
))
if
(
!
err
&&
(
flags
&
AUDIT_AT_EXIT
))
err
=
audit_del_rule
(
data
,
&
audit_extlist
);
err
=
audit_del_rule
(
data
,
&
audit_extlist
);
audit_log
(
NULL
,
"auid %u removed an audit rule
\n
"
,
loginuid
);
audit_log
(
NULL
,
AUDIT_CONFIG_CHANGE
,
"auid=%u removed an audit rule
\n
"
,
loginuid
);
break
;
break
;
default:
default:
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -305,7 +328,6 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
...
@@ -305,7 +328,6 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
return
err
;
return
err
;
}
}
#endif
/* Compare a task_struct with an audit_rule. Return 1 on match, 0
/* Compare a task_struct with an audit_rule. Return 1 on match, 0
* otherwise. */
* otherwise. */
...
@@ -444,7 +466,7 @@ static enum audit_state audit_filter_task(struct task_struct *tsk)
...
@@ -444,7 +466,7 @@ static enum audit_state audit_filter_task(struct task_struct *tsk)
/* At syscall entry and exit time, this filter is called if the
/* At syscall entry and exit time, this filter is called if the
* audit_state is not low enough that auditing cannot take place, but is
* audit_state is not low enough that auditing cannot take place, but is
* also not high enough that we already know we have to write an
d
audit
* also not high enough that we already know we have to write an audit
* record (i.e., the state is AUDIT_SETUP_CONTEXT or AUDIT_BUILD_CONTEXT).
* record (i.e., the state is AUDIT_SETUP_CONTEXT or AUDIT_BUILD_CONTEXT).
*/
*/
static
enum
audit_state
audit_filter_syscall
(
struct
task_struct
*
tsk
,
static
enum
audit_state
audit_filter_syscall
(
struct
task_struct
*
tsk
,
...
@@ -532,6 +554,12 @@ static inline void audit_free_names(struct audit_context *context)
...
@@ -532,6 +554,12 @@ static inline void audit_free_names(struct audit_context *context)
if
(
context
->
names
[
i
].
name
)
if
(
context
->
names
[
i
].
name
)
__putname
(
context
->
names
[
i
].
name
);
__putname
(
context
->
names
[
i
].
name
);
context
->
name_count
=
0
;
context
->
name_count
=
0
;
if
(
context
->
pwd
)
dput
(
context
->
pwd
);
if
(
context
->
pwdmnt
)
mntput
(
context
->
pwdmnt
);
context
->
pwd
=
NULL
;
context
->
pwdmnt
=
NULL
;
}
}
static
inline
void
audit_free_aux
(
struct
audit_context
*
context
)
static
inline
void
audit_free_aux
(
struct
audit_context
*
context
)
...
@@ -539,6 +567,11 @@ static inline void audit_free_aux(struct audit_context *context)
...
@@ -539,6 +567,11 @@ static inline void audit_free_aux(struct audit_context *context)
struct
audit_aux_data
*
aux
;
struct
audit_aux_data
*
aux
;
while
((
aux
=
context
->
aux
))
{
while
((
aux
=
context
->
aux
))
{
if
(
aux
->
type
==
AUDIT_AVC_PATH
)
{
struct
audit_aux_data_path
*
axi
=
(
void
*
)
aux
;
dput
(
axi
->
dentry
);
mntput
(
axi
->
mnt
);
}
context
->
aux
=
aux
->
next
;
context
->
aux
=
aux
->
next
;
kfree
(
aux
);
kfree
(
aux
);
}
}
...
@@ -625,7 +658,8 @@ static void audit_log_task_info(struct audit_buffer *ab)
...
@@ -625,7 +658,8 @@ static void audit_log_task_info(struct audit_buffer *ab)
struct
vm_area_struct
*
vma
;
struct
vm_area_struct
*
vma
;
get_task_comm
(
name
,
current
);
get_task_comm
(
name
,
current
);
audit_log_format
(
ab
,
" comm=%s"
,
name
);
audit_log_format
(
ab
,
" comm="
);
audit_log_untrustedstring
(
ab
,
name
);
if
(
!
mm
)
if
(
!
mm
)
return
;
return
;
...
@@ -649,23 +683,24 @@ static void audit_log_exit(struct audit_context *context)
...
@@ -649,23 +683,24 @@ static void audit_log_exit(struct audit_context *context)
{
{
int
i
;
int
i
;
struct
audit_buffer
*
ab
;
struct
audit_buffer
*
ab
;
struct
audit_aux_data
*
aux
;
ab
=
audit_log_start
(
context
);
ab
=
audit_log_start
(
context
,
AUDIT_SYSCALL
);
if
(
!
ab
)
if
(
!
ab
)
return
;
/* audit_panic has been called */
return
;
/* audit_panic has been called */
audit_log_format
(
ab
,
"syscall=%d"
,
context
->
major
);
audit_log_format
(
ab
,
"arch=%x syscall=%d"
,
context
->
arch
,
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
,
" success=%s exit=%ld"
,
audit_log_format
(
ab
,
" success=%s exit=%ld"
,
(
context
->
return_valid
==
AUDITSC_SUCCESS
)
?
"yes"
:
"no"
,
(
context
->
return_valid
==
AUDITSC_SUCCESS
)
?
"yes"
:
"no"
,
context
->
return_code
);
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
auid=%u uid=%u gid=%u
"
" euid=%
d suid=%d fsuid=%d
"
" euid=%
u suid=%u fsuid=%u
"
" egid=%
d sgid=%d fsgid=%d
"
,
" egid=%
u sgid=%u fsgid=%u
"
,
context
->
argv
[
0
],
context
->
argv
[
0
],
context
->
argv
[
1
],
context
->
argv
[
1
],
context
->
argv
[
2
],
context
->
argv
[
2
],
...
@@ -679,33 +714,57 @@ static void audit_log_exit(struct audit_context *context)
...
@@ -679,33 +714,57 @@ static void audit_log_exit(struct audit_context *context)
context
->
egid
,
context
->
sgid
,
context
->
fsgid
);
context
->
egid
,
context
->
sgid
,
context
->
fsgid
);
audit_log_task_info
(
ab
);
audit_log_task_info
(
ab
);
audit_log_end
(
ab
);
audit_log_end
(
ab
);
while
(
context
->
aux
)
{
struct
audit_aux_data
*
aux
;
ab
=
audit_log_start
(
context
);
for
(
aux
=
context
->
aux
;
aux
;
aux
=
aux
->
next
)
{
ab
=
audit_log_start
(
context
,
aux
->
type
);
if
(
!
ab
)
if
(
!
ab
)
continue
;
/* audit_panic has been called */
continue
;
/* audit_panic has been called */
aux
=
context
->
aux
;
context
->
aux
=
aux
->
next
;
audit_log_format
(
ab
,
"auxitem=%d"
,
aux
->
type
);
switch
(
aux
->
type
)
{
switch
(
aux
->
type
)
{
case
AUDIT_
AUX_IPCPERM
:
{
case
AUDIT_
IPC
:
{
struct
audit_aux_data_ipcctl
*
axi
=
(
void
*
)
aux
;
struct
audit_aux_data_ipcctl
*
axi
=
(
void
*
)
aux
;
audit_log_format
(
ab
,
audit_log_format
(
ab
,
" qbytes=%lx
uid=%d gid=%d
mode=%x"
,
" qbytes=%lx
iuid=%u igid=%u
mode=%x"
,
axi
->
qbytes
,
axi
->
uid
,
axi
->
gid
,
axi
->
mode
);
axi
->
qbytes
,
axi
->
uid
,
axi
->
gid
,
axi
->
mode
);
}
break
;
}
case
AUDIT_SOCKETCALL
:
{
int
i
;
struct
audit_aux_data_socketcall
*
axs
=
(
void
*
)
aux
;
audit_log_format
(
ab
,
"nargs=%d"
,
axs
->
nargs
);
for
(
i
=
0
;
i
<
axs
->
nargs
;
i
++
)
audit_log_format
(
ab
,
" a%d=%lx"
,
i
,
axs
->
args
[
i
]);
break
;
}
case
AUDIT_SOCKADDR
:
{
struct
audit_aux_data_sockaddr
*
axs
=
(
void
*
)
aux
;
audit_log_format
(
ab
,
"saddr="
);
audit_log_hex
(
ab
,
axs
->
a
,
axs
->
len
);
break
;
}
case
AUDIT_AVC_PATH
:
{
struct
audit_aux_data_path
*
axi
=
(
void
*
)
aux
;
audit_log_d_path
(
ab
,
"path="
,
axi
->
dentry
,
axi
->
mnt
);
break
;
}
}
}
audit_log_end
(
ab
);
audit_log_end
(
ab
);
kfree
(
aux
);
}
}
if
(
context
->
pwd
&&
context
->
pwdmnt
)
{
ab
=
audit_log_start
(
context
,
AUDIT_CWD
);
if
(
ab
)
{
audit_log_d_path
(
ab
,
"cwd="
,
context
->
pwd
,
context
->
pwdmnt
);
audit_log_end
(
ab
);
}
}
for
(
i
=
0
;
i
<
context
->
name_count
;
i
++
)
{
for
(
i
=
0
;
i
<
context
->
name_count
;
i
++
)
{
ab
=
audit_log_start
(
context
);
ab
=
audit_log_start
(
context
,
AUDIT_PATH
);
if
(
!
ab
)
if
(
!
ab
)
continue
;
/* audit_panic has been called */
continue
;
/* audit_panic has been called */
audit_log_format
(
ab
,
"item=%d"
,
i
);
audit_log_format
(
ab
,
"item=%d"
,
i
);
if
(
context
->
names
[
i
].
name
)
{
if
(
context
->
names
[
i
].
name
)
{
audit_log_format
(
ab
,
" name="
);
audit_log_format
(
ab
,
" name="
);
...
@@ -713,7 +772,7 @@ static void audit_log_exit(struct audit_context *context)
...
@@ -713,7 +772,7 @@ static void audit_log_exit(struct audit_context *context)
}
}
if
(
context
->
names
[
i
].
ino
!=
(
unsigned
long
)
-
1
)
if
(
context
->
names
[
i
].
ino
!=
(
unsigned
long
)
-
1
)
audit_log_format
(
ab
,
" inode=%lu dev=%02x:%02x mode=%#o"
audit_log_format
(
ab
,
" inode=%lu dev=%02x:%02x mode=%#o"
"
uid=%d gid=%d
rdev=%02x:%02x"
,
"
ouid=%u ogid=%u
rdev=%02x:%02x"
,
context
->
names
[
i
].
ino
,
context
->
names
[
i
].
ino
,
MAJOR
(
context
->
names
[
i
].
dev
),
MAJOR
(
context
->
names
[
i
].
dev
),
MINOR
(
context
->
names
[
i
].
dev
),
MINOR
(
context
->
names
[
i
].
dev
),
...
@@ -741,42 +800,12 @@ void audit_free(struct task_struct *tsk)
...
@@ -741,42 +800,12 @@ void audit_free(struct task_struct *tsk)
/* Check for system calls that do not go through the exit
/* Check for system calls that do not go through the exit
* function (e.g., exit_group), then free context block. */
* function (e.g., exit_group), then free context block. */
if
(
context
->
in_syscall
&&
context
->
auditable
)
if
(
context
->
in_syscall
&&
context
->
auditable
&&
context
->
pid
!=
audit_pid
)
audit_log_exit
(
context
);
audit_log_exit
(
context
);
audit_free_context
(
context
);
audit_free_context
(
context
);
}
}
/* Compute a serial number for the audit record. Audit records are
* written to user-space as soon as they are generated, so a complete
* audit record may be written in several pieces. The timestamp of the
* record and this serial number are used by the user-space daemon to
* determine which pieces belong to the same audit record. The
* (timestamp,serial) tuple is unique for each syscall and is live from
* syscall entry to syscall exit.
*
* Atomic values are only guaranteed to be 24-bit, so we count down.
*
* NOTE: Another possibility is to store the formatted records off the
* audit context (for those records that have a context), and emit them
* all at syscall exit. However, this could delay the reporting of
* significant errors until syscall exit (or never, if the system
* halts). */
static
inline
unsigned
int
audit_serial
(
void
)
{
static
atomic_t
serial
=
ATOMIC_INIT
(
0xffffff
);
unsigned
int
a
,
b
;
do
{
a
=
atomic_read
(
&
serial
);
if
(
atomic_dec_and_test
(
&
serial
))
atomic_set
(
&
serial
,
0xffffff
);
b
=
atomic_read
(
&
serial
);
}
while
(
b
!=
a
-
1
);
return
0xffffff
-
b
;
}
/* Fill in audit context at syscall entry. This only happens if the
/* Fill in audit context at syscall entry. This only happens if the
* audit context was created when the task was created and the state or
* audit context was created when the task was created and the state or
* filters demand the audit context be built. If the state from the
* filters demand the audit context be built. If the state from the
...
@@ -876,7 +905,7 @@ void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code)
...
@@ -876,7 +905,7 @@ void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code)
if
(
likely
(
!
context
))
if
(
likely
(
!
context
))
return
;
return
;
if
(
context
->
in_syscall
&&
context
->
auditable
)
if
(
context
->
in_syscall
&&
context
->
auditable
&&
context
->
pid
!=
audit_pid
)
audit_log_exit
(
context
);
audit_log_exit
(
context
);
context
->
in_syscall
=
0
;
context
->
in_syscall
=
0
;
...
@@ -916,6 +945,13 @@ void audit_getname(const char *name)
...
@@ -916,6 +945,13 @@ void audit_getname(const char *name)
context
->
names
[
context
->
name_count
].
name
=
name
;
context
->
names
[
context
->
name_count
].
name
=
name
;
context
->
names
[
context
->
name_count
].
ino
=
(
unsigned
long
)
-
1
;
context
->
names
[
context
->
name_count
].
ino
=
(
unsigned
long
)
-
1
;
++
context
->
name_count
;
++
context
->
name_count
;
if
(
!
context
->
pwd
)
{
read_lock
(
&
current
->
fs
->
lock
);
context
->
pwd
=
dget
(
current
->
fs
->
pwd
);
context
->
pwdmnt
=
mntget
(
current
->
fs
->
pwdmnt
);
read_unlock
(
&
current
->
fs
->
lock
);
}
}
}
/* Intercept a putname request. Called from
/* Intercept a putname request. Called from
...
@@ -994,34 +1030,26 @@ void audit_inode(const char *name, const struct inode *inode)
...
@@ -994,34 +1030,26 @@ void audit_inode(const char *name, const struct inode *inode)
context
->
names
[
idx
].
rdev
=
inode
->
i_rdev
;
context
->
names
[
idx
].
rdev
=
inode
->
i_rdev
;
}
}
void
audit_get_stamp
(
struct
audit_context
*
ctx
,
void
audit
sc
_get_stamp
(
struct
audit_context
*
ctx
,
struct
timespec
*
t
,
unsigned
int
*
serial
)
struct
timespec
*
t
,
unsigned
int
*
serial
)
{
{
if
(
ctx
)
{
t
->
tv_sec
=
ctx
->
ctime
.
tv_sec
;
t
->
tv_sec
=
ctx
->
ctime
.
tv_sec
;
t
->
tv_nsec
=
ctx
->
ctime
.
tv_nsec
;
t
->
tv_nsec
=
ctx
->
ctime
.
tv_nsec
;
*
serial
=
ctx
->
serial
;
*
serial
=
ctx
->
serial
;
ctx
->
auditable
=
1
;
ctx
->
auditable
=
1
;
}
else
{
*
t
=
CURRENT_TIME
;
*
serial
=
0
;
}
}
}
extern
int
audit_set_type
(
struct
audit_buffer
*
ab
,
int
type
);
int
audit_set_loginuid
(
struct
task_struct
*
task
,
uid_t
loginuid
)
int
audit_set_loginuid
(
struct
task_struct
*
task
,
uid_t
loginuid
)
{
{
if
(
task
->
audit_context
)
{
if
(
task
->
audit_context
)
{
struct
audit_buffer
*
ab
;
struct
audit_buffer
*
ab
;
ab
=
audit_log_start
(
NULL
);
ab
=
audit_log_start
(
NULL
,
AUDIT_LOGIN
);
if
(
ab
)
{
if
(
ab
)
{
audit_log_format
(
ab
,
"login pid=%d uid=%u "
audit_log_format
(
ab
,
"login pid=%d uid=%u "
"old
loginuid=%u new login
uid=%u"
,
"old
auid=%u new a
uid=%u"
,
task
->
pid
,
task
->
uid
,
task
->
pid
,
task
->
uid
,
task
->
audit_context
->
loginuid
,
loginuid
);
task
->
audit_context
->
loginuid
,
loginuid
);
audit_set_type
(
ab
,
AUDIT_LOGIN
);
audit_log_end
(
ab
);
audit_log_end
(
ab
);
}
}
task
->
audit_context
->
loginuid
=
loginuid
;
task
->
audit_context
->
loginuid
=
loginuid
;
...
@@ -1051,8 +1079,89 @@ int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
...
@@ -1051,8 +1079,89 @@ int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
ax
->
gid
=
gid
;
ax
->
gid
=
gid
;
ax
->
mode
=
mode
;
ax
->
mode
=
mode
;
ax
->
d
.
type
=
AUDIT_AUX_IPCPERM
;
ax
->
d
.
type
=
AUDIT_IPC
;
ax
->
d
.
next
=
context
->
aux
;
context
->
aux
=
(
void
*
)
ax
;
return
0
;
}
int
audit_socketcall
(
int
nargs
,
unsigned
long
*
args
)
{
struct
audit_aux_data_socketcall
*
ax
;
struct
audit_context
*
context
=
current
->
audit_context
;
if
(
likely
(
!
context
))
return
0
;
ax
=
kmalloc
(
sizeof
(
*
ax
)
+
nargs
*
sizeof
(
unsigned
long
),
GFP_KERNEL
);
if
(
!
ax
)
return
-
ENOMEM
;
ax
->
nargs
=
nargs
;
memcpy
(
ax
->
args
,
args
,
nargs
*
sizeof
(
unsigned
long
));
ax
->
d
.
type
=
AUDIT_SOCKETCALL
;
ax
->
d
.
next
=
context
->
aux
;
context
->
aux
=
(
void
*
)
ax
;
return
0
;
}
int
audit_sockaddr
(
int
len
,
void
*
a
)
{
struct
audit_aux_data_sockaddr
*
ax
;
struct
audit_context
*
context
=
current
->
audit_context
;
if
(
likely
(
!
context
))
return
0
;
ax
=
kmalloc
(
sizeof
(
*
ax
)
+
len
,
GFP_KERNEL
);
if
(
!
ax
)
return
-
ENOMEM
;
ax
->
len
=
len
;
memcpy
(
ax
->
a
,
a
,
len
);
ax
->
d
.
type
=
AUDIT_SOCKADDR
;
ax
->
d
.
next
=
context
->
aux
;
ax
->
d
.
next
=
context
->
aux
;
context
->
aux
=
(
void
*
)
ax
;
context
->
aux
=
(
void
*
)
ax
;
return
0
;
return
0
;
}
}
int
audit_avc_path
(
struct
dentry
*
dentry
,
struct
vfsmount
*
mnt
)
{
struct
audit_aux_data_path
*
ax
;
struct
audit_context
*
context
=
current
->
audit_context
;
if
(
likely
(
!
context
))
return
0
;
ax
=
kmalloc
(
sizeof
(
*
ax
),
GFP_ATOMIC
);
if
(
!
ax
)
return
-
ENOMEM
;
ax
->
dentry
=
dget
(
dentry
);
ax
->
mnt
=
mntget
(
mnt
);
ax
->
d
.
type
=
AUDIT_AVC_PATH
;
ax
->
d
.
next
=
context
->
aux
;
context
->
aux
=
(
void
*
)
ax
;
return
0
;
}
void
audit_signal_info
(
int
sig
,
struct
task_struct
*
t
)
{
extern
pid_t
audit_sig_pid
;
extern
uid_t
audit_sig_uid
;
if
(
unlikely
(
audit_pid
&&
t
->
pid
==
audit_pid
))
{
if
(
sig
==
SIGTERM
||
sig
==
SIGHUP
)
{
struct
audit_context
*
ctx
=
current
->
audit_context
;
audit_sig_pid
=
current
->
pid
;
if
(
ctx
)
audit_sig_uid
=
ctx
->
loginuid
;
else
audit_sig_uid
=
current
->
uid
;
}
}
}
kernel/signal.c
浏览文件 @
19fa95e9
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
#include <linux/ptrace.h>
#include <linux/ptrace.h>
#include <linux/posix-timers.h>
#include <linux/posix-timers.h>
#include <linux/signal.h>
#include <linux/signal.h>
#include <linux/audit.h>
#include <asm/param.h>
#include <asm/param.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
#include <asm/unistd.h>
...
@@ -667,7 +668,11 @@ static int check_kill_permission(int sig, struct siginfo *info,
...
@@ -667,7 +668,11 @@ static int check_kill_permission(int sig, struct siginfo *info,
&&
(
current
->
uid
^
t
->
suid
)
&&
(
current
->
uid
^
t
->
uid
)
&&
(
current
->
uid
^
t
->
suid
)
&&
(
current
->
uid
^
t
->
uid
)
&&
!
capable
(
CAP_KILL
))
&&
!
capable
(
CAP_KILL
))
return
error
;
return
error
;
return
security_task_kill
(
t
,
info
,
sig
);
error
=
security_task_kill
(
t
,
info
,
sig
);
if
(
!
error
)
audit_signal_info
(
sig
,
t
);
/* Let audit system see the signal */
return
error
;
}
}
/* forward decl */
/* forward decl */
...
...
net/socket.c
浏览文件 @
19fa95e9
...
@@ -81,6 +81,7 @@
...
@@ -81,6 +81,7 @@
#include <linux/syscalls.h>
#include <linux/syscalls.h>
#include <linux/compat.h>
#include <linux/compat.h>
#include <linux/kmod.h>
#include <linux/kmod.h>
#include <linux/audit.h>
#ifdef CONFIG_NET_RADIO
#ifdef CONFIG_NET_RADIO
#include <linux/wireless.h>
/* Note : will define WIRELESS_EXT */
#include <linux/wireless.h>
/* Note : will define WIRELESS_EXT */
...
@@ -226,7 +227,7 @@ int move_addr_to_kernel(void __user *uaddr, int ulen, void *kaddr)
...
@@ -226,7 +227,7 @@ int move_addr_to_kernel(void __user *uaddr, int ulen, void *kaddr)
return
0
;
return
0
;
if
(
copy_from_user
(
kaddr
,
uaddr
,
ulen
))
if
(
copy_from_user
(
kaddr
,
uaddr
,
ulen
))
return
-
EFAULT
;
return
-
EFAULT
;
return
0
;
return
audit_sockaddr
(
ulen
,
kaddr
)
;
}
}
/**
/**
...
@@ -1906,7 +1907,11 @@ asmlinkage long sys_socketcall(int call, unsigned long __user *args)
...
@@ -1906,7 +1907,11 @@ asmlinkage long sys_socketcall(int call, unsigned long __user *args)
/* copy_from_user should be SMP safe. */
/* copy_from_user should be SMP safe. */
if
(
copy_from_user
(
a
,
args
,
nargs
[
call
]))
if
(
copy_from_user
(
a
,
args
,
nargs
[
call
]))
return
-
EFAULT
;
return
-
EFAULT
;
err
=
audit_socketcall
(
nargs
[
call
]
/
sizeof
(
unsigned
long
),
a
);
if
(
err
)
return
err
;
a0
=
a
[
0
];
a0
=
a
[
0
];
a1
=
a
[
1
];
a1
=
a
[
1
];
...
...
security/selinux/avc.c
浏览文件 @
19fa95e9
...
@@ -242,7 +242,7 @@ void __init avc_init(void)
...
@@ -242,7 +242,7 @@ void __init avc_init(void)
avc_node_cachep
=
kmem_cache_create
(
"avc_node"
,
sizeof
(
struct
avc_node
),
avc_node_cachep
=
kmem_cache_create
(
"avc_node"
,
sizeof
(
struct
avc_node
),
0
,
SLAB_PANIC
,
NULL
,
NULL
);
0
,
SLAB_PANIC
,
NULL
,
NULL
);
audit_log
(
current
->
audit_context
,
"AVC INITIALIZED
\n
"
);
audit_log
(
current
->
audit_context
,
AUDIT_KERNEL
,
"AVC INITIALIZED
\n
"
);
}
}
int
avc_get_hash_stats
(
char
*
page
)
int
avc_get_hash_stats
(
char
*
page
)
...
@@ -532,6 +532,7 @@ void avc_audit(u32 ssid, u32 tsid,
...
@@ -532,6 +532,7 @@ void avc_audit(u32 ssid, u32 tsid,
u16
tclass
,
u32
requested
,
u16
tclass
,
u32
requested
,
struct
av_decision
*
avd
,
int
result
,
struct
avc_audit_data
*
a
)
struct
av_decision
*
avd
,
int
result
,
struct
avc_audit_data
*
a
)
{
{
struct
task_struct
*
tsk
=
current
;
struct
inode
*
inode
=
NULL
;
struct
inode
*
inode
=
NULL
;
u32
denied
,
audited
;
u32
denied
,
audited
;
struct
audit_buffer
*
ab
;
struct
audit_buffer
*
ab
;
...
@@ -549,12 +550,18 @@ void avc_audit(u32 ssid, u32 tsid,
...
@@ -549,12 +550,18 @@ void avc_audit(u32 ssid, u32 tsid,
return
;
return
;
}
}
ab
=
audit_log_start
(
current
->
audit_context
);
ab
=
audit_log_start
(
current
->
audit_context
,
AUDIT_AVC
);
if
(
!
ab
)
if
(
!
ab
)
return
;
/* audit_panic has been called */
return
;
/* audit_panic has been called */
audit_log_format
(
ab
,
"avc: %s "
,
denied
?
"denied"
:
"granted"
);
audit_log_format
(
ab
,
"avc: %s "
,
denied
?
"denied"
:
"granted"
);
avc_dump_av
(
ab
,
tclass
,
audited
);
avc_dump_av
(
ab
,
tclass
,
audited
);
audit_log_format
(
ab
,
" for "
);
audit_log_format
(
ab
,
" for "
);
if
(
a
&&
a
->
tsk
)
tsk
=
a
->
tsk
;
if
(
tsk
&&
tsk
->
pid
)
{
audit_log_format
(
ab
,
" pid=%d comm="
,
tsk
->
pid
);
audit_log_untrustedstring
(
ab
,
tsk
->
comm
);
}
if
(
a
)
{
if
(
a
)
{
switch
(
a
->
type
)
{
switch
(
a
->
type
)
{
case
AVC_AUDIT_DATA_IPC
:
case
AVC_AUDIT_DATA_IPC
:
...
@@ -566,21 +573,18 @@ void avc_audit(u32 ssid, u32 tsid,
...
@@ -566,21 +573,18 @@ void avc_audit(u32 ssid, u32 tsid,
case
AVC_AUDIT_DATA_FS
:
case
AVC_AUDIT_DATA_FS
:
if
(
a
->
u
.
fs
.
dentry
)
{
if
(
a
->
u
.
fs
.
dentry
)
{
struct
dentry
*
dentry
=
a
->
u
.
fs
.
dentry
;
struct
dentry
*
dentry
=
a
->
u
.
fs
.
dentry
;
if
(
a
->
u
.
fs
.
mnt
)
{
if
(
a
->
u
.
fs
.
mnt
)
audit_log_d_path
(
ab
,
"path="
,
dentry
,
audit_avc_path
(
dentry
,
a
->
u
.
fs
.
mnt
);
a
->
u
.
fs
.
mnt
);
audit_log_format
(
ab
,
" name="
);
}
else
{
audit_log_untrustedstring
(
ab
,
dentry
->
d_name
.
name
);
audit_log_format
(
ab
,
" name=%s"
,
dentry
->
d_name
.
name
);
}
inode
=
dentry
->
d_inode
;
inode
=
dentry
->
d_inode
;
}
else
if
(
a
->
u
.
fs
.
inode
)
{
}
else
if
(
a
->
u
.
fs
.
inode
)
{
struct
dentry
*
dentry
;
struct
dentry
*
dentry
;
inode
=
a
->
u
.
fs
.
inode
;
inode
=
a
->
u
.
fs
.
inode
;
dentry
=
d_find_alias
(
inode
);
dentry
=
d_find_alias
(
inode
);
if
(
dentry
)
{
if
(
dentry
)
{
audit_log_format
(
ab
,
" name=
%s"
,
audit_log_format
(
ab
,
" name=
"
);
dentry
->
d_name
.
name
);
audit_log_untrustedstring
(
ab
,
dentry
->
d_name
.
name
);
dput
(
dentry
);
dput
(
dentry
);
}
}
}
}
...
@@ -623,22 +627,20 @@ void avc_audit(u32 ssid, u32 tsid,
...
@@ -623,22 +627,20 @@ void avc_audit(u32 ssid, u32 tsid,
case
AF_UNIX
:
case
AF_UNIX
:
u
=
unix_sk
(
sk
);
u
=
unix_sk
(
sk
);
if
(
u
->
dentry
)
{
if
(
u
->
dentry
)
{
audit_log_d_path
(
ab
,
"path="
,
audit_avc_path
(
u
->
dentry
,
u
->
mnt
);
u
->
dentry
,
u
->
mnt
);
audit_log_format
(
ab
,
" name="
);
audit_log_untrustedstring
(
ab
,
u
->
dentry
->
d_name
.
name
);
break
;
break
;
}
}
if
(
!
u
->
addr
)
if
(
!
u
->
addr
)
break
;
break
;
len
=
u
->
addr
->
len
-
sizeof
(
short
);
len
=
u
->
addr
->
len
-
sizeof
(
short
);
p
=
&
u
->
addr
->
name
->
sun_path
[
0
];
p
=
&
u
->
addr
->
name
->
sun_path
[
0
];
audit_log_format
(
ab
,
" path="
);
if
(
*
p
)
if
(
*
p
)
audit_log_format
(
ab
,
audit_log_untrustedstring
(
ab
,
p
);
"path=%*.*s"
,
len
,
len
,
p
);
else
else
audit_log_format
(
ab
,
audit_log_hex
(
ab
,
p
,
len
);
"path=@%*.*s"
,
len
-
1
,
len
-
1
,
p
+
1
);
break
;
break
;
}
}
}
}
...
...
security/selinux/hooks.c
浏览文件 @
19fa95e9
...
@@ -3419,7 +3419,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
...
@@ -3419,7 +3419,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
err
=
selinux_nlmsg_lookup
(
isec
->
sclass
,
nlh
->
nlmsg_type
,
&
perm
);
err
=
selinux_nlmsg_lookup
(
isec
->
sclass
,
nlh
->
nlmsg_type
,
&
perm
);
if
(
err
)
{
if
(
err
)
{
if
(
err
==
-
EINVAL
)
{
if
(
err
==
-
EINVAL
)
{
audit_log
(
current
->
audit_context
,
audit_log
(
current
->
audit_context
,
AUDIT_SELINUX_ERR
,
"SELinux: unrecognized netlink message"
"SELinux: unrecognized netlink message"
" type=%hu for sclass=%hu
\n
"
,
" type=%hu for sclass=%hu
\n
"
,
nlh
->
nlmsg_type
,
isec
->
sclass
);
nlh
->
nlmsg_type
,
isec
->
sclass
);
...
...
security/selinux/nlmsgtab.c
浏览文件 @
19fa95e9
...
@@ -97,6 +97,7 @@ static struct nlmsg_perm nlmsg_audit_perms[] =
...
@@ -97,6 +97,7 @@ static struct nlmsg_perm nlmsg_audit_perms[] =
{
AUDIT_ADD
,
NETLINK_AUDIT_SOCKET__NLMSG_WRITE
},
{
AUDIT_ADD
,
NETLINK_AUDIT_SOCKET__NLMSG_WRITE
},
{
AUDIT_DEL
,
NETLINK_AUDIT_SOCKET__NLMSG_WRITE
},
{
AUDIT_DEL
,
NETLINK_AUDIT_SOCKET__NLMSG_WRITE
},
{
AUDIT_USER
,
NETLINK_AUDIT_SOCKET__NLMSG_RELAY
},
{
AUDIT_USER
,
NETLINK_AUDIT_SOCKET__NLMSG_RELAY
},
{
AUDIT_SIGNAL_INFO
,
NETLINK_AUDIT_SOCKET__NLMSG_READ
},
};
};
...
@@ -141,8 +142,13 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
...
@@ -141,8 +142,13 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
break
;
break
;
case
SECCLASS_NETLINK_AUDIT_SOCKET
:
case
SECCLASS_NETLINK_AUDIT_SOCKET
:
err
=
nlmsg_perm
(
nlmsg_type
,
perm
,
nlmsg_audit_perms
,
if
(
nlmsg_type
>=
AUDIT_FIRST_USER_MSG
&&
sizeof
(
nlmsg_audit_perms
));
nlmsg_type
<=
AUDIT_LAST_USER_MSG
)
{
*
perm
=
NETLINK_AUDIT_SOCKET__NLMSG_RELAY
;
}
else
{
err
=
nlmsg_perm
(
nlmsg_type
,
perm
,
nlmsg_audit_perms
,
sizeof
(
nlmsg_audit_perms
));
}
break
;
break
;
/* No messaging from userspace, or class unknown/unhandled */
/* No messaging from userspace, or class unknown/unhandled */
...
...
security/selinux/ss/services.c
浏览文件 @
19fa95e9
...
@@ -365,7 +365,7 @@ static int security_validtrans_handle_fail(struct context *ocontext,
...
@@ -365,7 +365,7 @@ static int security_validtrans_handle_fail(struct context *ocontext,
goto
out
;
goto
out
;
if
(
context_struct_to_string
(
tcontext
,
&
t
,
&
tlen
)
<
0
)
if
(
context_struct_to_string
(
tcontext
,
&
t
,
&
tlen
)
<
0
)
goto
out
;
goto
out
;
audit_log
(
current
->
audit_context
,
audit_log
(
current
->
audit_context
,
AUDIT_SELINUX_ERR
,
"security_validate_transition: denied for"
"security_validate_transition: denied for"
" oldcontext=%s newcontext=%s taskcontext=%s tclass=%s"
,
" oldcontext=%s newcontext=%s taskcontext=%s tclass=%s"
,
o
,
n
,
t
,
policydb
.
p_class_val_to_name
[
tclass
-
1
]);
o
,
n
,
t
,
policydb
.
p_class_val_to_name
[
tclass
-
1
]);
...
@@ -742,7 +742,7 @@ static int compute_sid_handle_invalid_context(
...
@@ -742,7 +742,7 @@ static int compute_sid_handle_invalid_context(
goto
out
;
goto
out
;
if
(
context_struct_to_string
(
newcontext
,
&
n
,
&
nlen
)
<
0
)
if
(
context_struct_to_string
(
newcontext
,
&
n
,
&
nlen
)
<
0
)
goto
out
;
goto
out
;
audit_log
(
current
->
audit_context
,
audit_log
(
current
->
audit_context
,
AUDIT_SELINUX_ERR
,
"security_compute_sid: invalid context %s"
"security_compute_sid: invalid context %s"
" for scontext=%s"
" for scontext=%s"
" tcontext=%s"
" tcontext=%s"
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录