[PATCH 0/4] AUDIT: enable build on 2.6.35.13-91 (or earlier) kernels
by Mr Dash Four
All,
Further to the private discussion I've had with Steve Grubb over the past few days, I am attaching a series of 4 patches enabling the AUDIT target, which was first introduced in the .39 version of the kernel, to run on version .35 (or even lower kernel versions, testing & further tweaking permitted).
The reason, which prompted me to adopt this in earlier versions is because I saw huge benefit in using this superb feature - at least on my systems here (it would finally enable me to combine all security-related reporting into one single, secure place/source, without messing about with syslogs spread over various different places) and I couldn't afford to wait until the .39 kernel becomes "official" (in Fedora terms, at least). The feature is deployed and in fully working order on two of my machines here, though I am having trouble producing matches (see below).
I have split the patches intentionally so that it is clear to everyone what is happening. All of them are made against the 2.6.35.13-91 source tree as distributed by Fedora (taken directly from the source rpm and dumped into a local git repository, after which I applied all the necessary source files to create the patches).
The first 3 patches are more-or-less carbon copy of what was submitted and implemented in the .39 version of the kernel, with one significant exception: xt_AUDIT.c has various #ifdef's added so that it disables IPV6-related stuff if IPV6 is not enabled on the kernel during compilation. This, I was told, was fixed in .37 (and later) versions of the kernel - commit 2ea6d8c4467 (net: Enter net/ipv6/ even if CONFIG_IPV6=n) and it is not necessary in later versions of that kernel.
I suspect the last patch is more interesting as it adds SELinux support to the AUDIT target. Typical (raw auditd) output after applying this patch would be something like this:
type=NETFILTER_PKT msg=audit(1305852240.082:31012): action=0 hook=3 len=52 inif=? outif=eth0 obj=system_u:object_r:ssh_client_packet_t:s0 saddr=10.1.1.7 daddr=10.1.2.1 ipid=16312 proto=6 sport=56150 dport=22
I am, however, unable to get any matching (particularly on SELinux role, subject or user) when using ausearch/aureport (one of the main reasons I wanted to get on this list and seek some advice).
Last, but not least, I am no expert in audit(d) and am still learning so go easy on me! :)
Mr Dash Four (4):
AUDIT: add source files to enable build on 2.6.35.13-91 kernel
AUDIT: modify Makefiles to enable build in 2.6.35.13-91 kernel
AUDIT: modify Kconfig to enable build in 2.6.35.13-91 kernel
AUDIT: add SELinux support
include/linux/audit.h | 2 +
include/linux/netfilter/Kbuild | 1 +
include/linux/netfilter/xt_AUDIT.h | 30 +++++
kernel/audit.c | 2 +
net/netfilter/Kconfig | 10 ++
net/netfilter/Makefile | 1 +
net/netfilter/xt_AUDIT.c | 249 ++++++++++++++++++++++++++++++++++++
7 files changed, 295 insertions(+), 0 deletions(-)
create mode 100644 include/linux/netfilter/xt_AUDIT.h
create mode 100644 net/netfilter/xt_AUDIT.c
--
1.7.3.4
13 years, 7 months
Re: [PATCH] audit: ia32entry.S drops useful return value sign bits
by Eric Paris
On Tue, 2011-05-24 at 09:18 -0700, H. Peter Anvin wrote:
> On 05/24/2011 06:55 AM, Thomas Gleixner wrote:
> >> This seems like the fundamental design error.
> >
> > I don't think so. We run in 64bit mode here and call into 64bit code
> > which expects a long being 64bit and not a 32bit truncated value. The
> > audit code is pure kernel stuff and this is not the return to
> > userspace.
>
> I don't agree, this is about auditing the return to userspace. For the
> IA32 entry point, the return value is a 32-bit value even if we happen
> to return to 64-bit userspace. Treating it as anything else is asking
> for a security hole when we audit something that isn't what we do.
>
> As such, the right thing to do is probably:
>
> movl %eax, %esi
> cmpl $-MAX_ERRNO, %eax
> jb 1f
> movslq %eax, %rsi
> 1: setae %al
I'll do it that way if you want. But you now have an extra jb and an
extra movl, neither of which do anything at all. It's no different than
movq %rax, %rsi
cmp{q,l} $-MAX_ERRNO, %{r,e}ax
setae %al
I know it's the same because I spent forever trying to hunt down movslq.
I don't understand why it's not in the Intel® 64 and IA-32 Architectures
Software Developer’s Manual Volume 2 (2A & 2B): Instruction Set
Reference, A-Z. That's exactly what I talked about, truncating the
upper 32 bits just the sign extend them right back.
I guess it comes down to picking one of these 3:
My version:
movq %rax,%rsi /* second arg, syscall return value */
cmpl $-MAX_ERRNO,%rax /* is it < 0? */
setbe %al /* 1 if so, 0 if not */
movzbl %al,%edi /* zero-extend that into %edi */
call __audit_syscall_exit
VS hpa version:
movl %eax,%esi /* move 32bits to second arg */
cmpl $-MAX_ERRNO,%eax /* check if fail */
jbe 1f
movslq %eax, %rsi /* re-sign-extend eax */
1: setbe %al
movzbl %al,%edi
call __audit_syscall_exit
VS alternate of hpa version without set:
movl $1,%edi /* syscall success argument */
movl %eax,%esi /* move 32bits to second arg */
cmpl $-MAX_ERRNO,%eax /* check if fail */
jbe 1f
xor %edi,%edi /* syscall failure argument */
movslq %eax, %rsi /* resign-extend eax */
1: call __audit_syscall_exit
If I have to go with the hpa version of truncation followed by sign
extension, is it any better/cheap/faster to use just movl in the
'common' case and movl+xor in the uncommon syscall failure? I don't
know how expensive or large the set+movzbl is....
13 years, 7 months
Re: [PATCH] audit: ia32entry.S drops useful return value sign bits
by Eric Paris
On 05/23/2011 09:19 PM, H. Peter Anvin wrote:
> On 05/23/2011 06:04 PM, Eric Paris wrote:
>> 1) The audit_syscall_exit function expects a long. But if you chop off
>> the upper 32 bits you can't tell positive from negative. Thus when it
>> prints to userspace using %ld we have a problem:
>> Aka printf("%ld", (long)(u32)(-13)) = "4294967283"
>> vs printf("%ld", (long)(-13)) = "-13"
>
> This seems like the fundamental design error.
Possibly so (I'm not convinced), but not a fixable problem given the bug
for bug compatibility requirements of the kernel. The syscall return
value (either rax or eax) is passed to audit_syscall_exit() which
believes it is a long (aka s64). It builds a string buffer using
sprintf("%ld") and then exports that buffer to userspace via a netlink
socket. That buffer gets dumped as a raw string into a file. Some
tools may later process the strings. Getting the right string into the
netlink socket is what I consider the unchangeable ABI. Prior to
5cbf1565f29eb57a this was all handled by normal 64bit C code which did
exactly what I'm describing here. It never needlessly truncated the
return code to 32 bits on ia32exit. Solving that regression is what I'm
fixing.
> You're missing something fundamental: if userspace is 32 bits, those
> bits don't even exist. If userspace is 64 bits (and it is possible for
> a 64-bit process to call the 32-bit entry point) those bits could at
> least theoretically contain bad information.
This is at syscall exit, in 64bit mode, so rax is going to contain a
64bit version of the return code. I'm not trying to hand 64 bit values
back to a 32 bit process. The code converts the return value using %ld
and then dumps it as a string to auditd. Even if auditd was 32bit, it's
not processing the string, just writing it to a file.
> It sounds like this code is broken in some very fundamental ways, and
> that you're trying to paper it over.
Obviously we agree there is a second problem not addressed in this patch
(that many arches uses +/- instead of >=-MAX_ERRNO) but the fact that we
have a regression in which the assembly removes the sign and then passes
the now truncated value to a function expecting a long is the problem of
this patch.
I could paper over the problem in the audit code, doing my own sign
craziness based on the arch, but I think the real problem is in the
assembly dropping information needlessly.....
-Eric
13 years, 7 months
Re: [PATCH] audit: ia32entry.S drops useful return value sign bits
by Eric Paris
On 05/23/2011 08:50 PM, H. Peter Anvin wrote:
> On 05/23/2011 05:41 PM, Eric Paris wrote:
>> In the ia32entry syscall exit audit fastpath we have assembly code which calls
>> audit_syscall_exit directly. This code was, however, incorrectly zeroing
>> the upper 32 bits of the return code. It then proceeded to do a 32bit check
>> for positive/negative to determine the syscalls success. This meant that
>> syscalls like mmap2 which might return a very large 32 bit address as the
>> pointer would be mistaken for a negative return code. It also meant that
>> negative return codes would be mistaken for 32 bit numbers on output.
>>
>> The fix is to not zero the upper 32 bits of the return value and to do a full
>> 64bit negative/postive determination for syscall success.
>>
>
> I'm not sure that's correct.
>
> I would argue that the fix is do a 32-bit comparison. Comparing the
> sign value is wrong, anyway: error is indicated by a value in the range
> -4095 to -1, so to match userspace expectations it should be:
>
> cmpl $-4095, %eax
> setae %al
>
> -hpa
I actually have a followup patch which does this, but which
simultaneously fixes all arches. It's bigger than this specific problem
though. I guess we can see this as 2 problems.
1) The audit_syscall_exit function expects a long. But if you chop off
the upper 32 bits you can't tell positive from negative. Thus when it
prints to userspace using %ld we have a problem:
Aka printf("%ld", (long)(u32)(-13)) = "4294967283"
vs printf("%ld", (long)(-13)) = "-13"
2) The current code uses pos/neg to determine 'success' on many arches.
It should use >= -MAX_ERRNO
I had patches briefly which truncated rax to 32 bits. Checked if it was
an errno, then if so, sign extended it back to 64 bits for the call to
audit_syscall_exit. Although that logically made sense it wasted
instructions doing truncation of rax->eax and then sometimes expansion
back when rax had the right upper 32 bits all along.
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index b2bea0a..d9170de 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -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>
@@ -210,11 +211,10 @@ sysexit_from_sys_call:
TRACE_IRQS_ON
sti
movq %rax,%rsi /* second arg, syscall return value */
- cmpq $0,%rax /* is it < 0? */
+ cmpq $-MAX_ERRNO,%rax /* is it < 0? */
13 years, 7 months
[PATCH] audit: ia32entry.S drops useful return value sign bits
by Eric Paris
In the ia32entry syscall exit audit fastpath we have assembly code which calls
audit_syscall_exit directly. This code was, however, incorrectly zeroing
the upper 32 bits of the return code. It then proceeded to do a 32bit check
for positive/negative to determine the syscalls success. This meant that
syscalls like mmap2 which might return a very large 32 bit address as the
pointer would be mistaken for a negative return code. It also meant that
negative return codes would be mistaken for 32 bit numbers on output.
The fix is to not zero the upper 32 bits of the return value and to do a full
64bit negative/postive determination for syscall success.
Old record returning a pointer:
type=SYSCALL msg=audit(1305733850.639:224): arch=40000003 syscall=192 success=no exit=4151844864
New Record with positive/negative test fixing "success":
type=SYSCALL msg=audit(1305733850.639:224): arch=40000003 syscall=192 success=yes exit=4151844864
Old record returning an error:
type=SYSCALL msg=audit(1306197182.256:281): arch=40000003 syscall=192 success=no exit=4294967283
New record returning -13:
type=SYSCALL msg=audit(1306197182.256:281): arch=40000003 syscall=192 success=no exit=-13
Signed-off-by: Eric Paris <eparis(a)redhat.com>
---
arch/x86/ia32/ia32entry.S | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index c1870dd..b2bea0a 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -209,14 +209,14 @@ sysexit_from_sys_call:
jnz ia32_ret_from_sys_call
TRACE_IRQS_ON
sti
- movl %eax,%esi /* second arg, syscall return value */
- cmpl $0,%eax /* is it < 0? */
+ movq %rax,%rsi /* second arg, syscall return value */
+ cmpq $0,%rax /* is it < 0? */
setl %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
GET_THREAD_INFO(%r10)
- movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall return value */
+ movq RAX-ARGOFFSET(%rsp),%rax /* reload syscall return value */
movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi
cli
TRACE_IRQS_OFF
13 years, 7 months
[PATCH] MIPS syscall auditing patches
by Ralf Baechle
this is the first cut of the MIPS auditing patches. MIPS doesn't quite
fit into the existing pattern of other architectures and I'd appreciate
your comments and maybe even an Acked-by.
- MIPS syscalls return a success / error flag in register $7. If the
flag is set then the return value in $2 is a *positive* error value.
This means the existing AUDITSC_RESULT() macro does not work on
MIPS and thus ptrace.c defines it's own version MIPS_AUDITSC_RESULT().
- Linux on MIPS extends the traditional syscall table used by older UNIX
implementations. This is why 32-bit Linux syscalls are starting from
4000; the native 64-bit syscalls start from 5000 and the N32 compat ABI
from 6000. The existing syscall bitmap is only large enough for at most
2048 syscalls, so I had to increase AUDIT_BITMASK_SIZE to 256 which
provides enough space for 8192 syscalls. Because include/linux/audit.h
and AUDIT_BITMASK_SIZE are exported to userspace I've used an #ifdef
__mips__ for this.
- I've introduced a flag __AUDIT_ARCH_ALT to indicate an alternative ABI.
The name of the flag is intentionally very generic to make the name
hopefully fit other architectures' eventual need as well. On MIPS it
indicates the 3rd ABI known as N32.
- To make matters worse, most MIPS processors can be configured to be
big or little endian. Traditionally the the 64-bit little endian
configuration is named mips64el, so I've changed references to MIPSEL64
in audit.h to MIPS64EL.
- The code treats the little endian MIPS architecture as separate from
big endian. Combined with the 3 ABIs that's 6 combinations. I tried
to sort of follow the example set by ARM which explicitly lists the
(rare) big endian architecture variant - but it doesn't seem to very
useful so I wonder if this could be squashed to just the three ABIs
without consideration of endianess?
- Talking about flags; I've defined the the N32 architecture flags were defined
#define AUDIT_ARCH_MIPS64_N32 (EM_MIPS|__AUDIT_ARCH_ALT)
#define AUDIT_ARCH_MIPS64EL_N32 (EM_MIPS|__AUDIT_ARCH_ALT|__AUDIT_ARCH_LE
N32 is a 32-bit ABI but one that only runs on 64-bit processors as it
uses 64-bit registers for 64-bit integers. So I'm uncertain if the
__AUDIT_ARCH_64BIT flags should be set or not.
Thanks in advance,
Signed-off-by: Ralf Baechle <ralf(a)linux-mips.org>
---
arch/mips/Kconfig | 12 +++++
arch/mips/include/asm/abi.h | 1 +
arch/mips/include/asm/unistd.h | 31 +++++++++----
arch/mips/kernel/Makefile | 4 ++
arch/mips/kernel/audit-n32.c | 58 ++++++++++++++++++++++++
arch/mips/kernel/audit-native.c | 92 +++++++++++++++++++++++++++++++++++++++
arch/mips/kernel/audit-o32.c | 60 +++++++++++++++++++++++++
arch/mips/kernel/ptrace.c | 24 ++++------
arch/mips/kernel/signal.c | 20 ++++++++-
arch/mips/kernel/signal32.c | 10 ++++-
arch/mips/kernel/signal_n32.c | 10 ++++-
arch/mips/kernel/syscall.c | 2 +
include/linux/audit.h | 21 ++++++++-
init/Kconfig | 2 +-
14 files changed, 319 insertions(+), 28 deletions(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 351c80f..f50c897 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1,6 +1,7 @@
config MIPS
bool
default y
+ select AUDIT_ARCH
select HAVE_GENERIC_DMA_COHERENT
select HAVE_IDE
select HAVE_OPROFILE
@@ -811,6 +812,15 @@ config ARC
config ARCH_MAY_HAVE_PC_FDC
bool
+config AUDIT_ARCH
+ bool
+
+config AUDITSYSCALL_O32
+ bool
+
+config AUDITSYSCALL_N32
+ bool
+
config BOOT_RAW
bool
@@ -2383,6 +2393,7 @@ config SYSVIPC_COMPAT
config MIPS32_O32
bool "Kernel support for o32 binaries"
depends on MIPS32_COMPAT
+ select AUDITSYSCALL_O32 if AUDITSYSCALL
help
Select this option if you want to run o32 binaries. These are pure
32-bit binaries as used by the 32-bit Linux/MIPS port. Most of
@@ -2393,6 +2404,7 @@ config MIPS32_O32
config MIPS32_N32
bool "Kernel support for n32 binaries"
depends on MIPS32_COMPAT
+ select AUDITSYSCALL_N32 if AUDITSYSCALL
help
Select this option if you want to run n32 binaries. These are
64-bit binaries using 32-bit quantities for addressing and certain
diff --git a/arch/mips/include/asm/abi.h b/arch/mips/include/asm/abi.h
index 9252d9b..af5f558 100644
--- a/arch/mips/include/asm/abi.h
+++ b/arch/mips/include/asm/abi.h
@@ -22,6 +22,7 @@ struct mips_abi {
sigset_t *set, siginfo_t *info);
const unsigned long rt_signal_return_offset;
const unsigned long restart;
+ const int audit_arch;
};
#endif /* _ASM_ABI_H */
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
index fa2e37e..fe7f3a5 100644
--- a/arch/mips/include/asm/unistd.h
+++ b/arch/mips/include/asm/unistd.h
@@ -5,16 +5,15 @@
*
* Copyright (C) 1995, 96, 97, 98, 99, 2000 by Ralf Baechle
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
- *
- * Changed system calls macros _syscall5 - _syscall7 to push args 5 to 7 onto
- * the stack. Robin Farine for ACN S.A, Copyright (C) 1996 by ACN S.A
*/
#ifndef _ASM_UNISTD_H
#define _ASM_UNISTD_H
#include <asm/sgidefs.h>
-#if _MIPS_SIM == _MIPS_SIM_ABI32
+#if (defined(__WANT_SYSCALL_NUMBERS) && \
+ (__WANT_SYSCALL_NUMBERS == _MIPS_SIM_ABI32)) || \
+ (!defined(__WANT_SYSCALL_NUMBERS) && _MIPS_SIM == _MIPS_SIM_ABI32)
/*
* Linux o32 style syscalls are in the range from 4000 to 4999.
@@ -369,12 +368,14 @@
*/
#define __NR_Linux_syscalls 342
-#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+#endif /* Want O32 || _MIPS_SIM == _MIPS_SIM_ABI32 */
#define __NR_O32_Linux 4000
#define __NR_O32_Linux_syscalls 342
-#if _MIPS_SIM == _MIPS_SIM_ABI64
+#if (defined(__WANT_SYSCALL_NUMBERS) && \
+ (__WANT_SYSCALL_NUMBERS == _MIPS_SIM_ABI64)) || \
+ (!defined(__WANT_SYSCALL_NUMBERS) && _MIPS_SIM == _MIPS_SIM_ABI64)
/*
* Linux 64-bit syscalls are in the range from 5000 to 5999.
@@ -688,12 +689,14 @@
*/
#define __NR_Linux_syscalls 301
-#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
+#endif /* Want N64 || _MIPS_SIM == _MIPS_SIM_ABI64 */
#define __NR_64_Linux 5000
#define __NR_64_Linux_syscalls 301
-#if _MIPS_SIM == _MIPS_SIM_NABI32
+#if (defined(__WANT_SYSCALL_NUMBERS) && \
+ (__WANT_SYSCALL_NUMBERS == _MIPS_SIM_NABI32)) || \
+ (!defined(__WANT_SYSCALL_NUMBERS) && _MIPS_SIM == _MIPS_SIM_NABI32)
/*
* Linux N32 syscalls are in the range from 6000 to 6999.
@@ -1012,7 +1015,7 @@
*/
#define __NR_Linux_syscalls 306
-#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
+#endif /* Want N32 || _MIPS_SIM == _MIPS_SIM_NABI32 */
#define __NR_N32_Linux 6000
#define __NR_N32_Linux_syscalls 306
@@ -1075,5 +1078,15 @@
*/
#define cond_syscall(x) asm(".weak\t" #x "\n" #x "\t=\tsys_ni_syscall")
+#ifdef CONFIG_MIPS32_N32
+#define NR_syscalls (__NR_N32_Linux + __NR_N32_Linux_syscalls)
+#elif defined(CONFIG_64BIT)
+#define NR_syscalls (__NR_64_Linux + __NR_64_Linux_syscalls)
+#elif defined(CONFIG_32BIT)
+#define NR_syscalls (__NR_O32_Linux + __NR_O32_Linux_syscalls)
+#else
+#error Must know ABIs in use to define NR_syscalls
+#endif
+
#endif /* __KERNEL__ */
#endif /* _ASM_UNISTD_H */
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index cedee2b..2016ca7 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -109,4 +109,8 @@ obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
+obj-$(CONFIG_AUDITSYSCALL_O32) += audit-o32.o
+obj-$(CONFIG_AUDITSYSCALL_N32) += audit-n32.o
+obj-$(CONFIG_AUDITSYSCALL) += audit-native.o
+
CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
diff --git a/arch/mips/kernel/audit-n32.c b/arch/mips/kernel/audit-n32.c
new file mode 100644
index 0000000..2248bad
--- /dev/null
+++ b/arch/mips/kernel/audit-n32.c
@@ -0,0 +1,58 @@
+#define __WANT_SYSCALL_NUMBERS _MIPS_SIM_NABI32
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/audit.h>
+#include <asm/unistd.h>
+
+static unsigned dir_class_n32[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+static unsigned read_class_n32[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+static unsigned write_class_n32[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+static unsigned chattr_class_n32[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+static unsigned signal_class_n32[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
+int audit_classify_syscall_n32(int abi, unsigned syscall)
+{
+ switch (syscall) {
+ case __NR_open:
+ return 2;
+ case __NR_openat:
+ return 3;
+ case __NR_execve:
+ return 5;
+ default:
+ return 0;
+ }
+}
+
+static int __init audit_classes_n32_init(void)
+{
+ audit_register_class(AUDIT_CLASS_WRITE_N32, write_class_n32);
+ audit_register_class(AUDIT_CLASS_READ_N32, read_class_n32);
+ audit_register_class(AUDIT_CLASS_DIR_WRITE_N32, dir_class_n32);
+ audit_register_class(AUDIT_CLASS_CHATTR_N32, chattr_class_n32);
+ audit_register_class(AUDIT_CLASS_SIGNAL_N32, signal_class_n32);
+
+ return 0;
+}
+
+__initcall(audit_classes_n32_init);
diff --git a/arch/mips/kernel/audit-native.c b/arch/mips/kernel/audit-native.c
new file mode 100644
index 0000000..e883094
--- /dev/null
+++ b/arch/mips/kernel/audit-native.c
@@ -0,0 +1,92 @@
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/audit.h>
+#include <asm/unistd.h>
+
+static unsigned dir_class[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+static unsigned read_class[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+static unsigned write_class[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+static unsigned chattr_class[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+static unsigned signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
+
+/*
+ * Pretend to be a single architecture
+ */
+int audit_classify_arch(int arch)
+{
+ return 0;
+}
+
+extern int audit_classify_syscall_o32(int abi, unsigned syscall);
+extern int audit_classify_syscall_n32(int abi, unsigned syscall);
+
+int audit_classify_syscall(int abi, unsigned syscall)
+{
+ int res;
+
+ switch (syscall) {
+ case __NR_open:
+ res = 2;
+ break;
+
+ case __NR_openat:
+ res = 3;
+ break;
+
+#ifdef __NR_socketcall /* Only exists on O32 */
+ case __NR_socketcall:
+ res = 4;
+ break;
+#endif
+ case __NR_execve:
+ res = 5;
+ break;
+ default:
+#ifdef CONFIG_AUDITSYSCALL_O32
+ res = audit_classify_syscall_o32(abi, syscall);
+ if (res)
+ break;
+#endif
+#ifdef CONFIG_AUDITSYSCALL_N32
+ res = audit_classify_syscall_n32(abi, syscall);
+ if (res)
+ break;
+#endif
+ res = 0;
+ }
+
+ return res;
+}
+
+static int __init audit_classes_init(void)
+{
+ audit_register_class(AUDIT_CLASS_WRITE, write_class);
+ audit_register_class(AUDIT_CLASS_READ, read_class);
+ audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
+ audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
+ audit_register_class(AUDIT_CLASS_SIGNAL, signal_class);
+
+ return 0;
+}
+
+__initcall(audit_classes_init);
diff --git a/arch/mips/kernel/audit-o32.c b/arch/mips/kernel/audit-o32.c
new file mode 100644
index 0000000..e8b9b50
--- /dev/null
+++ b/arch/mips/kernel/audit-o32.c
@@ -0,0 +1,60 @@
+#define __WANT_SYSCALL_NUMBERS _MIPS_SIM_ABI32
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/audit.h>
+#include <linux/unistd.h>
+
+static unsigned dir_class_o32[] = {
+#include <asm-generic/audit_dir_write.h>
+~0U
+};
+
+static unsigned read_class_o32[] = {
+#include <asm-generic/audit_read.h>
+~0U
+};
+
+static unsigned write_class_o32[] = {
+#include <asm-generic/audit_write.h>
+~0U
+};
+
+static unsigned chattr_class_o32[] = {
+#include <asm-generic/audit_change_attr.h>
+~0U
+};
+
+static unsigned signal_class_o32[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
+int audit_classify_syscall_o32(int abi, unsigned syscall)
+{
+ switch (syscall) {
+ case __NR_open:
+ return 2;
+ case __NR_openat:
+ return 3;
+ case __NR_socketcall:
+ return 4;
+ case __NR_execve:
+ return 5;
+ default:
+ return 0;
+ }
+}
+
+static int __init audit_classes_o32_init(void)
+{
+ audit_register_class(AUDIT_CLASS_WRITE_32, write_class_o32);
+ audit_register_class(AUDIT_CLASS_READ_32, read_class_o32);
+ audit_register_class(AUDIT_CLASS_DIR_WRITE_32, dir_class_o32);
+ audit_register_class(AUDIT_CLASS_CHATTR_32, chattr_class_o32);
+ audit_register_class(AUDIT_CLASS_SIGNAL_32, signal_class_o32);
+
+ return 0;
+}
+
+__initcall(audit_classes_o32_init);
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 584e6b5..33bb84a 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -26,6 +26,7 @@
#include <linux/audit.h>
#include <linux/seccomp.h>
+#include <asm/abi.h>
#include <asm/byteorder.h>
#include <asm/cpu.h>
#include <asm/dsp.h>
@@ -40,6 +41,12 @@
#include <asm/reg.h>
/*
+ * The standard AUDITSC_RESULT() assumes errno values < 0 indicate error
+ * but MIPS passes an error flag instead.
+ */
+#define MIPS_AUDITSC_RESULT(x) ((x) ? AUDITSC_FAILURE : AUDITSC_SUCCESS)
+
+/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure single step bits etc are not set.
@@ -517,18 +524,6 @@ long arch_ptrace(struct task_struct *child, long request,
return ret;
}
-static inline int audit_arch(void)
-{
- int arch = EM_MIPS;
-#ifdef CONFIG_64BIT
- arch |= __AUDIT_ARCH_64BIT;
-#endif
-#if defined(__LITTLE_ENDIAN)
- arch |= __AUDIT_ARCH_LE;
-#endif
- return arch;
-}
-
/*
* Notification of system call entry/exit
* - triggered by current->work.syscall_trace
@@ -540,7 +535,7 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
secure_computing(regs->regs[2]);
if (unlikely(current->audit_context) && entryexit)
- audit_syscall_exit(AUDITSC_RESULT(regs->regs[7]),
+ audit_syscall_exit(MIPS_AUDITSC_RESULT(regs->regs[7]),
-regs->regs[2]);
if (!(current->ptrace & PT_PTRACED))
@@ -566,7 +561,8 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
out:
if (unlikely(current->audit_context) && !entryexit)
- audit_syscall_entry(audit_arch(), regs->regs[2],
+ audit_syscall_entry(current->thread.abi->audit_arch,
+ regs->regs[2],
regs->regs[4], regs->regs[5],
regs->regs[6], regs->regs[7]);
}
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index dbbe0ce..71dafb0 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -7,6 +7,7 @@
* Copyright (C) 1994 - 2000 Ralf Baechle
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
+#include <linux/audit.h>
#include <linux/cache.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -537,7 +538,24 @@ struct mips_abi mips_abi = {
.setup_rt_frame = setup_rt_frame,
.rt_signal_return_offset =
offsetof(struct mips_vdso, rt_signal_trampoline),
- .restart = __NR_restart_syscall
+ .restart = __NR_restart_syscall,
+#ifdef CONFIG_64BIT
+# ifdef __BIG_ENDIAN
+ .audit_arch = AUDIT_ARCH_MIPS64,
+# elif defined(__LITTLE_ENDIAN)
+ .audit_arch = AUDIT_ARCH_MIPS64EL,
+# else
+# error "Neither big nor little endian ???"
+# endif
+#else
+# ifdef __BIG_ENDIAN
+ .audit_arch = AUDIT_ARCH_MIPS,
+# elif defined(__LITTLE_ENDIAN)
+ .audit_arch = AUDIT_ARCH_MIPSEL,
+# else
+# error "Neither big nor little endian ???"
+# endif
+#endif
};
static int handle_signal(unsigned long sig, siginfo_t *info,
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index aae9866..a633edc 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -7,6 +7,7 @@
* Copyright (C) 1994 - 2000, 2006 Ralf Baechle
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
+#include <linux/audit.h>
#include <linux/cache.h>
#include <linux/compat.h>
#include <linux/sched.h>
@@ -683,7 +684,14 @@ struct mips_abi mips_abi_32 = {
.setup_rt_frame = setup_rt_frame_32,
.rt_signal_return_offset =
offsetof(struct mips_vdso, o32_rt_signal_trampoline),
- .restart = __NR_O32_restart_syscall
+ .restart = __NR_O32_restart_syscall,
+#ifdef __BIG_ENDIAN
+ .audit_arch = AUDIT_ARCH_MIPS,
+#elif defined(__LITTLE_ENDIAN)
+ .audit_arch = AUDIT_ARCH_MIPSEL,
+#else
+# error "Neither big nor little endian ???"
+#endif
};
SYSCALL_DEFINE4(32_rt_sigaction, int, sig,
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index ee24d81..1e9603b 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -15,6 +15,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+#include <linux/audit.h>
#include <linux/cache.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -226,5 +227,12 @@ struct mips_abi mips_abi_n32 = {
.setup_rt_frame = setup_rt_frame_n32,
.rt_signal_return_offset =
offsetof(struct mips_vdso, n32_rt_signal_trampoline),
- .restart = __NR_N32_restart_syscall
+ .restart = __NR_N32_restart_syscall,
+#ifdef __BIG_ENDIAN
+ .audit_arch = AUDIT_ARCH_MIPS64_N32,
+#elif defined(__LITTLE_ENDIAN)
+ .audit_arch = AUDIT_ARCH_MIPSEL64_N32,
+#else
+# error "Neither big nor little endian ???"
+#endif
};
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 58beabf..ced2f5c 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -447,6 +447,8 @@ int kernel_execve(const char *filename,
register unsigned long __a3 asm("$7");
unsigned long __v0;
+ current->thread.abi = &mips_abi;
+
__asm__ volatile (" \n"
" .set noreorder \n"
" li $2, %5 # __NR_execve \n"
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 9d339eb..b96bd19 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -159,7 +159,11 @@
* AUDIT_LIST commands must be implemented. */
#define AUDIT_MAX_FIELDS 64
#define AUDIT_MAX_KEY_LEN 256
+#ifdef __mips__
+#define AUDIT_BITMASK_SIZE 256
+#else
#define AUDIT_BITMASK_SIZE 64
+#endif
#define AUDIT_WORD(nr) ((__u32)((nr)/32))
#define AUDIT_BIT(nr) (1 << ((nr) - AUDIT_WORD(nr)*32))
@@ -175,6 +179,18 @@
#define AUDIT_CLASS_SIGNAL 8
#define AUDIT_CLASS_SIGNAL_32 9
+/*
+ * WARNING: Not officially assigned by upstream yet; the names of these
+ * constants might change breaking source compatibility. The values might
+ * change breaking binary compatibility. With the audit package being the
+ * only known user at this time the potencial problem is small
+ */
+#define AUDIT_CLASS_DIR_WRITE_N32 10
+#define AUDIT_CLASS_CHATTR_N32 11
+#define AUDIT_CLASS_READ_N32 12
+#define AUDIT_CLASS_WRITE_N32 13
+#define AUDIT_CLASS_SIGNAL_N32 14
+
/* This bitmask is used to validate user input. It represents all bits that
* are currently used in an audit field constant understood by the kernel.
* If you are adding a new #define AUDIT_<whatever>, please ensure that
@@ -284,6 +300,7 @@ enum {
/* distinguish syscall tables */
#define __AUDIT_ARCH_64BIT 0x80000000
#define __AUDIT_ARCH_LE 0x40000000
+#define __AUDIT_ARCH_ALT 0x20000000 /* indicates alternative ABI */
#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)
@@ -297,7 +314,9 @@ enum {
#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_MIPS64EL (EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_MIPS64_N32 (EM_MIPS|__AUDIT_ARCH_ALT)
+#define AUDIT_ARCH_MIPS64EL_N32 (EM_MIPS|__AUDIT_ARCH_ALT|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_PARISC (EM_PARISC)
#define AUDIT_ARCH_PARISC64 (EM_PARISC|__AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_PPC (EM_PPC)
diff --git a/init/Kconfig b/init/Kconfig
index 56240e7..d32af62 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -347,7 +347,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 || MIPS)
default y if SECURITY_SELINUX
help
Enable low-overhead system-call auditing infrastructure that
13 years, 7 months
user showing up as unset
by Harris, Todd
So I was wondering if anyone had seen this. I have a set of nodes that
when we setup auditd on them the events we get back list the auid as
unset for basically everything except for login which shows up
correctly. Does anyone know where I may need to look at the config,
something in PAM or else where?
_______________________________
Todd Harris
Progeny Systems
Office Number: 703-368-6107 ext517
13 years, 7 months
Fwd: Patch for using /proc/<id>oom_score_adj with newer kernels
by Tony Jones
I'm not sure what the policy is on moderator approval for posts. AJ sent this
a while ago and resent again on 4/27 (he is not subscribed, so both times the
post was waiting moderator approval). Anyways, we've had this patch in our
OpenSuSE version for a while.
Tony
----- Forwarded message from Andreas Jaeger <aj(a)novell.com> -----
Date: Wed, 27 Apr 2011 08:43:00 +0200
From: Andreas Jaeger <aj(a)novell.com>
To: linux-audit(a)redhat.com
Cc: Tony Jones <tonyj(a)suse.de>
Subject: Fwd: Patch for using /proc/<id>oom_score_adj with newer kernels
User-Agent: KMail/1.13.7 (Linux/2.6.37.6-0.0.30.67cfac5-desktop; KDE/4.6.2;
x86_64; ; )
I send the following message some time ago but do not see it in the archives
and it seems this patch is still needed, so let me resend it,
Andreas
---------- Forwarded Message ----------
Subject: Patch for using /proc/<id>oom_score_adj with newer kernels
Date: Tuesday, September 28, 2010, 09:25:02
From: Andreas Jaeger <aj(a)novell.com>
To: linux-audit(a)redhat.com
Hi,
I see in dmesg on my 2.6.36 kernel:
[ 19.424535] auditd (2576): /proc/2576/oom_adj is deprecated, please use
/proc/2576/oom_score_adj instead.
Since oom_adj is deprecated, let's use oom_score_adj.
Patch appended,
Andreas
From: aj(a)suse.de
Subject: Use oom_score_adj on newer kernels
Date: 2010-09-27
Signed-Off-by: Andreas Jaeger <aj(a)suse.de>
I see in dmesg on my 2.6.36 kernel:
[ 19.424535] auditd (2576): /proc/2576/oom_adj is deprecated, please use
/proc/2576/oom_score_adj instead.
Since oom_adj is deprecated, let's use oom_score_adj.
Index: src/auditd.c
===================================================================
--- src/auditd.c.orig
+++ src/auditd.c
@@ -265,7 +265,15 @@ static int write_pid_file(void)
static void avoid_oom_killer(void)
{
int oomfd;
-
+
+ /* Newer kernels (noticed in 2.6.36) */
+ oomfd = open("/proc/self/oom_score_adj", O_NOFOLLOW | O_WRONLY);
+ if (oomfd >= 0) {
+ (void)write(oomfd, "0", 1);
+ close(oomfd);
+ return;
+ }
+ /* Older kernel */
oomfd = open("/proc/self/oom_adj", O_NOFOLLOW | O_WRONLY);
if (oomfd >= 0) {
(void)write(oomfd, "-17", 3);
--
Andreas Jaeger, Program Manager openSUSE, aj(a){novell.com,opensuse.org}
Twitter: jaegerandi | Identica: jaegerandi
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
Maxfeldstr. 5, 90409 Nürnberg, Germany
GPG fingerprint = 93A3 365E CE47 B889 DF7F FED1 389A 563C C272 A126
13 years, 7 months
Audit slowing system.
by David Flatley
RHEL 4.7 system running Steve Grubb's STIG compliant audit.rules file.
System seems to be struggling to run audit. I run this
config on several systems with no problems. Top does not show anything
that indicates a problem, no directories filling. Any
suggestions on settings to change? It is a 64 bit system with the 32 bit
rules commented out in the rules file.
Thanks.
D Flatley
13 years, 7 months