aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/exec.c6
-rw-r--r--include/linux/audit.h6
-rw-r--r--kernel/audit.c8
-rw-r--r--kernel/auditsc.c51
4 files changed, 67 insertions, 4 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 3a79d97ac234..d07858c0b7c4 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -49,6 +49,7 @@
49#include <linux/rmap.h> 49#include <linux/rmap.h>
50#include <linux/acct.h> 50#include <linux/acct.h>
51#include <linux/cn_proc.h> 51#include <linux/cn_proc.h>
52#include <linux/audit.h>
52 53
53#include <asm/uaccess.h> 54#include <asm/uaccess.h>
54#include <asm/mmu_context.h> 55#include <asm/mmu_context.h>
@@ -1085,6 +1086,11 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1085 /* kernel module loader fixup */ 1086 /* kernel module loader fixup */
1086 /* so we don't try to load run modprobe in kernel space. */ 1087 /* so we don't try to load run modprobe in kernel space. */
1087 set_fs(USER_DS); 1088 set_fs(USER_DS);
1089
1090 retval = audit_bprm(bprm);
1091 if (retval)
1092 return retval;
1093
1088 retval = -ENOENT; 1094 retval = -ENOENT;
1089 for (try=0; try<2; try++) { 1095 for (try=0; try<2; try++) {
1090 read_lock(&binfmt_lock); 1096 read_lock(&binfmt_lock);
diff --git a/include/linux/audit.h b/include/linux/audit.h
index e65399bf2710..1a221b65f7b7 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -83,6 +83,7 @@
83#define AUDIT_CONFIG_CHANGE 1305 /* Audit system configuration change */ 83#define AUDIT_CONFIG_CHANGE 1305 /* Audit system configuration change */
84#define AUDIT_SOCKADDR 1306 /* sockaddr copied as syscall arg */ 84#define AUDIT_SOCKADDR 1306 /* sockaddr copied as syscall arg */
85#define AUDIT_CWD 1307 /* Current working directory */ 85#define AUDIT_CWD 1307 /* Current working directory */
86#define AUDIT_EXECVE 1309 /* execve arguments */
86#define AUDIT_IPC_SET_PERM 1311 /* IPC new permissions record type */ 87#define AUDIT_IPC_SET_PERM 1311 /* IPC new permissions record type */
87 88
88#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ 89#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
@@ -283,6 +284,7 @@ struct audit_buffer;
283struct audit_context; 284struct audit_context;
284struct inode; 285struct inode;
285struct netlink_skb_parms; 286struct netlink_skb_parms;
287struct linux_binprm;
286 288
287#define AUDITSC_INVALID 0 289#define AUDITSC_INVALID 0
288#define AUDITSC_SUCCESS 1 290#define AUDITSC_SUCCESS 1
@@ -322,6 +324,7 @@ extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
322extern uid_t audit_get_loginuid(struct audit_context *ctx); 324extern uid_t audit_get_loginuid(struct audit_context *ctx);
323extern int audit_ipc_obj(struct kern_ipc_perm *ipcp); 325extern int audit_ipc_obj(struct kern_ipc_perm *ipcp);
324extern int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp); 326extern int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp);
327extern int audit_bprm(struct linux_binprm *bprm);
325extern int audit_socketcall(int nargs, unsigned long *args); 328extern int audit_socketcall(int nargs, unsigned long *args);
326extern int audit_sockaddr(int len, void *addr); 329extern int audit_sockaddr(int len, void *addr);
327extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); 330extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
@@ -342,6 +345,7 @@ extern int audit_set_macxattr(const char *name);
342#define audit_get_loginuid(c) ({ -1; }) 345#define audit_get_loginuid(c) ({ -1; })
343#define audit_ipc_obj(i) ({ 0; }) 346#define audit_ipc_obj(i) ({ 0; })
344#define audit_ipc_set_perm(q,u,g,m,i) ({ 0; }) 347#define audit_ipc_set_perm(q,u,g,m,i) ({ 0; })
348#define audit_bprm(p) ({ 0; })
345#define audit_socketcall(n,a) ({ 0; }) 349#define audit_socketcall(n,a) ({ 0; })
346#define audit_sockaddr(len, addr) ({ 0; }) 350#define audit_sockaddr(len, addr) ({ 0; })
347#define audit_avc_path(dentry, mnt) ({ 0; }) 351#define audit_avc_path(dentry, mnt) ({ 0; })
@@ -364,7 +368,7 @@ extern void audit_log_end(struct audit_buffer *ab);
364extern void audit_log_hex(struct audit_buffer *ab, 368extern void audit_log_hex(struct audit_buffer *ab,
365 const unsigned char *buf, 369 const unsigned char *buf,
366 size_t len); 370 size_t len);
367extern void audit_log_untrustedstring(struct audit_buffer *ab, 371extern const char * audit_log_untrustedstring(struct audit_buffer *ab,
368 const char *string); 372 const char *string);
369extern void audit_log_d_path(struct audit_buffer *ab, 373extern void audit_log_d_path(struct audit_buffer *ab,
370 const char *prefix, 374 const char *prefix,
diff --git a/kernel/audit.c b/kernel/audit.c
index bf74bf02aa4b..d09f131b111a 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1026,18 +1026,20 @@ void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf,
1026 * or a space. Unescaped strings will start and end with a double quote mark. 1026 * or a space. Unescaped strings will start and end with a double quote mark.
1027 * Strings that are escaped are printed in hex (2 digits per char). 1027 * Strings that are escaped are printed in hex (2 digits per char).
1028 */ 1028 */
1029void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) 1029const char *audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
1030{ 1030{
1031 const unsigned char *p = string; 1031 const unsigned char *p = string;
1032 size_t len = strlen(string);
1032 1033
1033 while (*p) { 1034 while (*p) {
1034 if (*p == '"' || *p < 0x21 || *p > 0x7f) { 1035 if (*p == '"' || *p < 0x21 || *p > 0x7f) {
1035 audit_log_hex(ab, string, strlen(string)); 1036 audit_log_hex(ab, string, len);
1036 return; 1037 return string + len + 1;
1037 } 1038 }
1038 p++; 1039 p++;
1039 } 1040 }
1040 audit_log_format(ab, "\"%s\"", string); 1041 audit_log_format(ab, "\"%s\"", string);
1042 return p + 1;
1041} 1043}
1042 1044
1043/* This is a helper-function to print the escaped d_path */ 1045/* This is a helper-function to print the escaped d_path */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 1c03a4ed1b27..114f921979ec 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -59,6 +59,7 @@
59#include <linux/list.h> 59#include <linux/list.h>
60#include <linux/tty.h> 60#include <linux/tty.h>
61#include <linux/selinux.h> 61#include <linux/selinux.h>
62#include <linux/binfmts.h>
62 63
63#include "audit.h" 64#include "audit.h"
64 65
@@ -110,6 +111,13 @@ struct audit_aux_data_ipcctl {
110 u32 osid; 111 u32 osid;
111}; 112};
112 113
114struct audit_aux_data_execve {
115 struct audit_aux_data d;
116 int argc;
117 int envc;
118 char mem[0];
119};
120
113struct audit_aux_data_socketcall { 121struct audit_aux_data_socketcall {
114 struct audit_aux_data d; 122 struct audit_aux_data d;
115 int nargs; 123 int nargs;
@@ -667,6 +675,16 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
667 kfree(ctx); 675 kfree(ctx);
668 } 676 }
669 break; } 677 break; }
678 case AUDIT_EXECVE: {
679 struct audit_aux_data_execve *axi = (void *)aux;
680 int i;
681 const char *p;
682 for (i = 0, p = axi->mem; i < axi->argc; i++) {
683 audit_log_format(ab, "a%d=", i);
684 p = audit_log_untrustedstring(ab, p);
685 audit_log_format(ab, "\n");
686 }
687 break; }
670 688
671 case AUDIT_SOCKETCALL: { 689 case AUDIT_SOCKETCALL: {
672 int i; 690 int i;
@@ -1231,6 +1249,39 @@ int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode,
1231 return 0; 1249 return 0;
1232} 1250}
1233 1251
1252int audit_bprm(struct linux_binprm *bprm)
1253{
1254 struct audit_aux_data_execve *ax;
1255 struct audit_context *context = current->audit_context;
1256 unsigned long p, next;
1257 void *to;
1258
1259 if (likely(!audit_enabled || !context))
1260 return 0;
1261
1262 ax = kmalloc(sizeof(*ax) + PAGE_SIZE * MAX_ARG_PAGES - bprm->p,
1263 GFP_KERNEL);
1264 if (!ax)
1265 return -ENOMEM;
1266
1267 ax->argc = bprm->argc;
1268 ax->envc = bprm->envc;
1269 for (p = bprm->p, to = ax->mem; p < MAX_ARG_PAGES*PAGE_SIZE; p = next) {
1270 struct page *page = bprm->page[p / PAGE_SIZE];
1271 void *kaddr = kmap(page);
1272 next = (p + PAGE_SIZE) & ~(PAGE_SIZE - 1);
1273 memcpy(to, kaddr + (p & (PAGE_SIZE - 1)), next - p);
1274 to += next - p;
1275 kunmap(page);
1276 }
1277
1278 ax->d.type = AUDIT_EXECVE;
1279 ax->d.next = context->aux;
1280 context->aux = (void *)ax;
1281 return 0;
1282}
1283
1284
1234/** 1285/**
1235 * audit_socketcall - record audit data for sys_socketcall 1286 * audit_socketcall - record audit data for sys_socketcall
1236 * @nargs: number of args 1287 * @nargs: number of args