[PATCH] execve argument logging
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
9044e6bca5
commit
473ae30bc7
|
@ -49,6 +49,7 @@
|
||||||
#include <linux/rmap.h>
|
#include <linux/rmap.h>
|
||||||
#include <linux/acct.h>
|
#include <linux/acct.h>
|
||||||
#include <linux/cn_proc.h>
|
#include <linux/cn_proc.h>
|
||||||
|
#include <linux/audit.h>
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/mmu_context.h>
|
#include <asm/mmu_context.h>
|
||||||
|
@ -1085,6 +1086,11 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
|
||||||
/* kernel module loader fixup */
|
/* kernel module loader fixup */
|
||||||
/* so we don't try to load run modprobe in kernel space. */
|
/* so we don't try to load run modprobe in kernel space. */
|
||||||
set_fs(USER_DS);
|
set_fs(USER_DS);
|
||||||
|
|
||||||
|
retval = audit_bprm(bprm);
|
||||||
|
if (retval)
|
||||||
|
return retval;
|
||||||
|
|
||||||
retval = -ENOENT;
|
retval = -ENOENT;
|
||||||
for (try=0; try<2; try++) {
|
for (try=0; try<2; try++) {
|
||||||
read_lock(&binfmt_lock);
|
read_lock(&binfmt_lock);
|
||||||
|
|
|
@ -83,6 +83,7 @@
|
||||||
#define AUDIT_CONFIG_CHANGE 1305 /* Audit system configuration change */
|
#define AUDIT_CONFIG_CHANGE 1305 /* Audit system configuration change */
|
||||||
#define AUDIT_SOCKADDR 1306 /* sockaddr copied as syscall arg */
|
#define AUDIT_SOCKADDR 1306 /* sockaddr copied as syscall arg */
|
||||||
#define AUDIT_CWD 1307 /* Current working directory */
|
#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_IPC_SET_PERM 1311 /* IPC new permissions record type */
|
||||||
|
|
||||||
#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
|
#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
|
||||||
|
@ -283,6 +284,7 @@ struct audit_buffer;
|
||||||
struct audit_context;
|
struct audit_context;
|
||||||
struct inode;
|
struct inode;
|
||||||
struct netlink_skb_parms;
|
struct netlink_skb_parms;
|
||||||
|
struct linux_binprm;
|
||||||
|
|
||||||
#define AUDITSC_INVALID 0
|
#define AUDITSC_INVALID 0
|
||||||
#define AUDITSC_SUCCESS 1
|
#define AUDITSC_SUCCESS 1
|
||||||
|
@ -322,6 +324,7 @@ extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
|
||||||
extern uid_t audit_get_loginuid(struct audit_context *ctx);
|
extern uid_t audit_get_loginuid(struct audit_context *ctx);
|
||||||
extern int audit_ipc_obj(struct kern_ipc_perm *ipcp);
|
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_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_socketcall(int nargs, unsigned long *args);
|
||||||
extern int audit_sockaddr(int len, void *addr);
|
extern int audit_sockaddr(int len, void *addr);
|
||||||
extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
|
extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
|
||||||
|
@ -342,6 +345,7 @@ extern int audit_set_macxattr(const char *name);
|
||||||
#define audit_get_loginuid(c) ({ -1; })
|
#define audit_get_loginuid(c) ({ -1; })
|
||||||
#define audit_ipc_obj(i) ({ 0; })
|
#define audit_ipc_obj(i) ({ 0; })
|
||||||
#define audit_ipc_set_perm(q,u,g,m,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_socketcall(n,a) ({ 0; })
|
||||||
#define audit_sockaddr(len, addr) ({ 0; })
|
#define audit_sockaddr(len, addr) ({ 0; })
|
||||||
#define audit_avc_path(dentry, mnt) ({ 0; })
|
#define audit_avc_path(dentry, mnt) ({ 0; })
|
||||||
|
@ -364,7 +368,7 @@ extern void audit_log_end(struct audit_buffer *ab);
|
||||||
extern void audit_log_hex(struct audit_buffer *ab,
|
extern void audit_log_hex(struct audit_buffer *ab,
|
||||||
const unsigned char *buf,
|
const unsigned char *buf,
|
||||||
size_t len);
|
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);
|
const char *string);
|
||||||
extern void audit_log_d_path(struct audit_buffer *ab,
|
extern void audit_log_d_path(struct audit_buffer *ab,
|
||||||
const char *prefix,
|
const char *prefix,
|
||||||
|
|
|
@ -1026,18 +1026,20 @@ void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf,
|
||||||
* or a space. Unescaped strings will start and end with a double quote mark.
|
* 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).
|
* 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;
|
const unsigned char *p = string;
|
||||||
|
size_t len = strlen(string);
|
||||||
|
|
||||||
while (*p) {
|
while (*p) {
|
||||||
if (*p == '"' || *p < 0x21 || *p > 0x7f) {
|
if (*p == '"' || *p < 0x21 || *p > 0x7f) {
|
||||||
audit_log_hex(ab, string, strlen(string));
|
audit_log_hex(ab, string, len);
|
||||||
return;
|
return string + len + 1;
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
audit_log_format(ab, "\"%s\"", string);
|
audit_log_format(ab, "\"%s\"", string);
|
||||||
|
return p + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a helper-function to print the escaped d_path */
|
/* This is a helper-function to print the escaped d_path */
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/tty.h>
|
#include <linux/tty.h>
|
||||||
#include <linux/selinux.h>
|
#include <linux/selinux.h>
|
||||||
|
#include <linux/binfmts.h>
|
||||||
|
|
||||||
#include "audit.h"
|
#include "audit.h"
|
||||||
|
|
||||||
|
@ -110,6 +111,13 @@ struct audit_aux_data_ipcctl {
|
||||||
u32 osid;
|
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_socketcall {
|
||||||
struct audit_aux_data d;
|
struct audit_aux_data d;
|
||||||
int nargs;
|
int nargs;
|
||||||
|
@ -667,6 +675,16 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
|
||||||
kfree(ctx);
|
kfree(ctx);
|
||||||
}
|
}
|
||||||
break; }
|
break; }
|
||||||
|
case AUDIT_EXECVE: {
|
||||||
|
struct audit_aux_data_execve *axi = (void *)aux;
|
||||||
|
int i;
|
||||||
|
const 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: {
|
case AUDIT_SOCKETCALL: {
|
||||||
int i;
|
int i;
|
||||||
|
@ -1231,6 +1249,39 @@ int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode,
|
||||||
return 0;
|
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
|
* audit_socketcall - record audit data for sys_socketcall
|
||||||
* @nargs: number of args
|
* @nargs: number of args
|
||||||
|
|
Loading…
Reference in New Issue