[PATCH] audit: remove newline accidentally added during session id helper refactor
by Richard Guy Briggs
A newline was accidentally added during session ID helper refactorization in
commit 4d3fb709. This needlessly uses up buffer space, messes up syslog
formatting and makes userspace processing less efficient. Remove it.
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
kernel/audit.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index 3d17670..ac16540 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1413,7 +1413,7 @@ void audit_log_session_info(struct audit_buffer *ab)
u32 sessionid = audit_get_sessionid(current);
uid_t auid = from_kuid(&init_user_ns, audit_get_loginuid(current));
- audit_log_format(ab, " auid=%u ses=%u\n", auid, sessionid);
+ audit_log_format(ab, " auid=%u ses=%u", auid, sessionid);
}
void audit_log_key(struct audit_buffer *ab, char *key)
--
1.7.1
11 years, 3 months
Re: Audit Cross Compile Support
by LC Bruzenak
On 09/20/2013 10:22 AM, LC Bruzenak wrote:
> On 09/20/2013 10:18 AM, clshotwe(a)rockwellcollins.com wrote:
>>
>> I don't believe mock will be able to execute the gen_tables
>> executables that are built for the ARM/PPC. I think the only way I
>> could do that would be to setup a QEMU target and that seems a little
>> excessive.
>
> I wonder how koji does it?
>
> I see an ARM build there:
> http://koji.fedoraproject.org/koji/buildinfo?buildID=439098
>
Oh. There are different build hosts supporting different arches.
LCB
--
LC (Lenny) Bruzenak
lenny(a)magitekltd.com
11 years, 3 months
Re: Audit Cross Compile Support
by clshotwe@rockwellcollins.com
Lenny,
LC Bruzenak <lenny(a)magitekltd.com> wrote on 09/20/2013 8:36 AM:
> I tried to do a base cross compile but I ran into an issue when the
> table header files are generated, the executable generated by the
> makefile were built for the target and not the host. I modified the
> makefile to build them for the host but I realized the executables
> would pull in the headers from the host rather than the target. I
> attempted to work around this by porting the gen_tables.c
> algorithm to
> a python script to duplicate the header file generation using the
> target headers rather than the host. Is this a good approach? Is
> there a better way that this could be done a better way
> that does not
> use python? Is this a desired feature?
>
>
> I use mock. It's pretty straightforward.
I don't believe mock will be able to execute the gen_tables executables
that are built for the ARM/PPC. I think the only way I could do that
would be to setup a QEMU target and that seems a little excessive.
Thanks,
Clayton
Clayton Shotwell
Software Engineer
MS 137-157, 855 35th St NE, Cedar Rapids, IA, 52498-3161, US
Phone: 319-263-2385
clshotwe(a)rockwellcollins.com
www.rockwellcollins.com
11 years, 3 months
When do audit log calls fail?
by Kenan Avdic
Hello,
We've recently started using audit instead of syslog for reliability
purposes (acknowledged logging). I'm trying to establish when the
various audit_log_* system calls fail, particularly audit_log_user_message.
Basically what we're after is a way of being sure that a message that
was sent for logging is "comitted", and react in some way if it is not.
We're using audit_log_user_message but this function never fails (i.e.
returns <=0, per manpage), even e.g. if the audit daemon is down. From
reading the source code it seems the only way for it to fail is when the
kernel is lacking support for auditing (or is too old or similar).
My conclusion, given the above assumption, is that these functions do
not provide a way to ascertain that a message is actually logged from
the system call, and that decisions about failed logging have to be made
by the daemon. Is there any other way to check what happens with a log
message once its sent using e.g. audit_log_user_message?
Thanks,
/Kenan
--
Kenan Avdic
link22 AB
Brigadgatan 1
587 58 Linköping, Sweden
kenan.avdic(a)link22.se
tel: +46 707 75 77 61
11 years, 3 months
[PATCH 8/8] audit: add audit_backlog_wait_time configuration option
by Richard Guy Briggs
reaahead-collector abuses the audit logging facility to discover which files
are accessed at boot time to make a pre-load list
Add a tuning option to audit_backlog_wait_time so that if auditd can't keep up,
or gets blocked, the callers won't be blocked.
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
include/uapi/linux/audit.h | 2 ++
kernel/audit.c | 22 +++++++++++++++++++++-
2 files changed, 23 insertions(+), 1 deletions(-)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 75cef3f..493a66e 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -316,6 +316,7 @@ enum {
#define AUDIT_STATUS_PID 0x0004
#define AUDIT_STATUS_RATE_LIMIT 0x0008
#define AUDIT_STATUS_BACKLOG_LIMIT 0x0010
+#define AUDIT_STATUS_BACKLOG_WAIT_TIME 0x0020
/* Failure-to-log actions */
#define AUDIT_FAIL_SILENT 0
#define AUDIT_FAIL_PRINTK 1
@@ -367,6 +368,7 @@ struct audit_status {
__u32 backlog_limit; /* waiting messages limit */
__u32 lost; /* messages lost */
__u32 backlog; /* messages waiting in queue */
+ __u32 backlog_wait_time;/* message queue wait timeout */
};
struct audit_tty_status {
diff --git a/kernel/audit.c b/kernel/audit.c
index 3d17670..fc535b6 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -321,6 +321,12 @@ static int audit_set_backlog_limit(int limit)
return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, limit);
}
+static int audit_set_backlog_wait_time(int timeout)
+{
+ return audit_do_config_change("audit_backlog_wait_time",
+ &audit_backlog_wait_time, timeout);
+}
+
static int audit_set_enabled(int state)
{
int rc;
@@ -669,6 +675,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
s.backlog_limit = audit_backlog_limit;
s.lost = atomic_read(&audit_lost);
s.backlog = skb_queue_len(&audit_skb_queue);
+ s.backlog_wait_time = audit_backlog_wait_time;
audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0,
&s, sizeof(s));
break;
@@ -701,8 +708,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (err < 0)
return err;
}
- if (s.mask & AUDIT_STATUS_BACKLOG_LIMIT)
+ if (s.mask & AUDIT_STATUS_BACKLOG_LIMIT) {
err = audit_set_backlog_limit(s.backlog_limit);
+ if (err < 0)
+ return err;
+ }
+ if (s.mask & AUDIT_STATUS_BACKLOG_WAIT_TIME) {
+ if (sizeof(s) > (size_t)nlh->nlmsg_len)
+ break;
+ if (s.backlog_wait_time < 0 ||
+ s.backlog_wait_time > 10*AUDIT_BACKLOG_WAIT_TIME)
+ return -EINVAL;
+ err = audit_set_backlog_wait_time(s.backlog_wait_time);
+ if (err < 0)
+ return err;
+ }
break;
}
case AUDIT_USER:
--
1.7.1
11 years, 3 months
[PATCH 6/8] audit: add boot option to override default backlog limit
by Richard Guy Briggs
The default audit_backlog_limit is 64. This was a reasonable limit at one time.
systemd causes so much audit queue activity on startup that auditd doesn't
start before the backlog queue has already overflowed by more than a factor of
2. On a system with audit= not set on the kernel command line, this isn't an
issue since that history isn't kept for auditd when it is available. On a
system with audit=1 set on the kernel command line, kaudit tries to keep that
history until auditd is able to drain the queue.
This default can be changed by the "-b" option in audit.rules once the system
has booted, but won't help with lost messages on boot.
One way to solve this would be to increase the default backlog queue size to
avoid losing any messages before auditd is able to consume them. This would
be overkill to the embedded community and insufficient for some servers.
Another way to solve it might be to add a kconfig option to set the default
based on the system type. An embedded system would get the current (or
smaller) default, while Workstations might get more than now and servers might
get more.
None of these solutions helps if a system's compiled default is too small to
see the lost messages without compiling a new kernel.
This patch adds a boot option (audit already has one to enable/disable it)
"audit_backlog_limit=<n>" that overrides the default to allow the system
administrator to set the backlog limit.
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
kernel/audit.c | 14 +++++++++++++-
1 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index 990d02f..acfa7a9 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -944,9 +944,21 @@ static int __init audit_enable(char *str)
return 1;
}
-
__setup("audit=", audit_enable);
+/* Process kernel command-line parameter at boot time. audit_backlog_limit=<n> */
+static int __init audit_backlog_limit_set(char *str)
+{
+ int audit_backlog_limit_arg = simple_strtol(str, NULL, 0);
+ if ((audit_backlog_limit_arg >= 0) && (audit_backlog_limit_arg < 8192))
+ audit_backlog_limit = audit_backlog_limit_arg;
+
+ printk(KERN_INFO "audit_backlog_limit: %d\n", audit_backlog_limit);
+
+ return 1;
+}
+__setup("audit_backlog_limit=", audit_backlog_limit_set);
+
static void audit_buffer_free(struct audit_buffer *ab)
{
unsigned long flags;
--
1.7.1
11 years, 3 months
[PATCH 5/8] audit: efficiency fix 2: request exclusive wait since all need same resource
by Richard Guy Briggs
author: Dan Duval <dan.duval(a)oracle.com>
These and similar errors were seen on a patched 3.8 kernel when the
audit subsystem was overrun during boot:
udevd[876]: worker [887] unexpectedly returned with status 0x0100
udevd[876]: worker [887] failed while handling
'/devices/pci0000:00/0000:00:03.0/0000:40:00.0'
udevd[876]: worker [880] unexpectedly returned with status 0x0100
udevd[876]: worker [880] failed while handling
'/devices/LNXSYSTM:00/LNXPWRBN:00/input/input1/event1'
udevadm settle - timeout of 180 seconds reached, the event queue
contains:
/sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input1/event1 (3995)
/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/INT3F0D:00 (4034)
audit: audit_backlog=258 > audit_backlog_limit=256
audit: audit_lost=1 audit_rate_limit=0 audit_backlog_limit=256
The change below increases the efficiency of the audit code and prevents it
from being overrun:
Use add_wait_queue_exclusive() in wait_for_auditd() to put the
thread on the wait queue. When kauditd dequeues an skb, all
of the waiting threads are waiting for the same resource, but
only one is going to get it, so there's no need to wake up
more than one waiter.
See: https://lkml.org/lkml/2013/9/2/479
Signed-off-by: Dan Duval <dan.duval(a)oracle.com>
Signed-off-by: Chuck Anderson <chuck.anderson(a)oracle.com>
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
kernel/audit.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index 25fab2d..990d02f 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1061,7 +1061,7 @@ static unsigned long wait_for_auditd(unsigned long sleep_time)
unsigned long timeout = sleep_time;
DECLARE_WAITQUEUE(wait, current);
set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&audit_backlog_wait, &wait);
+ add_wait_queue_exclusive(&audit_backlog_wait, &wait);
if (audit_backlog_limit &&
skb_queue_len(&audit_skb_queue) > audit_backlog_limit)
--
1.7.1
11 years, 3 months
[PATCH 4/8] audit: efficiency fix 1: only wake up if queue shorter than backlog limit
by Richard Guy Briggs
author: Dan Duval <dan.duval(a)oracle.com>
These and similar errors were seen on a patched 3.8 kernel when the
audit subsystem was overrun during boot:
udevd[876]: worker [887] unexpectedly returned with status 0x0100
udevd[876]: worker [887] failed while handling
'/devices/pci0000:00/0000:00:03.0/0000:40:00.0'
udevd[876]: worker [880] unexpectedly returned with status 0x0100
udevd[876]: worker [880] failed while handling
'/devices/LNXSYSTM:00/LNXPWRBN:00/input/input1/event1'
udevadm settle - timeout of 180 seconds reached, the event queue
contains:
/sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input1/event1 (3995)
/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/INT3F0D:00 (4034)
audit: audit_backlog=258 > audit_backlog_limit=256
audit: audit_lost=1 audit_rate_limit=0 audit_backlog_limit=256
The change below increases the efficiency of the audit code and prevents it
from being overrun:
Only issue a wake_up in kauditd if the length of the skb queue is less than the
backlog limit. Otherwise, threads waiting in wait_for_auditd() will simply
wake up, discover that the queue is still too long for them to proceed, and go
back to sleep. This results in wasted context switches and machine cycles.
kauditd_thread() is the only function that removes buffers from audit_skb_queue
so we can't race. If we did, the timeout in wait_for_auditd() would expire and
the waiting thread would continue.
See: https://lkml.org/lkml/2013/9/2/479
Signed-off-by: Dan Duval <dan.duval(a)oracle.com>
Signed-off-by: Chuck Anderson <chuck.anderson(a)oracle.com>
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
kernel/audit.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index 42c68db..25fab2d 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -448,8 +448,10 @@ static int kauditd_thread(void *dummy)
flush_hold_queue();
skb = skb_dequeue(&audit_skb_queue);
- wake_up(&audit_backlog_wait);
+
if (skb) {
+ if(skb_queue_len(&audit_skb_queue) <= audit_backlog_limit)
+ wake_up(&audit_backlog_wait);
if (audit_pid)
kauditd_send_skb(skb);
else
--
1.7.1
11 years, 3 months
[PATCH 3/8] audit: make use of remaining sleep time from wait_for_auditd
by Richard Guy Briggs
If wait_for_auditd() times out, go immediately to the error function rather
than retesting the loop conditions.
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
kernel/audit.c | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index 772725e..42c68db 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1054,18 +1054,21 @@ static inline void audit_get_stamp(struct audit_context *ctx,
/*
* Wait for auditd to drain the queue a little
*/
-static void wait_for_auditd(unsigned long sleep_time)
+static unsigned long wait_for_auditd(unsigned long sleep_time)
{
+ unsigned long timeout = sleep_time;
DECLARE_WAITQUEUE(wait, current);
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&audit_backlog_wait, &wait);
if (audit_backlog_limit &&
skb_queue_len(&audit_skb_queue) > audit_backlog_limit)
- schedule_timeout(sleep_time);
+ timeout = schedule_timeout(sleep_time);
__set_current_state(TASK_RUNNING);
remove_wait_queue(&audit_backlog_wait, &wait);
+
+ return timeout;
}
/* Obtain an audit buffer. This routine does locking to obtain the
@@ -1119,8 +1122,9 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
sleep_time = timeout_start + audit_backlog_wait_time -
jiffies;
if ((long)sleep_time > 0) {
- wait_for_auditd(sleep_time);
- continue;
+ sleep_time = wait_for_auditd(sleep_time);
+ if ((long)sleep_time > 0)
+ continue;
}
}
if (audit_rate_check() && printk_ratelimit())
--
1.7.1
11 years, 3 months
[PATCH 2/8] audit: reset audit backlog wait time after error recovery
by Richard Guy Briggs
When the audit queue overflows and times out (audit_backlog_wait_time), the
audit queue overflow timeout is set to zero. Once the audit queue overflow
timeout condition recovers, the timeout should be reset to the original value.
See also:
https://lkml.org/lkml/2013/9/2/473
Signed-off-by: Luiz Capitulino <lcapitulino(a)redhat.com>
Signed-off-by: Dan Duval <dan.duval(a)oracle.com>
Signed-off-by: Chuck Anderson <chuck.anderson(a)oracle.com>
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
kernel/audit.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index 7b0e23a..772725e 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -103,7 +103,8 @@ static int audit_rate_limit;
/* Number of outstanding audit_buffers allowed. */
static int audit_backlog_limit = 64;
-static int audit_backlog_wait_time = 60 * HZ;
+#define AUDIT_BACKLOG_WAIT_TIME (60 * HZ)
+static int audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME;
static int audit_backlog_wait_overflow = 0;
/* The identity of the user shutting down the audit system. */
@@ -1134,6 +1135,8 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
return NULL;
}
+ audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME;
+
ab = audit_buffer_alloc(ctx, gfp_mask, type);
if (!ab) {
audit_log_lost("out of memory in audit_log_start");
--
1.7.1
11 years, 3 months