[PATCH 1/1] Added exe field to audit core dump signal log
by Paul Davies C
Currently when the coredump signals are logged by the audit system , the
actual path to the executable is not logged. Without details of exe , the
system admin may not have an exact idea on what program failed.
This patch changes the audit_log_task() so that the path to the exe is also
logged.
Signed-off-by: Paul Davies C <pauldaviesc(a)gmail.com>
---
kernel/auditsc.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 9845cb3..988de72 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -2353,6 +2353,7 @@ static void audit_log_task(struct audit_buffer *ab)
kuid_t auid, uid;
kgid_t gid;
unsigned int sessionid;
+ struct mm_struct *mm = current->mm;
auid = audit_get_loginuid(current);
sessionid = audit_get_sessionid(current);
@@ -2366,6 +2367,12 @@ static void audit_log_task(struct audit_buffer *ab)
audit_log_task_context(ab);
audit_log_format(ab, " pid=%d comm=", current->pid);
audit_log_untrustedstring(ab, current->comm);
+ if (mm) {
+ down_read(&mm->mmap_sem);
+ if (mm->exe_file)
+ audit_log_d_path(ab, " exe=", &mm->exe_file->f_path);
+ up_read(&mm->mmap_sem);
+ }
}
static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr)
--
1.7.9.5
9 years, 3 months
[PATCH v10 0/3] arm64: Add audit support
by AKASHI Takahiro
(This patchset was already acked by the maintainers, and
re-targeting v3.17. See change history.)
(I don't think that discussions below about ptrace() have impact on
this patchset.
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/268923.html
)
This patchset adds system call audit support on arm64.
Both 32-bit (AUDIT_ARCH_ARM) and 64-bit tasks (AUDIT_ARCH_AARCH64)
are supported. Since arm64 has the exact same set of system calls
on LE and BE, we don't care about endianness (or more specifically
__AUDIT_ARCH_64BIT bit in AUDIT_ARCH_*).
This patch should work correctly with:
* userspace audit tool (v2.3.6 or later)
This code was tested on both 32-bit and 64-bit LE userland
in the following two ways:
1) basic operations with auditctl/autrace
# auditctl -a exit,always -S openat -F path=/etc/inittab
# auditctl -a exit,always -F dir=/tmp -F perm=rw
# auditctl -a task,always
# autrace /bin/ls
by comparing output from autrace with one from strace
2) audit-test-code (+ my workarounds for arm/arm64)
by running "audit-tool", "filter" and "syscalls" test categories.
Changes v9 -> v10:
* rebased on 3.16-rc3
* included Catalin's patch[1/3] and added more syscall definitions for 3.16
Changes v8 -> v9:
* rebased on 3.15-rc, especially due to the change of syscall_get_arch()
interface [1,2/2]
Changes v7 -> v8:
* aligned with the change in "audit: generic compat system call audit
support" v5 [1/2]
* aligned with the change in "arm64: split syscall_trace() into separate
functions for enter/exit" v5 [2/2]
Changes v6 -> v7:
* changed an include file in syscall.h from <linux/audit.h> to
<uapi/linux/audit.h> [1/2]
* aligned with the patch, "arm64: split syscall_trace() into separate
functions for enter/exit" [2/2]
Changes v5 -> v6:
* removed and put "arm64: Add regs_return_value() in syscall.h" patch into
a separate set
* aligned with the change in "arm64: make a single hook to syscall_trace()
for all syscall features" v3 [1/2]
Changes v4 -> v5:
* rebased to 3.14-rcX
* added a guard against TIF_SYSCALL_AUDIT [3/3]
* aligned with the change in "arm64: make a single hook to syscall_trace()
for all syscall features" v2 [3/3]
Changes v3 -> v4:
* Modified to sync with the patch, "make a single hook to syscall_trace()
for all syscall features"
* aligned with "audit: Add CONFIG_HAVE_ARCH_AUDITSYSCALL" patch
Changes v2 -> v3:
* Remove asm/audit.h.
See "generic compat syscall audit support" patch v4
* Remove endianness dependency, ie. AUDIT_ARCH_ARMEB/AARCH64EB.
* Remove kernel/syscalls/Makefile which was used to create unistd32.h.
See Catalin's "Add __NR_* definitions for compat syscalls" patch
Changes v1 -> v2:
* Modified to utilize "generic compat system call audit" [3/6, 4/6, 5/6]
Please note that a required header, unistd_32.h, is automatically
generated from unistd32.h.
* Refer to regs->orig_x0 instead of regs->x0 as the first argument of
system call in audit_syscall_entry() [6/6]
* Include "Add regs_return_value() in syscall.h" patch [2/6],
which was not intentionally included in v1 because it could be added
by "kprobes support".
AKASHI Takahiro (2):
arm64: Add audit support
arm64: audit: Add audit hook in syscall_trace_enter/exit()
Catalin Marinas (1):
arm64: Add __NR_* definitions for compat syscalls
arch/arm64/Kconfig | 2 +
arch/arm64/include/asm/syscall.h | 14 +
arch/arm64/include/asm/unistd.h | 17 +
arch/arm64/include/asm/unistd32.h | 1166 ++++++++++++++++++++++++-------------
arch/arm64/kernel/entry.S | 1 -
arch/arm64/kernel/kuser32.S | 2 +-
arch/arm64/kernel/ptrace.c | 7 +
arch/arm64/kernel/signal32.c | 2 +-
arch/arm64/kernel/sys_compat.c | 2 +-
include/uapi/linux/audit.h | 1 +
10 files changed, 810 insertions(+), 404 deletions(-)
--
1.7.9.5
9 years, 9 months
[PATCH] TaskTracker : Simplified thread information tracker.
by Tetsuo Handa
Yesterday I went to LinuxCon Japan 2014 and stopped at Red Hat's booth
and Oracle's booth. I explained about this module ( using page 92 of
http://I-love.SAKURA.ne.jp/tomoyo/LCJ2014-en.pdf ) and got positive
responses from persons who have experienced troubleshooting jobs.
I was convinced that I am not the only person who is bothered by lack of
process history information in the logs. Therefore, I repost this module
toward inclusion into mainline Linux kernel.
Changes from previous version ( http://lwn.net/Articles/575044/ ):
(1) Assign a value to "u32 *seclen" in addition to "char *secdata"
at security_task_getsecid() hook.
(2) Make calculation of time stamp a bit faster.
Background:
When an unexpected system event (e.g. reboot) occurs, the administrator may
want to identify which application triggered the event. System call auditing
could be used for recording such event. However, the audit log may not be
able to provide sufficient information for identifying the application
because the audit log does not reflect how the program was executed.
I sometimes receive "which application triggered the event" questions on RHEL
systems. TOMOYO security module can track how the program was executed, but
TOMOYO is not yet available in Fedora/RHEL distributions.
Although subj= field is added to the audit log if SELinux is not disabled,
SELinux is too difficult to customize as fine grained as I expect in order to
reflect how the program was executed. Therefore, I'm currently using AKARI
and SystemTap for emulating TOMOYO-like tracing.
But AKARI and SystemTap do not help unless the kernel module is loaded before
the unexpected system event occurs. Generally, the administrator is failing
to record the first event, and has to wait for the same event to occur again
after loading the kernel module and/or configuring auditing. I came to think
that we want a built-in kernel routine which is automatically started upon
boot so that we don't fail to record the first event.
What I did:
Assuming that multiple concurrent LSM support comes in the near future,
I wrote a trivial LSM module which emits TOMOYO-like information into the
audit logs.
Usage:
Just register this LSM module. No configuration is needed. You will get
history of current thread in the form of comm name and time stamp pairs
in the subj= field of audit logs like examples shown in the patch
description.
----------
>From ff68d3a4cd496bd263d2939848777fffc30cbc0b Mon Sep 17 00:00:00 2001
From: Tetsuo Handa <penguin-kernel(a)I-love.SAKURA.ne.jp>
Date: Fri, 23 May 2014 21:31:56 +0900
Subject: [PATCH] TaskTracker : Simplified thread information tracker.
Existing audit logs generated via system call auditing functionality include
current thread's comm name. But it is not always sufficient for identifying
which application has requested specific operations because comm name does not
reflect history of current thread.
This security module adds functionality for adding current thread's history
information like TOMOYO security module does, expecting that this module can
help us getting more information from system call auditing functionality.
type=USER_LOGIN msg=audit(1400879947.084:24): pid=4308 uid=0 auid=0 ses=2
subj="swapper/0(2014/05/23-21:17:30)=>init(2014/05/23-21:17:33)=>
switch_root(2014/05/23-21:17:34)=>init(2014/05/23-21:17:34)=>
sh(2014/05/23-21:17:56)=>mingetty(2014/05/23-21:17:56)=>
login(2014/05/23-21:19:05)" msg='op=login id=0 exe="/bin/login" hostname=?
addr=? terminal=tty1 res=success'
type=SYSCALL msg=audit(1400880014.444:26): arch=40000003 syscall=11
success=yes exit=0 a0=8140f78 a1=812b7d8 a2=812b248 a3=812b7d8 items=2
ppid=4323 pid=4355 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0
fsgid=0 tty=pts0 ses=1 comm="tail" exe="/usr/bin/tail"
subj="swapper/0(2014/05/23-21:17:30)=>init(2014/05/23-21:17:33)=>
switch_root(2014/05/23-21:17:34)=>init(2014/05/23-21:17:34)=>
sh(2014/05/23-21:17:37)=>rc(2014/05/23-21:17:37)=>
S55sshd(2014/05/23-21:17:53)=>sshd(2014/05/23-21:17:53)=>
sshd(2014/05/23-21:18:17)=>bash(2014/05/23-21:18:21)=>
tail(2014/05/23-21:20:14)" key=(null)
Signed-off-by: Tetsuo Handa <penguin-kernel(a)I-love.SAKURA.ne.jp>
---
security/Kconfig | 6 +
security/Makefile | 2 +
security/tasktracker/Kconfig | 35 +++++
security/tasktracker/Makefile | 1 +
security/tasktracker/tasktracker.c | 282 ++++++++++++++++++++++++++++++++++++
5 files changed, 326 insertions(+), 0 deletions(-)
create mode 100644 security/tasktracker/Kconfig
create mode 100644 security/tasktracker/Makefile
create mode 100644 security/tasktracker/tasktracker.c
diff --git a/security/Kconfig b/security/Kconfig
index beb86b5..14e7d27 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -122,6 +122,7 @@ source security/smack/Kconfig
source security/tomoyo/Kconfig
source security/apparmor/Kconfig
source security/yama/Kconfig
+source security/tasktracker/Kconfig
source security/integrity/Kconfig
@@ -132,6 +133,7 @@ choice
default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO
default DEFAULT_SECURITY_APPARMOR if SECURITY_APPARMOR
default DEFAULT_SECURITY_YAMA if SECURITY_YAMA
+ default DEFAULT_SECURITY_TT if SECURITY_TT
default DEFAULT_SECURITY_DAC
help
@@ -153,6 +155,9 @@ choice
config DEFAULT_SECURITY_YAMA
bool "Yama" if SECURITY_YAMA=y
+ config DEFAULT_SECURITY_TT
+ bool "TaskTracker" if SECURITY_TT=y
+
config DEFAULT_SECURITY_DAC
bool "Unix Discretionary Access Controls"
@@ -165,6 +170,7 @@ config DEFAULT_SECURITY
default "tomoyo" if DEFAULT_SECURITY_TOMOYO
default "apparmor" if DEFAULT_SECURITY_APPARMOR
default "yama" if DEFAULT_SECURITY_YAMA
+ default "tt" if DEFAULT_SECURITY_TT
default "" if DEFAULT_SECURITY_DAC
endmenu
diff --git a/security/Makefile b/security/Makefile
index 05f1c93..28a90ed 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -8,6 +8,7 @@ subdir-$(CONFIG_SECURITY_SMACK) += smack
subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo
subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
subdir-$(CONFIG_SECURITY_YAMA) += yama
+subdir-$(CONFIG_SECURITY_TT) += tasktracker
# always enable default capabilities
obj-y += commoncap.o
@@ -22,6 +23,7 @@ obj-$(CONFIG_AUDIT) += lsm_audit.o
obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/
obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/
obj-$(CONFIG_SECURITY_YAMA) += yama/
+obj-$(CONFIG_SECURITY_TT) += tasktracker/
obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
# Object integrity file lists
diff --git a/security/tasktracker/Kconfig b/security/tasktracker/Kconfig
new file mode 100644
index 0000000..6de5354
--- /dev/null
+++ b/security/tasktracker/Kconfig
@@ -0,0 +1,35 @@
+config SECURITY_TT
+ bool "TaskTracker support"
+ depends on SECURITY
+ default n
+ help
+ Existing audit logs generated via system call auditing functionality
+ include current thread's comm name. But it is not always sufficient
+ for identifying which application has requested specific operations
+ because comm name does not reflect history of current thread.
+
+ This security module adds functionality for adding current thread's
+ history information like TOMOYO security module does, expecting that
+ this module can help us getting more information from system call
+ auditing functionality.
+
+ If you are unsure how to answer this question, answer N.
+
+ Usage:
+
+ Just register this module. No configuration is needed.
+
+ You will get history of current thread in the form of
+ comm name and time stamp pairs in the subj= field of audit logs
+ like an example shown below.
+
+ type=SYSCALL msg=audit(1400880014.444:26): arch=40000003 syscall=11
+ success=yes exit=0 a0=8140f78 a1=812b7d8 a2=812b248 a3=812b7d8
+ items=2 ppid=4323 pid=4355 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0
+ egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="tail"
+ exe="/usr/bin/tail" subj="swapper/0(2014/05/23-21:17:30)=>
+ init(2014/05/23-21:17:33)=>switch_root(2014/05/23-21:17:34)=>
+ init(2014/05/23-21:17:34)=>sh(2014/05/23-21:17:37)=>
+ rc(2014/05/23-21:17:37)=>S55sshd(2014/05/23-21:17:53)=>
+ sshd(2014/05/23-21:17:53)=>sshd(2014/05/23-21:18:17)=>
+ bash(2014/05/23-21:18:21)=>tail(2014/05/23-21:20:14)" key=(null)
diff --git a/security/tasktracker/Makefile b/security/tasktracker/Makefile
new file mode 100644
index 0000000..15d03ce
--- /dev/null
+++ b/security/tasktracker/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SECURITY_TT) := tasktracker.o
diff --git a/security/tasktracker/tasktracker.c b/security/tasktracker/tasktracker.c
new file mode 100644
index 0000000..ec4eb0c
--- /dev/null
+++ b/security/tasktracker/tasktracker.c
@@ -0,0 +1,282 @@
+/*
+ * tasktracker.c - Simplified thread information tracker.
+ *
+ * Copyright (C) 2010-2014 Tetsuo Handa <penguin-kernel(a)I-love.SAKURA.ne.jp>
+ */
+#include <linux/security.h>
+#include <linux/binfmts.h>
+
+/* Wrapper structure for passing string buffer. */
+struct tt_record {
+ char history[1024];
+};
+
+/* Structure for representing YYYY/MM/DD hh/mm/ss. */
+struct tt_time {
+ u16 year;
+ u8 month;
+ u8 day;
+ u8 hour;
+ u8 min;
+ u8 sec;
+};
+
+/**
+ * tt_get_time - Get current time in YYYY/MM/DD hh/mm/ss format.
+ *
+ * @stamp: Pointer to "struct tt_time".
+ *
+ * Returns nothing.
+ *
+ * This function does not handle Y2038 problem.
+ */
+static void tt_get_time(struct tt_time *stamp)
+{
+ struct timeval tv;
+ static const u16 tt_eom[2][12] = {
+ { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
+ { 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
+ };
+ u16 y = 1970;
+ u8 m;
+ bool r;
+ time_t time;
+ do_gettimeofday(&tv);
+ time = tv.tv_sec;
+ stamp->sec = time % 60;
+ time /= 60;
+ stamp->min = time % 60;
+ time /= 60;
+ stamp->hour = time % 24;
+ time /= 24;
+ if (time >= 16071) {
+ /* Start from 2014/01/01 rather than 1970/01/01. */
+ time -= 16071;
+ y += 44;
+ }
+ while (1) {
+ const unsigned short days = (y & 3) ? 365 : 366;
+ if (time < days)
+ break;
+ time -= days;
+ y++;
+ }
+ r = (y & 3) == 0;
+ for (m = 0; m < 11 && time >= tt_eom[r][m]; m++)
+ ;
+ if (m)
+ time -= tt_eom[r][m - 1];
+ stamp->year = y;
+ stamp->month = ++m;
+ stamp->day = ++time;
+}
+
+/**
+ * tt_update_record - Update "struct tt_record" for given credential.
+ *
+ * @record: Pointer to "struct tt_record".
+ *
+ * Returns nothing.
+ */
+static void tt_update_record(struct tt_record *record)
+{
+ char *cp;
+ int i;
+ struct tt_time stamp;
+ tt_get_time(&stamp);
+ /*
+ * Lockless update because current thread's record is not concurrently
+ * accessible, for "struct cred"->security is not visible from other
+ * threads because this function is called upon only boot up and
+ * successful execve() operation.
+ */
+ cp = record->history;
+ i = strlen(cp);
+ while (i >= sizeof(record->history) - (TASK_COMM_LEN * 4 + 30)) {
+ /*
+ * Since this record is not for making security decision,
+ * I don't care by-chance matching "=>" in task's commname.
+ */
+ char *cp2 = strstr(cp + 2, "=>");
+ if (!cp2)
+ return;
+ memmove(cp + 1, cp2, strlen(cp2) + 1);
+ i = strlen(cp);
+ }
+ if (!i)
+ *cp++ = '"';
+ else {
+ cp += i - 1;
+ *cp++ = '=';
+ *cp++ = '>';
+ }
+ /*
+ * Lockless read because this is current thread and being unexpectedly
+ * modified by other thread is not a fatal problem.
+ */
+ for (i = 0; i < TASK_COMM_LEN; i++) {
+ const unsigned char c = current->comm[i];
+ if (!c)
+ break;
+ else if (c == '"' || c == '\\' || c < 0x21 || c > 0x7e) {
+ *cp++ = '\\';
+ *cp++ = (c >> 6) + '0';
+ *cp++ = ((c >> 3) & 7) + '0';
+ *cp++ = (c & 7) + '0';
+ } else
+ *cp++ = c;
+ }
+ sprintf(cp, "(%04u/%02u/%02u-%02u:%02u:%02u)\"", stamp.year,
+ stamp.month, stamp.day, stamp.hour, stamp.min, stamp.sec);
+}
+
+/**
+ * tt_find_record - Find "struct tt_record" for given credential.
+ *
+ * @cred: Pointer to "struct cred".
+ *
+ * Returns pointer to "struct tt_record".
+ */
+static inline struct tt_record *tt_find_record(const struct cred *cred)
+{
+ return cred->security;
+}
+
+/**
+ * tt_cred_alloc_blank - Allocate memory for new credentials.
+ *
+ * @new: Pointer to "struct cred".
+ * @gfp: Memory allocation flags.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tt_cred_alloc_blank(struct cred *new, gfp_t gfp)
+{
+ new->security = kzalloc(sizeof(struct tt_record), gfp);
+ return new->security ? 0 : -ENOMEM;
+}
+
+/**
+ * tt_cred_prepare - Allocate memory for new credentials.
+ *
+ * @new: Pointer to "struct cred".
+ * @old: Pointer to "struct cred".
+ * @gfp: Memory allocation flags.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tt_cred_prepare(struct cred *new, const struct cred *old,
+ gfp_t gfp)
+{
+ if (tt_cred_alloc_blank(new, gfp))
+ return -ENOMEM;
+ strcpy(tt_find_record(new)->history, tt_find_record(old)->history);
+ return 0;
+}
+
+/**
+ * tt_cred_free - Release memory used by credentials.
+ *
+ * @cred: Pointer to "struct cred".
+ *
+ * Returns nothing.
+ */
+static void tt_cred_free(struct cred *cred)
+{
+ kfree(cred->security);
+}
+
+/**
+ * tt_cred_transfer - Transfer "struct tt_record" between credentials.
+ *
+ * @new: Pointer to "struct cred".
+ * @old: Pointer to "struct cred".
+ *
+ * Returns nothing.
+ */
+static void tt_cred_transfer(struct cred *new, const struct cred *old)
+{
+ strcpy(tt_find_record(new)->history, tt_find_record(old)->history);
+}
+
+/**
+ * tt_bprm_committing_creds - A hook which is called when do_execve() succeeded.
+ *
+ * @bprm: Pointer to "struct linux_binprm".
+ *
+ * Returns nothing.
+ */
+static void tt_bprm_committing_creds(struct linux_binprm *bprm)
+{
+ tt_update_record(tt_find_record(bprm->cred));
+}
+
+/**
+ * tt_task_getsecid - Check whether to audit or not.
+ *
+ * @p: Pointer to "struct task_struct".
+ * @secid: Pointer to flag.
+ */
+static void tt_task_getsecid(struct task_struct *p, u32 *secid)
+{
+ *secid = (p == current);
+}
+
+/**
+ * tt_secid_to_secctx - Allocate memory used for auditing.
+ *
+ * @secid: Bool flag to allocate.
+ * @secdata: Pointer to allocate memory.
+ * @seclen: Size of allocated memory.
+ *
+ * Returns 0 on success, -EINVAL otherwise.
+ */
+static int tt_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+{
+ struct tt_record *record;
+ /* Ignore unless current thread's record is requested. */
+ if (secid != 1)
+ return -EINVAL;
+ /*
+ * We don't need to duplicate the string because current thread's
+ * record is updated upon only boot up and successful execve()
+ * operation, even if current thread's record is shared between
+ * multiple threads.
+ */
+ record = tt_find_record(current->real_cred);
+ *secdata = record->history;
+ *seclen = strlen(record->history);
+ return 0;
+}
+
+/* List of hooks. */
+static struct security_operations tasktracker_ops = {
+ .name = "tt",
+ .secid_to_secctx = tt_secid_to_secctx,
+ .task_getsecid = tt_task_getsecid,
+ .cred_prepare = tt_cred_prepare,
+ .cred_free = tt_cred_free,
+ .cred_alloc_blank = tt_cred_alloc_blank,
+ .cred_transfer = tt_cred_transfer,
+ .bprm_committing_creds = tt_bprm_committing_creds,
+};
+
+/**
+ * tt_init - Initialize this module.
+ *
+ * Returns 0 on success, panic otherwise.
+ */
+static int __init tt_init(void)
+{
+ struct cred *cred = (struct cred *) current_cred();
+ if (!security_module_enable(&tasktracker_ops))
+ return 0;
+ if (tt_cred_alloc_blank(cred, GFP_ATOMIC) ||
+ register_security(&tasktracker_ops))
+ panic("Failure registering TaskTracker");
+ tt_update_record(tt_find_record(cred));
+ pr_info("TaskTracker initialized\n");
+ return 0;
+}
+
+security_initcall(tt_init);
--
1.7.1
9 years, 9 months
[PATCH] audit: restore AUDIT_LOGINUID unset ABI
by Richard Guy Briggs
A regression was caused by commit 780a7654cee8:
audit: Make testing for a valid loginuid explicit.
(which in turn attempted to fix a regression caused by e1760bd)
When audit_krule_to_data() fills in the rules to get a listing, there was a
missing clause to convert back from AUDIT_LOGINUID_SET to AUDIT_LOGINUID.
This broke userspace by not returning the same information that was sent and
expected.
The rule:
auditctl -a exit,never -F auid=-1
gives:
auditctl -l
LIST_RULES: exit,never f24=0 syscall=all
when it should give:
LIST_RULES: exit,never auid=-1 (0xffffffff) syscall=all
Tag it so that it is reported the same way it was set.
Note: move the field validation call ahead of the mutation code to have it work
on the original field set.
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
include/uapi/linux/audit.h | 3 +++
kernel/auditfilter.c | 19 +++++++++++++------
kernel/auditsc.c | 2 +-
3 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 4d100c8..860df86 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -274,6 +274,9 @@
#define AUDIT_FILTERKEY 210
+/* Flag to indicate legacy AUDIT_LOGINUID unset usage */
+#define AUDIT_LOGINUID_LEGACY 0x80000000
+
#define AUDIT_NEGATE 0x80000000
/* These are the supported operators.
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 40ed981..39ce3e6 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -438,9 +438,13 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
f->type = data->fields[i];
f->val = data->values[i];
+ err = audit_field_valid(entry, f);
+ if (err)
+ goto exit_free;
+
/* Support legacy tests for a valid loginuid */
if ((f->type == AUDIT_LOGINUID) && (f->val == AUDIT_UID_UNSET)) {
- f->type = AUDIT_LOGINUID_SET;
+ f->type = AUDIT_LOGINUID_SET | AUDIT_LOGINUID_LEGACY;
f->val = 0;
}
@@ -457,10 +461,6 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
rcu_read_unlock();
}
- err = audit_field_valid(entry, f);
- if (err)
- goto exit_free;
-
err = -EINVAL;
switch (f->type) {
case AUDIT_LOGINUID:
@@ -630,6 +630,13 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
data->buflen += data->values[i] =
audit_pack_string(&bufp, krule->filterkey);
break;
+ case AUDIT_LOGINUID_SET | AUDIT_LOGINUID_LEGACY:
+ if (!f->val) {
+ data->fields[i] = AUDIT_LOGINUID;
+ data->values[i] = AUDIT_UID_UNSET;
+ break;
+ }
+ /* fallthrough if set */
default:
data->values[i] = f->val;
}
@@ -1270,7 +1277,7 @@ static int audit_filter_user_rules(struct audit_krule *rule, int type,
int result = 0;
u32 sid;
- switch (f->type) {
+ switch (f->type & ~AUDIT_LOGINUID_LEGACY) {
case AUDIT_PID:
pid = task_pid_nr(current);
result = audit_comparator(pid, f->op, f->val);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 8933572..ef25cbc 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -452,7 +452,7 @@ static int audit_filter_rules(struct task_struct *tsk,
int result = 0;
pid_t pid;
- switch (f->type) {
+ switch (f->type & ~AUDIT_LOGINUID_LEGACY) {
case AUDIT_PID:
pid = task_pid_nr(tsk);
result = audit_comparator(pid, f->op, f->val);
--
1.7.1
9 years, 10 months
[PATCH] auparse.c events_are_equal() and event matching
by Guillaume Destuynder
Hi,
on our RHEL6 machines, with kernel 2.6.32, we noticed that sometimes an
audit message comes in but libaudit does not see it as the same event.
The milliseconds field of the timestamp differs (but the timestamp
seconds and event serial are identical).
The check to determine if 2 messages are part of the same event is done
by events_are_equal() in auparse/auparse.c (audit userspace library).
There is a comment that indicate that this is voluntary - however, I
could not find why. I suspect this is for searches over long periods of
time when the serial may roll over.
In case this was simply overlooked I'm attaching a patch that fixes it
for us. It keeps the timestamp check for the seconds, which works fine
and would still work with serial rolling over.
Again- its relatively rare in our logs that the timestamp's millisecond
field differs and we log very heavily - so it's not that easy to reproduce.
Thanks!
Guillaume
Index: trunk/auparse/auparse.c
===================================================================
--- trunk/auparse/auparse.c (revision 1063)
+++ trunk/auparse/auparse.c (working copy)
@@ -752,10 +752,10 @@
static int inline events_are_equal(au_event_t *e1, au_event_t *e2)
{
- // Check time & serial first since its most likely way
- // to spot 2 different events
- if (!(e1->serial == e2->serial && e1->milli == e2->milli &&
- e1->sec == e2->sec))
+ // Check serial and timestamp - but not milliseconds
+ // as, even if rare, these may not match for the same message due to
+ // kernel processing delays
+ if (!(e1->serial == e2->serial && e1->sec == e2->sec))
return 0;
// Hmm...same so far, check if both have a host, only a string
// compare can tell if they are the same. Otherwise, if only one
9 years, 10 months
[PATCH] audit: add ppc64 mach support
by Tony Jones
Add support for ppc64le.
$ uname -a
Linux cabernet 3.12.26-3-default #1 SMP Mon Aug 18 15:07:30 UTC 2014 (d318f3a) ppc64le ppc64le ppc64le GNU/Linux
Without this, perf trace and auditctl fail. There is no 32 bit (ppcle).
Signed-off-by: Tony Jones <tonyj(a)suse.de>
---
Index: trunk/lib/libaudit.c
===================================================================
--- trunk/lib/libaudit.c (revision 1011)
+++ trunk/lib/libaudit.c (working copy)
@@ -1195,6 +1195,11 @@
return -6;
break;
#endif
+ case MACH_PPC64LE:
+ if (bits != __AUDIT_ARCH_64BIT)
+ return -6;
+ break;
+
case MACH_86_64: /* fallthrough */
case MACH_PPC64: /* fallthrough */
case MACH_S390X: /* fallthrough */
Index: trunk/lib/libaudit.h
===================================================================
--- trunk/lib/libaudit.h (revision 1011)
+++ trunk/lib/libaudit.h (working copy)
@@ -356,6 +356,9 @@
#define AUDIT_ARCH_AARCH64 (EM_AARCH64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#endif
+#ifndef AUDIT_ARCH_PPC64LE
+#define AUDIT_ARCH_PPC64LE (EM_PPC64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#endif
//////////////////////////////////////////////////////
// This is an external ABI. Any changes in here will
@@ -438,7 +441,8 @@
MACH_S390,
MACH_ALPHA,
MACH_ARM,
- MACH_AARCH64
+ MACH_AARCH64,
+ MACH_PPC64LE
} machine_t;
/* These are the valid audit failure tunable enum values */
Index: trunk/lib/lookup_table.c
===================================================================
--- trunk/lib/lookup_table.c (revision 1011)
+++ trunk/lib/lookup_table.c (working copy)
@@ -70,6 +70,7 @@
{ MACH_86_64, AUDIT_ARCH_X86_64 },
{ MACH_IA64, AUDIT_ARCH_IA64 },
{ MACH_PPC64, AUDIT_ARCH_PPC64 },
+ { MACH_PPC64LE, AUDIT_ARCH_PPC64LE},
{ MACH_PPC, AUDIT_ARCH_PPC },
{ MACH_S390X, AUDIT_ARCH_S390X },
{ MACH_S390, AUDIT_ARCH_S390 },
@@ -123,6 +124,7 @@
found = ia64_syscall_s2i(sc, &res);
break;
case MACH_PPC64:
+ case MACH_PPC64LE:
case MACH_PPC:
found = ppc_syscall_s2i(sc, &res);
break;
@@ -169,6 +171,7 @@
case MACH_IA64:
return ia64_syscall_i2s(sc);
case MACH_PPC64:
+ case MACH_PPC64LE:
case MACH_PPC:
return ppc_syscall_i2s(sc);
case MACH_S390X:
Index: trunk/lib/machinetab.h
===================================================================
--- trunk/lib/machinetab.h (revision 1011)
+++ trunk/lib/machinetab.h (working copy)
@@ -27,6 +27,7 @@
_S(MACH_86_64, "x86_64" )
_S(MACH_IA64, "ia64" )
_S(MACH_PPC64, "ppc64" )
+_S(MACH_PPC64LE, "ppc64le")
_S(MACH_PPC, "ppc" )
_S(MACH_S390X, "s390x" )
_S(MACH_S390, "s390" )
9 years, 11 months
[PATCH] lsm: copy comm before calling audit_log to avoid race in string printing
by Richard Guy Briggs
When task->comm is passed directly to audit_log_untrustedstring() without
getting a copy or using the task_lock, there is a race that could happen that
would output a NULL (\0) in the middle of the output string that would
effectively truncate the rest of the report text after the comm= field in the
audit log message, losing fields.
Using get_task_comm() to get a copy while acquiring the task_lock to prevent
this and to prevent the result from being a mixture of old and new values of
comm would incur potentially unacceptable overhead, considering that the value
can be influenced by userspace and therefore untrusted anyways.
Copy the value before passing it to audit_log_untrustedstring() ensures that a
local copy is used to calculate the length *and* subsequently printed. Even if
this value contains a mix of old and new values, it will only calculate and
copy up to the first NULL, preventing the rest of the audit log message being
truncated.
The LSM_AUDIT_DATA_TASK pid= and comm= labels are duplicates of those at the
start of this function with different values. Rename them to their object
counterparts opid= and ocomm= to disambiguate. Use a second local copy of comm
to avoid a race between the first and second calls to
audit_log_untrustedstring() with comm.
Reported-by: Tetsuo Handa <penguin-kernel(a)I-love.SAKURA.ne.jp>
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
security/lsm_audit.c | 17 ++++++++++-------
1 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 69fdf3b..3323144 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -211,7 +211,7 @@ static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
static void dump_common_audit_data(struct audit_buffer *ab,
struct common_audit_data *a)
{
- struct task_struct *tsk = current;
+ char comm[sizeof(current->comm)];
/*
* To keep stack sizes in check force programers to notice if they
@@ -220,8 +220,8 @@ static void dump_common_audit_data(struct audit_buffer *ab,
*/
BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2);
- audit_log_format(ab, " pid=%d comm=", task_pid_nr(tsk));
- audit_log_untrustedstring(ab, tsk->comm);
+ audit_log_format(ab, " pid=%d comm=", task_pid_nr(current));
+ audit_log_untrustedstring(ab, memcpy(comm, current->comm, sizeof(comm)));
switch (a->type) {
case LSM_AUDIT_DATA_NONE:
@@ -276,16 +276,19 @@ static void dump_common_audit_data(struct audit_buffer *ab,
audit_log_format(ab, " ino=%lu", inode->i_ino);
break;
}
- case LSM_AUDIT_DATA_TASK:
- tsk = a->u.tsk;
+ case LSM_AUDIT_DATA_TASK: {
+ struct task_struct *tsk = a->u.tsk;
if (tsk) {
pid_t pid = task_pid_nr(tsk);
if (pid) {
- audit_log_format(ab, " pid=%d comm=", pid);
- audit_log_untrustedstring(ab, tsk->comm);
+ char comm[sizeof(tsk->comm)];
+ audit_log_format(ab, " opid=%d ocomm=", pid);
+ audit_log_untrustedstring(ab,
+ memcpy(comm, tsk->comm, sizeof(comm)));
}
}
break;
+ }
case LSM_AUDIT_DATA_NET:
if (a->u.net->sk) {
struct sock *sk = a->u.net->sk;
--
1.7.1
9 years, 11 months
STIG issue with auditctl -l
by leam hall
The RHEL 6 STIG says:
auditctl -l | grep syscall | grep chmod
Should return lines referring to chmod. Those lines are in my
audit.rules. Just doing an:
auditctl -l | grep syscall
Returns nothing. I've got no issues telling the STIG folks how to do
their work, but wanted to make sure I know what I'm talking about
first.
Am I missing something if there's no "syscall" line(s) returned?
Thanks!
Leam
--
Mind on a Mission
9 years, 11 months
Excluding few executable from audit.rules in redhat6.5
by Tilden Doran D
Hi All,
I am new to Redhat Audit logging.
Our Server Configurations: Redhat 6.5 OS and Oracle 11g , and SELinux is enabled.
We are getting lots of logs messages in /var/log/messages.
type=SYSCALL msg=audit(1416235337.083:2109222): arch=c000003e syscall=90 success=yes exit=0 a0=7f52ae9f1a20 a1=3ff a2=ffffffffffffff88 a3=fffffffffffffff0 items=1 ppid=1 pid=46859 auid=500 uid=345 gid=345 euid=345 suid=345 fsuid=345 egid=345 sgid=345 fsgid=345 tty=(none) ses=28 comm="ohasd.bin" exe="/opt/oracle_homes/oracle/grid/11.2.0/bin/ohasd.bin" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="perm_mod"
type=PATH msg=audit(1416235337.083:2109222): item=0 name="/opt/oracle_homes/oracle/grid/11.2.0/auth/ohasd/dl360x3364/A7679703" inode=4718596 dev=fd:00 mode=041755 ouid=345 ogid=345 rdev=00:00 obj=unconfined_u:object_r:usr_t:s0 nametype=NORMAL
Later we found and removed message type "CWD", but still we are getting lot of logs.
And also found that the below mentioned executable are creating the problem.
13351. 11/16/2014 18:11:34 /opt/oracle_homes/oracle/grid/11.2.0/bin/ohasd.bin (none) ? 500 1599360
13352. 11/16/2014 18:11:34 /opt/oracle_homes/oracle/rdbms/11.2.0/bin/oracle (none) ? 500 1599354
13353. 11/16/2014 18:11:34 /opt/oracle_homes/oracle/grid/11.2.0/bin/oraagent.bin (none) ? 500 1599361
Can you please help me in excluding the above mentioned Executable `s in the audit. rules files .
Thanks in advance.
--Tilden
Ericsson AB
9 years, 11 months