Linux-audit Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/2] audit: log binding and unbinding to netlink multicast socket
From: Steve Grubb @ 2015-07-23 20:45 UTC (permalink / raw)
  To: linux-audit

Log information about programs connecting and disconnecting to the audit
netlink multicast socket. This is needed so that during investigations a
security officer can tell who or what had access to the audit trail. This
helps to meet the FAU_SAR.2 requirement for Common Criteria.

Signed-off-by: Steve Grubb <sgrubb@redhat.com>
---
 include/uapi/linux/audit.h |  1 +
 kernel/audit.c             | 30 ++++++++++++++++++++++++++++--
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index d3475e1..bb4555a 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -110,6 +110,7 @@
 #define AUDIT_SECCOMP		1326	/* Secure Computing event */
 #define AUDIT_PROCTITLE		1327	/* Proctitle emit event */
 #define AUDIT_FEATURE_CHANGE	1328	/* audit log listing feature changes */
+#define AUDIT_EVENT_LISTENER	1329	/* task joined multicast read socket */
 
 #define AUDIT_AVC		1400	/* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR	1401	/* Internal SE Linux Errors */
diff --git a/kernel/audit.c b/kernel/audit.c
index 29fb38b..3253f1b 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1135,13 +1135,36 @@ void audit_log_task_simple(struct audit_buffer *ab, struct task_struct *tsk)
 }
 EXPORT_SYMBOL(audit_log_task_simple);
 
+static void audit_log_bind(int group, const char *op, int err)
+{
+	struct audit_buffer *ab;
+
+	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_EVENT_LISTENER);
+	if (!ab)
+		return;
+
+	audit_log_task_simple(ab, current);
+	audit_log_format(ab, " nlnk-grp=%d", group);
+	audit_log_format(ab, " op=%s", op);
+	audit_log_format(ab, " res=%d", !err);
+	audit_log_end(ab);
+}
+
 /* Run custom bind function on netlink socket group connect or bind requests. */
 static int audit_bind(struct net *net, int group)
 {
+	int err = 0;
+
 	if (!capable(CAP_AUDIT_READ))
-		return -EPERM;
+		err = -EPERM;
+	audit_log_bind(group, "connect", err);
 
-	return 0;
+	return err;
+}
+
+static void audit_unbind(struct net *net, int group)
+{
+	audit_log_bind(group, "disconnect", 0);
 }
 
 static int __net_init audit_net_init(struct net *net)
@@ -1151,6 +1176,7 @@ static int __net_init audit_net_init(struct net *net)
 		.bind	= audit_bind,
 		.flags	= NL_CFG_F_NONROOT_RECV,
 		.groups	= AUDIT_NLGRP_MAX,
+		.unbind	= audit_unbind,
 	};
 
 	struct audit_net *aunet = net_generic(net, audit_net_id);
-- 
2.4.3

^ permalink raw reply related

* [PATCH 1/2] audit: log binding and unbinding to netlink multicast socket
From: Steve Grubb @ 2015-07-23 20:45 UTC (permalink / raw)
  To: linux-audit

The audit subsystem could use a function that logs the commonly needed
fields for a typical audit event. This logs less that audit_log_task_info
and reduces the need to hand code individual fields.

Signed-off-by: Steve Grubb <sgrubb@redhat.com>
---
 include/linux/audit.h |  5 +++++
 kernel/audit.c        | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index c2e7e3a..2620847 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -484,6 +484,8 @@ static inline void	    audit_log_secctx(struct audit_buffer *ab, u32 secid)
 extern int audit_log_task_context(struct audit_buffer *ab);
 extern void audit_log_task_info(struct audit_buffer *ab,
 				struct task_struct *tsk);
+extern void audit_log_task_simple(struct audit_buffer *ab,
+				struct task_struct *tsk);
 
 extern int		    audit_update_lsm_rules(void);
 
@@ -540,6 +542,9 @@ static inline int audit_log_task_context(struct audit_buffer *ab)
 static inline void audit_log_task_info(struct audit_buffer *ab,
 				       struct task_struct *tsk)
 { }
+static inline void audit_log_task_simple(struct audit_buffer *ab,
+				       struct task_struct *tsk)
+{ }
 #define audit_enabled 0
 #endif /* CONFIG_AUDIT */
 static inline void audit_log_string(struct audit_buffer *ab, const char *buf)
diff --git a/kernel/audit.c b/kernel/audit.c
index 1c13e42..29fb38b 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1100,6 +1100,41 @@ static void audit_receive(struct sk_buff  *skb)
 	mutex_unlock(&audit_cmd_mutex);
 }
 
+/* This function logs the essential information needed to understand
+ * what or who is causing the event */
+void audit_log_task_simple(struct audit_buffer *ab, struct task_struct *tsk)
+{
+	const struct cred *cred;
+	char comm[sizeof(tsk->comm)];
+	char *tty;
+
+	if (!ab)
+		return;
+
+	/* tsk == current */
+	cred = current_cred();
+
+	spin_lock_irq(&tsk->sighand->siglock);
+	if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name)
+		tty = tsk->signal->tty->name;
+	else
+		tty = "(none)";
+	spin_unlock_irq(&tsk->sighand->siglock);
+
+	audit_log_format(ab, "pid=%u uid=%u auid=%u tty=%s ses=%u",
+			 task_pid_nr(tsk),
+			 from_kuid(&init_user_ns, cred->uid),
+			 from_kuid(&init_user_ns, audit_get_loginuid(tsk)),
+			 tty, audit_get_sessionid(tsk));
+
+	audit_log_task_context(ab); /* subj= */
+	audit_log_format(ab, " comm=");
+	audit_log_untrustedstring(ab, get_task_comm(comm, tsk));
+
+	audit_log_d_path_exe(ab, tsk->mm); /* exe= */
+}
+EXPORT_SYMBOL(audit_log_task_simple);
+
 /* Run custom bind function on netlink socket group connect or bind requests. */
 static int audit_bind(struct net *net, int group)
 {
-- 
2.4.3

^ permalink raw reply related

* [PATCH 0/2] audit: log binding and unbinding to netlink multicast socket
From: Steve Grubb @ 2015-07-23 20:45 UTC (permalink / raw)
  To: linux-audit

Hello,

I am resurrecting this old patch. Its been cleaned up by adding a simple task 
logging function which should, in the future, serve almost all kernel logging 
needs. The cleaned up bind and unbind functions call it to create the preamble 
and then finish with specific data items for bind/unbinding.

In essence, this patch logs connecting and unconnecting to the audit netlink 
multicast socket. This is needed so that during investigations a security 
officer can tell who or what had access to the audit trail. This helps to meet 
the FAU_SAR.2 SFR for Common Criteria.

Sample output:

type=UNKNOWN[1329] msg=audit(1437683193.897:725): pid=10068 uid=0 auid=4325 
tty=pts0 ses=1 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 
comm="test" exe="/home/sgrubb/test/multicast/test" nlnk-grp=1 op=connect res=1
type=UNKNOWN[1329] msg=audit(1437683308.055:741): pid=10068 uid=0 auid=4325 
tty=pts0 ses=1 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 
comm="test" exe=(null) nlnk-grp=1 op=disconnect res=1

Signed-off-by: Steve Grubb <sgrubb@redhat.com>

---

^ permalink raw reply

* [PATCH] Missed cross compile fixes
From: Clayton Shotwell @ 2015-07-22 14:52 UTC (permalink / raw)
  To: linux-audit

My previous patch set attempted to fix the building of the gen_tables.c
applications so they can run on the build machine when cross compiling.
I failed to realize that automake would still attempt to insert the
CFLAGS and CPPFLAGS variables even when they should be CFLAGS_FOR_BUILD
and CPPFLAGS_FOR_BUILD. This change set should override those FLAGS
variables properly.

Signed-off-by: Clayton Shotwell <clayton.shotwell@rockwellcollins.com>
---
 auparse/Makefile.am | 185 +++++++++++++++++++++++++++++++++++++++++-----------
 lib/Makefile.am     |  85 +++++++++++++++++++-----
 2 files changed, 216 insertions(+), 54 deletions(-)

diff --git a/auparse/Makefile.am b/auparse/Makefile.am
index 742f7ba..4b864d7 100644
--- a/auparse/Makefile.am
+++ b/auparse/Makefile.am
@@ -79,302 +79,413 @@ noinst_PROGRAMS = gen_accesstabs_h gen_captabs_h gen_clock_h \
 	gen_umounttabs_h
 
 gen_accesstabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h accesstab.h
-gen_accesstabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="accesstab.h"'
+gen_accesstabs_h_CFLAGS = '-DTABLE_H="accesstab.h"'
 $(gen_accesstabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_accesstabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_accesstabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_accesstabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_accesstabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_accesstabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 accesstabs.h: gen_accesstabs_h Makefile
 	./gen_accesstabs_h --i2s-transtab access > $@
 
 gen_captabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h captab.h
-gen_captabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="captab.h"'
+gen_captabs_h_CFLAGS = '-DTABLE_H="captab.h"'
 $(gen_captabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_captabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_captabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_captabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_captabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_captabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 captabs.h: gen_captabs_h Makefile
 	./gen_captabs_h --i2s cap > $@
 
 gen_clock_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h clocktab.h
-gen_clock_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="clocktab.h"'
+gen_clock_h_CFLAGS = '-DTABLE_H="clocktab.h"'
 $(gen_clock_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_clock_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_clock_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_clock_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_clock_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_clock_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 clocktabs.h: gen_clock_h Makefile
 	./gen_clock_h --i2s clock > $@
 
 gen_clone_flagtabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h \
 	clone-flagtab.h
-gen_clone_flagtabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="clone-flagtab.h"'
+gen_clone_flagtabs_h_CFLAGS = '-DTABLE_H="clone-flagtab.h"'
 $(gen_clone_flagtabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_clone_flagtabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_clone_flagtabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_clone-flagtabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_clone-flagtabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_clone-flagtabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 clone-flagtabs.h: gen_clone-flagtabs_h Makefile
 	./gen_clone-flagtabs_h --i2s-transtab clone_flag > $@
 
 gen_epoll_ctls_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h epoll_ctl.h
-gen_epoll_ctls_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="epoll_ctl.h"'
+gen_epoll_ctls_h_CFLAGS = '-DTABLE_H="epoll_ctl.h"'
 $(gen_epoll_ctls_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_epoll_ctls_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_epoll_ctls_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_epoll_ctls_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_epoll_ctls_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_epoll_ctls_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 epoll_ctls.h: gen_epoll_ctls_h Makefile
 	./gen_epoll_ctls_h --i2s epoll_ctl > $@
 
 gen_famtabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h famtab.h
-gen_famtabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="famtab.h"'
+gen_famtabs_h_CFLAGS = '-DTABLE_H="famtab.h"'
 $(gen_famtabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_famtabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_famtabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_famtabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_famtabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_famtabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 famtabs.h: gen_famtabs_h Makefile
 	./gen_famtabs_h --i2s fam > $@
 
 gen_flagtabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h flagtab.h
 # ../auparse/ is used to avoid using ../lib/flagtab.h
-gen_flagtabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="../auparse/flagtab.h"'
+gen_flagtabs_h_CFLAGS = '-DTABLE_H="../auparse/flagtab.h"'
 $(gen_flagtabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_flagtabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_flagtabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_flagtabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_flagtabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_flagtabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 flagtabs.h: gen_flagtabs_h Makefile
 	./gen_flagtabs_h --i2s-transtab flag > $@
 
 gen_fcntl_cmdtabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h \
 	fcntl-cmdtab.h
-gen_fcntl_cmdtabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="fcntl-cmdtab.h"'
+gen_fcntl_cmdtabs_h_CFLAGS = '-DTABLE_H="fcntl-cmdtab.h"'
 $(gen_fcntl_cmdtabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_fcntl_cmdtabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_fcntl_cmdtabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_fcntl-cmdtabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_fcntl-cmdtabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_fcntl-cmdtabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 fcntl-cmdtabs.h: gen_fcntl-cmdtabs_h Makefile
 	./gen_fcntl-cmdtabs_h --i2s fcntl > $@
 
 gen_icmptypetabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h icmptypetab.h
-gen_icmptypetabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="icmptypetab.h"'
+gen_icmptypetabs_h_CFLAGS = '-DTABLE_H="icmptypetab.h"'
 $(gen_icmptypetabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_icmptypetabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_icmptypetabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_icmptypetabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_icmptypetabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_icmptypetabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 icmptypetabs.h: gen_icmptypetabs_h Makefile
 	./gen_icmptypetabs_h --i2s icmptype > $@
 
 gen_ioctlreqtabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h ioctlreqtab.h
-gen_ioctlreqtabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="ioctlreqtab.h"'
+gen_ioctlreqtabs_h_CFLAGS = '-DTABLE_H="ioctlreqtab.h"'
 $(gen_ioctlreqtabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_ioctlreqtabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_ioctlreqtabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_ioctlreqtabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_ioctlreqtabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_ioctlreqtabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 ioctlreqtabs.h: gen_ioctlreqtabs_h Makefile
 	./gen_ioctlreqtabs_h --i2s ioctlreq > $@
 
 gen_ipctabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h ipctab.h
-gen_ipctabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="ipctab.h"'
+gen_ipctabs_h_CFLAGS = '-DTABLE_H="ipctab.h"'
 $(gen_ipctabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_ipctabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_ipctabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_ipctabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_ipctabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_ipctabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 ipctabs.h: gen_ipctabs_h Makefile
 	./gen_ipctabs_h --i2s ipc > $@
 
 gen_ipccmdtabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h ipccmdtab.h
-gen_ipccmdtabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="ipccmdtab.h"'
+gen_ipccmdtabs_h_CFLAGS = '-DTABLE_H="ipccmdtab.h"'
 $(gen_ipccmdtabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_ipccmdtabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_ipccmdtabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_ipccmdtabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_ipccmdtabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_ipccmdtabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 ipccmdtabs.h: gen_ipccmdtabs_h Makefile
 	./gen_ipccmdtabs_h --i2s-transtab ipccmd > $@
 
 gen_ipoptnametabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h ipoptnametab.h
-gen_ipoptnametabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="ipoptnametab.h"'
+gen_ipoptnametabs_h_CFLAGS = '-DTABLE_H="ipoptnametab.h"'
 $(gen_ipoptnametabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_ipoptnametabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_ipoptnametabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_ipoptnametabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_ipoptnametabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_ipoptnametabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 ipoptnametabs.h: gen_ipoptnametabs_h Makefile
 	./gen_ipoptnametabs_h --i2s ipoptname > $@
 
 gen_ip6optnametabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h ip6optnametab.h
-gen_ip6optnametabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="ip6optnametab.h"'
+gen_ip6optnametabs_h_CFLAGS = '-DTABLE_H="ip6optnametab.h"'
 $(gen_ip6optnametabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_ip6optnametabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_ip6optnametabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_ip6optnametabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_ip6optnametabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_ip6optnametabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 ip6optnametabs.h: gen_ip6optnametabs_h Makefile
 	./gen_ip6optnametabs_h --i2s ip6optname > $@
 
 gen_mmaptabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h mmaptab.h
-gen_mmaptabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="mmaptab.h"'
+gen_mmaptabs_h_CFLAGS = '-DTABLE_H="mmaptab.h"'
 $(gen_mmaptabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_mmaptabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_mmaptabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_mmaptabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_mmaptabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_mmaptabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 mmaptabs.h: gen_mmaptabs_h Makefile
 	./gen_mmaptabs_h --i2s-transtab mmap > $@
 
 gen_mounttabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h mounttab.h
-gen_mounttabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="mounttab.h"'
+gen_mounttabs_h_CFLAGS = '-DTABLE_H="mounttab.h"'
 $(gen_mounttabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_mounttabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_mounttabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_mounttabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_mounttabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_mounttabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 mounttabs.h: gen_mounttabs_h Makefile
 	./gen_mounttabs_h --i2s-transtab mount > $@
 
 gen_nfprototabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h nfprototab.h
-gen_nfprototabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="nfprototab.h"'
+gen_nfprototabs_h_CFLAGS = '-DTABLE_H="nfprototab.h"'
 $(gen_nfprototabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_nfprototabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_nfprototabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_nfprototabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_nfprototabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_nfprototabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 nfprototabs.h: gen_nfprototabs_h Makefile
 	./gen_nfprototabs_h --i2s nfproto > $@
 
 gen_open_flagtabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h \
 	open-flagtab.h
-gen_open_flagtabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="open-flagtab.h"'
+gen_open_flagtabs_h_CFLAGS = '-DTABLE_H="open-flagtab.h"'
 $(gen_open_flagtabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_open_flagtabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_open_flagtabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_open-flagtabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_open-flagtabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_open-flagtabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 open-flagtabs.h: gen_open-flagtabs_h Makefile
 	./gen_open-flagtabs_h --i2s-transtab open_flag > $@
 
 gen_persontabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h persontab.h
-gen_persontabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="persontab.h"'
+gen_persontabs_h_CFLAGS = '-DTABLE_H="persontab.h"'
 $(gen_persontabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_persontabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_persontabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_persontabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_persontabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_persontabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 persontabs.h: gen_persontabs_h Makefile
 	./gen_persontabs_h --i2s person > $@
 
 gen_ptracetabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h ptracetab.h
-gen_ptracetabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="ptracetab.h"'
+gen_ptracetabs_h_CFLAGS = '-DTABLE_H="ptracetab.h"'
 $(gen_ptracetabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_ptracetabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_ptracetabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_ptracetabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_ptracetabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_ptracetabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 ptracetabs.h: gen_ptracetabs_h Makefile
 	./gen_ptracetabs_h --i2s ptrace > $@
 
 gen_prctl_opttabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h prctl-opt-tab.h
-gen_prctl_opttabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="prctl-opt-tab.h"'
+gen_prctl_opttabs_h_CFLAGS = '-DTABLE_H="prctl-opt-tab.h"'
 $(gen_prctl_opttabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_prctl_opttabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_prctl_opttabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_prctl_opttabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_prctl_opttabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_prctl_opttabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 prctl_opttabs.h: gen_prctl_opttabs_h Makefile
 	./gen_prctl_opttabs_h --i2s prctl_opt > $@
 
 gen_pktoptnametabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h pktoptnametab.h
-gen_pktoptnametabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="pktoptnametab.h"'
+gen_pktoptnametabs_h_CFLAGS = '-DTABLE_H="pktoptnametab.h"'
 $(gen_pktoptnametabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_pktoptnametabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_pktoptnametabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_pktoptnametabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_pktoptnametabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_pktoptnametabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 pktoptnametabs.h: gen_pktoptnametabs_h Makefile
 	./gen_pktoptnametabs_h --i2s pktoptname > $@
 
 gen_prottabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h prottab.h
-gen_prottabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="prottab.h"'
+gen_prottabs_h_CFLAGS = '-DTABLE_H="prottab.h"'
 $(gen_prottabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_prottabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_prottabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_prottabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_prottabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_prottabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 prottabs.h: gen_prottabs_h Makefile
 	./gen_prottabs_h --i2s-transtab prot > $@
 
 gen_recvtabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h recvtab.h
-gen_recvtabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="recvtab.h"'
+gen_recvtabs_h_CFLAGS = '-DTABLE_H="recvtab.h"'
 $(gen_recvtabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_recvtabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_recvtabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_recvtabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_recvtabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_recvtabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 recvtabs.h: gen_recvtabs_h Makefile
 	./gen_recvtabs_h --i2s-transtab recv > $@
 
 gen_rlimit_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h rlimittab.h
-gen_rlimit_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="rlimittab.h"'
+gen_rlimit_h_CFLAGS = '-DTABLE_H="rlimittab.h"'
 $(gen_rlimit_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_rlimit_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_rlimit_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_rlimit_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_rlimit_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_rlimit_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 rlimittabs.h: gen_rlimit_h Makefile
 	./gen_rlimit_h --i2s rlimit > $@
 
 gen_schedtabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h schedtab.h
-gen_schedtabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="schedtab.h"'
+gen_schedtabs_h_CFLAGS = '-DTABLE_H="schedtab.h"'
 $(gen_schedtabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_schedtabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_schedtabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_schedtabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_schedtabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_schedtabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 schedtabs.h: gen_schedtabs_h Makefile
 	./gen_schedtabs_h --i2s sched > $@
 
 gen_seccomptabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h seccomptab.h
-gen_seccomptabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="seccomptab.h"'
+gen_seccomptabs_h_CFLAGS = '-DTABLE_H="seccomptab.h"'
 $(gen_seccomptabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_seccomptabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_seccomptabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_seccomptabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_seccomptabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_seccomptabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 seccomptabs.h: gen_seccomptabs_h Makefile
 	./gen_seccomptabs_h --i2s seccomp > $@
 
 gen_seektabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h seektab.h
-gen_seektabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="seektab.h"'
+gen_seektabs_h_CFLAGS = '-DTABLE_H="seektab.h"'
 $(gen_seektabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_seektabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_seektabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_seektabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_seektabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_seektabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 seektabs.h: gen_seektabs_h Makefile
 	./gen_seektabs_h --i2s seek > $@
 
 gen_shm_modetabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h shm_modetab.h
-gen_shm_modetabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="shm_modetab.h"'
+gen_shm_modetabs_h_CFLAGS = '-DTABLE_H="shm_modetab.h"'
 $(gen_shm_modetabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_shm_modetabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_shm_modetabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_shm_modetabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_shm_modetabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_shm_modetabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 shm_modetabs.h: gen_shm_modetabs_h Makefile
 	./gen_shm_modetabs_h --i2s-transtab shm_mode > $@
 
 gen_signals_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h signaltab.h
-gen_signals_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="signaltab.h"'
+gen_signals_h_CFLAGS = '-DTABLE_H="signaltab.h"'
 $(gen_signals_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_signals_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_signals_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_signals_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_signals_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_signals_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 signaltabs.h: gen_signals_h Makefile
 	./gen_signals_h --i2s signal > $@
 
 gen_sockleveltabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h sockleveltab.h
-gen_sockleveltabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="sockleveltab.h"'
+gen_sockleveltabs_h_CFLAGS = '-DTABLE_H="sockleveltab.h"'
 $(gen_sockleveltabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_sockleveltabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_sockleveltabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_sockleveltabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_sockleveltabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_sockleveltabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 sockleveltabs.h: gen_sockleveltabs_h Makefile
 	./gen_sockleveltabs_h --i2s socklevel > $@
 
 gen_sockoptnametabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h sockoptnametab.h
-gen_sockoptnametabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="sockoptnametab.h"'
+gen_sockoptnametabs_h_CFLAGS = '-DTABLE_H="sockoptnametab.h"'
 $(gen_sockoptnametabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_sockoptnametabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_sockoptnametabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_sockoptnametabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_sockoptnametabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_sockoptnametabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 sockoptnametabs.h: gen_sockoptnametabs_h Makefile
 	./gen_sockoptnametabs_h --i2s sockoptname > $@
 
 gen_socktabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h socktab.h
-gen_socktabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="socktab.h"'
+gen_socktabs_h_CFLAGS = '-DTABLE_H="socktab.h"'
 $(gen_socktabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_socktabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_socktabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_socktabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_socktabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_socktabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 socktabs.h: gen_socktabs_h Makefile
 	./gen_socktabs_h --i2s sock > $@
 
 gen_socktypetabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h socktypetab.h
-gen_socktypetabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="socktypetab.h"'
+gen_socktypetabs_h_CFLAGS = '-DTABLE_H="socktypetab.h"'
 $(gen_socktypetabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_socktypetabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_socktypetabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_socktypetabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_socktypetabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_socktypetabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 socktypetabs.h: gen_socktypetabs_h Makefile
 	./gen_socktypetabs_h --i2s sock_type > $@
 
 gen_tcpoptnametabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h tcpoptnametab.h
-gen_tcpoptnametabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="tcpoptnametab.h"'
+gen_tcpoptnametabs_h_CFLAGS = '-DTABLE_H="tcpoptnametab.h"'
 $(gen_tcpoptnametabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_tcpoptnametabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_tcpoptnametabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_tcpoptnametabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_tcpoptnametabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_tcpoptnametabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 tcpoptnametabs.h: gen_tcpoptnametabs_h Makefile
 	./gen_tcpoptnametabs_h --i2s tcpoptname > $@
 
 gen_typetabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h typetab.h
-gen_typetabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="typetab.h"'
+gen_typetabs_h_CFLAGS = '-DTABLE_H="typetab.h"'
 $(gen_typetabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_typetabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_typetabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_typetabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_typetabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_typetabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 typetabs.h: gen_typetabs_h Makefile
 	./gen_typetabs_h --s2i type > $@
 
 gen_umounttabs_h_SOURCES = ../lib/gen_tables.c ../lib/gen_tables.h umounttab.h
-gen_umounttabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="umounttab.h"'
+gen_umounttabs_h_CFLAGS = '-DTABLE_H="umounttab.h"'
 $(gen_umounttabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_umounttabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_umounttabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_umounttabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_umounttabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_umounttabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 umounttabs.h: gen_umounttabs_h Makefile
 	./gen_umounttabs_h --i2s-transtab umount > $@
 
diff --git a/lib/Makefile.am b/lib/Makefile.am
index dddadd5..e2ed101 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -70,145 +70,196 @@ if USE_AARCH64
 noinst_PROGRAMS += gen_aarch64_tables_h
 endif
 gen_actiontabs_h_SOURCES = gen_tables.c gen_tables.h actiontab.h
-gen_actiontabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="actiontab.h"'
+gen_actiontabs_h_CFLAGS = '-DTABLE_H="actiontab.h"'
 $(gen_actiontabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_actiontabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_actiontabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_actiontabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_actiontabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_actiontabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 actiontabs.h: gen_actiontabs_h Makefile
 	./gen_actiontabs_h --lowercase --i2s --s2i action > $@
 
 if USE_ALPHA
 gen_alpha_tables_h_SOURCES = gen_tables.c gen_tables.h alpha_table.h
-gen_alpha_tables_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="alpha_table.h"'
+gen_alpha_tables_h_CFLAGS = '-DTABLE_H="alpha_table.h"'
 $(gen_alpha_tables_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_alpha_tables_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_alpha_tables_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_alpha_tables_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_alpha_tables_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_alpha_tables_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 alpha_tables.h: gen_alpha_tables_h Makefile
 	./gen_alpha_tables_h --lowercase --i2s --s2i alpha_syscall > $@
 endif
 
 if USE_ARM
 gen_arm_tables_h_SOURCES = gen_tables.c gen_tables.h arm_table.h
-gen_arm_tables_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="arm_table.h"'
+gen_arm_tables_h_CFLAGS = '-DTABLE_H="arm_table.h"'
 $(gen_arm_tables_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_arm_tables_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_arm_tables_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_arm_tables_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_arm_tables_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_arm_tables_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 arm_tables.h: gen_arm_tables_h Makefile
 	./gen_arm_tables_h --lowercase --i2s --s2i arm_syscall > $@
 endif
 
 if USE_AARCH64
 gen_aarch64_tables_h_SOURCES = gen_tables.c gen_tables.h aarch64_table.h
-gen_aarch64_tables_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="aarch64_table.h"'
+gen_aarch64_tables_h_CFLAGS = '-DTABLE_H="aarch64_table.h"'
 $(gen_aarch64_tables_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_aarch64_tables_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_aarch64_tables_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_aarch64_tables_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_aarch64_tables_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_aarch64_tables_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 aarch64_tables.h: gen_aarch64_tables_h Makefile
 	./gen_aarch64_tables_h --lowercase --i2s --s2i aarch64_syscall > $@
 endif
 
 gen_errtabs_h_SOURCES = gen_tables.c gen_tables.h errtab.h
-gen_errtabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="errtab.h"'
+gen_errtabs_h_CFLAGS = '-DTABLE_H="errtab.h"'
 $(gen_errtabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_errtabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_errtabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_errtabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_errtabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_errtabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 errtabs.h: gen_errtabs_h Makefile
 	./gen_errtabs_h --duplicate-ints --uppercase --i2s --s2i err > $@
 
 gen_fieldtabs_h_SOURCES = gen_tables.c gen_tables.h fieldtab.h
-gen_fieldtabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="fieldtab.h"'
+gen_fieldtabs_h_CFLAGS = '-DTABLE_H="fieldtab.h"'
 $(gen_fieldtabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_fieldtabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_fieldtabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_fieldtabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_fieldtabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_fieldtabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 fieldtabs.h: gen_fieldtabs_h Makefile
 	./gen_fieldtabs_h --duplicate-ints --lowercase --i2s --s2i field > $@
 
 gen_flagtabs_h_SOURCES = gen_tables.c gen_tables.h flagtab.h
-gen_flagtabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="flagtab.h"'
+gen_flagtabs_h_CFLAGS = '-DTABLE_H="flagtab.h"'
 $(gen_flagtabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_flagtabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_flagtabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_flagtabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_flagtabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_flagtabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 flagtabs.h: gen_flagtabs_h Makefile
 	./gen_flagtabs_h --lowercase --i2s --s2i flag > $@
 
 gen_ftypetabs_h_SOURCES = gen_tables.c gen_tables.h ftypetab.h
-gen_ftypetabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="ftypetab.h"'
+gen_ftypetabs_h_CFLAGS = '-DTABLE_H="ftypetab.h"'
 $(gen_ftypetabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_ftypetabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_ftypetabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_ftypetabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_ftypetabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_ftypetabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 ftypetabs.h: gen_ftypetabs_h Makefile
 	./gen_ftypetabs_h --lowercase --i2s --s2i ftype > $@
 
 gen_i386_tables_h_SOURCES = gen_tables.c gen_tables.h i386_table.h
-gen_i386_tables_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="i386_table.h"'
+gen_i386_tables_h_CFLAGS = '-DTABLE_H="i386_table.h"'
 $(gen_i386_tables_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_i386_tables_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_i386_tables_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_i386_tables_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_i386_tables_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_i386_tables_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 i386_tables.h: gen_i386_tables_h Makefile
 	./gen_i386_tables_h --duplicate-ints --lowercase --i2s --s2i \
 		i386_syscall > $@
 
 gen_ia64_tables_h_SOURCES = gen_tables.c gen_tables.h ia64_table.h
-gen_ia64_tables_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="ia64_table.h"'
+gen_ia64_tables_h_CFLAGS = '-DTABLE_H="ia64_table.h"'
 $(gen_ia64_tables_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_ia64_tables_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_ia64_tables_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_ia64_tables_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_ia64_tables_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_ia64_tables_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 ia64_tables.h: gen_ia64_tables_h Makefile
 	./gen_ia64_tables_h --lowercase --i2s --s2i ia64_syscall > $@
 
 gen_machinetabs_h_SOURCES = gen_tables.c gen_tables.h machinetab.h
-gen_machinetabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="machinetab.h"'
+gen_machinetabs_h_CFLAGS = '-DTABLE_H="machinetab.h"'
 $(gen_machinetabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_machinetabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_machinetabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_machinetabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_machinetabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_machinetabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 machinetabs.h: gen_machinetabs_h Makefile
 	./gen_machinetabs_h --duplicate-ints --lowercase --i2s --s2i machine \
 		> $@
 
 gen_msg_typetabs_h_SOURCES = gen_tables.c gen_tables.h msg_typetab.h
-gen_msg_typetabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="msg_typetab.h"'
+gen_msg_typetabs_h_CFLAGS = '-DTABLE_H="msg_typetab.h"'
 $(gen_msg_typetabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_msg_typetabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_msg_typetabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_msg_typetabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_msg_typetabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_msg_typetabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 msg_typetabs.h: gen_msg_typetabs_h Makefile
 	./gen_msg_typetabs_h --uppercase --i2s --s2i msg_type > $@
 
 gen_optabs_h_SOURCES = gen_tables.c gen_tables.h optab.h
-gen_optabs_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="optab.h"'
+gen_optabs_h_CFLAGS = '-DTABLE_H="optab.h"'
 $(gen_optabs_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_optabs_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_optabs_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_optabs_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_optabs_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_optabs_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 optabs.h: gen_optabs_h Makefile
 	./gen_optabs_h --i2s op > $@
 
 gen_ppc_tables_h_SOURCES = gen_tables.c gen_tables.h ppc_table.h
-gen_ppc_tables_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="ppc_table.h"'
+gen_ppc_tables_h_CFLAGS = '-DTABLE_H="ppc_table.h"'
 $(gen_ppc_tables_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_ppc_tables_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_ppc_tables_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_ppc_tables_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_ppc_tables_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_ppc_tables_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 ppc_tables.h: gen_ppc_tables_h Makefile
 	./gen_ppc_tables_h --lowercase --i2s --s2i ppc_syscall > $@
 
 gen_s390_tables_h_SOURCES = gen_tables.c gen_tables.h s390_table.h
-gen_s390_tables_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="s390_table.h"'
+gen_s390_tables_h_CFLAGS = '-DTABLE_H="s390_table.h"'
 $(gen_s390_tables_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_s390_tables_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_s390_tables_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_s390_tables_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_s390_tables_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_s390_tables_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 s390_tables.h: gen_s390_tables_h Makefile
 	./gen_s390_tables_h --lowercase --i2s --s2i s390_syscall > $@
 
 gen_s390x_tables_h_SOURCES = gen_tables.c gen_tables.h s390x_table.h
-gen_s390x_tables_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="s390x_table.h"'
+gen_s390x_tables_h_CFLAGS = '-DTABLE_H="s390x_table.h"'
 $(gen_s390x_tables_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_s390x_tables_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_s390x_tables_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_s390x_tables_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_s390x_tables_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_s390x_tables_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 s390x_tables.h: gen_s390x_tables_h Makefile
 	./gen_s390x_tables_h --lowercase --i2s --s2i s390x_syscall > $@
 
 gen_x86_64_tables_h_SOURCES = gen_tables.c gen_tables.h x86_64_table.h
-gen_x86_64_tables_h_CFLAGS = $(CFLAGS_FOR_BUILD) '-DTABLE_H="x86_64_table.h"'
+gen_x86_64_tables_h_CFLAGS = '-DTABLE_H="x86_64_table.h"'
 $(gen_x86_64_tables_h_OBJECTS): CC=$(CC_FOR_BUILD)
+$(gen_x86_64_tables_h_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 $(gen_x86_64_tables_h_OBJECTS): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 gen_x86_64_tables_h$(BUILD_EXEEXT): CC=$(CC_FOR_BUILD)
+gen_x86_64_tables_h$(BUILD_EXEEXT): CFLAGS=$(CFLAGS_FOR_BUILD)
+gen_x86_64_tables_h$(BUILD_EXEEXT): CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
 x86_64_tables.h: gen_x86_64_tables_h Makefile
 	./gen_x86_64_tables_h --lowercase --i2s --s2i x86_64_syscall > $@
-- 
1.9.1

^ permalink raw reply related

* Re: Auditd framework slowdowns (sometimes freezes) the entire system.
From: Paul Moore @ 2015-07-21 23:02 UTC (permalink / raw)
  To: Steve Grubb, Kangkook Jee; +Cc: linux-audit
In-Reply-To: <1580419.1BsfLsUxHh@x2>

On Tue, Jul 21, 2015 at 2:14 PM, Steve Grubb <sgrubb@redhat.com> wrote:
> On Tuesday, July 21, 2015 01:23:49 PM Kangkook Jee wrote:
>> Therefore I'm trying to use audit multicast feature you mentioned
>> (https://lwn.net/Articles/587166/). I found out that this feature is
>> recently added and I have a few questions using it.
>>
>> Q1. I've gone over journald source code and found out that it issues a
>> number of netlink socket api calls to join in multi-cast group and receive
>> datagrams. Do you support rather cleaner api to use this feature? I
>> couldn't find anything from libaudit.h.
>
> This is one for the kernel developers.

We only support the two APIs at the moment.  We will be doing some
rework of the audit APIs that should improve performance, but that is
far from being ready.

-- 
paul moore
www.paul-moore.com

^ permalink raw reply

* Re: Configuration file monitoring - reporting content changes
From: Burn Alting @ 2015-07-21 21:54 UTC (permalink / raw)
  To: Steve Grubb; +Cc: linux-audit
In-Reply-To: <3307081.aEimE15yPr@x2>

On Tue, 2015-07-21 at 13:59 -0400, Steve Grubb wrote:
> On Tuesday, July 21, 2015 10:38:31 AM John Dennis wrote:
> > On 07/20/2015 07:08 PM, Steve Grubb wrote:
> > > On Monday, July 20, 2015 09:53:47 PM Burn Alting wrote:
> > >> I am interested in any Linux based capability that will monitor
> > >> identified files and report on actual changes to the monitored file.
> > > 
> > > I know of nothing that does this. But as long as the list of files is
> > > limited, it doesn't sound like a hard program to write.
> > > 
> > > Any one else with an opinion?
> > 
> > Yes :-) I'm not so sure it's an easy program to write and be robust in a
> > variety of scenarios. I know because I wrote such a program once. The
> > basic problem is most people think in terms of monitoring a file by name
> > (e.g. it's pathname). But inotify operates on inodes, not filenames. If
> > that file is subject to any variety of log rotation strategies or
> > modifications by a configuration manager whereby the file is renamed or
> > moved to a different directory then any program using inotify to monitor
> > the file needs to become reasonably sophisticated and be able to track
> > those changes. It is entirely possible for two processes to have opened
> > the same file by name but have them be 2 different files (e.g. after
> > opening the file path is modified but the process still has the original
> > inode open, now a 2nd process opens the same filename but gets a
> > different inode). Conflating inodes with filenames can lead to
> > unexpected results and if the purpose is some sort of security
> > monitoring it will be important these issues are accounted for.
> 
> I recently was doing some experimenting with the fanotify API. In my mind, I 
> think its likely to be better. But it has limitations such as mmap'ed file may 
> not generate a modify event. So, if I were going to do it, I'd start there. 
> But you do raise a whole lot of good points. My guess is this would watch 
> config files which logrotate wouldn't apply. But yes, editors do open a temp 
> copy and then do a rename. In my experimenting, I didn't bother to see how 
> fanotify handle renames. (You would think its a modify event.)
> 
> -Steve

I suppose one could follow tail(1)'s lead and monitor via a combination
of inotify() supplemented by file, path and inode monitoring as well.
Perhaps not elegant, but it may do the job.

Burn

^ permalink raw reply

* RE: EXT :Re: Configuration file monitoring - reporting content changes
From: Burn Alting @ 2015-07-21 21:48 UTC (permalink / raw)
  To: Boyce, Kevin P (AS); +Cc: linux-audit@redhat.com
In-Reply-To: <c2247a9ca2b74a43a81715af4f220a77@XCGVAG30.northgrum.com>

Kevin,

I believe there may be some work in this space occurring in the not too
distant future.

Regards

On Tue, 2015-07-21 at 13:47 +0000, Boyce, Kevin P (AS) wrote:
> Not to hijack your thread here, but as long as there might be development in the area of auditing changes to file with aide (sounds like maybe it would be an aide plugin), I would suggest it would also be very nice to know the names of files being copied/burned to removable media.  I don't know how one would accomplish this though.
> 
> Kevin
> 
> -----Original Message-----
> From: linux-audit-bounces@redhat.com [mailto:linux-audit-bounces@redhat.com] On Behalf Of Steve Grubb
> Sent: Monday, July 20, 2015 7:08 PM
> To: linux-audit@redhat.com; burn@swtf.dyndns.org
> Subject: EXT :Re: Configuration file monitoring - reporting content changes
> 
> On Monday, July 20, 2015 09:53:47 PM Burn Alting wrote:
> > I am interested in any Linux based capability that will monitor 
> > identified files and report on actual changes to the monitored file.
> 
> I know of nothing that does this. But as long as the list of files is limited, it doesn't sound like a hard program to write.
> 
> > I know there are methods of recording that the file has been changed (e.g.
> > aide and/or monitor writes via auditd), but I want to know what has 
> > changed ... basically something that would provide a 'diff' like output.
> > 
> > Now there are tools like Samhain that will record the content changes 
> > of a file that is <= 92000 bytes in size, but I am interested in a 
> > more lightweight solution ... perhaps a simple inotify(7) based 
> > utility that perhaps maintains a copy of the file(s) in core (in 
> > compressed format) and based on inotify() returns checks for changes 
> > and reports (somehow yet to be defined) the before/after changes.
> 
> It would have to be after the changes since inotify would tell you something happened.
> 
> > Is there anything 'out there' that list members are aware of?
> > 
> > If not, would the following utility be of interest?
> 
> I am certain there are people that are interested in this even if no one is speaking up on it.
> 
> 
> > On startup, load the monitored file(s) (saving a compressed copy in memory).
> > Then, using inotify, monitor for changes and if so, emit some kind of record
> > defining the change and change the compressed in-memory copy. If so, is
> > our mailing list and the contributed portion of auditd an appropriate
> > repository for such a tool.
> 
> That's an interesting question. 
> 
> > Naturally, such a tool would be supported by appropriate auditd
> > monitoring that will take care of changing file attributes etc and file
> > writes. That is, auditd tells me who and the utility tells me what.
> 
> Correlating the changes might be interesting. There can be a long time between 
> opening a file and closing it. The inotify might trigger on the changes during 
> flushing to disk. Or what if the file was mmap'ed? I don't know if that would be 
> caught. But there's only 1 way to find out. :-)
> 
> Like I said, I think its a straight forward program to write. No one's 
> specifically asked for this. But we tap dance around the subject by patching 
> programs to record what is being changed (shadow-utils). So, there is a 
> precedence that this is needed. But Common Criteria makes it only for trusted 
> databases. One file you would exempt, I presume, is /etc/shadow and 
> /etc/gshadow.
> 
> Any one else with an opinion?
> 
> -Steve
> 
> --
> Linux-audit mailing list
> Linux-audit@redhat.com
> https://www.redhat.com/mailman/listinfo/linux-audit

^ permalink raw reply

* Re: Auditd framework slowdowns (sometimes freezes) the entire system.
From: Steve Grubb @ 2015-07-21 18:14 UTC (permalink / raw)
  To: Kangkook Jee; +Cc: linux-audit
In-Reply-To: <6C8DEEDF-06C7-4819-A6A7-78699D733B82@gmail.com>

On Tuesday, July 21, 2015 01:23:49 PM Kangkook Jee wrote:
> With our custom audit client, we prefer not to take too much resources (CPUs
> or memory) from user machine and rather want to drop some events.

Maybe set a smaller backlog and tell it to ignore overflows?

-b 512
-f 0


> Therefore I'm trying to use audit multicast feature you mentioned
> (https://lwn.net/Articles/587166/). I found out that this feature is
> recently added and I have a few questions using it.
> 
> Q1. I've gone over journald source code and found out that it issues a
> number of netlink socket api calls to join in multi-cast group and receive
> datagrams. Do you support rather cleaner api to use this feature? I
> couldn't find anything from libaudit.h.

This is one for the kernel developers.

> Q2. By joining in audit multi-cast group, can we avoid auditing the audit
> client itself? As you know, with audit_set_pid(), it prevents from
> gathering and reporting audit event for user-space audit client. We can
> expect the same thing?

You can set a rule once your program starts up and you have access to your 
pid. It would be the equivalent of this:

-a never,exit -S all -F pid=<pid>


> Q3. By only having a read-only user-space audit client and not having
> bi-direction audit client running from the system,  are we going to see
> audit entries logged from default system log frameworks which output to
> /var/log/kernel.log (Debian family), syslog, or dmesg?

You should not. I know you said you looked at Journald as an example of how to 
do it. It might be joining a lot more than audit. I haven't looked.

 
> Q4. Our environment for deployment comprises many different types of legacy
> distributions (i.e., CentOS 5 or 6, Ubuntu 12.04 ...), could you inform me
> from what audit version (or kernel version) audit multicast is supported?

It seems to be 3.16.

 
> Q5. I'm also considering another design choice to use *rate_limit* to limit
> the amount of audit messages delivered to user-level client. Do you think
> kauditd will drop some messages with this setting enabled?

I have not played with it. Maybe one of the kernel developers has an opinion. 
I am pretty sure you can just ignore queue overflows, though.
 
-Steve

^ permalink raw reply

* Re: Configuration file monitoring - reporting content changes
From: Steve Grubb @ 2015-07-21 17:59 UTC (permalink / raw)
  To: John Dennis; +Cc: linux-audit
In-Reply-To: <55AE5967.70609@redhat.com>

On Tuesday, July 21, 2015 10:38:31 AM John Dennis wrote:
> On 07/20/2015 07:08 PM, Steve Grubb wrote:
> > On Monday, July 20, 2015 09:53:47 PM Burn Alting wrote:
> >> I am interested in any Linux based capability that will monitor
> >> identified files and report on actual changes to the monitored file.
> > 
> > I know of nothing that does this. But as long as the list of files is
> > limited, it doesn't sound like a hard program to write.
> > 
> > Any one else with an opinion?
> 
> Yes :-) I'm not so sure it's an easy program to write and be robust in a
> variety of scenarios. I know because I wrote such a program once. The
> basic problem is most people think in terms of monitoring a file by name
> (e.g. it's pathname). But inotify operates on inodes, not filenames. If
> that file is subject to any variety of log rotation strategies or
> modifications by a configuration manager whereby the file is renamed or
> moved to a different directory then any program using inotify to monitor
> the file needs to become reasonably sophisticated and be able to track
> those changes. It is entirely possible for two processes to have opened
> the same file by name but have them be 2 different files (e.g. after
> opening the file path is modified but the process still has the original
> inode open, now a 2nd process opens the same filename but gets a
> different inode). Conflating inodes with filenames can lead to
> unexpected results and if the purpose is some sort of security
> monitoring it will be important these issues are accounted for.

I recently was doing some experimenting with the fanotify API. In my mind, I 
think its likely to be better. But it has limitations such as mmap'ed file may 
not generate a modify event. So, if I were going to do it, I'd start there. 
But you do raise a whole lot of good points. My guess is this would watch 
config files which logrotate wouldn't apply. But yes, editors do open a temp 
copy and then do a rename. In my experimenting, I didn't bother to see how 
fanotify handle renames. (You would think its a modify event.)

-Steve


> Some of this is discussed in these documents which accompany the lwatch
> (Log Watch) program I wrote:
> 
> https://jdennis.fedorapeople.org/lwatch/html/InotifyOverview.html
> https://jdennis.fedorapeople.org/lwatch/html/LogWatchOverview.html

^ permalink raw reply

* Re: Auditd framework slowdowns (sometimes freezes) the entire system.
From: Kangkook Jee @ 2015-07-21 17:23 UTC (permalink / raw)
  To: Steve Grubb; +Cc: linux-audit
In-Reply-To: <2121523.C9610qWeF3@x2>

Dear Steve, 

Thanks a lot for your sincere reply.

With our custom audit client, we prefer not to take too much resources (CPUs or
memory) from user machine and rather want to drop some events. 

Therefore I'm trying to use audit multicast feature you mentioned
(https://lwn.net/Articles/587166/). I found out that this feature is recently
added and I have a few questions using it. 

Q1. I've gone over journald source code and found out that it issues a number of
netlink socket api calls to join in multi-cast group and receive datagrams. Do
you support rather cleaner api to use this feature? I couldn't find anything
from libaudit.h.

Q2. By joining in audit multi-cast group, can we avoid auditing the audit client
itself? As you know, with audit_set_pid(), it prevents from gathering and
reporting audit event for user-space audit client. We can expect the same
thing?

Q3. By only having a read-only user-space audit client and not having
bi-direction audit client running from the system,  are we going to see audit
entries logged from default system log frameworks which output to
/var/log/kernel.log (Debian family), syslog, or dmesg?

Q4. Our environment for deployment comprises many different types of legacy
distributions (i.e., CentOS 5 or 6, Ubuntu 12.04 ...), could you inform me from
what audit version (or kernel version) audit multicast is supported?

Q5. I'm also considering another design choice to use *rate_limit* to limit the
amount of audit messages delivered to user-level client. Do you think kauditd
will drop some messages with this setting enabled?

Thanks again for your help!

Regards, Kangkook


> On Jul 16, 2015, at 8:56 AM, Steve Grubb <sgrubb@redhat.com> wrote:
> 
> On Thursday, July 16, 2015 08:38:22 AM Kangkook Jee wrote:
>> I'm writing a custom user-land auditd client subscribing to kauditd to
>> monitor a number of system calls that we are interested. My auditd client
>> seems to work fine in overall but I found unexpected behavior of auditd
>> framework which slows down (or sometimes freezes) the entire system as the
>> consuming rate of audit client couldn't catch up the speed of audit message
>> generation.
> 
> This is by design. Auditing is so important that we cannot let even 1 event 
> escape the audit trail. To people that count on auditing, they would normally 
> rather have access denied than lose the ability to track who's accessing 
> something.
> 
> This leads to a couple issues. One is have you done anything about priority? 
> Did you give your daemon a healthy boost over the other processes so it gets 
> more runtime than normal processes? How about cgroups? Have you checked disk 
> synchronization techniques (some yield worse performance but guarantee its 
> written)? What about gprof traces to see where the "hotspots" are in your 
> daemon?
> 
>> Here's the simple code snippet used to reproduce the problem.
>> 
>> //
>> // To build.
>> // g++ -o simple_audit -std=c++11 -L/usr/lib/x86_64-linux-gnu/  main.cpp
>> -laudit //
>> #include <libaudit.h>
>> #include <sys/types.h>
>> #include <unistd.h>
>> 
>> #include <cassert>
>> #include <iostream>
>> 
>> static int32_t fd = -1;
>> static bool au_listen_flag = true;
>> 
>> int main(int argc, char* argv[]) {
>>    struct audit_reply rep;
>>    uint64_t cnt = 0;
>> 
>>    if (argc != 2) {
>>        fprintf(stderr, "Invalid usage: %s <sleep_interval>\n", argv[0]);
>>        exit(1);
>>    }
>> 
>>    uint32_t sleep_time = atoi(argv[1]);
>> 
>>    fd = audit_open();
>>    if (fd < 0) {
>>        // error handling.
>>        std::cerr << "Invalid fd returned: " + std::to_string(fd) <<
>> std::endl; exit(-1);
>>    }
>>    int32_t ret = audit_set_pid(fd, getpid(), WAIT_YES);
>>    if (ret < 0) {
>>        std::cerr << "audit_set_pid failed: " + std::to_string(fd) <<
>> std::endl; exit(-1);
>>    }
>> 
>>    while (au_listen_flag) {
>>        int32_t rc = audit_get_reply(fd, &rep, GET_REPLY_BLOCKING, 0);
>>        if (rc > 0) {
>>            cnt++;
>>        }
>> 
>>        usleep(sleep_time);
> 
> Why would you do this? You ought to be using epoll or something like that to 
> wait on next event.
> 
>>        if (cnt % 10000 == 0) {
>>            printf ("messages %lu\n", cnt);
>>        }
>>    }
>>    close(fd);
>> }
>> 
>> 
>> The problem becomes more apparent as we increase the amount of sleep time
>> that is provided as a first command line argument (say a thousand
>> Milli-seconds) and simultaneously run some heavy-load tasks (i.e., kernel
>> build).
>> 
>> sudo ./simple_audit 1000
>> 
>> Here's the command line that we used to add system calls to be monitored and
>> enable.
>> 
>> # Adding events.
>> /sbin/auditctl -a exit,always -F arch=b64 -S clone -S close -S creat -S dup
>> -S dup2 -S dup3 -S execve -S exit -S exit_group -S fork -S open -S openat
>> -S unlink -S unlinkat -S vfork -S 288 -S accept -S bind -S connect -S
>> listen -S socket -S socketpair
> 
> Next question...why would you want all those syscalls? Do you want them for 
> daemons and users? Normally daemons are considered normal system function and 
> are not of interest. What is of interest is what users do. So, to weed out 
> damons, you don't want anything with auid=-1. Because the kernel uses unsigned 
> numbers, you would add
> 
> -F auid>=1000 -F auid!=-1
> 
> to the rule. That might make a big difference.
> 
>> # Enabling events.
>> /sbin/auditctl -e1 -b 102400
>> 
>> At the very moment, "auditctl -s" indicating that kernel buffer is filled up
>> but it does not throw away audit messages ('lost' is not increasing ).
>> 
>> # auditctl -s
>> AUDIT_STATUS: enabled=1 flag=1 pid=29887 rate_limit=0 backlog_limit=102400
>> lost=270878600 backlog=102402 # auditctl -s
>> AUDIT_STATUS: enabled=1 flag=1 pid=29887 rate_limit=0 backlog_limit=102400
>> lost=270878600 backlog=102402
>> 
>> Could anyone guide me how to configure kauditd's buffer setting so that it
>> can dump audit messages when the buffer is filled up and user-land consumer
>> can't catch up the speed of audit message produce?
> 
> If you don't mind losing events, you can also listen on the netlink socket 
> without setting the pid the same way that journald does it. That is a best 
> effort connection and not guaranteed to be lossless.
> 
> -Steve

^ permalink raw reply

* Re: Configuration file monitoring - reporting content changes
From: John Dennis @ 2015-07-21 14:38 UTC (permalink / raw)
  To: Steve Grubb, linux-audit, burn
In-Reply-To: <7607942.YQGEPIT7XG@x2>

On 07/20/2015 07:08 PM, Steve Grubb wrote:
> On Monday, July 20, 2015 09:53:47 PM Burn Alting wrote:
>> I am interested in any Linux based capability that will monitor
>> identified files and report on actual changes to the monitored file.
>
> I know of nothing that does this. But as long as the list of files is limited,
> it doesn't sound like a hard program to write.

> Any one else with an opinion?

Yes :-) I'm not so sure it's an easy program to write and be robust in a 
variety of scenarios. I know because I wrote such a program once. The 
basic problem is most people think in terms of monitoring a file by name 
(e.g. it's pathname). But inotify operates on inodes, not filenames. If 
that file is subject to any variety of log rotation strategies or 
modifications by a configuration manager whereby the file is renamed or 
moved to a different directory then any program using inotify to monitor 
the file needs to become reasonably sophisticated and be able to track 
those changes. It is entirely possible for two processes to have opened 
the same file by name but have them be 2 different files (e.g. after 
opening the file path is modified but the process still has the original 
inode open, now a 2nd process opens the same filename but gets a 
different inode). Conflating inodes with filenames can lead to 
unexpected results and if the purpose is some sort of security 
monitoring it will be important these issues are accounted for.

Some of this is discussed in these documents which accompany the lwatch 
(Log Watch) program I wrote:

https://jdennis.fedorapeople.org/lwatch/html/InotifyOverview.html
https://jdennis.fedorapeople.org/lwatch/html/LogWatchOverview.html


-- 
John

^ permalink raw reply

* RE: EXT :Re: Configuration file monitoring - reporting content changes
From: Boyce, Kevin P (AS) @ 2015-07-21 13:47 UTC (permalink / raw)
  To: Steve Grubb, linux-audit@redhat.com, burn@swtf.dyndns.org
In-Reply-To: <7607942.YQGEPIT7XG@x2>

Not to hijack your thread here, but as long as there might be development in the area of auditing changes to file with aide (sounds like maybe it would be an aide plugin), I would suggest it would also be very nice to know the names of files being copied/burned to removable media.  I don't know how one would accomplish this though.

Kevin

-----Original Message-----
From: linux-audit-bounces@redhat.com [mailto:linux-audit-bounces@redhat.com] On Behalf Of Steve Grubb
Sent: Monday, July 20, 2015 7:08 PM
To: linux-audit@redhat.com; burn@swtf.dyndns.org
Subject: EXT :Re: Configuration file monitoring - reporting content changes

On Monday, July 20, 2015 09:53:47 PM Burn Alting wrote:
> I am interested in any Linux based capability that will monitor 
> identified files and report on actual changes to the monitored file.

I know of nothing that does this. But as long as the list of files is limited, it doesn't sound like a hard program to write.

> I know there are methods of recording that the file has been changed (e.g.
> aide and/or monitor writes via auditd), but I want to know what has 
> changed ... basically something that would provide a 'diff' like output.
> 
> Now there are tools like Samhain that will record the content changes 
> of a file that is <= 92000 bytes in size, but I am interested in a 
> more lightweight solution ... perhaps a simple inotify(7) based 
> utility that perhaps maintains a copy of the file(s) in core (in 
> compressed format) and based on inotify() returns checks for changes 
> and reports (somehow yet to be defined) the before/after changes.

It would have to be after the changes since inotify would tell you something happened.

> Is there anything 'out there' that list members are aware of?
> 
> If not, would the following utility be of interest?

I am certain there are people that are interested in this even if no one is speaking up on it.


> On startup, load the monitored file(s) (saving a compressed copy in memory).
> Then, using inotify, monitor for changes and if so, emit some kind of record
> defining the change and change the compressed in-memory copy. If so, is
> our mailing list and the contributed portion of auditd an appropriate
> repository for such a tool.

That's an interesting question. 

> Naturally, such a tool would be supported by appropriate auditd
> monitoring that will take care of changing file attributes etc and file
> writes. That is, auditd tells me who and the utility tells me what.

Correlating the changes might be interesting. There can be a long time between 
opening a file and closing it. The inotify might trigger on the changes during 
flushing to disk. Or what if the file was mmap'ed? I don't know if that would be 
caught. But there's only 1 way to find out. :-)

Like I said, I think its a straight forward program to write. No one's 
specifically asked for this. But we tap dance around the subject by patching 
programs to record what is being changed (shadow-utils). So, there is a 
precedence that this is needed. But Common Criteria makes it only for trusted 
databases. One file you would exempt, I presume, is /etc/shadow and 
/etc/gshadow.

Any one else with an opinion?

-Steve

--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit

^ permalink raw reply

* Re: Configuration file monitoring - reporting content changes
From: Steve Grubb @ 2015-07-20 23:08 UTC (permalink / raw)
  To: linux-audit, burn
In-Reply-To: <1437393227.26354.16.camel@swtf.swtf.dyndns.org>

On Monday, July 20, 2015 09:53:47 PM Burn Alting wrote:
> I am interested in any Linux based capability that will monitor
> identified files and report on actual changes to the monitored file.

I know of nothing that does this. But as long as the list of files is limited, 
it doesn't sound like a hard program to write.

> I know there are methods of recording that the file has been changed (e.g.
> aide and/or monitor writes via auditd), but I want to know what has
> changed ... basically something that would provide a 'diff' like output.
> 
> Now there are tools like Samhain that will record the content changes of
> a file that is <= 92000 bytes in size, but I am interested in a more
> lightweight solution ... perhaps a simple inotify(7) based utility that
> perhaps maintains a copy of the file(s) in core (in compressed format)
> and based on inotify() returns checks for changes and reports (somehow
> yet to be defined) the before/after changes.

It would have to be after the changes since inotify would tell you something 
happened.

> Is there anything 'out there' that list members are aware of?
> 
> If not, would the following utility be of interest?

I am certain there are people that are interested in this even if no one is 
speaking up on it.


> On startup, load the monitored file(s) (saving a compressed copy in memory).
> Then, using inotify, monitor for changes and if so, emit some kind of record
> defining the change and change the compressed in-memory copy. If so, is
> our mailing list and the contributed portion of auditd an appropriate
> repository for such a tool.

That's an interesting question. 

> Naturally, such a tool would be supported by appropriate auditd
> monitoring that will take care of changing file attributes etc and file
> writes. That is, auditd tells me who and the utility tells me what.

Correlating the changes might be interesting. There can be a long time between 
opening a file and closing it. The inotify might trigger on the changes during 
flushing to disk. Or what if the file was mmap'ed? I don't know if that would be 
caught. But there's only 1 way to find out. :-)

Like I said, I think its a straight forward program to write. No one's 
specifically asked for this. But we tap dance around the subject by patching 
programs to record what is being changed (shadow-utils). So, there is a 
precedence that this is needed. But Common Criteria makes it only for trusted 
databases. One file you would exempt, I presume, is /etc/shadow and 
/etc/gshadow.

Any one else with an opinion?

-Steve

^ permalink raw reply

* Re: Configuration file monitoring - reporting content changes
From: Burn Alting @ 2015-07-20 22:12 UTC (permalink / raw)
  To: Smith, Gary R; +Cc: linux-audit@redhat.com
In-Reply-To: <DEE39E62895A1A4B870B6E879DADFA081A5093F4@EX10MBOX03.pnnl.gov>

Gary,

Thanks. Although quite comprehensive about raising an alert when a large
variety action occur to a file, it still doesn't give me the core
requirement of reporting what content has changed. At best, one could
use the 'execute a command option' to, say do a diff on certain actions,
but you would also need to set up capability to replicate the file in
the first place, and, hope no one deletes the replicated file which
would defeat the purpose of the watch. Too many moving parts that can be
attacked.

To me, something like iwatch is a useful capability that can fire off an
alert as soon as the action occurs. At this point a Security Operations
Centre could take action. Although, I would expect them to wait for the
auditd events that not only record the action, but also the high level
command involved (PROCTITLE) and the user (auid) and what privileges
(*uid, *gid) they had.

Again, I am looking for a light weight, self contained tool.

Regards

On Mon, 2015-07-20 at 17:53 +0000, Smith, Gary R wrote:
> Hello Burn,
> 
> Have you considered iwatch (no, not the Apple wrist gadget). It monitors
> files and can alert on a large set file conditions. Check out this man
> page at: http://manpages.ubuntu.com/manpages/utopic/man1/iwatch.1.html
> 
> Best regards,
> 
> Gary Smith
> 
> On 7/20/15 4:56 AM, Burn Alting wrote:
> > All,
> >
> > I am interested in any Linux based capability that will monitor
> > identified files and report on actual changes to the monitored file. I
> > know there are methods of recording that the file has been changed (e.g.
> > aide and/or monitor writes via auditd), but I want to know what has
> > changed ... basically something that would provide a 'diff' like output.
> >
> > Now there are tools like Samhain that will record the content changes of
> > a file that is <= 92000 bytes in size, but I am interested in a more
> > lightweight solution ... perhaps a simple inotify(7) based utility that
> > perhaps maintains a copy of the file(s) in core (in compressed format)
> > and based on inotify() returns checks for changes and reports (somehow
> > yet to be defined) the before/after changes.
> >
> > Is there anything 'out there' that list members are aware of?
> >
> > If not, would the following utility be of interest? On startup, load the
> > monitored file(s) (saving a compressed copy in memory). Then, using
> > inotify, monitor for changes and if so, emit some kind of record
> > defining the change and change the compressed in-memory copy. If so, is
> > our mailing list and the contributed portion of auditd an appropriate
> > repository for such a tool.
> >
> > Naturally, such a tool would be supported by appropriate auditd
> > monitoring that will take care of changing file attributes etc and file
> > writes. That is, auditd tells me who and the utility tells me what.
> >
> >
> > Regards
> > Burn
> >
> > --
> > Linux-audit mailing list
> > Linux-audit@redhat.com
> > https://www.redhat.com/mailman/listinfo/linux-audit
> >
> 

^ permalink raw reply

* Re: Configuration file monitoring - reporting content changes
From: Smith, Gary R @ 2015-07-20 17:53 UTC (permalink / raw)
  To: burn@swtf.dyndns.org, linux-audit@redhat.com
In-Reply-To: <1437393227.26354.16.camel@swtf.swtf.dyndns.org>

Hello Burn,

Have you considered iwatch (no, not the Apple wrist gadget). It monitors
files and can alert on a large set file conditions. Check out this man
page at: http://manpages.ubuntu.com/manpages/utopic/man1/iwatch.1.html

Best regards,

Gary Smith

On 7/20/15 4:56 AM, Burn Alting wrote:
> All,
>
> I am interested in any Linux based capability that will monitor
> identified files and report on actual changes to the monitored file. I
> know there are methods of recording that the file has been changed (e.g.
> aide and/or monitor writes via auditd), but I want to know what has
> changed ... basically something that would provide a 'diff' like output.
>
> Now there are tools like Samhain that will record the content changes of
> a file that is <= 92000 bytes in size, but I am interested in a more
> lightweight solution ... perhaps a simple inotify(7) based utility that
> perhaps maintains a copy of the file(s) in core (in compressed format)
> and based on inotify() returns checks for changes and reports (somehow
> yet to be defined) the before/after changes.
>
> Is there anything 'out there' that list members are aware of?
>
> If not, would the following utility be of interest? On startup, load the
> monitored file(s) (saving a compressed copy in memory). Then, using
> inotify, monitor for changes and if so, emit some kind of record
> defining the change and change the compressed in-memory copy. If so, is
> our mailing list and the contributed portion of auditd an appropriate
> repository for such a tool.
>
> Naturally, such a tool would be supported by appropriate auditd
> monitoring that will take care of changing file attributes etc and file
> writes. That is, auditd tells me who and the utility tells me what.
>
>
> Regards
> Burn
>
> --
> Linux-audit mailing list
> Linux-audit@redhat.com
> https://www.redhat.com/mailman/listinfo/linux-audit
>

^ permalink raw reply

* Re: [PATCH V6 1/4] audit: implement audit by executable
From: Paul Moore @ 2015-07-20 15:10 UTC (permalink / raw)
  To: Richard Guy Briggs; +Cc: linux-audit, linux-kernel
In-Reply-To: <20150717204618.GB28281@madcap2.tricolour.ca>

On Friday, July 17, 2015 04:46:18 PM Richard Guy Briggs wrote:
> On 15/07/17, Paul Moore wrote:
> > You could do a "based on" or similar tag if you want.  I'm honestly not
> > sure what the official tags are beyond signed-off, acked, and reviewed. 
> > Those are the only ones I really care about anyway ;)
> 
> From Documentation/SubmittingPatches:
> 	11) Signed-off-by:
> 	12) Acked-by: and Cc:
> 	13) Reported-by:, Tested-by:, Reviewed-by:, Suggested-by: and Fixes:

... you would think after referring people to this file I would have a better 
idea of what currently lives in there ;)

Thanks for the info.

-- 
paul moore
security @ redhat

^ permalink raw reply

* Re: Configuration file monitoring - reporting content changes
From: Burn Alting @ 2015-07-20 13:03 UTC (permalink / raw)
  To: Tetsuo Handa; +Cc: linux-audit
In-Reply-To: <201507202109.GAJ05274.tSFOJFFVQMLOHO@I-love.SAKURA.ne.jp>

Mon, 2015-07-20 at 21:09 +0900, Tetsuo Handa wrote:
> Burn Alting wrote:
> > All,
> > 
> > I am interested in any Linux based capability that will monitor
> > identified files and report on actual changes to the monitored file. I
> > know there are methods of recording that the file has been changed (e.g.
> > aide and/or monitor writes via auditd), but I want to know what has
> > changed ... basically something that would provide a 'diff' like output.
> > 
> > Now there are tools like Samhain that will record the content changes of
> > a file that is <= 92000 bytes in size, but I am interested in a more
> > lightweight solution ... perhaps a simple inotify(7) based utility that
> > perhaps maintains a copy of the file(s) in core (in compressed format)
> > and based on inotify() returns checks for changes and reports (somehow
> > yet to be defined) the before/after changes.
> > 
> > Is there anything 'out there' that list members are aware of?
> 
> If you don't need to protect "copy of the file(s)" from malicious attacks,
> I think cvs / svn / git etc. would be sufficient.
> 
> If you need to protect "copy of the file(s)" from malicious attacks,
> you would need to use access control mechanisms (e.g. SELinux).
Tetsuo,

I appreciate what you say, but I am looking at this problem from the
point of view of
a. There is no central management of configuration files, which means
git/puppet is not a viable solution.
b. The entity that  will change the file is authorized to make the
change. That is, I just want to know what has changed. I am assuming
there are sufficient access control mechanisms to 'protect the file'.

Regards

^ permalink raw reply

* Configuration file monitoring - reporting content changes
From: Burn Alting @ 2015-07-20 11:53 UTC (permalink / raw)
  To: linux-audit

All,

I am interested in any Linux based capability that will monitor
identified files and report on actual changes to the monitored file. I
know there are methods of recording that the file has been changed (e.g.
aide and/or monitor writes via auditd), but I want to know what has
changed ... basically something that would provide a 'diff' like output.

Now there are tools like Samhain that will record the content changes of
a file that is <= 92000 bytes in size, but I am interested in a more
lightweight solution ... perhaps a simple inotify(7) based utility that
perhaps maintains a copy of the file(s) in core (in compressed format)
and based on inotify() returns checks for changes and reports (somehow
yet to be defined) the before/after changes.

Is there anything 'out there' that list members are aware of?

If not, would the following utility be of interest? On startup, load the
monitored file(s) (saving a compressed copy in memory). Then, using
inotify, monitor for changes and if so, emit some kind of record
defining the change and change the compressed in-memory copy. If so, is
our mailing list and the contributed portion of auditd an appropriate
repository for such a tool.

Naturally, such a tool would be supported by appropriate auditd
monitoring that will take care of changing file attributes etc and file
writes. That is, auditd tells me who and the utility tells me what.


Regards
Burn

^ permalink raw reply

* Re: [PATCH V6 1/4] audit: implement audit by executable
From: Richard Guy Briggs @ 2015-07-17 20:46 UTC (permalink / raw)
  To: Paul Moore; +Cc: peter, linux-audit, linux-kernel
In-Reply-To: <1483198.YaQkdzj5I8@sifl>

On 15/07/17, Paul Moore wrote:
> On Friday, July 17, 2015 11:33:17 AM Richard Guy Briggs wrote:
> > On 15/07/16, Paul Moore wrote:
> > > On Tuesday, July 14, 2015 11:50:23 AM Richard Guy Briggs wrote:
> > > > From: Eric Paris <eparis@redhat.com>
> > > > 
> > > > This patch implements the ability to filter on the executable.  It is
> > > > clearly incomplete!  This patch adds the inode/dev of the executable at
> > > > the moment the rule is loaded.  It does not update if the executable is
> > > > updated/moved/whatever.  That should be added.  But at this moment, this
> > > > patch works.
> > > 
> > > This needs work.  Either this patch is incomplete as the description says,
> > > in which case I'm not going to merge it, or the description is out of
> > > date and needs to be updated.
> > 
> > It is pretty close to the original, so the description is valid, however
> > combining this patch with 3/4 and 4/4 triggers a rewrite.
> > 
> > > If later patches in the series fix deficiencies in this patch (I haven't
> > > gotten past this description yet) then we should consider merging some of
> > > the patches together so they are more useful.
> > 
> > Ok, no problem.  (More below...)
> > 
> > > > RGB: Explicitly declare prototypes as extern.
> > > > RGB: Rename audit_dup_exe() to audit_dupe_exe() consistent with rule,
> > > > watch, lsm_field.
> > > > 
> > > > Based-on-user-interface-by: Richard Guy Briggs <rgb@redhat.com>
> > > > Based-on-idea-by: Peter Moody <pmoody@google.com>
> > > 
> > > I'm not fully up on the different patch metadata the cool kids are using
> > > these days, but I think it is okay to simply credit Peter in the patch
> > > description and omit the two lines above.  Giving credit is important,
> > > but these metadata tags are a bit silly in my opinion.
> > 
> > Fair enough.  If it doesn't need to be machine-readable, I'll merge it
> > into the patch description prose.
> 
> You could do a "based on" or similar tag if you want.  I'm honestly not sure 
> what the official tags are beyond signed-off, acked, and reviewed.  Those are 
> the only ones I really care about anyway ;)

>From Documentation/SubmittingPatches:
	11) Signed-off-by:
	12) Acked-by: and Cc:
	13) Reported-by:, Tested-by:, Reviewed-by:, Suggested-by: and Fixes:

> It isn't something I care enough about to reject a patch over, I figured you 
> were going to need to do some respin work anyway so I wanted to mention it.

The description will need a complete overhaul, so it'll get fixed.

> > > > diff --git a/kernel/audit.h b/kernel/audit.h
> > > > index d641f9b..3aca24f 100644
> > > > --- a/kernel/audit.h
> > > > +++ b/kernel/audit.h
> > > > @@ -278,6 +286,30 @@ extern int audit_watch_compare(struct audit_watch
> > > > *watch, unsigned long ino, dev #define audit_watch_path(w) ""
> > > > 
> > > >  #define audit_watch_compare(w, i, d) 0
> > > > 
> > > > +static inline int audit_make_exe_rule(struct audit_krule *krule, char
> > > > *pathname, int len, u32 op)
> > > > +{
> > > > +	return -EINVAL;
> > > > +}
> > > > +static inline void audit_remove_exe_rule(struct audit_krule *krule)
> > > > +{
> > > > +	BUG();
> > > > +	return 0;
> > > > +}
> > > > +static inline char *audit_exe_path(struct audit_exe *exe)
> > > > +{
> > > > +	BUG();
> > > > +	return "";
> > > > +}
> > > > +static inline int audit_dupe_exe(struct audit_krule *new, struct
> > > > audit_krule *old) +{
> > > > +	BUG();
> > > > +	return -EINVAL
> > > > +}
> > > > +static inline int audit_exe_compare(struct task_struct *tsk, struct
> > > > audit_exe *exe) +{
> > > > +	BUG();
> > > > +	return 0;
> > > > +}
> > > > 
> > > >  #endif /* CONFIG_AUDIT_WATCH */
> > > 
> > > Not a big fan of the BUG() calls in the stubs above, let's get rid of
> > > them.
> > 
> > Ok, that way I can more easily convert them to #defines.
> > 
> > > Yes, I know some other audit stubs are defined as BUG(), or similar, those
> > > aren't a good idea either, but they are already there ...
> > 
> > Ok, cleanup patch later...
> 
> Much later.  It isn't something I worry much about, I just don't want to see 
> us going crazy with BUG assertions in new code.
> 
> > > > diff --git a/kernel/audit_exe.c b/kernel/audit_exe.c
> > > > new file mode 100644
> > > > index 0000000..d4cc8b5
> > > > --- /dev/null
> > > > +++ b/kernel/audit_exe.c
> > > > @@ -0,0 +1,109 @@
> > > > +/* audit_exe.c -- filtering of audit events
> > > > + *
> > > > + * Copyright 2014-2015 Red Hat, Inc.
> > > > + *
> > > > + * This program is free software; you can redistribute it and/or modify
> > > > + * it under the terms of the GNU General Public License as published by
> > > > + * the Free Software Foundation; either version 2 of the License, or
> > > > + * (at your option) any later version.
> > > > + *
> > > > + * This program is distributed in the hope that it will be useful,
> > > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > > > + * GNU General Public License for more details.
> > > > + */
> > > > +
> > > > +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> > > > +
> > > > +#include <linux/kernel.h>
> > > > +#include <linux/audit.h>
> > > > +#include <linux/mutex.h>
> > > > +#include <linux/fs.h>
> > > > +#include <linux/namei.h>
> > > > +#include <linux/slab.h>
> > > > +#include "audit.h"
> > > > +
> > > > +struct audit_exe {
> > > > +	char *pathname;
> > > > +	unsigned long ino;
> > > > +	dev_t dev;
> > > > +};
> > > > +
> > > > +/* Translate a watch string to kernel respresentation. */
> > > > +int audit_make_exe_rule(struct audit_krule *krule, char *pathname, int
> > > > len, u32 op)
> > > > +{
> > > > +	struct audit_exe *exe;
> > > > +	struct path path;
> > > > +	struct dentry *dentry;
> > > > +	unsigned long ino;
> > > > +	dev_t dev;
> > > > +
> > > > +	if (pathname[0] != '/' || pathname[len-1] == '/')
> > > > +		return -EINVAL;
> > > > +
> > > > +	dentry = kern_path_locked(pathname, &path);
> > > > +	if (IS_ERR(dentry))
> > > > +		return PTR_ERR(dentry);
> > > > +	mutex_unlock(&path.dentry->d_inode->i_mutex);
> > > > +
> > > > +	if (!dentry->d_inode)
> > > > +		return -ENOENT;
> > > > +	dev = dentry->d_inode->i_sb->s_dev;
> > > > +	ino = dentry->d_inode->i_ino;
> > > > +	dput(dentry);
> > > > +
> > > > +	exe = kmalloc(sizeof(*exe), GFP_KERNEL);
> > > > +	if (!exe)
> > > > +		return -ENOMEM;
> > > > +	exe->ino = ino;
> > > > +	exe->dev = dev;
> > > > +	exe->pathname = pathname;
> > > > +	krule->exe = exe;
> > > 
> > > You don't need the dev and ino variables here, just move the kmalloc() to
> > > just after the dentry->d_inode check ... or put it after the sanity
> > > checks, although you'll have to be careful to free it on error.
> > 
> > I'll take a closer look.  As referenced elsewhere, I agree a helper
> > function may be useful.
> 
> Once again, not something I would worry about for this patchset, let's just 
> get this code fixed up and merged.  It was more of an observation that I see a 
> lot of kernel audit structures storing and comparing dev/inode information and 
> each way is slightly different ... I *love* consistency in code to an 
> unhealthy level, so this bugs me a bit more than it probably should.
> 
> > > > +	return 0;
> > > > +}
> > > > +
> > > > +void audit_remove_exe_rule(struct audit_krule *krule)
> > > > +{
> > > > +	struct audit_exe *exe;
> > > > +
> > > > +	exe = krule->exe;
> > > > +	krule->exe = NULL;
> > > > +	kfree(exe->pathname);
> > > > +	kfree(exe);
> > > > +}
> > > 
> > > Not your fault, and nothing to change here, but I really hate how audit
> > > dups strings outside the rule creation functions, but frees the strings
> > > in the rule free routines; it's almost asking to be misused.
> > 
> > Again, cleanup patch later maybe...
> 
> Yeah ... maybe.  World peace too.
> 
> > > > +char *audit_exe_path(struct audit_exe *exe)
> > > > +{
> > > > +	return exe->pathname;
> > > > +}
> > > > +
> > > > +int audit_dupe_exe(struct audit_krule *new, struct audit_krule *old)
> > > > +{
> > > > +	struct audit_exe *exe;
> > > > +
> > > > +	exe = kmalloc(sizeof(*exe), GFP_KERNEL);
> > > > +	if (!exe)
> > > > +		return -ENOMEM;
> > > > +
> > > > +	exe->pathname = kstrdup(old->exe->pathname, GFP_KERNEL);
> > > > +	if (!exe->pathname) {
> > > > +		kfree(exe);
> > > > +		return -ENOMEM;
> > > > +	}
> > > > +
> > > > +	exe->ino = old->exe->ino;
> > > > +	exe->dev = old->exe->dev;
> > > > +	new->exe = exe;
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > > +int audit_exe_compare(struct task_struct *tsk, struct audit_exe *exe)
> > > > +{
> > > > +	if (tsk->mm->exe_file->f_inode->i_ino != exe->ino)
> > > > +		return 0;
> > > > +	if (tsk->mm->exe_file->f_inode->i_sb->s_dev != exe->dev)
> > > > +		return 0;
> > > > +	return 1;
> > > > +}
> > > 
> > > I suspect Eric put the above functions in a separate file to ease
> > > development (no need to work about messy porting as upstream moved on),
> > > but I see no reason why these functions couldn't be folded into
> > > auditfilter.c.
> > 
> > I thought it made sense where Eric put it.  It somewhat parallelled the
> > watch and tree code.  It might be tempting to put it in
> > audit_fsnotify.c, but I don't really want to overload that, since the
> > fsnotify code may be used to simpify the watch code in the future.  When
> > we're done after 3/4, audit_exe.c is down to 50 lines...
> 
> See, there ya go ... I don't see the point of adding a new file for 50 lines.
> 
> > Mind you, auditsc.c is a bit overloaded with stuff that doesn't
> > necessarily belong there...
> 
> At some point we'll clean things up a bit - most likely as part of the 
> upcoming audit rework - but it doesn't need to happen with this patchset.
> 
> > > > diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> > > > index 9fb9d1c..bf745c7 100644
> > > > --- a/kernel/auditsc.c
> > > > +++ b/kernel/auditsc.c
> > > > @@ -48,6 +48,7 @@
> > > > 
> > > >  #include <asm/types.h>
> > > >  #include <linux/atomic.h>
> > > >  #include <linux/fs.h>
> > > > 
> > > > +#include <linux/dcache.h>
> > > > 
> > > >  #include <linux/namei.h>
> > > >  #include <linux/mm.h>
> > > >  #include <linux/export.h>
> > > > 
> > > > @@ -71,6 +72,7 @@
> > > > 
> > > >  #include <linux/capability.h>
> > > >  #include <linux/fs_struct.h>
> > > >  #include <linux/compat.h>
> > > > 
> > > > +#include <linux/sched.h>
> > > > 
> > > >  #include <linux/ctype.h>
> > > >  #include <linux/string.h>
> > > >  #include <uapi/linux/limits.h>
> > > > 
> > > > @@ -466,6 +468,20 @@ static int audit_filter_rules(struct task_struct
> > > > *tsk,
> > > > 
> > > >  				result = audit_comparator(ctx->ppid, f->op, f->val);
> > > >  			
> > > >  			}
> > > >  			break;
> > > > 
> > > > +		case AUDIT_EXE:
> > > > +			result = audit_exe_compare(tsk, rule->exe);
> > > > +			break;
> > > > +		case AUDIT_EXE_CHILDREN:
> > > > +		{
> > > > +			struct task_struct *ptsk;
> > > > +			for (ptsk = tsk; ptsk->parent->pid > 0; ptsk =
> > > > 
> > > >              find_task_by_vpid(ptsk->parent->pid)) {
> > > > 
> > > > +				if (audit_exe_compare(ptsk, rule->exe)) {
> > > > +					++result;
> > > > +					break;
> > > > +				}
> > > > +			}
> > > > +		}
> > > > +			break;
> > > 
> > > I don't completely understand the point of AUDIT_EXE_CHILDREN filter, what
> > > problem are we trying to solve?  It checks to see if there is an
> > > executable match starting with the current process and walking up the
> > > process' parents in the current pid namespace?
> > 
> > Say we want to monitor /usr/sbin/apache2 and all its spawned processes.
> > Set up a rule that uses AUDIT_EXE_CHILDREN with /usr/sbin/apache2, then
> > when it spawns a cgi running perl or php, those actions will be caught.
> > 
> > > Help me understand what this accomplishes, I'm a little tried right now
> > > and I just don't get it.
> > 
> > This was Peter Moody's idea and it made sense, so we kept it.
> 
> I suppose my confusion is that I see the exe filtering as very similar to our 
> PID filtering, the big difference is that we allow you to match on an on-disk 
> binary and not a running process.  We don't currently have a PID_CHILDREN 
> filter and presumably no one has asked for it.  Yes we do have PPID, but it 
> only goes up one level, e.g. it's PPID and not PPPPPPPPID, not like the 
> potentially nasty loop we've got with EXE_CHILDREN.
> 
> I'm not super excited about the loop so I'd really like to hear how this is 
> solving an actual user need and not just a "hey, wouldn't it be cool?" 
> feature.
> 
> -- 
> paul moore
> security @ redhat
> 
> --
> Linux-audit mailing list
> Linux-audit@redhat.com
> https://www.redhat.com/mailman/listinfo/linux-audit

- RGB

--
Richard Guy Briggs <rbriggs@redhat.com>
Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545

^ permalink raw reply

* Re: [PATCH V6 1/4] audit: implement audit by executable
From: Richard Guy Briggs @ 2015-07-17 20:27 UTC (permalink / raw)
  To: Paul Moore; +Cc: peter, linux-audit, linux-kernel
In-Reply-To: <20150717153317.GH32473@madcap2.tricolour.ca>

On 15/07/17, Richard Guy Briggs wrote:
> On 15/07/16, Paul Moore wrote:
> > On Tuesday, July 14, 2015 11:50:23 AM Richard Guy Briggs wrote:
> > > From: Eric Paris <eparis@redhat.com>
> > > 
> > > This patch implements the ability to filter on the executable.  It is
> > > clearly incomplete!  This patch adds the inode/dev of the executable at
> > > the moment the rule is loaded.  It does not update if the executable is
> > > updated/moved/whatever.  That should be added.  But at this moment, this
> > > patch works.

<snip>

> > > diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> > > index 9fb9d1c..bf745c7 100644
> > > --- a/kernel/auditsc.c
> > > +++ b/kernel/auditsc.c
> > > @@ -71,6 +72,7 @@
> > >  #include <linux/capability.h>
> > >  #include <linux/fs_struct.h>
> > >  #include <linux/compat.h>
> > > +#include <linux/sched.h>
> > >  #include <linux/ctype.h>
> > >  #include <linux/string.h>
> > >  #include <uapi/linux/limits.h>
> > > @@ -466,6 +468,20 @@ static int audit_filter_rules(struct task_struct *tsk,
> > >  				result = audit_comparator(ctx->ppid, f->op, f->val);
> > >  			}
> > >  			break;
> > > +		case AUDIT_EXE:
> > > +			result = audit_exe_compare(tsk, rule->exe);
> > > +			break;
> > > +		case AUDIT_EXE_CHILDREN:
> > > +		{
> > > +			struct task_struct *ptsk;
> > > +			for (ptsk = tsk; ptsk->parent->pid > 0; ptsk =
> > >              find_task_by_vpid(ptsk->parent->pid)) {
> > > +				if (audit_exe_compare(ptsk, rule->exe)) {
> > > +					++result;
> > > +					break;
> > > +				}
> > > +			}
> > > +		}
> > > +			break;
> > 
> > I don't completely understand the point of AUDIT_EXE_CHILDREN filter, what 
> > problem are we trying to solve?  It checks to see if there is an executable 
> > match starting with the current process and walking up the process' parents in 
> > the current pid namespace?
> 
> Say we want to monitor /usr/sbin/apache2 and all its spawned processes.
> Set up a rule that uses AUDIT_EXE_CHILDREN with /usr/sbin/apache2, then
> when it spawns a cgi running perl or php, those actions will be caught.
> 
> > Help me understand what this accomplishes, I'm a little tried right now and I 
> > just don't get it.
> 
> This was Peter Moody's idea and it made sense, so we kept it.

Peter, do you have anything to add to justify keeping
AUDIT_EXE_CHILDREN?

> > paul moore
> 
> - RGB

- RGB

--
Richard Guy Briggs <rbriggs@redhat.com>
Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545

^ permalink raw reply

* Re: [PATCH V6 1/4] audit: implement audit by executable
From: Paul Moore @ 2015-07-17 18:24 UTC (permalink / raw)
  To: Richard Guy Briggs; +Cc: linux-audit, linux-kernel, Eric Paris, sgrubb, pmoody
In-Reply-To: <20150717153317.GH32473@madcap2.tricolour.ca>

On Friday, July 17, 2015 11:33:17 AM Richard Guy Briggs wrote:
> On 15/07/16, Paul Moore wrote:
> > On Tuesday, July 14, 2015 11:50:23 AM Richard Guy Briggs wrote:
> > > From: Eric Paris <eparis@redhat.com>
> > > 
> > > This patch implements the ability to filter on the executable.  It is
> > > clearly incomplete!  This patch adds the inode/dev of the executable at
> > > the moment the rule is loaded.  It does not update if the executable is
> > > updated/moved/whatever.  That should be added.  But at this moment, this
> > > patch works.
> > 
> > This needs work.  Either this patch is incomplete as the description says,
> > in which case I'm not going to merge it, or the description is out of
> > date and needs to be updated.
> 
> It is pretty close to the original, so the description is valid, however
> combining this patch with 3/4 and 4/4 triggers a rewrite.
> 
> > If later patches in the series fix deficiencies in this patch (I haven't
> > gotten past this description yet) then we should consider merging some of
> > the patches together so they are more useful.
> 
> Ok, no problem.  (More below...)
> 
> > > RGB: Explicitly declare prototypes as extern.
> > > RGB: Rename audit_dup_exe() to audit_dupe_exe() consistent with rule,
> > > watch, lsm_field.
> > > 
> > > Based-on-user-interface-by: Richard Guy Briggs <rgb@redhat.com>
> > > Based-on-idea-by: Peter Moody <pmoody@google.com>
> > 
> > I'm not fully up on the different patch metadata the cool kids are using
> > these days, but I think it is okay to simply credit Peter in the patch
> > description and omit the two lines above.  Giving credit is important,
> > but these metadata tags are a bit silly in my opinion.
> 
> Fair enough.  If it doesn't need to be machine-readable, I'll merge it
> into the patch description prose.

You could do a "based on" or similar tag if you want.  I'm honestly not sure 
what the official tags are beyond signed-off, acked, and reviewed.  Those are 
the only ones I really care about anyway ;)

It isn't something I care enough about to reject a patch over, I figured you 
were going to need to do some respin work anyway so I wanted to mention it.

> > > diff --git a/kernel/audit.h b/kernel/audit.h
> > > index d641f9b..3aca24f 100644
> > > --- a/kernel/audit.h
> > > +++ b/kernel/audit.h
> > > @@ -278,6 +286,30 @@ extern int audit_watch_compare(struct audit_watch
> > > *watch, unsigned long ino, dev #define audit_watch_path(w) ""
> > > 
> > >  #define audit_watch_compare(w, i, d) 0
> > > 
> > > +static inline int audit_make_exe_rule(struct audit_krule *krule, char
> > > *pathname, int len, u32 op)
> > > +{
> > > +	return -EINVAL;
> > > +}
> > > +static inline void audit_remove_exe_rule(struct audit_krule *krule)
> > > +{
> > > +	BUG();
> > > +	return 0;
> > > +}
> > > +static inline char *audit_exe_path(struct audit_exe *exe)
> > > +{
> > > +	BUG();
> > > +	return "";
> > > +}
> > > +static inline int audit_dupe_exe(struct audit_krule *new, struct
> > > audit_krule *old) +{
> > > +	BUG();
> > > +	return -EINVAL
> > > +}
> > > +static inline int audit_exe_compare(struct task_struct *tsk, struct
> > > audit_exe *exe) +{
> > > +	BUG();
> > > +	return 0;
> > > +}
> > > 
> > >  #endif /* CONFIG_AUDIT_WATCH */
> > 
> > Not a big fan of the BUG() calls in the stubs above, let's get rid of
> > them.
> 
> Ok, that way I can more easily convert them to #defines.
> 
> > Yes, I know some other audit stubs are defined as BUG(), or similar, those
> > aren't a good idea either, but they are already there ...
> 
> Ok, cleanup patch later...

Much later.  It isn't something I worry much about, I just don't want to see 
us going crazy with BUG assertions in new code.

> > > diff --git a/kernel/audit_exe.c b/kernel/audit_exe.c
> > > new file mode 100644
> > > index 0000000..d4cc8b5
> > > --- /dev/null
> > > +++ b/kernel/audit_exe.c
> > > @@ -0,0 +1,109 @@
> > > +/* audit_exe.c -- filtering of audit events
> > > + *
> > > + * Copyright 2014-2015 Red Hat, Inc.
> > > + *
> > > + * This program is free software; you can redistribute it and/or modify
> > > + * it under the terms of the GNU General Public License as published by
> > > + * the Free Software Foundation; either version 2 of the License, or
> > > + * (at your option) any later version.
> > > + *
> > > + * This program is distributed in the hope that it will be useful,
> > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > > + * GNU General Public License for more details.
> > > + */
> > > +
> > > +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> > > +
> > > +#include <linux/kernel.h>
> > > +#include <linux/audit.h>
> > > +#include <linux/mutex.h>
> > > +#include <linux/fs.h>
> > > +#include <linux/namei.h>
> > > +#include <linux/slab.h>
> > > +#include "audit.h"
> > > +
> > > +struct audit_exe {
> > > +	char *pathname;
> > > +	unsigned long ino;
> > > +	dev_t dev;
> > > +};
> > > +
> > > +/* Translate a watch string to kernel respresentation. */
> > > +int audit_make_exe_rule(struct audit_krule *krule, char *pathname, int
> > > len, u32 op)
> > > +{
> > > +	struct audit_exe *exe;
> > > +	struct path path;
> > > +	struct dentry *dentry;
> > > +	unsigned long ino;
> > > +	dev_t dev;
> > > +
> > > +	if (pathname[0] != '/' || pathname[len-1] == '/')
> > > +		return -EINVAL;
> > > +
> > > +	dentry = kern_path_locked(pathname, &path);
> > > +	if (IS_ERR(dentry))
> > > +		return PTR_ERR(dentry);
> > > +	mutex_unlock(&path.dentry->d_inode->i_mutex);
> > > +
> > > +	if (!dentry->d_inode)
> > > +		return -ENOENT;
> > > +	dev = dentry->d_inode->i_sb->s_dev;
> > > +	ino = dentry->d_inode->i_ino;
> > > +	dput(dentry);
> > > +
> > > +	exe = kmalloc(sizeof(*exe), GFP_KERNEL);
> > > +	if (!exe)
> > > +		return -ENOMEM;
> > > +	exe->ino = ino;
> > > +	exe->dev = dev;
> > > +	exe->pathname = pathname;
> > > +	krule->exe = exe;
> > 
> > You don't need the dev and ino variables here, just move the kmalloc() to
> > just after the dentry->d_inode check ... or put it after the sanity
> > checks, although you'll have to be careful to free it on error.
> 
> I'll take a closer look.  As referenced elsewhere, I agree a helper
> function may be useful.

Once again, not something I would worry about for this patchset, let's just 
get this code fixed up and merged.  It was more of an observation that I see a 
lot of kernel audit structures storing and comparing dev/inode information and 
each way is slightly different ... I *love* consistency in code to an 
unhealthy level, so this bugs me a bit more than it probably should.

> > > +	return 0;
> > > +}
> > > +
> > > +void audit_remove_exe_rule(struct audit_krule *krule)
> > > +{
> > > +	struct audit_exe *exe;
> > > +
> > > +	exe = krule->exe;
> > > +	krule->exe = NULL;
> > > +	kfree(exe->pathname);
> > > +	kfree(exe);
> > > +}
> > 
> > Not your fault, and nothing to change here, but I really hate how audit
> > dups strings outside the rule creation functions, but frees the strings
> > in the rule free routines; it's almost asking to be misused.
> 
> Again, cleanup patch later maybe...

Yeah ... maybe.  World peace too.

> > > +char *audit_exe_path(struct audit_exe *exe)
> > > +{
> > > +	return exe->pathname;
> > > +}
> > > +
> > > +int audit_dupe_exe(struct audit_krule *new, struct audit_krule *old)
> > > +{
> > > +	struct audit_exe *exe;
> > > +
> > > +	exe = kmalloc(sizeof(*exe), GFP_KERNEL);
> > > +	if (!exe)
> > > +		return -ENOMEM;
> > > +
> > > +	exe->pathname = kstrdup(old->exe->pathname, GFP_KERNEL);
> > > +	if (!exe->pathname) {
> > > +		kfree(exe);
> > > +		return -ENOMEM;
> > > +	}
> > > +
> > > +	exe->ino = old->exe->ino;
> > > +	exe->dev = old->exe->dev;
> > > +	new->exe = exe;
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +int audit_exe_compare(struct task_struct *tsk, struct audit_exe *exe)
> > > +{
> > > +	if (tsk->mm->exe_file->f_inode->i_ino != exe->ino)
> > > +		return 0;
> > > +	if (tsk->mm->exe_file->f_inode->i_sb->s_dev != exe->dev)
> > > +		return 0;
> > > +	return 1;
> > > +}
> > 
> > I suspect Eric put the above functions in a separate file to ease
> > development (no need to work about messy porting as upstream moved on),
> > but I see no reason why these functions couldn't be folded into
> > auditfilter.c.
> 
> I thought it made sense where Eric put it.  It somewhat parallelled the
> watch and tree code.  It might be tempting to put it in
> audit_fsnotify.c, but I don't really want to overload that, since the
> fsnotify code may be used to simpify the watch code in the future.  When
> we're done after 3/4, audit_exe.c is down to 50 lines...

See, there ya go ... I don't see the point of adding a new file for 50 lines.

> Mind you, auditsc.c is a bit overloaded with stuff that doesn't
> necessarily belong there...

At some point we'll clean things up a bit - most likely as part of the 
upcoming audit rework - but it doesn't need to happen with this patchset.

> > > diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> > > index 9fb9d1c..bf745c7 100644
> > > --- a/kernel/auditsc.c
> > > +++ b/kernel/auditsc.c
> > > @@ -48,6 +48,7 @@
> > > 
> > >  #include <asm/types.h>
> > >  #include <linux/atomic.h>
> > >  #include <linux/fs.h>
> > > 
> > > +#include <linux/dcache.h>
> > > 
> > >  #include <linux/namei.h>
> > >  #include <linux/mm.h>
> > >  #include <linux/export.h>
> > > 
> > > @@ -71,6 +72,7 @@
> > > 
> > >  #include <linux/capability.h>
> > >  #include <linux/fs_struct.h>
> > >  #include <linux/compat.h>
> > > 
> > > +#include <linux/sched.h>
> > > 
> > >  #include <linux/ctype.h>
> > >  #include <linux/string.h>
> > >  #include <uapi/linux/limits.h>
> > > 
> > > @@ -466,6 +468,20 @@ static int audit_filter_rules(struct task_struct
> > > *tsk,
> > > 
> > >  				result = audit_comparator(ctx->ppid, f->op, f->val);
> > >  			
> > >  			}
> > >  			break;
> > > 
> > > +		case AUDIT_EXE:
> > > +			result = audit_exe_compare(tsk, rule->exe);
> > > +			break;
> > > +		case AUDIT_EXE_CHILDREN:
> > > +		{
> > > +			struct task_struct *ptsk;
> > > +			for (ptsk = tsk; ptsk->parent->pid > 0; ptsk =
> > > 
> > >              find_task_by_vpid(ptsk->parent->pid)) {
> > > 
> > > +				if (audit_exe_compare(ptsk, rule->exe)) {
> > > +					++result;
> > > +					break;
> > > +				}
> > > +			}
> > > +		}
> > > +			break;
> > 
> > I don't completely understand the point of AUDIT_EXE_CHILDREN filter, what
> > problem are we trying to solve?  It checks to see if there is an
> > executable match starting with the current process and walking up the
> > process' parents in the current pid namespace?
> 
> Say we want to monitor /usr/sbin/apache2 and all its spawned processes.
> Set up a rule that uses AUDIT_EXE_CHILDREN with /usr/sbin/apache2, then
> when it spawns a cgi running perl or php, those actions will be caught.
> 
> > Help me understand what this accomplishes, I'm a little tried right now
> > and I just don't get it.
> 
> This was Peter Moody's idea and it made sense, so we kept it.

I suppose my confusion is that I see the exe filtering as very similar to our 
PID filtering, the big difference is that we allow you to match on an on-disk 
binary and not a running process.  We don't currently have a PID_CHILDREN 
filter and presumably no one has asked for it.  Yes we do have PPID, but it 
only goes up one level, e.g. it's PPID and not PPPPPPPPID, not like the 
potentially nasty loop we've got with EXE_CHILDREN.

I'm not super excited about the loop so I'd really like to hear how this is 
solving an actual user need and not just a "hey, wouldn't it be cool?" 
feature.

-- 
paul moore
security @ redhat

^ permalink raw reply

* Re: [PATCH V6 4/4] audit: avoid double copying the audit_exe path string
From: Paul Moore @ 2015-07-17 18:09 UTC (permalink / raw)
  To: Richard Guy Briggs; +Cc: Eric Paris, linux-audit, linux-kernel, sgrubb
In-Reply-To: <20150717164853.GB20540@madcap2.tricolour.ca>

On Friday, July 17, 2015 12:48:53 PM Richard Guy Briggs wrote:
> On 15/07/16, Paul Moore wrote:
> > On Thursday, July 16, 2015 10:01:30 PM Eric Paris wrote:
> > > I have to admit, I'm partial to not merging this (with the other
> > > patches).  Changing object lifetimes in what i seem to remember is long
> > > standing code (auditfilter, not auditexe) seems to me like something we
> > > really would want to be git bisectable, not mushed with an unrelated
> > > feature addition. But it ain't my tree   :)
> > 
> > It's been a long day, and maybe I'm missing something here, but this patch
> > only affects the new code, no?
> 
> Correct.  However, it aims to follow the approach used in watch and tree
> code, rather than making yet another copy.

I guess I still don't understand why this is separate - either I'm missing 
something painfully obvious or we're just not on the same page ...?  Oh well, 
this patch isn't really a bugfix or something that makes the feature 
functionally complete so I suppose keeping it as a separate patch is harmless.

In general, when adding new functionality I like to see individual patches 
that are functionally complete, hence my request to merge patch 1/4 and 3/4; 
the only solid reason I can think of for not doing so is due to size 
constraints on the mailing list (and reviewers minds).

> > > On Thu, 2015-07-16 at 22:01 -0400, Richard Guy Briggs wrote:
> > > > On 15/07/16, Paul Moore wrote:
> > > > > On Tuesday, July 14, 2015 11:50:26 AM Richard Guy Briggs wrote:
> > > > > > Make this interface consistent with watch and filter key,
> > > > > > avoiding the extra
> > > > > > string copy and simply consume the new string pointer.
> > > > > > 
> > > > > > Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
> > > > > > ---
> > > > > > 
> > > > > >  kernel/audit_exe.c      |    8 ++++++--
> > > > > >  kernel/audit_fsnotify.c |    9 +--------
> > > > > >  kernel/auditfilter.c    |    2 +-
> > > > > >  3 files changed, 8 insertions(+), 11 deletions(-)
> > > > > 
> > > > > Merge this patch too, there is no reason why these needs to be its
> > > > > own patch.
> > > > 
> > > > I wanted to keep this patch seperate until it is well understood and
> > > > accepted rather than mix it in.
> > > > 
> > > > I'm fine merging it if you prefer.
> > > > 
> > > > > > diff --git a/kernel/audit_exe.c b/kernel/audit_exe.c
> > > > > > index 75ad4f2..09e4eb4 100644
> > > > > > --- a/kernel/audit_exe.c
> > > > > > +++ b/kernel/audit_exe.c
> > > > > > @@ -27,11 +27,15 @@ int audit_dupe_exe(struct audit_krule *new,
> > > > > > struct
> > > > > > audit_krule *old) struct audit_fsnotify_mark *audit_mark;
> > > > > > 
> > > > > >  	char *pathname;
> > > > > > 
> > > > > > -	pathname = audit_mark_path(old->exe);
> > > > > > +	pathname = kstrdup(audit_mark_path(old->exe),
> > > > > > GFP_KERNEL);
> > > > > > +	if (!pathname)
> > > > > > +		return -ENOMEM;
> > > > > > 
> > > > > >  	audit_mark = audit_alloc_mark(new, pathname,
> > > > > > 
> > > > > > strlen(pathname));
> > > > > > -	if (IS_ERR(audit_mark))
> > > > > > +	if (IS_ERR(audit_mark)) {
> > > > > > +		kfree(pathname);
> > > > > > 
> > > > > >  		return PTR_ERR(audit_mark);
> > > > > > 
> > > > > > +	}
> > > > > > 
> > > > > >  	new->exe = audit_mark;
> > > > > >  	
> > > > > >  	return 0;
> > > > > > 
> > > > > > diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c
> > > > > > index a4e7b16..e57e08a 100644
> > > > > > --- a/kernel/audit_fsnotify.c
> > > > > > +++ b/kernel/audit_fsnotify.c
> > > > > > @@ -94,7 +94,6 @@ struct audit_fsnotify_mark
> > > > > > *audit_alloc_mark(struct
> > > > > > audit_krule *krule, char *pa struct dentry *dentry;
> > > > > > 
> > > > > >  	struct inode *inode;
> > > > > >  	unsigned long ino;
> > > > > > 
> > > > > > -	char *local_pathname;
> > > > > > 
> > > > > >  	dev_t dev;
> > > > > >  	int ret;
> > > > > > 
> > > > > > @@ -115,21 +114,15 @@ struct audit_fsnotify_mark
> > > > > > *audit_alloc_mark(struct
> > > > > > audit_krule *krule, char *pa ino = dentry->d_inode->i_ino;
> > > > > > 
> > > > > >  	}
> > > > > > 
> > > > > > -	audit_mark = ERR_PTR(-ENOMEM);
> > > > > > -	local_pathname = kstrdup(pathname, GFP_KERNEL);
> > > > > > -	if (!local_pathname)
> > > > > > -		goto out;
> > > > > > -
> > > > > > 
> > > > > >  	audit_mark = kzalloc(sizeof(*audit_mark), GFP_KERNEL);
> > > > > >  	if (unlikely(!audit_mark)) {
> > > > > > 
> > > > > > -		kfree(local_pathname);
> > > > > > 
> > > > > >  		audit_mark = ERR_PTR(-ENOMEM);
> > > > > >  		goto out;
> > > > > >  	
> > > > > >  	}
> > > > > >  	
> > > > > >  	fsnotify_init_mark(&audit_mark->mark,
> > > > > > 
> > > > > > audit_fsnotify_free_mark);
> > > > > > 
> > > > > >  	audit_mark->mark.mask = AUDIT_FS_EVENTS;
> > > > > > 
> > > > > > -	audit_mark->path = local_pathname;
> > > > > > +	audit_mark->path = pathname;
> > > > > > 
> > > > > >  	audit_mark->ino = ino;
> > > > > >  	audit_mark->dev = dev;
> > > > > >  	audit_mark->rule = krule;
> > > > > > 
> > > > > > diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
> > > > > > index f65c97f..f46ed69 100644
> > > > > > --- a/kernel/auditfilter.c
> > > > > > +++ b/kernel/auditfilter.c
> > > > > > @@ -559,8 +559,8 @@ static struct audit_entry
> > > > > > *audit_data_to_entry(struct
> > > > > > audit_rule_data *data, entry->rule.buflen += f->val;
> > > > > > 
> > > > > >  			audit_mark = audit_alloc_mark(&entry
> > > > > > 
> > > > > > ->rule, str, f->val);
> > > > > > -			kfree(str);
> > > > > > 
> > > > > >  			if (IS_ERR(audit_mark)) {
> > > > > > 
> > > > > > +				kfree(str);
> > > > > > 
> > > > > >  				err = PTR_ERR(audit_mark);
> > > > > >  				goto exit_free;
> > > > > >  			
> > > > > >  			}
> 
> - RGB
> 
> --
> Richard Guy Briggs <rbriggs@redhat.com>
> Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems,
> Red Hat Remote, Ottawa, Canada
> Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545

-- 
paul moore
security @ redhat

^ permalink raw reply

* Re: [PATCH V6 4/4] audit: avoid double copying the audit_exe path string
From: Paul Moore @ 2015-07-17 18:01 UTC (permalink / raw)
  To: Richard Guy Briggs; +Cc: Eric Paris, linux-audit, linux-kernel, sgrubb
In-Reply-To: <20150717161827.GA20540@madcap2.tricolour.ca>

On Friday, July 17, 2015 12:18:27 PM Richard Guy Briggs wrote:
> On 15/07/16, Eric Paris wrote:
> > I have to admit, I'm partial to not merging this (with the other
> > patches).  Changing object lifetimes in what i seem to remember is long
> > standing code (auditfilter, not auditexe) seems to me like something we
> > really would want to be git bisectable, not mushed with an unrelated
> > feature addition. But it ain't my tree   :)
> 
> So maybe even fixing this before applying the audit exe stuff has
> merit...

No, let's get the exe filter stuff in now just so I can get all you guys off 
my back about it :)

The refcnt stuff is almost surely going to get messy and I would just assume 
not deal with that right now since it appears to be working.  We have other 
stuff we need to fix first.

-- 
paul moore
security @ redhat

^ permalink raw reply

* Re: [PATCH V6 2/2] audit: eliminate unnecessary extra layer of watch parent references
From: Paul Moore @ 2015-07-17 17:58 UTC (permalink / raw)
  To: Richard Guy Briggs; +Cc: linux-audit, linux-kernel, sgrubb
In-Reply-To: <20150717014510.GE32473@madcap2.tricolour.ca>

On Thursday, July 16, 2015 09:45:10 PM Richard Guy Briggs wrote:
> On 15/07/16, Paul Moore wrote:
> > On Tuesday, July 14, 2015 11:40:42 AM Richard Guy Briggs wrote:
> > > The audit watch parent count was imbalanced, adding an unnecessary layer
> > > of
> > > watch parent references.  Decrement the additional parent reference when
> > > a
> > > watch is reused, already having a reference to the parent.
> > > 
> > > Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
> > > ---
> > > 
> > >  kernel/audit_watch.c |    6 ++----
> > >  1 files changed, 2 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
> > > index f33f54c..8f123d7 100644
> > > --- a/kernel/audit_watch.c
> > > +++ b/kernel/audit_watch.c
> > > @@ -391,11 +391,12 @@ static void audit_add_to_parent(struct audit_krule
> > > *krule,
> > > 
> > >  		audit_get_watch(w);
> > >  		krule->watch = watch = w;
> > > 
> > > +
> > > +		audit_put_parent(parent);
> > > 
> > >  		break;
> > >  	
> > >  	}
> > >  	
> > >  	if (!watch_found) {
> > > 
> > > -		audit_get_parent(parent);
> > > 
> > >  		watch->parent = parent;
> > 
> > I understand removing the get() here and the put() in audit_add_watch, but
> > I don't understand adding the put() above, can you help me understand?
>
> audit_find_parent() gets a reference to the parent, if the parent is
> already known.  This additional parental reference is not needed if the
> watch is subsequently found by audit_add_to_parent(), and consumed if
> the watch does not already exist, so we need to put the parent if the
> watch is found, and do nothing if this new watch is added to the parent.
> 
> If the parent wasn't already known, it is created with a refcount of 1
> and added to the audit_watch_group, then incremented by one to be
> subsequently consumed by the newly created watch in
> audit_add_to_parent().
> 
> The graph below may help to visualize it.
> 
> The rule points to the watch, not to the parent, so the rule's refcount
> gets bumped, not the parent's.

Great, thanks for the explanation.  Fix up the goto/return in patch 1/2, 
resubmit and I'll merge this patchset into audit#next.

-- 
paul moore
security @ redhat

^ permalink raw reply

* Re: [PATCH V6 4/4] audit: avoid double copying the audit_exe path string
From: Richard Guy Briggs @ 2015-07-17 16:48 UTC (permalink / raw)
  To: Paul Moore; +Cc: linux-audit, linux-kernel
In-Reply-To: <4796630.rR8ukBJnXA@sifl>

On 15/07/16, Paul Moore wrote:
> On Thursday, July 16, 2015 10:01:30 PM Eric Paris wrote:
> > I have to admit, I'm partial to not merging this (with the other
> > patches).  Changing object lifetimes in what i seem to remember is long
> > standing code (auditfilter, not auditexe) seems to me like something we
> > really would want to be git bisectable, not mushed with an unrelated
> > feature addition. But it ain't my tree   :)
> 
> It's been a long day, and maybe I'm missing something here, but this patch 
> only affects the new code, no?

Correct.  However, it aims to follow the approach used in watch and tree
code, rather than making yet another copy.

> > On Thu, 2015-07-16 at 22:01 -0400, Richard Guy Briggs wrote:
> > > On 15/07/16, Paul Moore wrote:
> > > > On Tuesday, July 14, 2015 11:50:26 AM Richard Guy Briggs wrote:
> > > > > Make this interface consistent with watch and filter key,
> > > > > avoiding the extra
> > > > > string copy and simply consume the new string pointer.
> > > > > 
> > > > > Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
> > > > > ---
> > > > > 
> > > > >  kernel/audit_exe.c      |    8 ++++++--
> > > > >  kernel/audit_fsnotify.c |    9 +--------
> > > > >  kernel/auditfilter.c    |    2 +-
> > > > >  3 files changed, 8 insertions(+), 11 deletions(-)
> > > > 
> > > > Merge this patch too, there is no reason why these needs to be its
> > > > own patch.
> > > 
> > > I wanted to keep this patch seperate until it is well understood and
> > > accepted rather than mix it in.
> > > 
> > > I'm fine merging it if you prefer.
> > > 
> > > > > diff --git a/kernel/audit_exe.c b/kernel/audit_exe.c
> > > > > index 75ad4f2..09e4eb4 100644
> > > > > --- a/kernel/audit_exe.c
> > > > > +++ b/kernel/audit_exe.c
> > > > > @@ -27,11 +27,15 @@ int audit_dupe_exe(struct audit_krule *new,
> > > > > struct
> > > > > audit_krule *old) struct audit_fsnotify_mark *audit_mark;
> > > > > 
> > > > >  	char *pathname;
> > > > > 
> > > > > -	pathname = audit_mark_path(old->exe);
> > > > > +	pathname = kstrdup(audit_mark_path(old->exe),
> > > > > GFP_KERNEL);
> > > > > +	if (!pathname)
> > > > > +		return -ENOMEM;
> > > > > 
> > > > >  	audit_mark = audit_alloc_mark(new, pathname,
> > > > > 
> > > > > strlen(pathname));
> > > > > -	if (IS_ERR(audit_mark))
> > > > > +	if (IS_ERR(audit_mark)) {
> > > > > +		kfree(pathname);
> > > > > 
> > > > >  		return PTR_ERR(audit_mark);
> > > > > 
> > > > > +	}
> > > > > 
> > > > >  	new->exe = audit_mark;
> > > > >  	
> > > > >  	return 0;
> > > > > 
> > > > > diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c
> > > > > index a4e7b16..e57e08a 100644
> > > > > --- a/kernel/audit_fsnotify.c
> > > > > +++ b/kernel/audit_fsnotify.c
> > > > > @@ -94,7 +94,6 @@ struct audit_fsnotify_mark
> > > > > *audit_alloc_mark(struct
> > > > > audit_krule *krule, char *pa struct dentry *dentry;
> > > > > 
> > > > >  	struct inode *inode;
> > > > >  	unsigned long ino;
> > > > > 
> > > > > -	char *local_pathname;
> > > > > 
> > > > >  	dev_t dev;
> > > > >  	int ret;
> > > > > 
> > > > > @@ -115,21 +114,15 @@ struct audit_fsnotify_mark
> > > > > *audit_alloc_mark(struct
> > > > > audit_krule *krule, char *pa ino = dentry->d_inode->i_ino;
> > > > > 
> > > > >  	}
> > > > > 
> > > > > -	audit_mark = ERR_PTR(-ENOMEM);
> > > > > -	local_pathname = kstrdup(pathname, GFP_KERNEL);
> > > > > -	if (!local_pathname)
> > > > > -		goto out;
> > > > > -
> > > > > 
> > > > >  	audit_mark = kzalloc(sizeof(*audit_mark), GFP_KERNEL);
> > > > >  	if (unlikely(!audit_mark)) {
> > > > > 
> > > > > -		kfree(local_pathname);
> > > > > 
> > > > >  		audit_mark = ERR_PTR(-ENOMEM);
> > > > >  		goto out;
> > > > >  	
> > > > >  	}
> > > > >  	
> > > > >  	fsnotify_init_mark(&audit_mark->mark,
> > > > > 
> > > > > audit_fsnotify_free_mark);
> > > > > 
> > > > >  	audit_mark->mark.mask = AUDIT_FS_EVENTS;
> > > > > 
> > > > > -	audit_mark->path = local_pathname;
> > > > > +	audit_mark->path = pathname;
> > > > > 
> > > > >  	audit_mark->ino = ino;
> > > > >  	audit_mark->dev = dev;
> > > > >  	audit_mark->rule = krule;
> > > > > 
> > > > > diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
> > > > > index f65c97f..f46ed69 100644
> > > > > --- a/kernel/auditfilter.c
> > > > > +++ b/kernel/auditfilter.c
> > > > > @@ -559,8 +559,8 @@ static struct audit_entry
> > > > > *audit_data_to_entry(struct
> > > > > audit_rule_data *data, entry->rule.buflen += f->val;
> > > > > 
> > > > >  			audit_mark = audit_alloc_mark(&entry
> > > > > 
> > > > > ->rule, str, f->val);
> > > > > -			kfree(str);
> > > > > 
> > > > >  			if (IS_ERR(audit_mark)) {
> > > > > 
> > > > > +				kfree(str);
> > > > > 
> > > > >  				err = PTR_ERR(audit_mark);
> > > > >  				goto exit_free;
> > > > >  			
> > > > >  			}
> 
> -- 
> paul moore
> security @ redhat
> 

- RGB

--
Richard Guy Briggs <rbriggs@redhat.com>
Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox