[PATCH ghak64 V3] audit: add saddr_fam filter field
by Richard Guy Briggs
Provide a method to filter out sockaddr and bind calls by network
address family.
Existing SOCKADDR records are listed for any network activity.
Implement the AUDIT_SADDR_FAM field selector to be able to classify or
limit records to specific network address families, such as AF_INET or
AF_INET6.
An example of a network record that is unlikely to be useful and flood
the logs:
type=SOCKADDR msg=audit(07/27/2017 12:18:27.019:845) : saddr={ fam=local
path=/var/run/nscd/socket }
type=SYSCALL msg=audit(07/27/2017 12:18:27.019:845) : arch=x86_64
syscall=connect success=no exit=ENOENT(No such file or directory) a0=0x3
a1=0x7fff229c4980 a2=0x6e a3=0x6 items=1 ppid=3301 pid=6145 auid=sgrubb
uid=sgrubb gid=sgrubb euid=sgrubb suid=sgrubb fsuid=sgrubb egid=sgrubb
sgid=sgrubb fsgid=sgrubb tty=pts3 ses=4 comm=bash exe=/usr/bin/bash
subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
key=network-test
Please see the audit-testsuite PR at
https://github.com/linux-audit/audit-testsuite/pull/87
Please see the github issue
https://github.com/linux-audit/audit-kernel/issues/64
Please see the github issue for the accompanying userspace support
https://github.com/linux-audit/audit-userspace/issues/93
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
Changelog:
v2:
- rebase on ghak73 v2
- check for valid range of saddr_fam value
v3:
- eliminate AF_UNSPEC check
include/uapi/linux/audit.h | 1 +
kernel/auditfilter.c | 5 +++++
kernel/auditsc.c | 5 +++++
3 files changed, 11 insertions(+)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index a1280af20336..c89c6495983d 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -281,6 +281,7 @@
#define AUDIT_OBJ_GID 110
#define AUDIT_FIELD_COMPARE 111
#define AUDIT_EXE 112
+#define AUDIT_SADDR_FAM 113
#define AUDIT_ARG0 200
#define AUDIT_ARG1 (AUDIT_ARG0+1)
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 5beb2244d5ba..df8a7d6184dc 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -387,6 +387,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
case AUDIT_SUCCESS:
case AUDIT_INODE:
case AUDIT_SESSIONID:
+ case AUDIT_SADDR_FAM:
/* bit ops are only useful on syscall args */
if (f->op == Audit_bitmask || f->op == Audit_bittest)
return -EINVAL;
@@ -438,6 +439,10 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
if (f->val > AUDIT_MAX_FIELD_COMPARE)
return -EINVAL;
break;
+ case AUDIT_SADDR_FAM:
+ if (f->val >= AF_MAX)
+ return -EINVAL;
+ break;
default:
break;
}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 4bd0ec60a0e8..aab364804b9b 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -623,6 +623,11 @@ static int audit_filter_rules(struct task_struct *tsk,
case AUDIT_LOGINUID_SET:
result = audit_comparator(audit_loginuid_set(tsk), f->op, f->val);
break;
+ case AUDIT_SADDR_FAM:
+ if (ctx->sockaddr)
+ result = audit_comparator(ctx->sockaddr->ss_family,
+ f->op, f->val);
+ break;
case AUDIT_SUBJ_USER:
case AUDIT_SUBJ_ROLE:
case AUDIT_SUBJ_TYPE:
--
1.8.3.1
5 years, 5 months
[PATCH ghak73 V3] audit: re-structure audit field valid checks
by Richard Guy Briggs
Multiple checks were being done in one switch case statement that
started to cause some redundancies and awkward exceptions. Separate the
valid field and op check from the select valid values checks.
Enforce the elimination of meaningless bitwise and greater/lessthan
checks on string fields and other fields with unrelated scalar values.
Please see the github issue
https://github.com/linux-audit/audit-kernel/issues/73
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
Changelog:
v3:
- remove op negation for WATCH, DIR, PERM, FILETYPE (ghak114)
- move AUDIT_{SUBJ_{CLR,SEN},OBJ_LEV_{LOW,HIGH}} to range
v2:
- address WATCH, DIR, FILETYPE, PERM lack of op checking
- touch up switch statement formatting
kernel/auditfilter.c | 56 +++++++++++++++++++++++++++++++---------------------
1 file changed, 34 insertions(+), 22 deletions(-)
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 303fb04770ce..d5e54e944f72 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -335,7 +335,7 @@ static u32 audit_to_op(u32 op)
/* check if an audit field is valid */
static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
{
- switch(f->type) {
+ switch (f->type) {
case AUDIT_MSGTYPE:
if (entry->rule.listnr != AUDIT_FILTER_EXCLUDE &&
entry->rule.listnr != AUDIT_FILTER_USER)
@@ -347,7 +347,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
break;
}
- switch(entry->rule.listnr) {
+ switch (entry->rule.listnr) {
case AUDIT_FILTER_FS:
switch(f->type) {
case AUDIT_FSTYPE:
@@ -358,9 +358,16 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
}
}
- switch(f->type) {
- default:
- return -EINVAL;
+ /* Check for valid field type and op */
+ switch (f->type) {
+ case AUDIT_ARG0:
+ case AUDIT_ARG1:
+ case AUDIT_ARG2:
+ case AUDIT_ARG3:
+ case AUDIT_PERS: /* <uapi/linux/personality.h> */
+ case AUDIT_DEVMINOR:
+ /* all ops are valid */
+ break;
case AUDIT_UID:
case AUDIT_EUID:
case AUDIT_SUID:
@@ -373,46 +380,52 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
case AUDIT_FSGID:
case AUDIT_OBJ_GID:
case AUDIT_PID:
- case AUDIT_PERS:
case AUDIT_MSGTYPE:
case AUDIT_PPID:
case AUDIT_DEVMAJOR:
- case AUDIT_DEVMINOR:
case AUDIT_EXIT:
case AUDIT_SUCCESS:
case AUDIT_INODE:
case AUDIT_SESSIONID:
+ case AUDIT_SUBJ_SEN:
+ case AUDIT_SUBJ_CLR:
+ case AUDIT_OBJ_LEV_LOW:
+ case AUDIT_OBJ_LEV_HIGH:
/* bit ops are only useful on syscall args */
if (f->op == Audit_bitmask || f->op == Audit_bittest)
return -EINVAL;
break;
- case AUDIT_ARG0:
- case AUDIT_ARG1:
- case AUDIT_ARG2:
- case AUDIT_ARG3:
case AUDIT_SUBJ_USER:
case AUDIT_SUBJ_ROLE:
case AUDIT_SUBJ_TYPE:
- case AUDIT_SUBJ_SEN:
- case AUDIT_SUBJ_CLR:
case AUDIT_OBJ_USER:
case AUDIT_OBJ_ROLE:
case AUDIT_OBJ_TYPE:
- case AUDIT_OBJ_LEV_LOW:
- case AUDIT_OBJ_LEV_HIGH:
case AUDIT_WATCH:
case AUDIT_DIR:
case AUDIT_FILTERKEY:
- break;
case AUDIT_LOGINUID_SET:
- if ((f->val != 0) && (f->val != 1))
- return -EINVAL;
- /* FALL THROUGH */
case AUDIT_ARCH:
case AUDIT_FSTYPE:
+ case AUDIT_PERM:
+ case AUDIT_FILETYPE:
+ case AUDIT_FIELD_COMPARE:
+ case AUDIT_EXE:
+ /* only equal and not equal valid ops */
if (f->op != Audit_not_equal && f->op != Audit_equal)
return -EINVAL;
break;
+ default:
+ /* field not recognized */
+ return -EINVAL;
+ }
+
+ /* Check for select valid field values */
+ switch (f->type) {
+ case AUDIT_LOGINUID_SET:
+ if ((f->val != 0) && (f->val != 1))
+ return -EINVAL;
+ break;
case AUDIT_PERM:
if (f->val & ~15)
return -EINVAL;
@@ -425,11 +438,10 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
if (f->val > AUDIT_MAX_FIELD_COMPARE)
return -EINVAL;
break;
- case AUDIT_EXE:
- if (f->op != Audit_not_equal && f->op != Audit_equal)
- return -EINVAL;
+ default:
break;
}
+
return 0;
}
--
1.8.3.1
5 years, 5 months
Auditing write syscall
by Ondra N.
Hello,
I would like to ask a question about auditing write syscalls. I am trying
to monitor all filesystem changes in a specific directory and process the
changes in near real time - audispd, was very helpful with that.
What concerns me is what if a filedescriptor is kept open for long periods
of time and written to once in a while? Only the open syscall is logged
when using a rule like this one.
auditctl -w /tmp/rnd_pop -p wa -k test_key
I was thinking that maybe being more explicit about what I want to do could
help like setting up a rule like this one.
auditctl -a always,exit -F dir=/tmp/rnd_pop -F perm=w -F succes=1 -k
test_key
But it doesnt seem to work for me, I guess I cannot filter write syscall by
directory because nothing ever shows up in the audit.log with a rule like
this.
What is the intended way to achieve logging of write syscalls in specific
directory, am i missing something? Should I check myself if the file is
still open when event is being processed and act accordingly?
Best regards,
Ondrej
5 years, 5 months
useradd question
by Lenny Bruzenak
If I add a new user with the "useradd" utility, it submits a ADD_USER
event, but the event itself has no interpretation for the new UID.
IOW, the "id" field is numeric and the translated data at the end of the
raw record has "ID=unknown(number)".
I'm guessing it is because until the user data has been successfully
entered, there is no translation. Perhaps the event submission should
wait until that happens?
I may be able to dig out the name from other related generated events,
but that is kind of a pain.
audit-2.8.5, RHEL 7.6
Thx,
LCB
--
Lenny Bruzenak
MagitekLTD
5 years, 5 months
[PATCH ghak73 V2] audit: re-structure audit field valid checks
by Richard Guy Briggs
Multiple checks were being done in one switch case statement that
started to cause some redundancies and awkward exceptions. Separate the
valid field and op check from the select valid values checks.
Enforce the elimination of meaningless bitwise and greater/lessthan
checks on string fields and other fields with unrelated scalar values.
Honour the operator for WATCH, DIR, PERM, FILETYPE fields as is done in
the EXE field.
Please see the github issue
https://github.com/linux-audit/audit-kernel/issues/73
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
Changelog:
v2:
- address WATCH, DIR, FILETYPE, PERM lack of op checking
- touch up switch statement formatting
kernel/auditfilter.c | 48 ++++++++++++++++++++++++++++++------------------
kernel/auditsc.c | 18 +++++++++++++++---
2 files changed, 45 insertions(+), 21 deletions(-)
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 1bc6410413e6..5beb2244d5ba 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -335,7 +335,7 @@ static u32 audit_to_op(u32 op)
/* check if an audit field is valid */
static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
{
- switch(f->type) {
+ switch (f->type) {
case AUDIT_MSGTYPE:
if (entry->rule.listnr != AUDIT_FILTER_EXCLUDE &&
entry->rule.listnr != AUDIT_FILTER_USER)
@@ -347,7 +347,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
break;
}
- switch(entry->rule.listnr) {
+ switch (entry->rule.listnr) {
case AUDIT_FILTER_FS:
switch(f->type) {
case AUDIT_FSTYPE:
@@ -358,9 +358,16 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
}
}
- switch(f->type) {
- default:
- return -EINVAL;
+ /* Check for valid field type and op */
+ switch (f->type) {
+ case AUDIT_ARG0:
+ case AUDIT_ARG1:
+ case AUDIT_ARG2:
+ case AUDIT_ARG3:
+ case AUDIT_PERS: /* <uapi/linux/personality.h> */
+ case AUDIT_DEVMINOR:
+ /* all ops are valid */
+ break;
case AUDIT_UID:
case AUDIT_EUID:
case AUDIT_SUID:
@@ -373,11 +380,9 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
case AUDIT_FSGID:
case AUDIT_OBJ_GID:
case AUDIT_PID:
- case AUDIT_PERS:
case AUDIT_MSGTYPE:
case AUDIT_PPID:
case AUDIT_DEVMAJOR:
- case AUDIT_DEVMINOR:
case AUDIT_EXIT:
case AUDIT_SUCCESS:
case AUDIT_INODE:
@@ -386,10 +391,6 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
if (f->op == Audit_bitmask || f->op == Audit_bittest)
return -EINVAL;
break;
- case AUDIT_ARG0:
- case AUDIT_ARG1:
- case AUDIT_ARG2:
- case AUDIT_ARG3:
case AUDIT_SUBJ_USER:
case AUDIT_SUBJ_ROLE:
case AUDIT_SUBJ_TYPE:
@@ -403,16 +404,28 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
case AUDIT_WATCH:
case AUDIT_DIR:
case AUDIT_FILTERKEY:
- break;
case AUDIT_LOGINUID_SET:
- if ((f->val != 0) && (f->val != 1))
- return -EINVAL;
- /* FALL THROUGH */
case AUDIT_ARCH:
case AUDIT_FSTYPE:
+ case AUDIT_PERM:
+ case AUDIT_FILETYPE:
+ case AUDIT_FIELD_COMPARE:
+ case AUDIT_EXE:
+ /* only equal and not equal valid ops */
if (f->op != Audit_not_equal && f->op != Audit_equal)
return -EINVAL;
break;
+ default:
+ /* field not recognized */
+ return -EINVAL;
+ }
+
+ /* Check for select valid field values */
+ switch (f->type) {
+ case AUDIT_LOGINUID_SET:
+ if ((f->val != 0) && (f->val != 1))
+ return -EINVAL;
+ break;
case AUDIT_PERM:
if (f->val & ~15)
return -EINVAL;
@@ -425,11 +438,10 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
if (f->val > AUDIT_MAX_FIELD_COMPARE)
return -EINVAL;
break;
- case AUDIT_EXE:
- if (f->op != Audit_not_equal && f->op != Audit_equal)
- return -EINVAL;
+ default:
break;
}
+
return 0;
}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 5371b59bde36..4bd0ec60a0e8 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -601,12 +601,20 @@ static int audit_filter_rules(struct task_struct *tsk,
}
break;
case AUDIT_WATCH:
- if (name)
- result = audit_watch_compare(rule->watch, name->ino, name->dev);
+ if (name) {
+ result = audit_watch_compare(rule->watch,
+ name->ino,
+ name->dev);
+ if (f->op == Audit_not_equal)
+ result = !result;
+ }
break;
case AUDIT_DIR:
- if (ctx)
+ if (ctx) {
result = match_tree_refs(ctx, rule->tree);
+ if (f->op == Audit_not_equal)
+ result = !result;
+ }
break;
case AUDIT_LOGINUID:
result = audit_uid_comparator(audit_get_loginuid(tsk),
@@ -684,9 +692,13 @@ static int audit_filter_rules(struct task_struct *tsk,
break;
case AUDIT_PERM:
result = audit_match_perm(ctx, f->val);
+ if (f->op == Audit_not_equal)
+ result = !result;
break;
case AUDIT_FILETYPE:
result = audit_match_filetype(ctx, f->val);
+ if (f->op == Audit_not_equal)
+ result = !result;
break;
case AUDIT_FIELD_COMPARE:
result = audit_field_compare(tsk, cred, f, ctx, name);
--
1.8.3.1
5 years, 5 months
[PATCH ghak111 V2] audit: deliver signal_info regarless of syscall
by Richard Guy Briggs
When a process signals the audit daemon (shutdown, rotate, resume,
reconfig) but syscall auditing is not enabled, we still want to know the
identity of the process sending the signal to the audit daemon.
Move audit_signal_info() out of syscall auditing to general auditing but
create a new function audit_signal_info_syscall() to take care of the
syscall dependent parts for when syscall auditing is enabled.
Please see the github kernel audit issue
https://github.com/linux-audit/audit-kernel/issues/111
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
Changelog:
v2:
- change patch title to avoid siginfo_t confusion
- change return value to "0" from AUDIT_OFF
- use dummy functions instead of macros in header files
Compile/boot/test auditsyscall enable/disable, audit disable,
auditsyscall enable/selinux disable.
include/linux/audit.h | 9 +++++++++
kernel/audit.c | 27 +++++++++++++++++++++++++++
kernel/audit.h | 8 ++++++--
kernel/auditsc.c | 19 +++----------------
kernel/signal.c | 2 +-
5 files changed, 46 insertions(+), 19 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 43a23e28ba23..b4078560cb73 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -196,6 +196,9 @@ static inline unsigned int audit_get_sessionid(struct task_struct *tsk)
}
extern u32 audit_enabled;
+
+extern int audit_signal_info(int sig, struct task_struct *t);
+
#else /* CONFIG_AUDIT */
static inline __printf(4, 5)
void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
@@ -249,6 +252,12 @@ static inline unsigned int audit_get_sessionid(struct task_struct *tsk)
}
#define audit_enabled AUDIT_OFF
+
+static inline int audit_signal_info(int sig, struct task_struct *t)
+{
+ return 0;
+}
+
#endif /* CONFIG_AUDIT */
#ifdef CONFIG_AUDIT_COMPAT_GENERIC
diff --git a/kernel/audit.c b/kernel/audit.c
index b96bf69183f4..67399ff72d43 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2274,6 +2274,33 @@ int audit_set_loginuid(kuid_t loginuid)
}
/**
+ * audit_signal_info - record signal info for shutting down audit subsystem
+ * @sig: signal value
+ * @t: task being signaled
+ *
+ * If the audit subsystem is being terminated, record the task (pid)
+ * and uid that is doing that.
+ */
+int audit_signal_info(int sig, struct task_struct *t)
+{
+ kuid_t uid = current_uid(), auid;
+
+ if (auditd_test_task(t) &&
+ (sig == SIGTERM || sig == SIGHUP ||
+ sig == SIGUSR1 || sig == SIGUSR2)) {
+ audit_sig_pid = task_tgid_nr(current);
+ auid = audit_get_loginuid(current);
+ if (uid_valid(auid))
+ audit_sig_uid = auid;
+ else
+ audit_sig_uid = uid;
+ security_task_getsecid(current, &audit_sig_sid);
+ }
+
+ return audit_signal_info_syscall(t);
+}
+
+/**
* audit_log_end - end one audit record
* @ab: the audit_buffer
*
diff --git a/kernel/audit.h b/kernel/audit.h
index 958d5b8fc1b3..e5df0c125e2d 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -299,7 +299,7 @@ extern bool audit_tree_match(struct audit_chunk *chunk,
extern void audit_put_tree(struct audit_tree *tree);
extern void audit_kill_trees(struct audit_context *context);
-extern int audit_signal_info(int sig, struct task_struct *t);
+extern int audit_signal_info_syscall(struct task_struct *t);
extern void audit_filter_inodes(struct task_struct *tsk,
struct audit_context *ctx);
extern struct list_head *audit_killed_trees(void);
@@ -330,7 +330,11 @@ extern void audit_filter_inodes(struct task_struct *tsk,
#define audit_tree_path(rule) "" /* never called */
#define audit_kill_trees(context) BUG()
-#define audit_signal_info(s, t) AUDIT_DISABLED
+static inline int audit_signal_info_syscall(struct task_struct *t)
+{
+ return 0;
+}
+
#define audit_filter_inodes(t, c) AUDIT_DISABLED
#endif /* CONFIG_AUDITSYSCALL */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 5371b59bde36..3209640df2cb 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -2360,30 +2360,17 @@ void __audit_ptrace(struct task_struct *t)
}
/**
- * audit_signal_info - record signal info for shutting down audit subsystem
- * @sig: signal value
+ * audit_signal_info_syscall - record signal info for syscalls
* @t: task being signaled
*
* If the audit subsystem is being terminated, record the task (pid)
* and uid that is doing that.
*/
-int audit_signal_info(int sig, struct task_struct *t)
+int audit_signal_info_syscall(struct task_struct *t)
{
struct audit_aux_data_pids *axp;
struct audit_context *ctx = audit_context();
- kuid_t uid = current_uid(), auid, t_uid = task_uid(t);
-
- if (auditd_test_task(t) &&
- (sig == SIGTERM || sig == SIGHUP ||
- sig == SIGUSR1 || sig == SIGUSR2)) {
- audit_sig_pid = task_tgid_nr(current);
- auid = audit_get_loginuid(current);
- if (uid_valid(auid))
- audit_sig_uid = auid;
- else
- audit_sig_uid = uid;
- security_task_getsecid(current, &audit_sig_sid);
- }
+ kuid_t t_uid = task_uid(t);
if (!audit_signals || audit_dummy_context())
return 0;
diff --git a/kernel/signal.c b/kernel/signal.c
index b7953934aa99..73db5dfa797d 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -43,6 +43,7 @@
#include <linux/compiler.h>
#include <linux/posix-timers.h>
#include <linux/livepatch.h>
+#include <linux/audit.h> /* audit_signal_info() */
#define CREATE_TRACE_POINTS
#include <trace/events/signal.h>
@@ -52,7 +53,6 @@
#include <asm/unistd.h>
#include <asm/siginfo.h>
#include <asm/cacheflush.h>
-#include "audit.h" /* audit_signal_info() */
/*
* SLAB caches for signal bits.
--
1.8.3.1
5 years, 5 months
Error starting auditd
by Wolff Felix (ETAS-SEC/ECT-Be)
Hello,
I am currently porting auditd to a new platform. When starting it using `auditd -f`, I get the following error:
"Error setting audit daemon pid (File exists)"
It occurs during the call to `audit_set_pid(fd, getpid(), WAIT_YES);` in auditd.c. If I understand correctly, this call registers auditd with the kernel, is that correct? fd looks like a valid file descriptor, at least its >0. Especially the "file exists" part confuses me. In which direction can I investigate that error?
Thank you and greets,
Felix
--
Mit freundlichen Grüßen/Best regards
Felix Wolff
Software Engineer
[ESCRYPT-Logo_RGB]
ESCRYPT GmbH
Wittener Straße 45
44789 Bochum, Germany
Email: felix.wolff(a)escrypt.com
Phone: +49 30 403 691 957
Mobile: +49 1525 6953 720
www.escrypt.com
Managing directors: Christopher White, Dr.-Ing. Thomas Wollinger
Registered office and court of registry: Bochum, Germany, HRB 7877
5 years, 5 months
[PATCH ghau90 v2] sig_info: use standard template for log messages
by Richard Guy Briggs
Records that are triggered by an AUDIT_SIGNAL_INFO message including
AUDIT_DAEMON_CONFIG (HUP), AUDIT_DAEMON_ROTATE (USR1),
AUDIT_DAEMON_RESUME (USR2) and AUDIT_DAEMON_END (TERM) have inconsistent
reporting of signal info and swinging field "state".
They also assume that an empty security context implies there is no
other useful information in the AUDIT_SIGNAL_INFO message so don't use
the information that is there.
Normalize AUDIT_DAEMON_CONFIG to use the value "reconfigure" and add the
"state" field where missing.
Use audit_sig_info values when available, not making assumptions about
their availability when the security context is absent.
See: https://github.com/linux-audit/audit-userspace/issues/90
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
Changelog:
v2:
- omit subj= if selinux unavailable
- add missing colon to daemon_config
docs/audit_request_signal_info.3 | 2 +-
lib/libaudit.c | 12 +++++++++
lib/libaudit.h | 1 +
src/auditd-event.c | 2 +-
src/auditd-reconfig.c | 9 +++----
src/auditd.c | 56 ++++++++++++++--------------------------
6 files changed, 38 insertions(+), 44 deletions(-)
diff --git a/docs/audit_request_signal_info.3 b/docs/audit_request_signal_info.3
index 873deb58bef3..b68d7bbefeed 100644
--- a/docs/audit_request_signal_info.3
+++ b/docs/audit_request_signal_info.3
@@ -8,7 +8,7 @@ int audit_request_signal_info(int fd);
.SH "DESCRIPTION"
-audit_request_signal_info requests that the kernel send information about the sender of a signal to the audit daemon. The sinal info structure is as follows:
+audit_request_signal_info requests that the kernel send information about the sender of a signal to the audit daemon. The signal info structure is as follows:
.nf
struct audit_sig_info {
diff --git a/lib/libaudit.c b/lib/libaudit.c
index 2af017a0e520..e695791f9243 100644
--- a/lib/libaudit.c
+++ b/lib/libaudit.c
@@ -674,6 +674,18 @@ int audit_request_signal_info(int fd)
return rc;
}
+char *audit_format_signal_info(char *buf, int len, char *op, struct audit_reply *rep, char *res)
+{
+ if (rep->len == 24)
+ snprintf(buf, len, "op=%s auid=%u pid=%d res=%s", op,
+ rep->signal_info->uid, rep->signal_info->pid, res);
+ else
+ snprintf(buf, len, "op=%s auid=%u pid=%d subj=%s res=%s",
+ op, rep->signal_info->uid, rep->signal_info->pid,
+ rep->signal_info->ctx, res);
+ return buf;
+}
+
int audit_update_watch_perms(struct audit_rule_data *rule, int perms)
{
unsigned int i, done=0;
diff --git a/lib/libaudit.h b/lib/libaudit.h
index 77e4142beea2..36ea8bc04e8a 100644
--- a/lib/libaudit.h
+++ b/lib/libaudit.h
@@ -573,6 +573,7 @@ extern int audit_setloginuid(uid_t uid);
extern uint32_t audit_get_session(void);
extern int audit_detect_machine(void);
extern int audit_determine_machine(const char *arch);
+extern char *audit_format_signal_info(char *buf, int len, char *op, struct audit_reply *rep, char *res);
/* Translation functions */
extern int audit_name_to_field(const char *field);
diff --git a/src/auditd-event.c b/src/auditd-event.c
index ef2828d8df94..2970aba44456 100644
--- a/src/auditd-event.c
+++ b/src/auditd-event.c
@@ -1572,7 +1572,7 @@ static void reconfigure(struct auditd_event *e)
e->reply.type = AUDIT_DAEMON_CONFIG;
e->reply.len = snprintf(e->reply.msg.data, MAX_AUDIT_MESSAGE_LENGTH-2,
- "%s op=reconfigure state=changed auid=%u pid=%d subj=%s res=success",
+ "%s : op=reconfigure state=changed auid=%u pid=%d subj=%s res=success",
date, uid, pid, ctx );
e->reply.message = e->reply.msg.data;
free((char *)ctx);
diff --git a/src/auditd-reconfig.c b/src/auditd-reconfig.c
index a03e29aa57ab..f5b00e6d1dc7 100644
--- a/src/auditd-reconfig.c
+++ b/src/auditd-reconfig.c
@@ -115,12 +115,9 @@ static void *config_thread_main(void *arg)
} else {
// need to send a failed event message
char txt[MAX_AUDIT_MESSAGE_LENGTH];
- snprintf(txt, sizeof(txt),
- "op=reconfigure state=no-change auid=%u pid=%d subj=%s res=failed",
- e->reply.signal_info->uid,
- e->reply.signal_info->pid,
- (e->reply.len > 24) ?
- e->reply.signal_info->ctx : "?");
+ audit_format_signal_info(txt, sizeof(txt),
+ "reconfigure state=no-change",
+ &e->reply, "failed");
// FIXME: need to figure out sending this
//send_audit_event(AUDIT_DAEMON_CONFIG, txt);
free_config(&new_config);
diff --git a/src/auditd.c b/src/auditd.c
index c04a1c9ce93f..63404b25fbc5 100644
--- a/src/auditd.c
+++ b/src/auditd.c
@@ -131,7 +131,7 @@ static void hup_handler( struct ev_loop *loop, struct ev_signal *sig, int revent
rc = audit_request_signal_info(fd);
if (rc < 0)
send_audit_event(AUDIT_DAEMON_CONFIG,
- "op=hup-info state=request-siginfo auid=-1 pid=-1 subj=? res=failed");
+ "op=reconfigure state=no-change auid=-1 pid=-1 subj=? res=failed");
else
hup_info_requested = 1;
}
@@ -147,7 +147,7 @@ static void user1_handler(struct ev_loop *loop, struct ev_signal *sig,
rc = audit_request_signal_info(fd);
if (rc < 0)
send_audit_event(AUDIT_DAEMON_ROTATE,
- "op=usr1-info auid=-1 pid=-1 subj=? res=failed");
+ "op=rotate-logs auid=-1 pid=-1 subj=? res=failed");
else
usr1_info_requested = 1;
}
@@ -163,7 +163,7 @@ static void user2_handler( struct ev_loop *loop, struct ev_signal *sig, int reve
if (rc < 0) {
resume_logging();
send_audit_event(AUDIT_DAEMON_RESUME,
- "op=resume-logging auid=-1 pid=-1 subj=? res=success");
+ "op=resume-logging auid=-1 pid=-1 subj=? res=failed");
} else
usr2_info_requested = 1;
}
@@ -515,45 +515,33 @@ static void netlink_handler(struct ev_loop *loop, struct ev_io *io,
break;
case AUDIT_SIGNAL_INFO:
if (hup_info_requested) {
+ char hup[MAX_AUDIT_MESSAGE_LENGTH];
audit_msg(LOG_DEBUG,
"HUP detected, starting config manager");
reconfig_ev = cur_event;
if (start_config_manager(cur_event)) {
- send_audit_event(
- AUDIT_DAEMON_CONFIG,
- "op=reconfigure state=no-change "
- "auid=-1 pid=-1 subj=? res=failed");
+ audit_format_signal_info(hup, sizeof(hup),
+ "reconfigure state=no-change",
+ &cur_event->reply,
+ "failed");
+ send_audit_event(AUDIT_DAEMON_CONFIG, hup);
}
cur_event = NULL;
hup_info_requested = 0;
} else if (usr1_info_requested) {
char usr1[MAX_AUDIT_MESSAGE_LENGTH];
- if (cur_event->reply.len == 24) {
- snprintf(usr1, sizeof(usr1),
- "op=rotate-logs auid=-1 pid=-1 subj=?");
- } else {
- snprintf(usr1, sizeof(usr1),
- "op=rotate-logs auid=%u pid=%d subj=%s",
- cur_event->reply.signal_info->uid,
- cur_event->reply.signal_info->pid,
- cur_event->reply.signal_info->ctx);
- }
+ audit_format_signal_info(usr1, sizeof(usr1),
+ "rotate-logs",
+ &cur_event->reply,
+ "success");
send_audit_event(AUDIT_DAEMON_ROTATE, usr1);
usr1_info_requested = 0;
} else if (usr2_info_requested) {
char usr2[MAX_AUDIT_MESSAGE_LENGTH];
- if (cur_event->reply.len == 24) {
- snprintf(usr2, sizeof(usr2),
- "op=resume-logging auid=-1 "
- "pid=-1 subj=? res=success");
- } else {
- snprintf(usr2, sizeof(usr2),
- "op=resume-logging "
- "auid=%u pid=%d subj=%s res=success",
- cur_event->reply.signal_info->uid,
- cur_event->reply.signal_info->pid,
- cur_event->reply.signal_info->ctx);
- }
+ audit_format_signal_info(usr2, sizeof(usr2),
+ "resume-logging",
+ &cur_event->reply,
+ "success");
resume_logging();
libdisp_resume();
send_audit_event(AUDIT_DAEMON_RESUME, usr2);
@@ -993,18 +981,14 @@ int main(int argc, char *argv[])
rc = get_reply(fd, &trep, rc);
if (rc > 0) {
char txt[MAX_AUDIT_MESSAGE_LENGTH];
- snprintf(txt, sizeof(txt),
- "op=terminate auid=%u "
- "pid=%d subj=%s res=success",
- trep.signal_info->uid,
- trep.signal_info->pid,
- trep.signal_info->ctx);
+ audit_format_signal_info(txt, sizeof(txt), "terminate",
+ &trep, "success");
send_audit_event(AUDIT_DAEMON_END, txt);
}
}
if (rc <= 0)
send_audit_event(AUDIT_DAEMON_END,
- "op=terminate auid=-1 pid=-1 subj=? res=success");
+ "op=terminate auid=-1 pid=-1 subj=? res=failed");
free(cur_event);
// Tear down IO watchers Part 2
--
1.8.3.1
5 years, 5 months
[PATCH ghak64 V2] audit: add saddr_fam filter field
by Richard Guy Briggs
Provide a method to filter out sockaddr and bind calls by network
address family.
Existing SOCKADDR records are listed for any network activity.
Implement the AUDIT_SADDR_FAM field selector to be able to classify or
limit records to specific network address families, such as AF_INET or
AF_INET6.
An example of a network record that is unlikely to be useful and flood
the logs:
type=SOCKADDR msg=audit(07/27/2017 12:18:27.019:845) : saddr={ fam=local
path=/var/run/nscd/socket }
type=SYSCALL msg=audit(07/27/2017 12:18:27.019:845) : arch=x86_64
syscall=connect success=no exit=ENOENT(No such file or directory) a0=0x3
a1=0x7fff229c4980 a2=0x6e a3=0x6 items=1 ppid=3301 pid=6145 auid=sgrubb
uid=sgrubb gid=sgrubb euid=sgrubb suid=sgrubb fsuid=sgrubb egid=sgrubb
sgid=sgrubb fsgid=sgrubb tty=pts3 ses=4 comm=bash exe=/usr/bin/bash
subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
key=network-test
Please see the audit-testsuite PR at
https://github.com/linux-audit/audit-testsuite/pull/87
Please see the github issue
https://github.com/linux-audit/audit-kernel/issues/64
Please see the github issue for the accompanying userspace support
https://github.com/linux-audit/audit-userspace/issues/93
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
Changelog:
v2:
- rebase on ghak73 v2
- check for valid range of saddr_fam value
include/uapi/linux/audit.h | 1 +
kernel/auditfilter.c | 5 +++++
kernel/auditsc.c | 5 +++++
3 files changed, 11 insertions(+)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index a1280af20336..c89c6495983d 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -281,6 +281,7 @@
#define AUDIT_OBJ_GID 110
#define AUDIT_FIELD_COMPARE 111
#define AUDIT_EXE 112
+#define AUDIT_SADDR_FAM 113
#define AUDIT_ARG0 200
#define AUDIT_ARG1 (AUDIT_ARG0+1)
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 5beb2244d5ba..4c897281beb8 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -387,6 +387,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
case AUDIT_SUCCESS:
case AUDIT_INODE:
case AUDIT_SESSIONID:
+ case AUDIT_SADDR_FAM:
/* bit ops are only useful on syscall args */
if (f->op == Audit_bitmask || f->op == Audit_bittest)
return -EINVAL;
@@ -438,6 +439,10 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
if (f->val > AUDIT_MAX_FIELD_COMPARE)
return -EINVAL;
break;
+ case AUDIT_SADDR_FAM:
+ if (f->val <= AF_UNSPEC || f->val >= AF_MAX)
+ return -EINVAL;
+ break;
default:
break;
}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 4bd0ec60a0e8..aab364804b9b 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -623,6 +623,11 @@ static int audit_filter_rules(struct task_struct *tsk,
case AUDIT_LOGINUID_SET:
result = audit_comparator(audit_loginuid_set(tsk), f->op, f->val);
break;
+ case AUDIT_SADDR_FAM:
+ if (ctx->sockaddr)
+ result = audit_comparator(ctx->sockaddr->ss_family,
+ f->op, f->val);
+ break;
case AUDIT_SUBJ_USER:
case AUDIT_SUBJ_ROLE:
case AUDIT_SUBJ_TYPE:
--
1.8.3.1
5 years, 5 months
[GIT PULL] Audit patches for v5.2
by Paul Moore
Hi Linus,
We've got a reasonably broad set of audit patches for the v5.2 merge
window, the highlights are below:
- The biggest change, and the source of all the arch/* changes, is the
patchset from Dmitry to help enable some of the work he is doing
around PTRACE_GET_SYSCALL_INFO. To be honest, including this in the
audit tree is a bit of a stretch, but it does help move audit a little
further along towards proper syscall auditing for all arches, and
everyone else seemed to agree that audit was a "good" spot for this to
land (or maybe they just didn't want to merge it? dunno.).
- We can now audit time/NTP adjustments.
- We continue the work to connect associated audit records into a single event.
As a FYI, you will likely run into two minor merge problems in
kernel/seccomp.c and arch/mips/kernel/ptrace.c; both are very similar
and have to do with the change to syscall_get_arch() and
syscall_get_arguments(). It should be easy to sort this out (you'll
see what I mean), but if you have any questions just let us know.
Please pull this for v5.2,
-Paul
--
The following changes since commit 9e98c678c2d6ae3a17cb2de55d17f69dddaa231b:
Linux 5.1-rc1 (2019-03-17 14:22:26 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git
tags/audit-pr-20190507
for you to fetch changes up to 70c4cf17e445264453bc5323db3e50aa0ac9e81f:
audit: fix a memory leak bug (2019-04-22 11:22:03 -0400)
----------------------------------------------------------------
audit/stable-5.2 PR 20190507
----------------------------------------------------------------
Dmitry V. Levin (13):
Move EM_ARCOMPACT and EM_ARCV2 to uapi/linux/elf-em.h
arc: define syscall_get_arch()
c6x: define syscall_get_arch()
h8300: define syscall_get_arch()
Move EM_HEXAGON to uapi/linux/elf-em.h
hexagon: define syscall_get_arch()
m68k: define syscall_get_arch()
Move EM_NDS32 to uapi/linux/elf-em.h
nds32: define syscall_get_arch()
nios2: define syscall_get_arch()
Move EM_UNICORE to uapi/linux/elf-em.h
unicore32: define syscall_get_arch()
syscall_get_arch: add "struct task_struct *" argument
Li RongQing (1):
audit: fix a memleak caused by auditing load module
Ondrej Mosnacek (2):
timekeeping: Audit clock adjustments
ntp: Audit NTP parameters adjustment
Richard Guy Briggs (3):
audit: connect LOGIN record to its syscall record
audit: link integrity evm_write_xattrs record to syscall event
audit: purge unnecessary list_empty calls
Wenwen Wang (1):
audit: fix a memory leak bug
YueHaibing (1):
audit: Make audit_log_cap and audit_copy_inode static
arch/alpha/include/asm/syscall.h | 2 +-
arch/arc/include/asm/elf.h | 6 +-
arch/arc/include/asm/syscall.h | 11 ++++
arch/arm/include/asm/syscall.h | 2 +-
arch/arm64/include/asm/syscall.h | 4 +-
arch/c6x/include/asm/syscall.h | 7 +++
arch/csky/include/asm/syscall.h | 2 +-
arch/h8300/include/asm/syscall.h | 6 ++
arch/hexagon/include/asm/elf.h | 6 +-
arch/hexagon/include/asm/syscall.h | 8 +++
arch/ia64/include/asm/syscall.h | 2 +-
arch/m68k/include/asm/syscall.h | 12 ++++
arch/microblaze/include/asm/syscall.h | 2 +-
arch/mips/include/asm/syscall.h | 6 +-
arch/mips/kernel/ptrace.c | 2 +-
arch/nds32/include/asm/elf.h | 3 +-
arch/nds32/include/asm/syscall.h | 9 +++
arch/nios2/include/asm/syscall.h | 6 ++
arch/openrisc/include/asm/syscall.h | 2 +-
arch/parisc/include/asm/syscall.h | 4 +-
arch/powerpc/include/asm/syscall.h | 10 ++-
arch/riscv/include/asm/syscall.h | 2 +-
arch/s390/include/asm/syscall.h | 4 +-
arch/sh/include/asm/syscall_32.h | 2 +-
arch/sh/include/asm/syscall_64.h | 2 +-
arch/sparc/include/asm/syscall.h | 5 +-
arch/unicore32/include/asm/elf.h | 3 +-
arch/unicore32/include/asm/syscall.h | 12 ++++
arch/x86/include/asm/syscall.h | 8 ++-
arch/x86/um/asm/syscall.h | 2 +-
arch/xtensa/include/asm/syscall.h | 2 +-
include/asm-generic/syscall.h | 5 +-
include/linux/audit.h | 75 +++++++++++++++++++++++
include/uapi/linux/audit.h | 14 +++++
include/uapi/linux/elf-em.h | 6 ++
kernel/audit.c | 2 +-
kernel/auditfilter.c | 14 ++---
kernel/auditsc.c | 115 +++++++++++++++++++++------------
kernel/seccomp.c | 4 +-
kernel/time/ntp.c | 22 ++++++-
kernel/time/ntp_internal.h | 4 +-
kernel/time/timekeeping.c | 13 +++-
security/integrity/evm/evm_secfs.c | 10 +--
43 files changed, 331 insertions(+), 107 deletions(-)
create mode 100644 arch/m68k/include/asm/syscall.h
create mode 100644 arch/unicore32/include/asm/syscall.h
--
paul moore
www.paul-moore.com
5 years, 5 months