[PATCH] auditing ptrace

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 773e30d..f93ce78 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -91,6 +91,7 @@
 #define AUDIT_MQ_GETSETATTR	1315	/* POSIX MQ get/set attribute record type */
 #define AUDIT_KERNEL_OTHER	1316	/* For use by 3rd party modules */
 #define AUDIT_FD_PAIR		1317    /* audit record for pipe/socketpair */
+#define AUDIT_OBJ_PID		1318	/* ptrace target */
 
 #define AUDIT_AVC		1400	/* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR	1401	/* Internal SE Linux Errors */
@@ -352,6 +353,8 @@
 extern void __audit_inode_child(const char *dname, const struct inode *inode,
 				const struct inode *parent);
 extern void __audit_inode_update(const struct inode *inode);
+extern void __audit_ptrace(struct task_struct *t);
+
 static inline int audit_dummy_context(void)
 {
 	void *p = current->audit_context;
@@ -377,6 +380,12 @@
 		__audit_inode_update(inode);
 }
 
+static inline void audit_ptrace(struct task_struct *t)
+{
+	if (unlikely(!audit_dummy_context()))
+		__audit_ptrace(t);
+}
+
 				/* Private API (for audit.c only) */
 extern unsigned int audit_serial(void);
 extern void auditsc_get_stamp(struct audit_context *ctx,
@@ -477,6 +486,7 @@
 #define audit_mq_timedreceive(d,l,p,t) ({ 0; })
 #define audit_mq_notify(d,n) ({ 0; })
 #define audit_mq_getsetattr(d,s) ({ 0; })
+#define audit_ptrace(t) ((void)0)
 #define audit_n_rules 0
 #endif
 
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 628c7ac..2243c55 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -209,6 +209,9 @@
 	unsigned long	    personality;
 	int		    arch;
 
+	pid_t		    target_pid;
+	u32		    target_sid;
+
 #if AUDIT_DEBUG
 	int		    put_count;
 	int		    ino_count;
@@ -973,6 +976,23 @@
 		audit_log_end(ab);
 	}
 
+	if (context->target_pid) {
+		ab =audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
+		if (ab) {
+			char *s = NULL, *t;
+			u32 len;
+			if (selinux_sid_to_string(context->target_sid,
+						    &s, &len))
+				t = "(none)";
+			else
+				t = s;
+			audit_log_format(ab, "opid=%d obj=%s",
+					context->target_pid, t);
+			audit_log_end(ab);
+			kfree(s);
+		}
+	}
+
 	if (context->pwd && context->pwdmnt) {
 		ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
 		if (ab) {
@@ -1193,6 +1213,7 @@
 	} else {
 		audit_free_names(context);
 		audit_free_aux(context);
+		context->target_pid = 0;
 		kfree(context->filterkey);
 		context->filterkey = NULL;
 		tsk->audit_context = context;
@@ -1880,6 +1901,14 @@
 	return 0;
 }
 
+void __audit_ptrace(struct task_struct *t)
+{
+	struct audit_context *context = current->audit_context;
+
+	context->target_pid = t->pid;
+	selinux_get_task_sid(t, &context->target_sid);
+}
+
 /**
  * audit_avc_path - record the granting or denial of permissions
  * @dentry: dentry to record
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 4d50e06..ad7949a 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -18,6 +18,7 @@
 #include <linux/ptrace.h>
 #include <linux/security.h>
 #include <linux/signal.h>
+#include <linux/audit.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -161,6 +162,8 @@
 {
 	int retval;
 
+	audit_ptrace(task);
+
 	retval = -EPERM;
 	if (task->pid <= 1)
 		goto out;