2010-07-30 01:48:05 +04:00
/*
* AppArmor security module
*
* This file contains AppArmor ipc mediation
*
* Copyright ( C ) 1998 - 2008 Novell / SUSE
* Copyright 2009 - 2010 Canonical Ltd .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation , version 2 of the
* License .
*/
# include <linux/gfp.h>
# include <linux/ptrace.h>
# include "include/audit.h"
# include "include/capability.h"
# include "include/context.h"
# include "include/policy.h"
2011-08-29 04:40:54 +04:00
# include "include/ipc.h"
2010-07-30 01:48:05 +04:00
/* call back to audit ptrace fields */
static void audit_cb ( struct audit_buffer * ab , void * va )
{
struct common_audit_data * sa = va ;
2017-01-16 11:43:02 +03:00
audit_log_format ( ab , " peer= " ) ;
audit_log_untrustedstring ( ab , aad ( sa ) - > peer - > base . hname ) ;
2010-07-30 01:48:05 +04:00
}
/**
* aa_audit_ptrace - do auditing for ptrace
* @ profile : profile being enforced ( NOT NULL )
* @ target : profile being traced ( NOT NULL )
* @ error : error condition
*
* Returns : % 0 or error code
*/
static int aa_audit_ptrace ( struct aa_profile * profile ,
struct aa_profile * target , int error )
{
2017-01-16 11:43:02 +03:00
DEFINE_AUDIT_DATA ( sa , LSM_AUDIT_DATA_NONE , OP_PTRACE ) ;
2010-07-30 01:48:05 +04:00
2017-01-16 11:43:02 +03:00
aad ( & sa ) - > peer = target ;
aad ( & sa ) - > error = error ;
return aa_audit ( AUDIT_APPARMOR_AUTO , profile , & sa , audit_cb ) ;
2010-07-30 01:48:05 +04:00
}
/**
* aa_may_ptrace - test if tracer task can trace the tracee
* @ tracer : profile of the task doing the tracing ( NOT NULL )
* @ tracee : task to be traced
* @ mode : whether PTRACE_MODE_READ | | PTRACE_MODE_ATTACH
*
* Returns : % 0 else error code if permission denied or error
*/
2013-10-08 16:37:18 +04:00
int aa_may_ptrace ( struct aa_profile * tracer , struct aa_profile * tracee ,
unsigned int mode )
2010-07-30 01:48:05 +04:00
{
/* TODO: currently only based on capability, not extended ptrace
* rules ,
* Test mode for PTRACE_MODE_READ | | PTRACE_MODE_ATTACH
*/
if ( unconfined ( tracer ) | | tracer = = tracee )
return 0 ;
/* log this capability request */
2013-10-08 16:37:18 +04:00
return aa_capable ( tracer , CAP_SYS_PTRACE , 1 ) ;
2010-07-30 01:48:05 +04:00
}
/**
* aa_ptrace - do ptrace permission check and auditing
* @ tracer : task doing the tracing ( NOT NULL )
* @ tracee : task being traced ( NOT NULL )
* @ mode : ptrace mode either PTRACE_MODE_READ | | PTRACE_MODE_ATTACH
*
* Returns : % 0 else error code if permission denied or error
*/
int aa_ptrace ( struct task_struct * tracer , struct task_struct * tracee ,
unsigned int mode )
{
/*
* tracer can ptrace tracee when
* - tracer is unconfined | |
* - tracer is in complain mode
* - tracer has rules allowing it to trace tracee currently this is :
* - confined by the same profile | |
* - tracer profile has CAP_SYS_PTRACE
*/
2013-02-19 04:03:34 +04:00
struct aa_profile * tracer_p = aa_get_task_profile ( tracer ) ;
2010-07-30 01:48:05 +04:00
int error = 0 ;
if ( ! unconfined ( tracer_p ) ) {
2013-02-19 04:03:34 +04:00
struct aa_profile * tracee_p = aa_get_task_profile ( tracee ) ;
2010-07-30 01:48:05 +04:00
2013-10-08 16:37:18 +04:00
error = aa_may_ptrace ( tracer_p , tracee_p , mode ) ;
2010-07-30 01:48:05 +04:00
error = aa_audit_ptrace ( tracer_p , tracee_p , error ) ;
2013-02-19 04:03:34 +04:00
aa_put_profile ( tracee_p ) ;
2010-07-30 01:48:05 +04:00
}
2013-02-19 04:03:34 +04:00
aa_put_profile ( tracer_p ) ;
2010-07-30 01:48:05 +04:00
return error ;
}