Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
6f817abc
Commit
6f817abc
authored
May 05, 2005
by
Dave Kleikamp
Browse files
Options
Browse Files
Download
Plain Diff
Merge with /home/shaggy/git/linus-clean/
parents
f77165df
bfd4bda0
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
269 additions
and
127 deletions
+269
-127
arch/i386/kernel/ptrace.c
arch/i386/kernel/ptrace.c
+9
-10
arch/ia64/kernel/ptrace.c
arch/ia64/kernel/ptrace.c
+13
-8
arch/mips/kernel/ptrace.c
arch/mips/kernel/ptrace.c
+28
-10
arch/ppc64/kernel/ptrace.c
arch/ppc64/kernel/ptrace.c
+10
-5
arch/s390/kernel/ptrace.c
arch/s390/kernel/ptrace.c
+11
-10
arch/um/kernel/ptrace.c
arch/um/kernel/ptrace.c
+12
-9
arch/x86_64/kernel/ptrace.c
arch/x86_64/kernel/ptrace.c
+15
-6
fs/namei.c
fs/namei.c
+12
-8
fs/proc/base.c
fs/proc/base.c
+1
-1
include/asm-um/ptrace-i386.h
include/asm-um/ptrace-i386.h
+2
-0
include/asm-um/ptrace-x86_64.h
include/asm-um/ptrace-x86_64.h
+2
-0
include/asm-um/thread_info.h
include/asm-um/thread_info.h
+3
-1
include/linux/audit.h
include/linux/audit.h
+55
-9
include/linux/netlink.h
include/linux/netlink.h
+1
-0
init/Kconfig
init/Kconfig
+1
-1
kernel/audit.c
kernel/audit.c
+60
-33
kernel/auditsc.c
kernel/auditsc.c
+31
-16
net/netlink/af_netlink.c
net/netlink/af_netlink.c
+3
-0
No files found.
arch/i386/kernel/ptrace.c
View file @
6f817abc
...
...
@@ -683,24 +683,18 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
/* do the secure computing check first */
secure_computing
(
regs
->
orig_eax
);
if
(
unlikely
(
current
->
audit_context
))
{
if
(
!
entryexit
)
audit_syscall_entry
(
current
,
regs
->
orig_eax
,
regs
->
ebx
,
regs
->
ecx
,
regs
->
edx
,
regs
->
esi
);
else
audit_syscall_exit
(
current
,
regs
->
eax
);
}
if
(
unlikely
(
current
->
audit_context
)
&&
entryexit
)
audit_syscall_exit
(
current
,
AUDITSC_RESULT
(
regs
->
eax
),
regs
->
eax
);
if
(
!
(
current
->
ptrace
&
PT_PTRACED
))
return
;
goto
out
;
/* Fake a debug trap */
if
(
test_thread_flag
(
TIF_SINGLESTEP
))
send_sigtrap
(
current
,
regs
,
0
);
if
(
!
test_thread_flag
(
TIF_SYSCALL_TRACE
))
return
;
goto
out
;
/* the 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
...
...
@@ -715,4 +709,9 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
send_sig
(
current
->
exit_code
,
current
,
1
);
current
->
exit_code
=
0
;
}
out:
if
(
unlikely
(
current
->
audit_context
)
&&
!
entryexit
)
audit_syscall_entry
(
current
,
AUDIT_ARCH_I386
,
regs
->
orig_eax
,
regs
->
ebx
,
regs
->
ecx
,
regs
->
edx
,
regs
->
esi
);
}
arch/ia64/kernel/ptrace.c
View file @
6f817abc
...
...
@@ -1596,20 +1596,25 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
long
arg4
,
long
arg5
,
long
arg6
,
long
arg7
,
struct
pt_regs
regs
)
{
long
syscall
;
if
(
test_thread_flag
(
TIF_SYSCALL_TRACE
)
&&
(
current
->
ptrace
&
PT_PTRACED
))
syscall_trace
();
if
(
unlikely
(
current
->
audit_context
))
{
if
(
IS_IA32_PROCESS
(
&
regs
))
long
syscall
;
int
arch
;
if
(
IS_IA32_PROCESS
(
&
regs
))
{
syscall
=
regs
.
r1
;
else
arch
=
AUDIT_ARCH_I386
;
}
else
{
syscall
=
regs
.
r15
;
arch
=
AUDIT_ARCH_IA64
;
}
audit_syscall_entry
(
current
,
syscall
,
arg0
,
arg1
,
arg2
,
arg3
);
audit_syscall_entry
(
current
,
arch
,
syscall
,
arg0
,
arg1
,
arg2
,
arg3
);
}
if
(
test_thread_flag
(
TIF_SYSCALL_TRACE
)
&&
(
current
->
ptrace
&
PT_PTRACED
))
syscall_trace
();
}
/* "asmlinkage" so the input arguments are preserved... */
...
...
@@ -1620,7 +1625,7 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
struct
pt_regs
regs
)
{
if
(
unlikely
(
current
->
audit_context
))
audit_syscall_exit
(
current
,
regs
.
r8
);
audit_syscall_exit
(
current
,
AUDITSC_RESULT
(
regs
.
r10
),
regs
.
r8
);
if
(
test_thread_flag
(
TIF_SYSCALL_TRACE
)
&&
(
current
->
ptrace
&
PT_PTRACED
))
...
...
arch/mips/kernel/ptrace.c
View file @
6f817abc
...
...
@@ -301,25 +301,38 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
return
ret
;
}
static
inline
int
audit_arch
(
void
)
{
#ifdef CONFIG_CPU_LITTLE_ENDIAN
#ifdef CONFIG_MIPS64
if
(
!
(
current
->
thread
.
mflags
&
MF_32BIT_REGS
))
return
AUDIT_ARCH_MIPSEL64
;
#endif
/* MIPS64 */
return
AUDIT_ARCH_MIPSEL
;
#else
/* big endian... */
#ifdef CONFIG_MIPS64
if
(
!
(
current
->
thread
.
mflags
&
MF_32BIT_REGS
))
return
AUDIT_ARCH_MIPS64
;
#endif
/* MIPS64 */
return
AUDIT_ARCH_MIPS
;
#endif
/* endian */
}
/*
* Notification of system call entry/exit
* - triggered by current->work.syscall_trace
*/
asmlinkage
void
do_syscall_trace
(
struct
pt_regs
*
regs
,
int
entryexit
)
{
if
(
unlikely
(
current
->
audit_context
))
{
if
(
!
entryexit
)
audit_syscall_entry
(
current
,
regs
->
regs
[
2
],
regs
->
regs
[
4
],
regs
->
regs
[
5
],
regs
->
regs
[
6
],
regs
->
regs
[
7
]);
else
audit_syscall_exit
(
current
,
regs
->
regs
[
2
]);
}
if
(
unlikely
(
current
->
audit_context
)
&&
entryexit
)
audit_syscall_exit
(
current
,
AUDITSC_RESULT
(
regs
->
regs
[
2
]),
regs
->
regs
[
2
]);
if
(
!
test_thread_flag
(
TIF_SYSCALL_TRACE
))
return
;
goto
out
;
if
(
!
(
current
->
ptrace
&
PT_PTRACED
))
return
;
goto
out
;
/* The 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
...
...
@@ -335,4 +348,9 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
send_sig
(
current
->
exit_code
,
current
,
1
);
current
->
exit_code
=
0
;
}
out:
if
(
unlikely
(
current
->
audit_context
)
&&
!
entryexit
)
audit_syscall_entry
(
current
,
audit_arch
(),
regs
->
regs
[
2
],
regs
->
regs
[
4
],
regs
->
regs
[
5
],
regs
->
regs
[
6
],
regs
->
regs
[
7
]);
}
arch/ppc64/kernel/ptrace.c
View file @
6f817abc
...
...
@@ -305,14 +305,17 @@ static void do_syscall_trace(void)
void
do_syscall_trace_enter
(
struct
pt_regs
*
regs
)
{
if
(
test_thread_flag
(
TIF_SYSCALL_TRACE
)
&&
(
current
->
ptrace
&
PT_PTRACED
))
do_syscall_trace
();
if
(
unlikely
(
current
->
audit_context
))
audit_syscall_entry
(
current
,
regs
->
gpr
[
0
],
audit_syscall_entry
(
current
,
test_thread_flag
(
TIF_32BIT
)
?
AUDIT_ARCH_PPC
:
AUDIT_ARCH_PPC64
,
regs
->
gpr
[
0
],
regs
->
gpr
[
3
],
regs
->
gpr
[
4
],
regs
->
gpr
[
5
],
regs
->
gpr
[
6
]);
if
(
test_thread_flag
(
TIF_SYSCALL_TRACE
)
&&
(
current
->
ptrace
&
PT_PTRACED
))
do_syscall_trace
();
}
void
do_syscall_trace_leave
(
struct
pt_regs
*
regs
)
...
...
@@ -320,7 +323,9 @@ void do_syscall_trace_leave(struct pt_regs *regs)
secure_computing
(
regs
->
gpr
[
0
]);
if
(
unlikely
(
current
->
audit_context
))
audit_syscall_exit
(
current
,
regs
->
result
);
audit_syscall_exit
(
current
,
(
regs
->
ccr
&
0x1000
)
?
AUDITSC_FAILURE
:
AUDITSC_SUCCESS
,
regs
->
result
);
if
((
test_thread_flag
(
TIF_SYSCALL_TRACE
)
||
test_thread_flag
(
TIF_SINGLESTEP
))
...
...
arch/s390/kernel/ptrace.c
View file @
6f817abc
...
...
@@ -712,18 +712,13 @@ sys_ptrace(long request, long pid, long addr, long data)
asmlinkage
void
syscall_trace
(
struct
pt_regs
*
regs
,
int
entryexit
)
{
if
(
unlikely
(
current
->
audit_context
))
{
if
(
!
entryexit
)
audit_syscall_entry
(
current
,
regs
->
gprs
[
2
],
regs
->
orig_gpr2
,
regs
->
gprs
[
3
],
regs
->
gprs
[
4
],
regs
->
gprs
[
5
]);
else
audit_syscall_exit
(
current
,
regs
->
gprs
[
2
]);
}
if
(
unlikely
(
current
->
audit_context
)
&&
entryexit
)
audit_syscall_exit
(
current
,
AUDITSC_RESULT
(
regs
->
gprs
[
2
]),
regs
->
gprs
[
2
]);
if
(
!
test_thread_flag
(
TIF_SYSCALL_TRACE
))
return
;
goto
out
;
if
(
!
(
current
->
ptrace
&
PT_PTRACED
))
return
;
goto
out
;
ptrace_notify
(
SIGTRAP
|
((
current
->
ptrace
&
PT_TRACESYSGOOD
)
?
0x80
:
0
));
...
...
@@ -736,4 +731,10 @@ syscall_trace(struct pt_regs *regs, int entryexit)
send_sig
(
current
->
exit_code
,
current
,
1
);
current
->
exit_code
=
0
;
}
out:
if
(
unlikely
(
current
->
audit_context
)
&&
!
entryexit
)
audit_syscall_entry
(
current
,
test_thread_flag
(
TIF_31BIT
)
?
AUDIT_ARCH_S390
:
AUDIT_ARCH_S390X
,
regs
->
gprs
[
2
],
regs
->
orig_gpr2
,
regs
->
gprs
[
3
],
regs
->
gprs
[
4
],
regs
->
gprs
[
5
]);
}
arch/um/kernel/ptrace.c
View file @
6f817abc
...
...
@@ -337,15 +337,18 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
if
(
unlikely
(
current
->
audit_context
))
{
if
(
!
entryexit
)
audit_syscall_entry
(
current
,
UPT_SYSCALL_NR
(
&
regs
->
regs
),
UPT_SYSCALL_ARG1
(
&
regs
->
regs
),
UPT_SYSCALL_ARG2
(
&
regs
->
regs
),
UPT_SYSCALL_ARG3
(
&
regs
->
regs
),
UPT_SYSCALL_ARG4
(
&
regs
->
regs
));
else
audit_syscall_exit
(
current
,
UPT_SYSCALL_RET
(
&
regs
->
regs
));
audit_syscall_entry
(
current
,
HOST_AUDIT_ARCH
,
UPT_SYSCALL_NR
(
regs
),
UPT_SYSCALL_ARG1
(
regs
),
UPT_SYSCALL_ARG2
(
regs
),
UPT_SYSCALL_ARG3
(
regs
),
UPT_SYSCALL_ARG4
(
regs
));
else
{
int
res
=
UPT_SYSCALL_RET
(
regs
);
audit_syscall_exit
(
current
,
AUDITSC_RESULT
(
res
),
res
);
}
}
/* Fake a debug trap */
...
...
arch/x86_64/kernel/ptrace.c
View file @
6f817abc
...
...
@@ -635,20 +635,29 @@ asmlinkage void syscall_trace_enter(struct pt_regs *regs)
/* do the secure computing check first */
secure_computing
(
regs
->
orig_rax
);
if
(
unlikely
(
current
->
audit_context
))
audit_syscall_entry
(
current
,
regs
->
orig_rax
,
regs
->
rdi
,
regs
->
rsi
,
regs
->
rdx
,
regs
->
r10
);
if
(
test_thread_flag
(
TIF_SYSCALL_TRACE
)
&&
(
current
->
ptrace
&
PT_PTRACED
))
syscall_trace
(
regs
);
if
(
unlikely
(
current
->
audit_context
))
{
if
(
test_thread_flag
(
TIF_IA32
))
{
audit_syscall_entry
(
current
,
AUDIT_ARCH_I386
,
regs
->
orig_rax
,
regs
->
rbx
,
regs
->
rcx
,
regs
->
rdx
,
regs
->
rsi
);
}
else
{
audit_syscall_entry
(
current
,
AUDIT_ARCH_X86_64
,
regs
->
orig_rax
,
regs
->
rdi
,
regs
->
rsi
,
regs
->
rdx
,
regs
->
r10
);
}
}
}
asmlinkage
void
syscall_trace_leave
(
struct
pt_regs
*
regs
)
{
if
(
unlikely
(
current
->
audit_context
))
audit_syscall_exit
(
current
,
regs
->
rax
);
audit_syscall_exit
(
current
,
AUDITSC_RESULT
(
regs
->
rax
),
regs
->
rax
);
if
((
test_thread_flag
(
TIF_SYSCALL_TRACE
)
||
test_thread_flag
(
TIF_SINGLESTEP
))
...
...
fs/namei.c
View file @
6f817abc
...
...
@@ -686,11 +686,11 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
/*
* Name resolution.
* This is the basic name resolution function, turning a pathname into
* the final dentry. We expect 'base' to be positive and a directory.
*
* This is the basic name resolution function, turning a pathname
* into the final dentry.
*
* We expect 'base' to be positive and a directory.
* Returns 0 and nd will have valid dentry and mnt on success.
* Returns error and drops reference to input namei data on failure.
*/
static
fastcall
int
__link_path_walk
(
const
char
*
name
,
struct
nameidata
*
nd
)
{
...
...
@@ -929,8 +929,10 @@ int fastcall path_walk(const char * name, struct nameidata *nd)
return
link_path_walk
(
name
,
nd
);
}
/* SMP-safe */
/* returns 1 if everything is done */
/*
* SMP-safe: Returns 1 and nd will have valid dentry and mnt, if
* everything is done. Returns 0 and drops input nd, if lookup failed;
*/
static
int
__emul_lookup_dentry
(
const
char
*
name
,
struct
nameidata
*
nd
)
{
if
(
path_walk
(
name
,
nd
))
...
...
@@ -994,9 +996,10 @@ void set_fs_altroot(void)
}
}
/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
int
fastcall
path_lookup
(
const
char
*
name
,
unsigned
int
flags
,
struct
nameidata
*
nd
)
{
int
retval
;
int
retval
=
0
;
nd
->
last_type
=
LAST_ROOT
;
/* if there are only slashes... */
nd
->
flags
=
flags
;
...
...
@@ -1009,7 +1012,7 @@ int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata
nd
->
dentry
=
dget
(
current
->
fs
->
altroot
);
read_unlock
(
&
current
->
fs
->
lock
);
if
(
__emul_lookup_dentry
(
name
,
nd
))
return
0
;
goto
out
;
/* found in altroot */
read_lock
(
&
current
->
fs
->
lock
);
}
nd
->
mnt
=
mntget
(
current
->
fs
->
rootmnt
);
...
...
@@ -1021,6 +1024,7 @@ int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata
read_unlock
(
&
current
->
fs
->
lock
);
current
->
total_link_count
=
0
;
retval
=
link_path_walk
(
name
,
nd
);
out:
if
(
unlikely
(
current
->
audit_context
&&
nd
&&
nd
->
dentry
&&
nd
->
dentry
->
d_inode
))
audit_inode
(
name
,
nd
->
dentry
->
d_inode
);
...
...
fs/proc/base.c
View file @
6f817abc
...
...
@@ -820,7 +820,7 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
goto
out_free_page
;
}
length
=
audit_set_loginuid
(
task
->
audit_context
,
loginuid
);
length
=
audit_set_loginuid
(
task
,
loginuid
);
if
(
likely
(
length
==
0
))
length
=
count
;
...
...
include/asm-um/ptrace-i386.h
View file @
6f817abc
...
...
@@ -6,6 +6,8 @@
#ifndef __UM_PTRACE_I386_H
#define __UM_PTRACE_I386_H
#define HOST_AUDIT_ARCH AUDIT_ARCH_I386
#include "sysdep/ptrace.h"
#include "asm/ptrace-generic.h"
...
...
include/asm-um/ptrace-x86_64.h
View file @
6f817abc
...
...
@@ -14,6 +14,8 @@
#include "asm/ptrace-generic.h"
#undef signal_fault
#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64
void
signal_fault
(
struct
pt_regs_subarch
*
regs
,
void
*
frame
,
char
*
where
);
#define FS_BASE (21 * sizeof(unsigned long))
...
...
include/asm-um/thread_info.h
View file @
6f817abc
...
...
@@ -72,12 +72,14 @@ static inline struct thread_info *current_thread_info(void)
*/
#define TIF_RESTART_BLOCK 4
#define TIF_MEMDIE 5
#define TIF_SYSCALL_AUDIT 6
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_RESTART_BLOCK (1 << TIF_RESTART_BLOCK)
#define _TIF_MEMDIE (1 << TIF_MEMDIE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#endif
...
...
include/linux/audit.h
View file @
6f817abc
/* audit.h -- Auditing support
-*- linux-c -*-
/* audit.h -- Auditing support
*
* Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
* All Rights Reserved.
...
...
@@ -24,6 +24,9 @@
#ifndef _LINUX_AUDIT_H_
#define _LINUX_AUDIT_H_
#include <linux/sched.h>
#include <linux/elf.h>
/* Request and reply types */
#define AUDIT_GET 1000
/* Get status */
#define AUDIT_SET 1001
/* Set status (enable/disable/auditd) */
...
...
@@ -67,6 +70,7 @@
#define AUDIT_FSGID 8
#define AUDIT_LOGINUID 9
#define AUDIT_PERS 10
#define AUDIT_ARCH 11
/* These are ONLY useful when checking
* at syscall exit time (AUDIT_AT_EXIT). */
...
...
@@ -96,6 +100,38 @@
#define AUDIT_FAIL_PRINTK 1
#define AUDIT_FAIL_PANIC 2
/* distinguish syscall tables */
#define __AUDIT_ARCH_64BIT 0x80000000
#define __AUDIT_ARCH_LE 0x40000000
#define AUDIT_ARCH_ALPHA (EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_ARMEB (EM_ARM)
#define AUDIT_ARCH_CRIS (EM_CRIS|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_FRV (EM_FRV)
#define AUDIT_ARCH_H8300 (EM_H8_300)
#define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_IA64 (EM_IA_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_M32R (EM_M32R)
#define AUDIT_ARCH_M68K (EM_68K)
#define AUDIT_ARCH_MIPS (EM_MIPS)
#define AUDIT_ARCH_MIPSEL (EM_MIPS|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_MIPS64 (EM_MIPS|__AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_MIPSEL64 (EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_PARISC (EM_PARISC)
#define AUDIT_ARCH_PARISC64 (EM_PARISC|__AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_PPC (EM_PPC)
#define AUDIT_ARCH_PPC64 (EM_PPC64|__AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_S390 (EM_S390)
#define AUDIT_ARCH_S390X (EM_S390|__AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_SH (EM_SH)
#define AUDIT_ARCH_SHEL (EM_SH|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_SH64 (EM_SH|__AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_SHEL64 (EM_SH|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_SPARC (EM_SPARC)
#define AUDIT_ARCH_SPARC64 (EM_SPARC64|__AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_V850 (EM_V850|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_X86_64 (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#ifndef __KERNEL__
struct
audit_message
{
struct
nlmsghdr
nlh
;
...
...
@@ -129,32 +165,36 @@ struct audit_buffer;
struct
audit_context
;
struct
inode
;
#define AUDITSC_INVALID 0
#define AUDITSC_SUCCESS 1
#define AUDITSC_FAILURE 2
#define AUDITSC_RESULT(x) ( ((long)(x))<0?AUDITSC_FAILURE:AUDITSC_SUCCESS )
#ifdef CONFIG_AUDITSYSCALL
/* These are defined in auditsc.c */
/* Public API */
extern
int
audit_alloc
(
struct
task_struct
*
task
);
extern
void
audit_free
(
struct
task_struct
*
task
);
extern
void
audit_syscall_entry
(
struct
task_struct
*
task
,
extern
void
audit_syscall_entry
(
struct
task_struct
*
task
,
int
arch
,
int
major
,
unsigned
long
a0
,
unsigned
long
a1
,
unsigned
long
a2
,
unsigned
long
a3
);
extern
void
audit_syscall_exit
(
struct
task_struct
*
task
,
int
return_code
);
extern
void
audit_syscall_exit
(
struct
task_struct
*
task
,
int
failed
,
long
return_code
);
extern
void
audit_getname
(
const
char
*
name
);
extern
void
audit_putname
(
const
char
*
name
);
extern
void
audit_inode
(
const
char
*
name
,
const
struct
inode
*
inode
);
/* Private API (for audit.c only) */
extern
int
audit_receive_filter
(
int
type
,
int
pid
,
int
uid
,
int
seq
,
void
*
data
);
void
*
data
,
uid_t
loginuid
);
extern
void
audit_get_stamp
(
struct
audit_context
*
ctx
,
struct
timespec
*
t
,
int
*
serial
);
extern
int
audit_set_loginuid
(
struct
audit_context
*
ctx
,
uid_t
loginuid
);
struct
timespec
*
t
,
unsigned
int
*
serial
);
extern
int
audit_set_loginuid
(
struct
task_struct
*
task
,
uid_t
loginuid
);
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
);
#else
#define audit_alloc(t) ({ 0; })
#define audit_free(t) do { ; } while (0)
#define audit_syscall_entry(t,a,b,c,d,e) do { ; } while (0)
#define audit_syscall_exit(t,r) do { ; } while (0)
#define audit_syscall_entry(t,
ta,
a,b,c,d,e) do { ; } while (0)
#define audit_syscall_exit(t,
f,
r) do { ; } while (0)
#define audit_getname(n) do { ; } while (0)
#define audit_putname(n) do { ; } while (0)
#define audit_inode(n,i) do { ; } while (0)
...
...
@@ -174,11 +214,15 @@ extern void audit_log_format(struct audit_buffer *ab,
const
char
*
fmt
,
...)
__attribute__
((
format
(
printf
,
2
,
3
)));
extern
void
audit_log_end
(
struct
audit_buffer
*
ab
);
extern
void
audit_log_hex
(
struct
audit_buffer
*
ab
,
const
unsigned
char
*
buf
,
size_t
len
);
extern
void
audit_log_untrustedstring
(
struct
audit_buffer
*
ab
,
const
char
*
string
);
extern
void
audit_log_d_path
(
struct
audit_buffer
*
ab
,
const
char
*
prefix
,
struct
dentry
*
dentry
,
struct
vfsmount
*
vfsmnt
);
/* Private API (for auditsc.c only) */
extern
void
audit_send_reply
(
int
pid
,
int
seq
,
int
type
,
int
done
,
int
multi
,
...
...
@@ -190,6 +234,8 @@ extern void audit_log_lost(const char *message);
#define audit_log_vformat(b,f,a) do { ; } while (0)
#define audit_log_format(b,f,...) do { ; } while (0)
#define audit_log_end(b) do { ; } while (0)
#define audit_log_hex(a,b,l) do { ; } while (0)
#define audit_log_untrustedstring(a,s) do { ; } while (0)
#define audit_log_d_path(b,p,d,v) do { ; } while (0)
#endif
#endif
...
...
include/linux/netlink.h
View file @
6f817abc
...
...
@@ -110,6 +110,7 @@ struct netlink_skb_parms
__u32
dst_pid
;
__u32
dst_groups
;
kernel_cap_t
eff_cap
;
__u32
loginuid
;
/* Login (audit) uid */
};
#define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb))
...
...
init/Kconfig
View file @
6f817abc
...
...
@@ -173,7 +173,7 @@ config AUDIT
config AUDITSYSCALL
bool "Enable system-call auditing support"
depends on AUDIT && (X86 || PPC64 || ARCH_S390 || IA64)
depends on AUDIT && (X86 || PPC64 || ARCH_S390 || IA64
|| UML
)
default y if SECURITY_SELINUX
help
Enable low-overhead system-call auditing infrastructure that
...
...
kernel/audit.c
View file @
6f817abc
/* audit.c -- Auditing support
-*- linux-c -*-
/* audit.c -- Auditing support
* Gateway between the kernel (e.g., selinux) and the user-space audit daemon.
* System-call specific features have moved to auditsc.c
*
...
...
@@ -38,7 +38,7 @@
* 6) Support low-overhead kernel-based filtering to minimize the
* information that must be passed to user-space.
*
* Example user-space utilities: http://people.redhat.com/
faith
/audit/
* Example user-space utilities: http://people.redhat.com/
sgrubb
/audit/
*/
#include <linux/init.h>
...
...
@@ -142,7 +142,6 @@ struct audit_buffer {
int
total
;
int
type
;
int
pid
;
int
count
;
/* Times requeued */
};
void
audit_set_type
(
struct
audit_buffer
*
ab
,
int
type
)
...
...
@@ -239,36 +238,36 @@ void audit_log_lost(const char *message)
}
static
int
audit_set_rate_limit
(
int
limit
)
static
int
audit_set_rate_limit
(
int
limit
,
uid_t
loginuid
)
{
int
old
=
audit_rate_limit
;
audit_rate_limit
=
limit
;
audit_log
(
current
->
audit_context
,
"audit_rate_limit=%d old=%d
"
,
audit_rate_limit
,
ol
d
);
audit_log
(
NULL
,
"audit_rate_limit=%d old=%d by auid %u
"
,
audit_rate_limit
,
old
,
loginui
d
);
return
old
;
}
static
int
audit_set_backlog_limit
(
int
limit
)
static
int
audit_set_backlog_limit
(
int
limit
,
uid_t
loginuid
)
{
int
old
=
audit_backlog_limit
;
audit_backlog_limit
=
limit
;
audit_log
(
current
->
audit_context
,
"audit_backlog_limit=%d old=%d
"
,
audit_backlog_limit
,
ol
d
);
audit_log
(
NULL
,
"audit_backlog_limit=%d old=%d by auid %u
"
,
audit_backlog_limit
,
old
,
loginui
d
);
return
old
;
}
static
int
audit_set_enabled
(
int
state
)
static
int
audit_set_enabled
(
int
state
,
uid_t
loginuid
)
{
int
old
=
audit_enabled
;
if
(
state
!=
0
&&
state
!=
1
)
return
-
EINVAL
;
audit_enabled
=
state
;
audit_log
(
current
->
audit_context
,
"audit_enabled=%d old=%d
"
,
audit_enabled
,
old
);
audit_log
(
NULL
,
"audit_enabled=%d old=%d by auid %u
"
,
audit_enabled
,
old
,
loginuid
);
return
old
;
}
static
int
audit_set_failure
(
int
state
)
static
int
audit_set_failure
(
int
state
,
uid_t
loginuid
)
{
int
old
=
audit_failure
;
if
(
state
!=
AUDIT_FAIL_SILENT
...
...
@@ -276,8 +275,8 @@ static int audit_set_failure(int state)
&&
state
!=
AUDIT_FAIL_PANIC
)
return
-
EINVAL
;
audit_failure
=
state
;
audit_log
(
current
->
audit_context
,
"audit_failure=%d old=%d
"
,
audit_failure
,
old
);
audit_log
(
NULL
,
"audit_failure=%d old=%d by auid %u
"
,
audit_failure
,
old
,
loginuid
);
return
old
;
}
...
...
@@ -344,6 +343,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
int
err
;
struct
audit_buffer
*
ab
;
u16
msg_type
=
nlh
->
nlmsg_type
;
uid_t
loginuid
;
/* loginuid of sender */
err
=
audit_netlink_ok
(
NETLINK_CB
(
skb
).
eff_cap
,
msg_type
);
if
(
err
)
...
...
@@ -351,6 +351,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
pid
=
NETLINK_CREDS
(
skb
)
->
pid
;
uid
=
NETLINK_CREDS
(
skb
)
->
uid
;
loginuid
=
NETLINK_CB
(
skb
).
loginuid
;
seq
=
nlh
->
nlmsg_seq
;
data
=
NLMSG_DATA
(
nlh
);
...
...
@@ -371,34 +372,36 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return
-
EINVAL
;
status_get
=
(
struct
audit_status
*
)
data
;
if
(
status_get
->
mask
&
AUDIT_STATUS_ENABLED
)
{
err
=
audit_set_enabled
(
status_get
->
enabled
);
err
=
audit_set_enabled
(
status_get
->
enabled
,
loginuid
);
if
(
err
<
0
)
return
err
;
}
if
(
status_get
->
mask
&
AUDIT_STATUS_FAILURE
)
{
err
=
audit_set_failure
(
status_get
->
failure
);
err
=
audit_set_failure
(
status_get
->
failure
,
loginuid
);
if
(
err
<
0
)
return
err
;
}
if
(
status_get
->
mask
&
AUDIT_STATUS_PID
)
{
int
old
=
audit_pid
;
audit_pid
=
status_get
->
pid
;
audit_log
(
current
->
audit_context
,
"audit_pid=%d old=%d"
,
audit_pid
,
ol
d
);
audit_log
(
NULL
,
"audit_pid=%d old=%d by auid %u"
,
audit_pid
,
old
,
loginui
d
);
}
if
(
status_get
->
mask
&
AUDIT_STATUS_RATE_LIMIT
)
audit_set_rate_limit
(
status_get
->
rate_limit
);
audit_set_rate_limit
(
status_get
->
rate_limit
,
loginuid
);
if
(
status_get
->
mask
&
AUDIT_STATUS_BACKLOG_LIMIT
)
audit_set_backlog_limit
(
status_get
->
backlog_limit
);
audit_set_backlog_limit
(
status_get
->
backlog_limit
,
loginuid
);
break
;
case
AUDIT_USER
:
ab
=
audit_log_start
(
NULL
);
if
(
!
ab
)
break
;
/* audit_panic has been called */
audit_log_format
(
ab
,
"user pid=%d uid=%d length=%d msg='%.1024s'"
,
"user pid=%d uid=%d length=%d loginuid=%u"
" msg='%.1024s'"
,
pid
,
uid
,
(
int
)(
nlh
->
nlmsg_len
-
((
char
*
)
data
-
(
char
*
)
nlh
)),
(
char
*
)
data
);
loginuid
,
(
char
*
)
data
);
ab
->
type
=
AUDIT_USER
;
ab
->
pid
=
pid
;
audit_log_end
(
ab
);
...
...
@@ -411,7 +414,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
case
AUDIT_LIST
:
#ifdef CONFIG_AUDITSYSCALL
err
=
audit_receive_filter
(
nlh
->
nlmsg_type
,
NETLINK_CB
(
skb
).
pid
,
uid
,
seq
,
data
);
uid
,
seq
,
data
,
loginuid
);
#else
err
=
-
EOPNOTSUPP
;
#endif
...
...
@@ -480,7 +483,7 @@ static void audit_log_move(struct audit_buffer *ab)
if
(
ab
->
len
==
0
)
return
;
skb
=
skb_peek
(
&
ab
->
sklist
);
skb
=
skb_peek
_tail
(
&
ab
->
sklist
);
if
(
!
skb
||
skb_tailroom
(
skb
)
<=
ab
->
len
+
extra
)
{
skb
=
alloc_skb
(
2
*
ab
->
len
+
extra
,
GFP_ATOMIC
);
if
(
!
skb
)
{
...
...
@@ -519,9 +522,9 @@ static inline int audit_log_drain(struct audit_buffer *ab)
retval
=
netlink_unicast
(
audit_sock
,
skb
,
audit_pid
,
MSG_DONTWAIT
);
}
if
(
retval
==
-
EAGAIN
&&
ab
->
count
<
5
)
{
++
ab
->
count
;
skb_queue_
tail
(
&
ab
->
sklist
,
skb
);
if
(
retval
==
-
EAGAIN
&&
(
atomic_read
(
&
audit_backlog
))
<
audit_backlog_limit
)
{
skb_queue_
head
(
&
ab
->
sklist
,
skb
);
audit_log_end_irq
(
ab
);
return
1
;
}
...
...
@@ -537,8 +540,8 @@ static inline int audit_log_drain(struct audit_buffer *ab)
if
(
!
audit_pid
)
{
/* No daemon */
int
offset
=
ab
->
nlh
?
NLMSG_SPACE
(
0
)
:
0
;
int
len
=
skb
->
len
-
offset
;
printk
(
KERN_ERR
"%*.*s
\n
"
,
len
,
len
,
skb
->
data
+
offset
);
skb
->
data
[
offset
+
len
]
=
'\0'
;
printk
(
KERN_ERR
"%s
\n
"
,
skb
->
data
+
offset
);
}
kfree_skb
(
skb
);
ab
->
nlh
=
NULL
;
...
...
@@ -617,7 +620,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx)
struct
audit_buffer
*
ab
=
NULL
;
unsigned
long
flags
;
struct
timespec
t
;
int
serial
=
0
;
unsigned
int
serial
;
if
(
!
audit_initialized
)
return
NULL
;
...
...
@@ -659,15 +662,16 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx)
ab
->
total
=
0
;
ab
->
type
=
AUDIT_KERNEL
;
ab
->
pid
=
0
;
ab
->
count
=
0
;
#ifdef CONFIG_AUDITSYSCALL
if
(
ab
->
ctx
)
audit_get_stamp
(
ab
->
ctx
,
&
t
,
&
serial
);
else
#endif
{
t
=
CURRENT_TIME
;
serial
=
0
;
}
audit_log_format
(
ab
,
"audit(%lu.%03lu:%u): "
,
t
.
tv_sec
,
t
.
tv_nsec
/
1000000
,
serial
);
return
ab
;
...
...
@@ -717,6 +721,29 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
va_end
(
args
);
}
void
audit_log_hex
(
struct
audit_buffer
*
ab
,
const
unsigned
char
*
buf
,
size_t
len
)
{
int
i
;
for
(
i
=
0
;
i
<
len
;
i
++
)
audit_log_format
(
ab
,
"%02x"
,
buf
[
i
]);
}
void
audit_log_untrustedstring
(
struct
audit_buffer
*
ab
,
const
char
*
string
)
{
const
unsigned
char
*
p
=
string
;
while
(
*
p
)
{
if
(
*
p
==
'"'
||
*
p
==
' '
||
*
p
<
0x20
||
*
p
>
0x7f
)
{
audit_log_hex
(
ab
,
string
,
strlen
(
string
));
return
;
}
p
++
;
}
audit_log_format
(
ab
,
"
\"
%s
\"
"
,
string
);
}
/* This is a helper-function to print the d_path without using a static
* buffer or allocating another buffer in addition to the one in
* audit_buffer. */
...
...
kernel/auditsc.c
View file @
6f817abc
/* auditsc.c -- System-call auditing support
-*- linux-c -*-
/* auditsc.c -- System-call auditing support
* Handles all system-call specific auditing features.
*
* Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
...
...
@@ -123,7 +123,7 @@ struct audit_context {
int
major
;
/* syscall number */
unsigned
long
argv
[
4
];
/* syscall arguments */
int
return_valid
;
/* return code is valid */
int
return_code
;
/* syscall return code */
long
return_code
;
/* syscall return code */
int
auditable
;
/* 1 if record should be written */
int
name_count
;
struct
audit_names
names
[
AUDIT_NAMES
];
...
...
@@ -135,6 +135,7 @@ struct audit_context {
uid_t
uid
,
euid
,
suid
,
fsuid
;
gid_t
gid
,
egid
,
sgid
,
fsgid
;
unsigned
long
personality
;
int
arch
;
#if AUDIT_DEBUG
int
put_count
;
...
...
@@ -250,7 +251,8 @@ static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s)
return
0
;
}
int
audit_receive_filter
(
int
type
,
int
pid
,
int
uid
,
int
seq
,
void
*
data
)
int
audit_receive_filter
(
int
type
,
int
pid
,
int
uid
,
int
seq
,
void
*
data
,
uid_t
loginuid
)
{
u32
flags
;
struct
audit_entry
*
entry
;
...
...
@@ -285,6 +287,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
err
=
audit_add_rule
(
entry
,
&
audit_entlist
);
if
(
!
err
&&
(
flags
&
AUDIT_AT_EXIT
))
err
=
audit_add_rule
(
entry
,
&
audit_extlist
);
audit_log
(
NULL
,
"auid %u added an audit rule
\n
"
,
loginuid
);
break
;
case
AUDIT_DEL
:
flags
=
((
struct
audit_rule
*
)
data
)
->
flags
;
...
...
@@ -294,6 +297,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
err
=
audit_del_rule
(
data
,
&
audit_entlist
);
if
(
!
err
&&
(
flags
&
AUDIT_AT_EXIT
))
err
=
audit_del_rule
(
data
,
&
audit_extlist
);
audit_log
(
NULL
,
"auid %u removed an audit rule
\n
"
,
loginuid
);
break
;
default:
return
-
EINVAL
;
...
...
@@ -348,6 +352,10 @@ static int audit_filter_rules(struct task_struct *tsk,
case
AUDIT_PERS
:
result
=
(
tsk
->
personality
==
value
);
break
;
case
AUDIT_ARCH
:
if
(
ctx
)
result
=
(
ctx
->
arch
==
value
);
break
;
case
AUDIT_EXIT
:
if
(
ctx
&&
ctx
->
return_valid
)
...
...
@@ -355,7 +363,7 @@ static int audit_filter_rules(struct task_struct *tsk,
break
;
case
AUDIT_SUCCESS
:
if
(
ctx
&&
ctx
->
return_valid
)
result
=
(
ctx
->
return_
code
>=
0
);
result
=
(
ctx
->
return_
valid
==
AUDITSC_SUCCESS
);
break
;
case
AUDIT_DEVMAJOR
:
if
(
ctx
)
{
...
...
@@ -648,8 +656,11 @@ static void audit_log_exit(struct audit_context *context)
audit_log_format
(
ab
,
"syscall=%d"
,
context
->
major
);
if
(
context
->
personality
!=
PER_LINUX
)
audit_log_format
(
ab
,
" per=%lx"
,
context
->
personality
);
audit_log_format
(
ab
,
" arch=%x"
,
context
->
arch
);
if
(
context
->
return_valid
)
audit_log_format
(
ab
,
" exit=%d"
,
context
->
return_code
);
audit_log_format
(
ab
,
" success=%s exit=%ld"
,
(
context
->
return_valid
==
AUDITSC_SUCCESS
)
?
"yes"
:
"no"
,
context
->
return_code
);
audit_log_format
(
ab
,
" a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
" pid=%d loginuid=%d uid=%d gid=%d"
...
...
@@ -696,9 +707,10 @@ static void audit_log_exit(struct audit_context *context)
if
(
!
ab
)
continue
;
/* audit_panic has been called */
audit_log_format
(
ab
,
"item=%d"
,
i
);
if
(
context
->
names
[
i
].
name
)
audit_log_format
(
ab
,
" name=%s"
,
context
->
names
[
i
].
name
);
if
(
context
->
names
[
i
].
name
)
{
audit_log_format
(
ab
,
" name="
);
audit_log_untrustedstring
(
ab
,
context
->
names
[
i
].
name
);
}
if
(
context
->
names
[
i
].
ino
!=
(
unsigned
long
)
-
1
)
audit_log_format
(
ab
,
" inode=%lu dev=%02x:%02x mode=%#o"
" uid=%d gid=%d rdev=%02x:%02x"
,
...
...
@@ -772,7 +784,7 @@ static inline unsigned int audit_serial(void)
* then the record will be written at syscall exit time (otherwise, it
* will only be written if another part of the kernel requests that it
* be written). */
void
audit_syscall_entry
(
struct
task_struct
*
tsk
,
int
major
,
void
audit_syscall_entry
(
struct
task_struct
*
tsk
,
int
arch
,
int
major
,
unsigned
long
a1
,
unsigned
long
a2
,
unsigned
long
a3
,
unsigned
long
a4
)
{
...
...
@@ -826,6 +838,7 @@ void audit_syscall_entry(struct task_struct *tsk, int major,
if
(
!
audit_enabled
)
return
;
context
->
arch
=
arch
;
context
->
major
=
major
;
context
->
argv
[
0
]
=
a1
;
context
->
argv
[
1
]
=
a2
;
...
...
@@ -849,13 +862,13 @@ void audit_syscall_entry(struct task_struct *tsk, int major,
* filtering, or because some other part of the kernel write an audit
* message), then write out the syscall information. In call cases,
* free the names stored from getname(). */
void
audit_syscall_exit
(
struct
task_struct
*
tsk
,
int
return_code
)
void
audit_syscall_exit
(
struct
task_struct
*
tsk
,
int
valid
,
long
return_code
)
{
struct
audit_context
*
context
;
get_task_struct
(
tsk
);
task_lock
(
tsk
);
context
=
audit_get_context
(
tsk
,
1
,
return_code
);
context
=
audit_get_context
(
tsk
,
valid
,
return_code
);
task_unlock
(
tsk
);
/* Not having a context here is ok, since the parent may have
...
...
@@ -868,6 +881,7 @@ void audit_syscall_exit(struct task_struct *tsk, int return_code)
context
->
in_syscall
=
0
;
context
->
auditable
=
0
;
if
(
context
->
previous
)
{
struct
audit_context
*
new_context
=
context
->
previous
;
context
->
previous
=
NULL
;
...
...
@@ -981,7 +995,7 @@ void audit_inode(const char *name, const struct inode *inode)
}
void
audit_get_stamp
(
struct
audit_context
*
ctx
,
struct
timespec
*
t
,
int
*
serial
)
struct
timespec
*
t
,
unsigned
int
*
serial
)
{
if
(
ctx
)
{
t
->
tv_sec
=
ctx
->
ctime
.
tv_sec
;
...
...
@@ -996,20 +1010,21 @@ void audit_get_stamp(struct audit_context *ctx,
extern
int
audit_set_type
(
struct
audit_buffer
*
ab
,
int
type
);
int
audit_set_loginuid
(
struct
audit_context
*
ctx
,
uid_t
loginuid
)
int
audit_set_loginuid
(
struct
task_struct
*
task
,
uid_t
loginuid
)
{
if
(
ctx
)
{
if
(
task
->
audit_context
)
{
struct
audit_buffer
*
ab
;
ab
=
audit_log_start
(
NULL
);
if
(
ab
)
{
audit_log_format
(
ab
,
"login pid=%d uid=%u "
"old loginuid=%u new loginuid=%u"
,
ctx
->
pid
,
ctx
->
uid
,
ctx
->
loginuid
,
loginuid
);
task
->
pid
,
task
->
uid
,
task
->
audit_context
->
loginuid
,
loginuid
);
audit_set_type
(
ab
,
AUDIT_LOGIN
);
audit_log_end
(
ab
);
}
ctx
->
loginuid
=
loginuid
;
task
->
audit_context
->
loginuid
=
loginuid
;
}
return
0
;
}
...
...
net/netlink/af_netlink.c
View file @
6f817abc
...
...
@@ -49,6 +49,8 @@
#include <linux/bitops.h>
#include <linux/mm.h>
#include <linux/types.h>
#include <linux/audit.h>
#include <net/sock.h>
#include <net/scm.h>
...
...
@@ -904,6 +906,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
NETLINK_CB
(
skb
).
groups
=
nlk
->
groups
;
NETLINK_CB
(
skb
).
dst_pid
=
dst_pid
;
NETLINK_CB
(
skb
).
dst_groups
=
dst_groups
;
NETLINK_CB
(
skb
).
loginuid
=
audit_get_loginuid
(
current
->
audit_context
);
memcpy
(
NETLINK_CREDS
(
skb
),
&
siocb
->
scm
->
creds
,
sizeof
(
struct
ucred
));
/* What can I do? Netlink is asynchronous, so that
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment