diff options
| author | Steve Grubb <sgrubb@redhat.com> | 2007-04-19 10:28:21 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2007-05-11 05:38:26 -0400 |
| commit | 0a4ff8c2598b72f2fa9d50aae9e1809e684dbf41 (patch) | |
| tree | 309f2b2b5874692302862534cd9052a1d96018ba | |
| parent | 5712e88f2b0f626a4857c24128810bbf8ce09537 (diff) | |
[PATCH] Abnormal End of Processes
Hi,
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>
| -rw-r--r-- | fs/exec.c | 2 | ||||
| -rw-r--r-- | include/linux/audit.h | 3 | ||||
| -rw-r--r-- | kernel/auditsc.c | 39 |
3 files changed, 44 insertions, 0 deletions
| @@ -1488,6 +1488,8 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
| 1488 | int flag = 0; | 1488 | int flag = 0; |
| 1489 | int ispipe = 0; | 1489 | int ispipe = 0; |
| 1490 | 1490 | ||
| 1491 | audit_core_dumps(signr); | ||
| 1492 | |||
| 1491 | binfmt = current->binfmt; | 1493 | binfmt = current->binfmt; |
| 1492 | if (!binfmt || !binfmt->core_dump) | 1494 | if (!binfmt || !binfmt->core_dump) |
| 1493 | goto fail; | 1495 | goto fail; |
diff --git a/include/linux/audit.h b/include/linux/audit.h index 22976ddbd264..fccc6e50298a 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
| @@ -112,6 +112,7 @@ | |||
| 112 | #define AUDIT_FIRST_KERN_ANOM_MSG 1700 | 112 | #define AUDIT_FIRST_KERN_ANOM_MSG 1700 |
| 113 | #define AUDIT_LAST_KERN_ANOM_MSG 1799 | 113 | #define AUDIT_LAST_KERN_ANOM_MSG 1799 |
| 114 | #define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */ | 114 | #define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */ |
| 115 | #define AUDIT_ANOM_ABEND 1701 /* Process ended abnormally */ | ||
| 115 | 116 | ||
| 116 | #define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */ | 117 | #define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */ |
| 117 | 118 | ||
| @@ -377,6 +378,7 @@ static inline void audit_inode_child(const char *dname, | |||
| 377 | if (unlikely(!audit_dummy_context())) | 378 | if (unlikely(!audit_dummy_context())) |
| 378 | __audit_inode_child(dname, inode, parent); | 379 | __audit_inode_child(dname, inode, parent); |
| 379 | } | 380 | } |
| 381 | void audit_core_dumps(long signr); | ||
| 380 | 382 | ||
| 381 | static inline void audit_ptrace(struct task_struct *t) | 383 | static inline void audit_ptrace(struct task_struct *t) |
| 382 | { | 384 | { |
| @@ -467,6 +469,7 @@ extern int audit_signals; | |||
| 467 | #define __audit_inode_child(d,i,p) do { ; } while (0) | 469 | #define __audit_inode_child(d,i,p) do { ; } while (0) |
| 468 | #define audit_inode(n,i) do { ; } while (0) | 470 | #define audit_inode(n,i) do { ; } while (0) |
| 469 | #define audit_inode_child(d,i,p) do { ; } while (0) | 471 | #define audit_inode_child(d,i,p) do { ; } while (0) |
| 472 | #define audit_core_dumps(i) do { ; } while (0) | ||
| 470 | #define auditsc_get_stamp(c,t,s) do { BUG(); } while (0) | 473 | #define auditsc_get_stamp(c,t,s) do { BUG(); } while (0) |
| 471 | #define audit_get_loginuid(c) ({ -1; }) | 474 | #define audit_get_loginuid(c) ({ -1; }) |
| 472 | #define audit_log_task_context(b) do { ; } while (0) | 475 | #define audit_log_task_context(b) do { ; } while (0) |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 5276b7ef05f1..e36481ed61b4 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -2037,3 +2037,42 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
| 2037 | 2037 | ||
| 2038 | return 0; | 2038 | return 0; |
| 2039 | } | 2039 | } |
| 2040 | |||
| 2041 | /** | ||
| 2042 | * audit_core_dumps - record information about processes that end abnormally | ||
| 2043 | * @sig: signal value | ||
| 2044 | * | ||
| 2045 | * If a process ends with a core dump, something fishy is going on and we | ||
| 2046 | * should record the event for investigation. | ||
| 2047 | */ | ||
| 2048 | void audit_core_dumps(long signr) | ||
| 2049 | { | ||
| 2050 | struct audit_buffer *ab; | ||
| 2051 | u32 sid; | ||
| 2052 | |||
| 2053 | if (!audit_enabled) | ||
| 2054 | return; | ||
| 2055 | |||
| 2056 | if (signr == SIGQUIT) /* don't care for those */ | ||
| 2057 | return; | ||
| 2058 | |||
| 2059 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); | ||
| 2060 | audit_log_format(ab, "auid=%u uid=%u gid=%u", | ||
| 2061 | audit_get_loginuid(current->audit_context), | ||
| 2062 | current->uid, current->gid); | ||
| 2063 | selinux_get_task_sid(current, &sid); | ||
| 2064 | if (sid) { | ||
| 2065 | char *ctx = NULL; | ||
| 2066 | u32 len; | ||
| 2067 | |||
| 2068 | if (selinux_sid_to_string(sid, &ctx, &len)) | ||
| 2069 | audit_log_format(ab, " ssid=%u", sid); | ||
| 2070 | else | ||
| 2071 | audit_log_format(ab, " subj=%s", ctx); | ||
| 2072 | kfree(ctx); | ||
| 2073 | } | ||
| 2074 | audit_log_format(ab, " pid=%d comm=", current->pid); | ||
| 2075 | audit_log_untrustedstring(ab, current->comm); | ||
| 2076 | audit_log_format(ab, " sig=%ld", signr); | ||
| 2077 | audit_log_end(ab); | ||
| 2078 | } | ||
