Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 205

kernel-2.6.18-238.el5.src.rpm

From: Eric Paris <eparis@redhat.com>
Date: Mon, 1 Oct 2007 17:52:57 -0400
Subject: [audit] collect events for segfaulting programs
Message-id: 1191275577.9506.5.camel@localhost.localdomain
O-Subject: [PATCH RHEL5.2] BZ 239061 - audit segfaulting programs
Bugzilla: 239061

BZ 239061

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=0a4ff8c2598b72f2fa9d50aae9e1809e684dbf41

Upsteam commit log:

I have been working on some code that detects abnormal events based on audit
system events. One kind of event that we currently have no visibility for is
when a program terminates due to segfault - which should never happen on a
production machine. And if it did, you'd want to investigate it. Attached is a
patch that collects these events and sends them into the audit system.

Signed-off-by: Steve Grubb <sgrubb@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

I tested this patch against a RHEL5 kernel and it appears to work:
[root@nec-em8 ~]# cat core.c
int main (void)
{
        int i[10];
        int j;
        for (j = 0; j < 100; j++) {
                i[j] = j;
        }
        return j;
}
[root@nec-em8 ~]# ./core
Segmentation fault
[root@nec-em8 ~]# cat /var/log/audit/audit.log

type=ANOM_ABEND msg=audit(1191275049.320:14): auid=0 uid=0 gid=0 subj=root:system_r:unconfined_t:s0-s0:c0.c1023 pid=4463 comm="core" sig=11

-Eric

Acked-by: James Morris <jmorris@redhat.com>
---
 fs/exec.c               |    2 ++
 include/linux/audit.h   |    3 +++
 include/linux/selinux.h |    1 +
 kernel/auditsc.c        |   39 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index a06b4fe..53e057b 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1467,6 +1467,8 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
 	int fsuid = current->fsuid;
 	int flag = 0;
 
+	audit_core_dumps(signr);
+
 	binfmt = current->binfmt;
 	if (!binfmt || !binfmt->core_dump)
 		goto fail;
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 961a823..1ab1314 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -112,6 +112,7 @@
 #define AUDIT_FIRST_KERN_ANOM_MSG   1700
 #define AUDIT_LAST_KERN_ANOM_MSG    1799
 #define AUDIT_ANOM_PROMISCUOUS      1700 /* Device changed promiscuous mode */
+#define AUDIT_ANOM_ABEND            1701 /* Process ended abnormally */
 
 #define AUDIT_KERNEL		2000	/* Asynchronous audit record. NOT A REQUEST. */
 
@@ -382,6 +383,7 @@ static inline void audit_inode_child(const char *dname,
 	if (unlikely(!audit_dummy_context()))
 		__audit_inode_child(dname, inode, parent);
 }
+void audit_core_dumps(long signr);
 
 static inline void audit_ptrace(struct task_struct *t)
 {
@@ -464,6 +466,7 @@ extern int audit_signals;
 #define __audit_inode_child(d,i,p) do { ; } while (0)
 #define audit_inode(n,d) do { ; } while (0)
 #define audit_inode_child(d,i,p) do { ; } while (0)
+#define audit_core_dumps(i) do { ; } while (0)
 #define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
 #define audit_get_loginuid(c) ({ -1; })
 #define audit_log_task_context(b) do { ; } while (0)
diff --git a/include/linux/selinux.h b/include/linux/selinux.h
index aad4e39..5939133 100644
--- a/include/linux/selinux.h
+++ b/include/linux/selinux.h
@@ -90,6 +90,7 @@ void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid);
  *     kfree() on it after use.
  */
 int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen);
+#define selinux_sid_to_string(sid,ctx,ctxlen) selinux_ctxid_to_string((sid),(ctx),(ctxlen))
 
 /**
  *     selinux_get_inode_sid - get the inode's security context ID
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 4d8c9f3..7fec531 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -2165,3 +2165,42 @@ int __audit_signal_info(int sig, struct task_struct *t)
 
 	return 0;
 }
+
+/**
+ * audit_core_dumps - record information about processes that end abnormally
+ * @sig: signal value
+ *
+ * If a process ends with a core dump, something fishy is going on and we
+ * should record the event for investigation.
+ */
+void audit_core_dumps(long signr)
+{
+	struct audit_buffer *ab;
+	u32 sid;
+
+	if (!audit_enabled)
+		return;
+
+	if (signr == SIGQUIT)	/* don't care for those */
+		return;
+
+	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
+	audit_log_format(ab, "auid=%u uid=%u gid=%u",
+			audit_get_loginuid(current->audit_context),
+			current->uid, current->gid);
+	selinux_get_task_sid(current, &sid);
+	if (sid) {
+		char *ctx = NULL;
+		u32 len;
+
+		if (selinux_sid_to_string(sid, &ctx, &len))
+			audit_log_format(ab, " ssid=%u", sid);
+		else
+			audit_log_format(ab, " subj=%s", ctx);
+		kfree(ctx);
+	}
+	audit_log_format(ab, " pid=%d comm=", current->pid);
+	audit_log_untrustedstring(ab, current->comm);
+	audit_log_format(ab, " sig=%ld", signr);
+	audit_log_end(ab);
+}
-- 
1.5.3.5.645.gbb47