* [PATCH] execve argument logging
@ 2006-04-21 11:33 Alexander Viro
2006-04-21 13:20 ` Steve Grubb
0 siblings, 1 reply; 8+ messages in thread
From: Alexander Viro @ 2006-04-21 11:33 UTC (permalink / raw)
To: linux-audit
diff --git a/fs/exec.c b/fs/exec.c
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -49,6 +49,7 @@
#include <linux/rmap.h>
#include <linux/acct.h>
#include <linux/cn_proc.h>
+#include <linux/audit.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
@@ -1085,6 +1086,11 @@ int search_binary_handler(struct linux_b
/* kernel module loader fixup */
/* so we don't try to load run modprobe in kernel space. */
set_fs(USER_DS);
+
+ retval = audit_bprm(bprm);
+ if (retval)
+ return retval;
+
retval = -ENOENT;
for (try=0; try<2; try++) {
read_lock(&binfmt_lock);
diff --git a/include/linux/audit.h b/include/linux/audit.h
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -83,6 +83,7 @@
#define AUDIT_CONFIG_CHANGE 1305 /* Audit system configuration change */
#define AUDIT_SOCKADDR 1306 /* sockaddr copied as syscall arg */
#define AUDIT_CWD 1307 /* Current working directory */
+#define AUDIT_EXECVE 1309 /* execve arguments */
#define AUDIT_IPC_SET_PERM 1311 /* IPC new permissions record type */
#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
@@ -283,6 +284,7 @@ struct audit_buffer;
struct audit_context;
struct inode;
struct netlink_skb_parms;
+struct linux_binprm;
#define AUDITSC_INVALID 0
#define AUDITSC_SUCCESS 1
@@ -322,6 +324,7 @@ extern int audit_set_loginuid(struct ta
extern uid_t audit_get_loginuid(struct audit_context *ctx);
extern int audit_ipc_obj(struct kern_ipc_perm *ipcp);
extern int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp);
+extern int audit_bprm(struct linux_binprm *bprm);
extern int audit_socketcall(int nargs, unsigned long *args);
extern int audit_sockaddr(int len, void *addr);
extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
@@ -342,6 +345,7 @@ extern int audit_set_macxattr(const char
#define audit_get_loginuid(c) ({ -1; })
#define audit_ipc_obj(i) ({ 0; })
#define audit_ipc_set_perm(q,u,g,m,i) ({ 0; })
+#define audit_bprm(p) ({ 0; })
#define audit_socketcall(n,a) ({ 0; })
#define audit_sockaddr(len, addr) ({ 0; })
#define audit_avc_path(dentry, mnt) ({ 0; })
@@ -364,7 +368,7 @@ extern void audit_log_end(struct au
extern void audit_log_hex(struct audit_buffer *ab,
const unsigned char *buf,
size_t len);
-extern void audit_log_untrustedstring(struct audit_buffer *ab,
+extern const char * audit_log_untrustedstring(struct audit_buffer *ab,
const char *string);
extern void audit_log_d_path(struct audit_buffer *ab,
const char *prefix,
diff --git a/kernel/audit.c b/kernel/audit.c
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -998,18 +998,20 @@ void audit_log_hex(struct audit_buffer *
* or a space. Unescaped strings will start and end with a double quote mark.
* Strings that are escaped are printed in hex (2 digits per char).
*/
-void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
+const char *audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
{
const unsigned char *p = string;
+ size_t len = strlen(string);
while (*p) {
if (*p == '"' || *p < 0x21 || *p > 0x7f) {
- audit_log_hex(ab, string, strlen(string));
- return;
+ audit_log_hex(ab, string, len);
+ return string + len + 1;
}
p++;
}
audit_log_format(ab, "\"%s\"", string);
+ return p + 1;
}
/* This is a helper-function to print the escaped d_path */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -59,6 +59,7 @@
#include <linux/list.h>
#include <linux/tty.h>
#include <linux/selinux.h>
+#include <linux/binfmts.h>
#include "audit.h"
@@ -110,6 +111,13 @@ struct audit_aux_data_ipcctl {
u32 osid;
};
+struct audit_aux_data_execve {
+ struct audit_aux_data d;
+ int argc;
+ int envc;
+ char mem[0];
+};
+
struct audit_aux_data_socketcall {
struct audit_aux_data d;
int nargs;
@@ -667,6 +675,16 @@ static void audit_log_exit(struct audit_
kfree(ctx);
}
break; }
+ case AUDIT_EXECVE: {
+ struct audit_aux_data_execve *axi = (void *)aux;
+ int i;
+ char *p;
+ for (i = 0, p = axi->mem; i < axi->argc; i++) {
+ audit_log_format(ab, "a%d=", i);
+ p = audit_log_untrustedstring(ab, p);
+ audit_log_format(ab, "\n");
+ }
+ break; }
case AUDIT_SOCKETCALL: {
int i;
@@ -1231,6 +1249,39 @@ int audit_ipc_set_perm(unsigned long qby
return 0;
}
+int audit_bprm(struct linux_binprm *bprm)
+{
+ struct audit_aux_data_execve *ax;
+ struct audit_context *context = current->audit_context;
+ unsigned long p, next;
+ void *to;
+
+ if (likely(!audit_enabled || !context))
+ return 0;
+
+ ax = kmalloc(sizeof(*ax) + PAGE_SIZE * MAX_ARG_PAGES - bprm->p,
+ GFP_KERNEL);
+ if (!ax)
+ return -ENOMEM;
+
+ ax->argc = bprm->argc;
+ ax->envc = bprm->envc;
+ for (p = bprm->p, to = ax->mem; p < MAX_ARG_PAGES*PAGE_SIZE; p = next) {
+ struct page *page = bprm->page[p / PAGE_SIZE];
+ void *kaddr = kmap(page);
+ next = (p + PAGE_SIZE) & ~(PAGE_SIZE - 1);
+ memcpy(to, kaddr + (p & (PAGE_SIZE - 1)), next - p);
+ to += next - p;
+ kunmap(page);
+ }
+
+ ax->d.type = AUDIT_EXECVE;
+ ax->d.next = context->aux;
+ context->aux = (void *)ax;
+ return 0;
+}
+
+
/**
* audit_socketcall - record audit data for sys_socketcall
* @nargs: number of args
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] execve argument logging
2006-04-21 11:33 [PATCH] execve argument logging Alexander Viro
@ 2006-04-21 13:20 ` Steve Grubb
2006-04-21 20:19 ` Valdis.Kletnieks
0 siblings, 1 reply; 8+ messages in thread
From: Steve Grubb @ 2006-04-21 13:20 UTC (permalink / raw)
To: linux-audit
Al,
Thanks for posting this.
Amy,
To give some background...we have this open bugzilla:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=168285
It was agreed last summer that this would be useful for people. It has nothing
to do with CAPP certification, so it was put on the back burner. No one had
the time to complete it until now. What the patch does is collect the string
arguments to execve and logs them as an auxiliary record. It was also put
onto linux-audit mail list as a proposal, item #1 here:
https://www.redhat.com/archives/linux-audit/2005-September/msg00061.html
Hope this helps...
-Steve
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] execve argument logging
2006-04-21 13:20 ` Steve Grubb
@ 2006-04-21 20:19 ` Valdis.Kletnieks
2006-04-21 20:22 ` Alexander Viro
2006-04-21 20:23 ` Steve Grubb
0 siblings, 2 replies; 8+ messages in thread
From: Valdis.Kletnieks @ 2006-04-21 20:19 UTC (permalink / raw)
To: Steve Grubb; +Cc: linux-audit
[-- Attachment #1.1: Type: text/plain, Size: 895 bytes --]
On Fri, 21 Apr 2006 09:20:10 EDT, Steve Grubb said:
> To give some background...we have this open bugzilla:
> https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=168285
>
> It was agreed last summer that this would be useful for people. It has nothing
> to do with CAPP certification, so it was put on the back burner. No one had
> the time to complete it until now. What the patch does is collect the string
> arguments to execve and logs them as an auxiliary record. It was also put
> onto linux-audit mail list as a proposal, item #1 here:
>
> https://www.redhat.com/archives/linux-audit/2005-September/msg00061.html
Does this allow an attacker to DoS the audit log by creating a fork/exec loop
intentionally invoking a totally duff binary, but that includes a very long argument?
Maybe a "first 32/64 bytes of each argument" limit is needed? Or is there one
there and I missed it?
[-- Attachment #1.2: Type: application/pgp-signature, Size: 226 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] execve argument logging
2006-04-21 20:19 ` Valdis.Kletnieks
@ 2006-04-21 20:22 ` Alexander Viro
2006-04-21 21:22 ` Valdis.Kletnieks
2006-04-21 20:23 ` Steve Grubb
1 sibling, 1 reply; 8+ messages in thread
From: Alexander Viro @ 2006-04-21 20:22 UTC (permalink / raw)
To: Valdis.Kletnieks; +Cc: linux-audit
On Fri, Apr 21, 2006 at 04:19:09PM -0400, Valdis.Kletnieks@vt.edu wrote:
> Maybe a "first 32/64 bytes of each argument" limit is needed? Or is there one
> there and I missed it?
You do realize that it makes e.g. any pathname arguments in effect not
logged at all - just slap 64 '/' in front of absolute pathname and you
are done.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] execve argument logging
2006-04-21 20:19 ` Valdis.Kletnieks
2006-04-21 20:22 ` Alexander Viro
@ 2006-04-21 20:23 ` Steve Grubb
1 sibling, 0 replies; 8+ messages in thread
From: Steve Grubb @ 2006-04-21 20:23 UTC (permalink / raw)
To: Valdis.Kletnieks; +Cc: linux-audit
On Friday 21 April 2006 16:19, Valdis.Kletnieks@vt.edu wrote:
> Does this allow an attacker to DoS the audit log by creating a fork/exec
> loop intentionally invoking a totally duff binary, but that includes a very
> long argument?
I personally haven't tried. Try it and let us know if you can DoS the machine.
> Maybe a "first 32/64 bytes of each argument" limit is needed? Or is there
> one there and I missed it?
There's no limit other than what the kernel imposes.
-Steve
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] execve argument logging
2006-04-21 20:22 ` Alexander Viro
@ 2006-04-21 21:22 ` Valdis.Kletnieks
2006-04-21 23:44 ` Steve Grubb
0 siblings, 1 reply; 8+ messages in thread
From: Valdis.Kletnieks @ 2006-04-21 21:22 UTC (permalink / raw)
To: Alexander Viro; +Cc: linux-audit
[-- Attachment #1.1: Type: text/plain, Size: 1878 bytes --]
On Fri, 21 Apr 2006 16:22:35 EDT, Alexander Viro said:
> On Fri, Apr 21, 2006 at 04:19:09PM -0400, Valdis.Kletnieks@vt.edu wrote:
> > Maybe a "first 32/64 bytes of each argument" limit is needed? Or is there one
> > there and I missed it?
>
> You do realize that it makes e.g. any pathname arguments in effect not
> logged at all - just slap 64 '/' in front of absolute pathname and you
> are done.
On the other hand, the 2.6.17-rc1-mm3 kernel I'm on now has:
include/linux/limits.h:#define ARG_MAX 131072 /* # bytes of args + environ for exec() */
which implies to me that I can blat a bit over 128K to the audit log per syscall.
With the default Fedora-rawhide auditd.conf config of:
num_logs = 4
max_log_file = 5
max_log_file_action = ROTATE
I can roll through all the logs and *effectively* make the arguments of whatever
I wanted to hide not visible with only 160 syscalls. 'man auditd.conf' says:
Space_left should be set to a number that gives the admin enough time
to react to any alert message and perform some maintenance to free up
disk space. This would typically involve running the aureport -t report
and moving the oldest logs to an archive area. The value of space_left
is site dependant since the rate at which events are generated varies
with each deployment. The space_left_action is recommended to be set to
email.
(And yes, I know if you're *serious* about this, you have action set to 'single'
or 'halt' or similar "die rather than lose records" setting. The problem is that
when you can blow through a megabyte of logspace with only 8 syscalls, finding a
good setting for "gives enough time" becomes a lot more challenging...)
How would everybody feel about wrapping this in a CONFIG_AUDIT_ARGV, and some
Kconfig wording warning about this burning through your audit space?
[-- Attachment #1.2: Type: application/pgp-signature, Size: 226 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] execve argument logging
2006-04-21 21:22 ` Valdis.Kletnieks
@ 2006-04-21 23:44 ` Steve Grubb
2006-04-22 1:05 ` Valdis.Kletnieks
0 siblings, 1 reply; 8+ messages in thread
From: Steve Grubb @ 2006-04-21 23:44 UTC (permalink / raw)
To: linux-audit; +Cc: Valdis.Kletnieks
On Friday 21 April 2006 17:22, Valdis.Kletnieks@vt.edu wrote:
> which implies to me that I can blat a bit over 128K to the audit log per
> syscall.
Users can do this already. Maybe not as quickly, but they can certainly fill
up your logs if they feel like it. If you do not want this message type in
your logs, then use this in your audit rules:
-a always,exclude -F msgtype=EXECVE
Problem Solved (tm).
-Steve
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] execve argument logging
2006-04-21 23:44 ` Steve Grubb
@ 2006-04-22 1:05 ` Valdis.Kletnieks
0 siblings, 0 replies; 8+ messages in thread
From: Valdis.Kletnieks @ 2006-04-22 1:05 UTC (permalink / raw)
To: Steve Grubb; +Cc: linux-audit
[-- Attachment #1.1: Type: text/plain, Size: 374 bytes --]
On Fri, 21 Apr 2006 19:44:55 EDT, Steve Grubb said:
> -a always,exclude -F msgtype=EXECVE
>
> Problem Solved (tm).
Damn, I read the patch over like 3 times, and didn't twig into it using
AUDIT_EXECVE (1309) - I managed to convince myself this was an expansion of the
record cut for the execve under AUDIT_SYSCALL (1300).
<mode="Emily Litella">
Nevermind...
</mode>
:)
[-- Attachment #1.2: Type: application/pgp-signature, Size: 226 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2006-04-22 1:05 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-04-21 11:33 [PATCH] execve argument logging Alexander Viro
2006-04-21 13:20 ` Steve Grubb
2006-04-21 20:19 ` Valdis.Kletnieks
2006-04-21 20:22 ` Alexander Viro
2006-04-21 21:22 ` Valdis.Kletnieks
2006-04-21 23:44 ` Steve Grubb
2006-04-22 1:05 ` Valdis.Kletnieks
2006-04-21 20:23 ` Steve Grubb
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox