public inbox for linux-audit@redhat.com
 help / color / mirror / Atom feed
* [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