execve argument logging
Subsystems (3)
PATCH 1/1 execve argument logging
fs/exec.c +6 -0
@@ -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);
include/linux/audit.h +5 -1
@@ -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 taextern 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 auextern 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,
kernel/audit.c +5 -3
@@ -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 */
kernel/auditsc.c +51 -0
75 lines not on this page · raw message
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
Quoted 10 lines · Steve Grubb
To give some background...we have this open bugzilla:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=168285It 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?
Quoted 2 lines · On Fri, Apr 21, 2006 at 04:19:09PM -0400, [email protected] 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.
Quoted 7 lines · Alexander Viro
Quoted 2 lines · On Fri, Apr 21, 2006 at 04:19:09PM -0400, [email protected] 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 = 4max_log_file = 5max_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?
Quoted 2 lines · On Friday 21 April 2006 17:22, [email protected] 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
Quoted 3 lines · Steve Grubb
-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>
:)
Quoted 3 lines · On Friday 21 April 2006 16:19, [email protected] 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.
Quoted 2 lines
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