2010-05-17 05:12:46 +04:00
/*
2011-07-14 09:46:51 +04:00
* security / tomoyo / securityfs_if . c
2010-05-17 05:12:46 +04:00
*
2011-07-14 09:46:51 +04:00
* Copyright ( C ) 2005 - 2011 NTT DATA CORPORATION
2010-05-17 05:12:46 +04:00
*/
# include <linux/security.h>
# include "common.h"
2011-09-10 10:25:58 +04:00
/**
* tomoyo_check_task_acl - Check permission for task operation .
*
* @ r : Pointer to " struct tomoyo_request_info " .
* @ ptr : Pointer to " struct tomoyo_acl_info " .
*
* Returns true if granted , false otherwise .
*/
static bool tomoyo_check_task_acl ( struct tomoyo_request_info * r ,
const struct tomoyo_acl_info * ptr )
{
const struct tomoyo_task_acl * acl = container_of ( ptr , typeof ( * acl ) ,
head ) ;
return ! tomoyo_pathcmp ( r - > param . task . domainname , acl - > domainname ) ;
}
/**
* tomoyo_write_self - write ( ) for / sys / kernel / security / tomoyo / self_domain interface .
*
* @ file : Pointer to " struct file " .
* @ buf : Domainname to transit to .
* @ count : Size of @ buf .
* @ ppos : Unused .
*
* Returns @ count on success , negative value otherwise .
*
* If domain transition was permitted but the domain transition failed , this
* function returns error rather than terminating current thread with SIGKILL .
*/
static ssize_t tomoyo_write_self ( struct file * file , const char __user * buf ,
size_t count , loff_t * ppos )
{
char * data ;
int error ;
if ( ! count | | count > = TOMOYO_EXEC_TMPSIZE - 10 )
return - ENOMEM ;
2015-12-24 08:06:05 +03:00
data = memdup_user_nul ( buf , count ) ;
if ( IS_ERR ( data ) )
return PTR_ERR ( data ) ;
2011-09-10 10:25:58 +04:00
tomoyo_normalize_line ( data ) ;
if ( tomoyo_correct_domain ( data ) ) {
const int idx = tomoyo_read_lock ( ) ;
struct tomoyo_path_info name ;
struct tomoyo_request_info r ;
name . name = data ;
tomoyo_fill_path_info ( & name ) ;
/* Check "task manual_domain_transition" permission. */
tomoyo_init_request_info ( & r , NULL , TOMOYO_MAC_FILE_EXECUTE ) ;
r . param_type = TOMOYO_TYPE_MANUAL_TASK_ACL ;
r . param . task . domainname = & name ;
tomoyo_check_acl ( & r , tomoyo_check_task_acl ) ;
if ( ! r . granted )
error = - EPERM ;
else {
struct tomoyo_domain_info * new_domain =
tomoyo_assign_domain ( data , true ) ;
if ( ! new_domain ) {
error = - ENOENT ;
} else {
struct cred * cred = prepare_creds ( ) ;
if ( ! cred ) {
error = - ENOMEM ;
} else {
struct tomoyo_domain_info * old_domain =
cred - > security ;
cred - > security = new_domain ;
atomic_inc ( & new_domain - > users ) ;
atomic_dec ( & old_domain - > users ) ;
commit_creds ( cred ) ;
error = 0 ;
}
}
}
tomoyo_read_unlock ( idx ) ;
} else
error = - EINVAL ;
kfree ( data ) ;
return error ? error : count ;
}
/**
* tomoyo_read_self - read ( ) for / sys / kernel / security / tomoyo / self_domain interface .
*
* @ file : Pointer to " struct file " .
* @ buf : Domainname which current thread belongs to .
* @ count : Size of @ buf .
* @ ppos : Bytes read by now .
*
* Returns read size on success , negative value otherwise .
*/
static ssize_t tomoyo_read_self ( struct file * file , char __user * buf ,
size_t count , loff_t * ppos )
{
const char * domain = tomoyo_domain ( ) - > domainname - > name ;
loff_t len = strlen ( domain ) ;
loff_t pos = * ppos ;
if ( pos > = len | | ! count )
return 0 ;
len - = pos ;
if ( count < len )
len = count ;
if ( copy_to_user ( buf , domain + pos , len ) )
return - EFAULT ;
* ppos + = len ;
return len ;
}
/* Operations for /sys/kernel/security/tomoyo/self_domain interface. */
static const struct file_operations tomoyo_self_operations = {
. write = tomoyo_write_self ,
. read = tomoyo_read_self ,
} ;
2010-05-17 05:12:46 +04:00
/**
* tomoyo_open - open ( ) for / sys / kernel / security / tomoyo / interface .
*
* @ inode : Pointer to " struct inode " .
* @ file : Pointer to " struct file " .
*
* Returns 0 on success , negative value otherwise .
*/
static int tomoyo_open ( struct inode * inode , struct file * file )
{
2013-01-24 02:07:38 +04:00
const int key = ( ( u8 * ) file_inode ( file ) - > i_private )
2010-05-17 05:12:46 +04:00
- ( ( u8 * ) NULL ) ;
return tomoyo_open_control ( key , file ) ;
}
/**
* tomoyo_release - close ( ) for / sys / kernel / security / tomoyo / interface .
*
* @ file : Pointer to " struct file " .
*
*/
static int tomoyo_release ( struct inode * inode , struct file * file )
{
2013-04-15 00:59:00 +04:00
tomoyo_close_control ( file - > private_data ) ;
return 0 ;
2010-05-17 05:12:46 +04:00
}
2010-06-25 07:22:09 +04:00
/**
2011-06-26 18:16:03 +04:00
* tomoyo_poll - poll ( ) for / sys / kernel / security / tomoyo / interface .
2010-06-25 07:22:09 +04:00
*
* @ file : Pointer to " struct file " .
2012-03-14 13:27:49 +04:00
* @ wait : Pointer to " poll_table " . Maybe NULL .
2010-06-25 07:22:09 +04:00
*
2012-03-14 13:27:49 +04:00
* Returns POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM if ready to read / write ,
* POLLOUT | POLLWRNORM otherwise .
2010-06-25 07:22:09 +04:00
*/
static unsigned int tomoyo_poll ( struct file * file , poll_table * wait )
{
return tomoyo_poll_control ( file , wait ) ;
}
2010-05-17 05:12:46 +04:00
/**
* tomoyo_read - read ( ) for / sys / kernel / security / tomoyo / interface .
*
* @ file : Pointer to " struct file " .
* @ buf : Pointer to buffer .
* @ count : Size of @ buf .
* @ ppos : Unused .
*
* Returns bytes read on success , negative value otherwise .
*/
static ssize_t tomoyo_read ( struct file * file , char __user * buf , size_t count ,
loff_t * ppos )
{
2011-06-26 18:16:36 +04:00
return tomoyo_read_control ( file - > private_data , buf , count ) ;
2010-05-17 05:12:46 +04:00
}
/**
* tomoyo_write - write ( ) for / sys / kernel / security / tomoyo / interface .
*
* @ file : Pointer to " struct file " .
* @ buf : Pointer to buffer .
* @ count : Size of @ buf .
* @ ppos : Unused .
*
* Returns @ count on success , negative value otherwise .
*/
static ssize_t tomoyo_write ( struct file * file , const char __user * buf ,
size_t count , loff_t * ppos )
{
2011-06-26 18:16:36 +04:00
return tomoyo_write_control ( file - > private_data , buf , count ) ;
2010-05-17 05:12:46 +04:00
}
/*
* tomoyo_operations is a " struct file_operations " which is used for handling
* / sys / kernel / security / tomoyo / interface .
*
* Some files under / sys / kernel / security / tomoyo / directory accept open ( O_RDWR ) .
* See tomoyo_io_buffer for internals .
*/
static const struct file_operations tomoyo_operations = {
. open = tomoyo_open ,
. release = tomoyo_release ,
2010-06-25 07:22:09 +04:00
. poll = tomoyo_poll ,
2010-05-17 05:12:46 +04:00
. read = tomoyo_read ,
. write = tomoyo_write ,
2010-07-08 16:57:41 +04:00
. llseek = noop_llseek ,
2010-05-17 05:12:46 +04:00
} ;
/**
* tomoyo_create_entry - Create interface files under / sys / kernel / security / tomoyo / directory .
*
* @ name : The name of the interface file .
* @ mode : The permission of the interface file .
* @ parent : The parent directory .
* @ key : Type of interface .
*
* Returns nothing .
*/
2011-07-26 12:30:04 +04:00
static void __init tomoyo_create_entry ( const char * name , const umode_t mode ,
2010-05-17 05:12:46 +04:00
struct dentry * parent , const u8 key )
{
securityfs_create_file ( name , mode , parent , ( ( u8 * ) NULL ) + key ,
& tomoyo_operations ) ;
}
/**
* tomoyo_initerface_init - Initialize / sys / kernel / security / tomoyo / interface .
*
* Returns 0.
*/
static int __init tomoyo_initerface_init ( void )
{
struct dentry * tomoyo_dir ;
/* Don't create securityfs entries unless registered. */
if ( current_cred ( ) - > security ! = & tomoyo_kernel_domain )
return 0 ;
tomoyo_dir = securityfs_create_dir ( " tomoyo " , NULL ) ;
tomoyo_create_entry ( " query " , 0600 , tomoyo_dir ,
TOMOYO_QUERY ) ;
tomoyo_create_entry ( " domain_policy " , 0600 , tomoyo_dir ,
TOMOYO_DOMAINPOLICY ) ;
tomoyo_create_entry ( " exception_policy " , 0600 , tomoyo_dir ,
TOMOYO_EXCEPTIONPOLICY ) ;
2011-06-26 18:18:58 +04:00
tomoyo_create_entry ( " audit " , 0400 , tomoyo_dir ,
TOMOYO_AUDIT ) ;
2010-05-17 05:12:46 +04:00
tomoyo_create_entry ( " .process_status " , 0600 , tomoyo_dir ,
TOMOYO_PROCESS_STATUS ) ;
2011-06-26 18:21:50 +04:00
tomoyo_create_entry ( " stat " , 0644 , tomoyo_dir ,
TOMOYO_STAT ) ;
2010-05-17 05:12:46 +04:00
tomoyo_create_entry ( " profile " , 0600 , tomoyo_dir ,
TOMOYO_PROFILE ) ;
tomoyo_create_entry ( " manager " , 0600 , tomoyo_dir ,
TOMOYO_MANAGER ) ;
tomoyo_create_entry ( " version " , 0400 , tomoyo_dir ,
TOMOYO_VERSION ) ;
2011-09-10 10:25:58 +04:00
securityfs_create_file ( " self_domain " , 0666 , tomoyo_dir , NULL ,
& tomoyo_self_operations ) ;
2011-09-25 12:49:09 +04:00
tomoyo_load_builtin_policy ( ) ;
2010-05-17 05:12:46 +04:00
return 0 ;
}
fs_initcall ( tomoyo_initerface_init ) ;