Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ec3b2fb authored by David Woodhouse's avatar David Woodhouse
Browse files

AUDIT: Capture sys_socketcall arguments and sockaddrs

parent 69887ac1
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -69,8 +69,9 @@
#define AUDIT_FS_WATCH		1301	/* Filesystem watch event */
#define AUDIT_PATH		1302	/* Filname path information */
#define AUDIT_IPC		1303	/* IPC record */
#define AUDIT_SOCKET		1304	/* Socket record */
#define AUDIT_SOCKETCALL	1304	/* sys_socketcall arguments */
#define AUDIT_CONFIG_CHANGE	1305	/* Audit system configuration change */
#define AUDIT_SOCKADDR		1306	/* sockaddr copied as syscall arg */

#define AUDIT_AVC		1400	/* SE Linux avc denial or grant */
#define AUDIT_SELINUX_ERR	1401	/* Internal SE Linux Errors */
@@ -235,6 +236,8 @@ extern int audit_get_stamp(struct audit_context *ctx,
extern int  audit_set_loginuid(struct task_struct *task, uid_t loginuid);
extern uid_t audit_get_loginuid(struct audit_context *ctx);
extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
extern int audit_socketcall(int nargs, unsigned long *args);
extern int audit_sockaddr(int len, void *addr);
extern void audit_signal_info(int sig, struct task_struct *t);
#else
#define audit_alloc(t) ({ 0; })
@@ -248,6 +251,8 @@ extern void audit_signal_info(int sig, struct task_struct *t);
#define audit_get_stamp(c,t,s) ({ 0; })
#define audit_get_loginuid(c) ({ -1; })
#define audit_ipc_perms(q,u,g,m) ({ 0; })
#define audit_socketcall(n,a) ({ 0; })
#define audit_sockaddr(len, addr) ({ 0; })
#define audit_signal_info(s,t) do { ; } while (0)
#endif

+71 −2
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@
#include <asm/types.h>
#include <linux/mm.h>
#include <linux/module.h>

#include <linux/socket.h>
#include <linux/audit.h>
#include <linux/personality.h>
#include <linux/time.h>
@@ -112,6 +112,18 @@ struct audit_aux_data_ipcctl {
	mode_t			mode;
};

struct audit_aux_data_socketcall {
	struct audit_aux_data	d;
	int			nargs;
	unsigned long		args[0];
};

struct audit_aux_data_sockaddr {
	struct audit_aux_data	d;
	int			len;
	char			a[0];
};


/* The per-task audit context. */
struct audit_context {
@@ -694,7 +706,22 @@ static void audit_log_exit(struct audit_context *context)
			audit_log_format(ab, 
					 " qbytes=%lx iuid=%d igid=%d mode=%x",
					 axi->qbytes, axi->uid, axi->gid, axi->mode);
			}
			break; }

		case AUDIT_SOCKETCALL: {
			int i;
			struct audit_aux_data_socketcall *axs = (void *)aux;
			audit_log_format(ab, "nargs=%d", axs->nargs);
			for (i=0; i<axs->nargs; i++)
				audit_log_format(ab, " a%d=%lx", i, axs->args[i]);
			break; }

		case AUDIT_SOCKADDR: {
			struct audit_aux_data_sockaddr *axs = (void *)aux;

			audit_log_format(ab, "saddr=");
			audit_log_hex(ab, axs->a, axs->len);
			break; }
		}
		audit_log_end(ab);

@@ -1053,6 +1080,48 @@ int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
	return 0;
}

int audit_socketcall(int nargs, unsigned long *args)
{
	struct audit_aux_data_socketcall *ax;
	struct audit_context *context = current->audit_context;

	if (likely(!context))
		return 0;

	ax = kmalloc(sizeof(*ax) + nargs * sizeof(unsigned long), GFP_KERNEL);
	if (!ax)
		return -ENOMEM;

	ax->nargs = nargs;
	memcpy(ax->args, args, nargs * sizeof(unsigned long));

	ax->d.type = AUDIT_SOCKETCALL;
	ax->d.next = context->aux;
	context->aux = (void *)ax;
	return 0;
}

int audit_sockaddr(int len, void *a)
{
	struct audit_aux_data_sockaddr *ax;
	struct audit_context *context = current->audit_context;

	if (likely(!context))
		return 0;

	ax = kmalloc(sizeof(*ax) + len, GFP_KERNEL);
	if (!ax)
		return -ENOMEM;

	ax->len = len;
	memcpy(ax->a, a, len);

	ax->d.type = AUDIT_SOCKADDR;
	ax->d.next = context->aux;
	context->aux = (void *)ax;
	return 0;
}

void audit_signal_info(int sig, struct task_struct *t)
{
	extern pid_t audit_sig_pid;
+7 −2
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@
#include <linux/syscalls.h>
#include <linux/compat.h>
#include <linux/kmod.h>
#include <linux/audit.h>

#ifdef CONFIG_NET_RADIO
#include <linux/wireless.h>		/* Note : will define WIRELESS_EXT */
@@ -226,7 +227,7 @@ int move_addr_to_kernel(void __user *uaddr, int ulen, void *kaddr)
		return 0;
	if(copy_from_user(kaddr,uaddr,ulen))
		return -EFAULT;
	return 0;
	return audit_sockaddr(ulen, kaddr);
}

/**
@@ -1907,6 +1908,10 @@ asmlinkage long sys_socketcall(int call, unsigned long __user *args)
	if (copy_from_user(a, args, nargs[call]))
		return -EFAULT;

	err = audit_socketcall(nargs[call]/sizeof(unsigned long), args);
	if (err)
		return err;

	a0=a[0];
	a1=a[1];