2019-06-01 11:08:55 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2010-07-30 01:48:03 +04:00
/*
* AppArmor security module
*
* This file contains AppArmor / proc / < pid > / attr / interface functions
*
* Copyright ( C ) 1998 - 2008 Novell / SUSE
* Copyright 2009 - 2010 Canonical Ltd .
*/
# include "include/apparmor.h"
2017-10-11 11:04:48 +03:00
# include "include/cred.h"
2010-07-30 01:48:03 +04:00
# include "include/policy.h"
2017-01-16 11:42:15 +03:00
# include "include/policy_ns.h"
2010-07-30 01:48:03 +04:00
# include "include/domain.h"
2011-08-29 05:45:44 +04:00
# include "include/procattr.h"
2010-07-30 01:48:03 +04:00
/**
* aa_getprocattr - Return the profile information for @ profile
* @ profile : the profile to print profile info about ( NOT NULL )
* @ string : Returns - string containing the profile info ( NOT NULL )
*
* Returns : length of @ string on success else error on failure
*
* Requires : profile ! = NULL
*
* Creates a string containing the namespace_name : //profile_name for
* @ profile .
*
* Returns : size of string placed in @ string else error code on failure
*/
2017-06-09 22:47:17 +03:00
int aa_getprocattr ( struct aa_label * label , char * * string )
2010-07-30 01:48:03 +04:00
{
2017-06-09 22:47:17 +03:00
struct aa_ns * ns = labels_ns ( label ) ;
2017-06-09 12:08:28 +03:00
struct aa_ns * current_ns = aa_get_current_ns ( ) ;
2017-06-09 22:47:17 +03:00
int len ;
2010-07-30 01:48:03 +04:00
2017-06-09 22:47:17 +03:00
if ( ! aa_ns_visible ( current_ns , ns , true ) ) {
aa_put_ns ( current_ns ) ;
2010-07-30 01:48:03 +04:00
return - EACCES ;
2017-06-09 22:47:17 +03:00
}
2010-07-30 01:48:03 +04:00
2017-06-09 22:47:17 +03:00
len = aa_label_snxprint ( NULL , 0 , current_ns , label ,
FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
FLAG_HIDDEN_UNCONFINED ) ;
AA_BUG ( len < 0 ) ;
2010-07-30 01:48:03 +04:00
2017-06-09 22:47:17 +03:00
* string = kmalloc ( len + 2 , GFP_KERNEL ) ;
if ( ! * string ) {
aa_put_ns ( current_ns ) ;
2010-07-30 01:48:03 +04:00
return - ENOMEM ;
2017-06-09 22:47:17 +03:00
}
2010-07-30 01:48:03 +04:00
2017-06-09 22:47:17 +03:00
len = aa_label_snxprint ( * string , len + 2 , current_ns , label ,
FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
FLAG_HIDDEN_UNCONFINED ) ;
if ( len < 0 ) {
aa_put_ns ( current_ns ) ;
return len ;
2010-07-30 01:48:03 +04:00
}
2017-06-09 22:47:17 +03:00
( * string ) [ len ] = ' \n ' ;
( * string ) [ len + 1 ] = 0 ;
aa_put_ns ( current_ns ) ;
return len + 1 ;
2010-07-30 01:48:03 +04:00
}
/**
* split_token_from_name - separate a string of form < token > ^ < name >
* @ op : operation being checked
* @ args : string to parse ( NOT NULL )
* @ token : stores returned parsed token value ( NOT NULL )
*
* Returns : start position of name after token else NULL on failure
*/
2017-01-16 11:43:01 +03:00
static char * split_token_from_name ( const char * op , char * args , u64 * token )
2010-07-30 01:48:03 +04:00
{
char * name ;
* token = simple_strtoull ( args , & name , 16 ) ;
if ( ( name = = args ) | | * name ! = ' ^ ' ) {
2017-01-16 11:43:01 +03:00
AA_ERROR ( " %s: Invalid input '%s' " , op , args ) ;
2010-07-30 01:48:03 +04:00
return ERR_PTR ( - EINVAL ) ;
}
name + + ; /* skip ^ */
if ( ! * name )
name = NULL ;
return name ;
}
/**
* aa_setprocattr_chagnehat - handle procattr interface to change_hat
* @ args : args received from writing to / proc / < pid > / attr / current ( NOT NULL )
* @ size : size of the args
2017-06-09 21:36:48 +03:00
* @ flags : set of flags governing behavior
2010-07-30 01:48:03 +04:00
*
* Returns : % 0 or error code if change_hat fails
*/
2017-06-09 21:36:48 +03:00
int aa_setprocattr_changehat ( char * args , size_t size , int flags )
2010-07-30 01:48:03 +04:00
{
char * hat ;
u64 token ;
const char * hats [ 16 ] ; /* current hard limit on # of names */
int count = 0 ;
hat = split_token_from_name ( OP_CHANGE_HAT , args , & token ) ;
if ( IS_ERR ( hat ) )
return PTR_ERR ( hat ) ;
if ( ! hat & & ! token ) {
AA_ERROR ( " change_hat: Invalid input, NULL hat and NULL magic " ) ;
return - EINVAL ;
}
if ( hat ) {
/* set up hat name vector, args guaranteed null terminated
* at args [ size ] by setprocattr .
*
* If there are multiple hat names in the buffer each is
* separated by a \ 0. Ie . userspace writes them pre tokenized
*/
char * end = args + size ;
for ( count = 0 ; ( hat < end ) & & count < 16 ; + + count ) {
char * next = hat + strlen ( hat ) + 1 ;
hats [ count ] = hat ;
2017-01-16 11:43:05 +03:00
AA_DEBUG ( " %s: (pid %d) Magic 0x%llx count %d hat '%s' \n "
, __func__ , current - > pid , token , count , hat ) ;
2010-07-30 01:48:03 +04:00
hat = next ;
}
2017-01-16 11:43:05 +03:00
} else
AA_DEBUG ( " %s: (pid %d) Magic 0x%llx count %d Hat '%s' \n " ,
__func__ , current - > pid , token , count , " <NULL> " ) ;
2010-07-30 01:48:03 +04:00
2017-06-09 21:36:48 +03:00
return aa_change_hat ( hats , count , token , flags ) ;
2010-07-30 01:48:03 +04:00
}