Re: w[PATCH V4 0/4] audit by executable name
by Vitaly Isaev
Hello, Richard,
We would like to thank you for implementing such a long-awaited feature like filtering audit events by exe name. We want to use this functionality on our systems (RHEL 6.4, kernel 2.6.32-358.11.1, audit-2.2-2) as soon as possible. Could you please provide some additional explanations of the use of your patch:
1. What kernel version is the patch proposed to be applied to? How much will it take to see the one in the upstream? (just your estimations)
2. Will the upcoming updates of 2.6.32 kernel include the patch? If not, do we have any technical restrictions for backporting ( on our own ) this patch to our old kernel?
Sincerely,
Vitaly Isaev
software engineer
ITS Ltd., Moscow, Russia
10 years, 4 months
[PATCH] audit: correct AUDIT_GET_FEATURE return message type
by Richard Guy Briggs
When an AUDIT_GET_FEATURE message is sent from userspace to the kernel, it
should reply with a message tagged as an AUDIT_GET_FEATURE type with a struct
audit_feature. The current reply is a message tagged as an AUDIT_GET
type with a struct audit_feature.
This appears to have been a cut-and-paste-eo in commit b0fed40.
Reported-by: Steve Grubb <sgrubb(a)redhat.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 d20f00f..3a80abb 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -724,7 +724,7 @@ static int audit_get_feature(struct sk_buff *skb)
seq = nlmsg_hdr(skb)->nlmsg_seq;
- audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &af, sizeof(af));
+ audit_send_reply(skb, seq, AUDIT_GET_FEATURE, 0, 0, &af, sizeof(af));
return 0;
}
--
1.7.1
10 years, 4 months
arm64 audit build failures in -next
by Mark Brown
On Sat, Aug 23, 2014 at 04:11:20PM +0100, Build bot for Mark Brown wrote:
> arm64-allmodconfig
> ../arch/arm64/kernel/ptrace.c:1120:3: error: too many arguments to function 'audit_syscall_entry'
This has now been broken in -next for about a month with a fix available
and since the merge window the arm64 audit support is in mainline so the
fix can be directly applied without cross tree issues (the audit changes
didn't get sent during the merge window). Catalin and Will have also
indicated that they want to remove the workaround that's in -next
currently to allow defconfig to build which would make the situation
even more pressing.
Do we have any idea when it will be possible to get a fix into -next?
10 years, 4 months
audit 2.4 released
by Steve Grubb
I've just released a new version of the audit daemon. It can be downloaded
from http://people.redhat.com/sgrubb/audit. It will also be in rawhide
soon. The ChangeLog is:
- Optionally parse loginuids, (e)uids, & (e)gids in ausearch/report
- In auvirt, anomaly events don't have uuid (#1111448)
- Fix category handling in various records (#1120286)
- Fix ausearch handling of session id on 32 bit systems
- Set systemd startup to wait until systemd-tmpfiles-setup.service (#1097314)
- Interpret a0 of socketcall and ipccall syscalls
- Add pkgconfig file for libaudit
- Add go language bindings for limited use of libaudit
- Fix ausearch handling of exit code on 32 bit systems
- Fix bug in aureport string linked list handling
- Document week-ago time setting in ausearch/report man page
- Update tables for 3.16 kernel
- In aulast, on bad logins only record user_login proof and use it
- Add libaudit API for kernel features
- If audit=0 on kernel cmnd line, skip systemd activation (Cristian RodrÃguez)
- Add checkpoint --start option to ausearch (Burn Alting)
- Fix arch matching in ausearch
- Add --loginuid-immutable option to auditctl
- Fix memory leak in auditd when log_format is set to NOLOG
- Update auditctl to display features in the status command
- Add ausearch_add_timestamp_item_ex() to auparse
This release has a couple new capabilities added. We can now set the
loginuid-immutable feature with an auditctl command. The status listing
has been reformatted with one status item per line. At the end it lists the
features and their values. It turns out there is a bug in the Linux kernel
that sends the status back instead of the feature values. So, until that
gets fixed and everyone uses new kernels, auditctl will appear to list
the status items twice.
This release also adds a limited audit-libs binding for golang and a
package-config file for the audit libraries. This release also updates the
interpretation tables for the 3.16 kernel. And a new --start option was
added to ausearch for checkpointed files.
Besides that, there were quite a few bugs fixed.
Please let me know if you run across any problems with this release.
-Steve
10 years, 4 months
[PATCH 1/7] audit: implement generic feature setting and retrieving
by Eric Paris
The audit_status structure was not designed with extensibility in mind.
Define a new AUDIT_SET_FEATURE message type which takes a new structure
of bits where things can be enabled/disabled/locked one at a time. This
structure should be able to grow in the future while maintaining forward
and backward compatibility (based loosly on the ideas from capabilities
and prctl)
This does not actually add any features, but is just infrastructure to
allow new on/off types of audit system features.
Signed-off-by: Eric Paris <eparis(a)redhat.com>
---
include/linux/audit.h | 2 +
include/uapi/linux/audit.h | 16 +++++++
kernel/audit.c | 110 ++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 127 insertions(+), 1 deletion(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 729a4d1..7b31bec 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -73,6 +73,8 @@ struct audit_field {
void *lsm_rule;
};
+extern int is_audit_feature_set(int which);
+
extern int __init audit_register_class(int class, unsigned *list);
extern int audit_classify_syscall(int abi, unsigned syscall);
extern int audit_classify_arch(int arch);
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index b7cb978..a053243 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -68,6 +68,9 @@
#define AUDIT_MAKE_EQUIV 1015 /* Append to watched tree */
#define AUDIT_TTY_GET 1016 /* Get TTY auditing status */
#define AUDIT_TTY_SET 1017 /* Set TTY auditing status */
+#define AUDIT_SET_FEATURE 1018 /* Turn an audit feature on or off */
+#define AUDIT_GET_FEATURE 1019 /* Get which features are enabled */
+#define AUDIT_FEATURE_CHANGE 1020 /* audit log listing feature changes */
#define AUDIT_FIRST_USER_MSG 1100 /* Userspace messages mostly uninteresting to kernel */
#define AUDIT_USER_AVC 1107 /* We filter this differently */
@@ -369,6 +372,19 @@ struct audit_status {
__u32 backlog; /* messages waiting in queue */
};
+struct audit_features {
+#define AUDIT_FEATURE_VERSION 1
+ __u32 vers;
+ __u32 mask; /* which bits we are dealing with */
+ __u32 features; /* which feature to enable/disable */
+ __u32 lock; /* which features to lock */
+};
+
+#define AUDIT_LAST_FEATURE -1
+
+#define audit_feature_valid(x) ((x) >= 0 && (x) <= AUDIT_LAST_FEATURE)
+#define AUDIT_FEATURE_TO_MASK(x) (1 << ((x) & 31)) /* mask for __u32 */
+
struct audit_tty_status {
__u32 enabled; /* 1 = enabled, 0 = disabled */
__u32 log_passwd; /* 1 = enabled, 0 = disabled */
diff --git a/kernel/audit.c b/kernel/audit.c
index f2f4666..3acbbc8 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -140,6 +140,15 @@ static struct task_struct *kauditd_task;
static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
+static struct audit_features af = {.vers = AUDIT_FEATURE_VERSION,
+ .mask = -1,
+ .features = 0,
+ .lock = 0,};
+
+static char *audit_feature_names[0] = {
+};
+
+
/* Serialize requests from userspace. */
DEFINE_MUTEX(audit_cmd_mutex);
@@ -584,6 +593,8 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
return -EOPNOTSUPP;
case AUDIT_GET:
case AUDIT_SET:
+ case AUDIT_GET_FEATURE:
+ case AUDIT_SET_FEATURE:
case AUDIT_LIST_RULES:
case AUDIT_ADD_RULE:
case AUDIT_DEL_RULE:
@@ -628,6 +639,94 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type)
return rc;
}
+int is_audit_feature_set(int i)
+{
+ return af.features & AUDIT_FEATURE_TO_MASK(i);
+}
+
+
+static int audit_get_feature(struct sk_buff *skb)
+{
+ u32 seq;
+
+ seq = nlmsg_hdr(skb)->nlmsg_seq;
+
+ audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0,
+ &af, sizeof(af));
+
+ return 0;
+}
+
+static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature,
+ u32 old_lock, u32 new_lock, int res)
+{
+ struct audit_buffer *ab;
+
+ ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_FEATURE_CHANGE);
+ audit_log_format(ab, "feature=%s new=%d old=%d old_lock=%d new_lock=%d res=%d",
+ audit_feature_names[which], !!old_feature, !!new_feature,
+ !!old_lock, !!new_lock, res);
+ audit_log_end(ab);
+}
+
+static int audit_set_feature(struct sk_buff *skb)
+{
+ struct audit_features *uaf;
+ int i;
+
+ BUILD_BUG_ON(AUDIT_LAST_FEATURE + 1 > sizeof(audit_feature_names)/sizeof(audit_feature_names[0]));
+ uaf = nlmsg_data(nlmsg_hdr(skb));
+
+ /* if there is ever a version 2 we should handle that here */
+
+ for (i = 0; i <= AUDIT_LAST_FEATURE; i++) {
+ u32 feature = AUDIT_FEATURE_TO_MASK(i);
+ u32 old_feature, new_feature, old_lock, new_lock;
+
+ /* if we are not changing this feature, move along */
+ if (!(feature & uaf->mask))
+ continue;
+
+ old_feature = af.features & feature;
+ new_feature = uaf->features & feature;
+ new_lock = (uaf->lock | af.lock) & feature;
+ old_lock = af.lock & feature;
+
+ /* are we changing a locked feature? */
+ if ((af.lock & feature) && (new_feature != old_feature)) {
+ audit_log_feature_change(i, old_feature, new_feature,
+ old_lock, new_lock, 0);
+ return -EPERM;
+ }
+ }
+ /* nothing invalid, do the changes */
+ for (i = 0; i <= AUDIT_LAST_FEATURE; i++) {
+ u32 feature = AUDIT_FEATURE_TO_MASK(i);
+ u32 old_feature, new_feature, old_lock, new_lock;
+
+ /* if we are not changing this feature, move along */
+ if (!(feature & uaf->mask))
+ continue;
+
+ old_feature = af.features & feature;
+ new_feature = uaf->features & feature;
+ old_lock = af.lock & feature;
+ new_lock = (uaf->lock | af.lock) & feature;
+
+ if (new_feature != old_feature)
+ audit_log_feature_change(i, old_feature, new_feature,
+ old_lock, new_lock, 1);
+
+ if (new_feature)
+ af.features |= feature;
+ else
+ af.features &= ~feature;
+ af.lock |= new_lock;
+ }
+
+ return 0;
+}
+
static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
u32 seq;
@@ -699,7 +798,16 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT)
err = audit_set_backlog_limit(status_get->backlog_limit);
break;
- case AUDIT_USER:
+ case AUDIT_GET_FEATURE:
+ err = audit_get_feature(skb);
+ if (err)
+ return err;
+ break;
+ case AUDIT_SET_FEATURE:
+ err = audit_set_feature(skb);
+ if (err)
+ return err;
+ break;
case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
if (!audit_enabled && msg_type != AUDIT_USER_AVC)
--
1.8.2.1
10 years, 4 months
[PATCH] audit: set nlmsg_len for multicast messages.
by Richard Guy Briggs
Report:
Looking at your example code in
http://people.redhat.com/rbriggs/audit-multicast-listen/audit-multicast-l...,
it seems that nlmsg_len field in the received messages is supposed to
contain the length of the header + payload, but it is always set to the
size of the header only, i.e. 16. The example program works, because
the printf format specifies the minimum width, not "precision", so it
simply prints out the payload until the first zero byte. This isn't too
much of a problem, but precludes the use of recvmmsg, iiuc?
(gdb) p *(struct nlmsghdr*)nlh
$14 = {nlmsg_len = 16, nlmsg_type = 1100, nlmsg_flags = 0, nlmsg_seq = 0, nlmsg_pid = 9910}
The only time nlmsg_len would have been updated was at audit_buffer_alloc()
inside audit_log_start() and never updated after. It should arguably be done
in audit_log_vformat(), but would be more efficient in audit_log_end().
Reported-by: Zbigniew Jędrzejewski-Szmek <zbyszek(a)in.waw.pl>
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
kernel/audit.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index aa99518..ca11482 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2035,6 +2035,7 @@ void audit_log_end(struct audit_buffer *ab)
} else {
struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
+ nlh->nlmsg_len = ab->skb->len;
kauditd_send_multicast_skb(ab->skb);
/*
@@ -2046,7 +2047,7 @@ void audit_log_end(struct audit_buffer *ab)
* protocol between the kaudit kernel subsystem and the auditd
* userspace code.
*/
- nlh->nlmsg_len = ab->skb->len - NLMSG_HDRLEN;
+ nlh->nlmsg_len -= NLMSG_HDRLEN;
if (audit_pid) {
skb_queue_tail(&audit_skb_queue, ab->skb);
--
1.7.1
10 years, 4 months
audit netlink multicast code
by Zbigniew Jędrzejewski-Szmek
Hi,
it seems that current kernel code sets the nlmsg_len field in multicast audit
netlink messages to a fixed size (16 bytes), and does not include the size
of the payload. I'm forwarding the message from Richard Briggs below in case
someone else runs into the same issue.
On Thu, Aug 21, 2014 at 01:39:24PM -0400, Richard Guy Briggs wrote:
> On 14/08/19, Zbigniew Jędrzejewski-Szmek wrote:
> > I was looking at adding support in journald for reading audit multicast
> > messages, but there's something I don't quite understand. Looking at your
> > example code in http://people.redhat.com/rbriggs/audit-multicast-listen/audit-multicast-l...,
> > it seems that nlmsg_len field in the received messages is supposed to contain
> > the length of the header + payload, but it is always set to the size of the
> > header only, i.e. 16. The example program works, because the printf
> > format specifies the minimum width, not "precision", so it simply prints
> > out the payload until the first zero byte. This isn't too much of a problem,
> > but precludes the use of recvmmsg, iiuc?
> >
> > (gdb) p *(struct nlmsghdr*)nlh
> > $14 = {nlmsg_len = 16, nlmsg_type = 1100, nlmsg_flags = 0, nlmsg_seq = 0, nlmsg_pid = 9910}
>
> Interesting. Ok, I thought I had traced down the code to verify that
> nlh->nlmsg_len was properly set by each step before audit_log_end(), but
> it appears the only time it would have been done was at
> audit_buffer_alloc() inside audit_log_start() and never updated after.
> It should arguably be done in audit_log_vformat(), but would be more
> efficient in audit_log_end(). I'll fix it in the latter.
>
> Thanks for tracking this down!
>
> > This is with kernel 3.16.1-300.playground.fc21.x86_64.
Zbyszek
10 years, 4 months
A memory leak problem when the the ”log_format = NOLOG“ is set in auditd.conf
by 崔捷
Hello,
I found a memory leak problem when the the ”log_format = NOLOG“ is set in
auditd.conf.
See the code in function "void enqueue_event(struct auditd_reply_list
*rep)" in "/src/auditd-event.c",
If it comes into the case LF_NOLOG, then there is no chance to free the
rep->reply.message because it returns so that the message cannot be
dequeued in function "static void *event_thread_main(void *arg) " to free
it.
The same problem may occurs in case "default:" below the case LF_NOLOG.
When the message type is between AUDIT_FIRST_DAEMON and AUDIT_LAST_DAEMON,
the rep->reply.message will be malloced in function "int
send_audit_event(int type, const char *str)" in "/src/auditd.c".
So I write a patch below, but I'm not sure whether this is the correct way
to submit a patch because this is my first submmition. So please tell me if
I'm wrong.
--- a/src/auditd-event.c
+++ b/src/auditd-event.c
@@ -172,6 +172,11 @@ void enqueue_event(struct auditd_reply_list *rep)
case LF_NOLOG:
// We need the rotate event to get enqueued
if (rep->reply.type != AUDIT_DAEMON_ROTATE ) {
+ /* Internal DAEMON messages should be free'd */
+ if (rep->reply.type >= AUDIT_FIRST_DAEMON &&
+ rep->reply.type <= AUDIT_LAST_DAEMON) {
+ free((void *)rep->reply.message);
+ }
free(rep);
return;
}
@@ -180,6 +185,11 @@ void enqueue_event(struct auditd_reply_list *rep)
audit_msg(LOG_ERR,
"Illegal log format detected %d",
consumer_data.config->log_format);
+ /* Internal DAEMON messages should be free'd */
+ if (rep->reply.type >= AUDIT_FIRST_DAEMON &&
+ rep->reply.type <= AUDIT_LAST_DAEMON) {
+ free((void *)rep->reply.message);
+ }
free(rep);
return;
}
10 years, 4 months
[PATCH V3 0/6] namespaces: log namespaces per task
by Richard Guy Briggs
The purpose is to track namespaces in use by logged processes from the
perspective of init_*_ns.
1/6 defines a function to generate them and assigns them.
Use a serial number per namespace (unique across one boot of one kernel)
instead of the inode number (which is claimed to have had the right to change
reserved and is not necessarily unique if there is more than one proc fs). It
could be argued that the inode numbers have now become a defacto interface and
can't change now, but I'm proposing this approach to see if this helps address
some of the objections to the earlier patchset.
2/6 adds access functions to get to the serial numbers in a similar way to
inode access for namespace proc operations.
3/6 implements, as suggested by Serge Hallyn, making these serial numbers
available in /proc/self/ns/{ipc,mnt,net,pid,user,uts}_snum. I chose "snum"
instead of "seq" for consistency with inum and there are a number of other uses
of "seq" in the namespace code.
4/6 exposes proc's ns entries structure which lists a number of useful
operations per namespace type for other subsystems to use.
5/6 provides an example of usage for audit_log_task_info() which is used by
syscall audits, among others. audit_log_task() and audit_common_recv_message()
would be other potential use cases.
Proposed output format:
This differs slightly from Aristeu's patch because of the label conflict with
"pid=" due to including it in existing records rather than it being a seperate
record. The serial numbers are printed in hex.
type=SYSCALL msg=audit(1399651071.433:72): arch=c000003e syscall=272 success=yes exit=0 a0=40000000 a1=ffffffffffffffff a2=0 a3=22 items=0 ppid=1 pid=483 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="(t-daemon)" exe="/usr/lib/systemd/systemd" netns=97 utsns=2 ipcns=1 pidns=4 userns=3 mntns=5 subj=system_u:system_r:init_t:s0 key=(null)
6/6 tracks the creation and deletion of of namespaces, listing the type of
namespace instance, related namespace id if there is one and the newly minted
serial number.
Proposed output format:
type=NS_INIT msg=audit(1400217435.706:94): pid=524 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:mount_t:s0 type=20000 old_snum=0 snum=a1 res=1
type=NS_DEL msg=audit(1400217435.730:95): pid=524 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:mount_t:s0 type=20000 snum=a1 res=1
v2 -> v3:
Use atomic64_t in ns_serial to simplify it.
Avoid funciton duplication in proc, keying on dentry.
Squash down audit patch to avoid rcu sleep issues.
Add tracking for creation and deletion of namespace instances.
v1 -> v2:
Avoid rollover by switching from an int to a long long.
Change rollover behaviour from simply avoiding zero to raising a BUG.
Expose serial numbers in /proc/<pid>/ns/*_snum.
Expose ns_entries and use it in audit.
Notes:
There has been some progress made for audit in net namespaces and pid
namespaces since this previous thread. net namespaces are now served as peers
by one auditd in the init_net namespace with processes in a non-init_net
namespace being able to write records if they are in the init_user_ns and have
CAP_AUDIT_WRITE. Processes in a non-init_pid_ns can now similarly write
records. As for CAP_AUDIT_READ, I just posted a patchset to check capabilities
of userspace processes that try to join netlink broadcast groups.
This set does not try to solve the non-init namespace audit messages and
auditd problem yet. That will come later, likely with additional auditd
instances running in another namespace with a limited ability to influence the
master auditd. I echo Eric B's idea that messages destined for different
namespaces would have to be tailored for that namespace with references that
make sense (such as the right pid number reported to that pid namespace, and
not leaking info about parents or peers).
Bugs:
Patch 6/6 has a timing bug such that mnt and net namespace initial namespaces
never get logged, I suspect because they are initialized before the audit
subsystem. I've tried moving audit from __initcall to subsys_initcall, but
that doesn't help.
Questions:
Is there a way to link serial numbers of namespaces involved in migration of a
container to another kernel? It sounds like what is needed is a part of a
mangement application that is able to pull the audit rcords from constituent
hosts to build an audit trail of a container.
What additional events should list this information?
Does this present any problematic information leaks? Only CAP_AUDIT_CONTROL
(and proposed CAP_AUDIT_READ) in init_user_ns can get to this information in
the init namespace at the moment from audit. *However*, the addition of the
proc/<pid>/ns/*_snum does make it available to other processes now.
Richard Guy Briggs (6):
namespaces: assign each namespace instance a serial number
namespaces: expose namespace instance serial number in proc_ns_operations
namespaces: expose ns instance serial numbers in proc
namespaces: expose ns_entries
audit: log namespace serial numbers
audit: log creation and deletion of namespace instances
fs/mount.h | 1 +
fs/namespace.c | 12 +++++++++
fs/proc/namespaces.c | 35 +++++++++++++++++++-------
include/linux/audit.h | 15 +++++++++++
include/linux/ipc_namespace.h | 1 +
include/linux/nsproxy.h | 8 ++++++
include/linux/pid_namespace.h | 1 +
include/linux/proc_ns.h | 2 +
include/linux/user_namespace.h | 1 +
include/linux/utsname.h | 1 +
include/net/net_namespace.h | 1 +
include/uapi/linux/audit.h | 2 +
init/version.c | 1 +
ipc/msgutil.c | 1 +
ipc/namespace.c | 20 +++++++++++++++
kernel/audit.c | 53 +++++++++++++++++++++++++++++++++++++++-
kernel/nsproxy.c | 17 +++++++++++++
kernel/pid.c | 1 +
kernel/pid_namespace.c | 19 ++++++++++++++
kernel/user.c | 1 +
kernel/user_namespace.c | 18 +++++++++++++
kernel/utsname.c | 20 +++++++++++++++
net/core/net_namespace.c | 20 ++++++++++++++-
23 files changed, 240 insertions(+), 11 deletions(-)
10 years, 4 months
ausearch checkpoint capability
by Burn Alting
Steve,
One of the issues with ausearch's checkpoint code is how to recover from
failures. A classic failure is to perform a checkpoint on a busy system
and then delay too long before running the next invocation of ausearch
and as a result of the delay, the checkpointed event cannot be found in
the files in /var/log/audit. There are other failures, such as re-use of
inodes etc.
For those of you who haven't noted the ausearch --checkpoint change, it
basically records the details of the last complete audit event it
processed or printed in a checkpoint file. It records not only the event
time, but also the event node, serial, type and the file device and
inode. Thus, when you next invoke ausearch with this option, the next
event to process is the next complete event since the one recorded.
Should an error occur when attempting to find the next complete event to
process, ausearch will exit. At this point, I believe the best recovery
action is to extract only the event time from the checkpoint file and
ask for all complete events after that time (i.e. as opposed to the
usual action of comparing time, event id, type, log file details etc).
There are at last two solutions:
a. We can patch ausearch to take a --checkpoint-time-only flag which
means ausearch will look for all events since the time in the checkpoint
file. This provides the best granularity in time as it goes down to
msecs.
b. We extract the timestamp from the checkpoint file, convert it to a
date and time and use ausearch's --start option to find all events since
the time in the checkpoint file.
The first provides greater granularity in time as it goes to msecs.
Steve,
I can provide a patch. Do you want it?
Rgds
Burn
10 years, 4 months