Commit a5cb013d authored by Al Viro's avatar Al Viro

[PATCH] auditing ptrace

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 129a84de
...@@ -91,6 +91,7 @@ ...@@ -91,6 +91,7 @@
#define AUDIT_MQ_GETSETATTR 1315 /* POSIX MQ get/set attribute record type */ #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_KERNEL_OTHER 1316 /* For use by 3rd party modules */
#define AUDIT_FD_PAIR 1317 /* audit record for pipe/socketpair */ #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_AVC 1400 /* SE Linux avc denial or grant */
#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
...@@ -352,6 +353,8 @@ extern void __audit_inode(const char *name, const struct inode *inode); ...@@ -352,6 +353,8 @@ extern void __audit_inode(const char *name, const struct inode *inode);
extern void __audit_inode_child(const char *dname, const struct inode *inode, extern void __audit_inode_child(const char *dname, const struct inode *inode,
const struct inode *parent); const struct inode *parent);
extern void __audit_inode_update(const struct inode *inode); extern void __audit_inode_update(const struct inode *inode);
extern void __audit_ptrace(struct task_struct *t);
static inline int audit_dummy_context(void) static inline int audit_dummy_context(void)
{ {
void *p = current->audit_context; void *p = current->audit_context;
...@@ -377,6 +380,12 @@ static inline void audit_inode_update(const struct inode *inode) { ...@@ -377,6 +380,12 @@ static inline void audit_inode_update(const struct inode *inode) {
__audit_inode_update(inode); __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) */ /* Private API (for audit.c only) */
extern unsigned int audit_serial(void); extern unsigned int audit_serial(void);
extern void auditsc_get_stamp(struct audit_context *ctx, extern void auditsc_get_stamp(struct audit_context *ctx,
...@@ -477,6 +486,7 @@ extern int audit_n_rules; ...@@ -477,6 +486,7 @@ extern int audit_n_rules;
#define audit_mq_timedreceive(d,l,p,t) ({ 0; }) #define audit_mq_timedreceive(d,l,p,t) ({ 0; })
#define audit_mq_notify(d,n) ({ 0; }) #define audit_mq_notify(d,n) ({ 0; })
#define audit_mq_getsetattr(d,s) ({ 0; }) #define audit_mq_getsetattr(d,s) ({ 0; })
#define audit_ptrace(t) ((void)0)
#define audit_n_rules 0 #define audit_n_rules 0
#endif #endif
......
...@@ -209,6 +209,9 @@ struct audit_context { ...@@ -209,6 +209,9 @@ struct audit_context {
unsigned long personality; unsigned long personality;
int arch; int arch;
pid_t target_pid;
u32 target_sid;
#if AUDIT_DEBUG #if AUDIT_DEBUG
int put_count; int put_count;
int ino_count; int ino_count;
...@@ -973,6 +976,23 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts ...@@ -973,6 +976,23 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
audit_log_end(ab); 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) { if (context->pwd && context->pwdmnt) {
ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD); ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
if (ab) { if (ab) {
...@@ -1193,6 +1213,7 @@ void audit_syscall_exit(int valid, long return_code) ...@@ -1193,6 +1213,7 @@ void audit_syscall_exit(int valid, long return_code)
} else { } else {
audit_free_names(context); audit_free_names(context);
audit_free_aux(context); audit_free_aux(context);
context->target_pid = 0;
kfree(context->filterkey); kfree(context->filterkey);
context->filterkey = NULL; context->filterkey = NULL;
tsk->audit_context = context; tsk->audit_context = context;
...@@ -1880,6 +1901,14 @@ int audit_sockaddr(int len, void *a) ...@@ -1880,6 +1901,14 @@ int audit_sockaddr(int len, void *a)
return 0; 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 * audit_avc_path - record the granting or denial of permissions
* @dentry: dentry to record * @dentry: dentry to record
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/security.h> #include <linux/security.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/audit.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -161,6 +162,8 @@ int ptrace_attach(struct task_struct *task) ...@@ -161,6 +162,8 @@ int ptrace_attach(struct task_struct *task)
{ {
int retval; int retval;
audit_ptrace(task);
retval = -EPERM; retval = -EPERM;
if (task->pid <= 1) if (task->pid <= 1)
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment