[PATCH] auditing ptrace
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
129a84de23
commit
a5cb013da7
@ -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);
|
|||||||
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) {
|
|||||||
__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;
|
|||||||
#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 {
|
|||||||
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
|
|||||||
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)
|
|||||||
} 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)
|
|||||||
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 @@
|
|||||||
#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)
|
|||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
audit_ptrace(task);
|
||||||
|
|
||||||
retval = -EPERM;
|
retval = -EPERM;
|
||||||
if (task->pid <= 1)
|
if (task->pid <= 1)
|
||||||
goto out;
|
goto out;
|
||||||
|
Loading…
Reference in New Issue
Block a user