2010-07-29 14:47:59 -07:00
/*
* AppArmor security module
*
* This file contains AppArmor contexts used to associate " labels " to objects .
*
* 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 .
*/
# ifndef __AA_CONTEXT_H
# define __AA_CONTEXT_H
# include <linux/cred.h>
# include <linux/slab.h>
# include <linux/sched.h>
2017-06-09 08:14:28 -07:00
# include "label.h"
2017-01-16 00:42:50 -08:00
# include "policy_ns.h"
2010-07-29 14:47:59 -07:00
2017-01-16 00:43:00 -08:00
# define cred_ctx(X) ((X)->security)
# define current_ctx() cred_ctx(current_cred())
2013-02-27 03:43:40 -08:00
2010-07-29 14:47:59 -07:00
/**
2017-01-16 00:43:00 -08:00
* struct aa_task_ctx - primary label for confined tasks
2017-06-09 08:14:28 -07:00
* @ label : the current label ( NOT NULL )
* @ exec : label to transition to on next exec ( MAYBE NULL )
* @ previous : label the task may return to ( MAYBE NULL )
* @ token : magic value the task must know for returning to @ previous
2010-07-29 14:47:59 -07:00
*
2017-06-09 08:14:28 -07:00
* Contains the task ' s current label ( which could change due to
2010-07-29 14:47:59 -07:00
* change_hat ) . Plus the hat_magic needed during change_hat .
*
* TODO : make so a task can be confined by a stack of contexts
*/
2017-01-16 00:43:00 -08:00
struct aa_task_ctx {
2017-06-09 08:14:28 -07:00
struct aa_label * label ;
struct aa_label * onexec ;
struct aa_label * previous ;
2010-07-29 14:47:59 -07:00
u64 token ;
} ;
2017-01-16 00:43:00 -08:00
struct aa_task_ctx * aa_alloc_task_context ( gfp_t flags ) ;
void aa_free_task_context ( struct aa_task_ctx * ctx ) ;
void aa_dup_task_context ( struct aa_task_ctx * new ,
const struct aa_task_ctx * old ) ;
2017-06-09 08:14:28 -07:00
int aa_replace_current_label ( struct aa_label * label ) ;
int aa_set_current_onexec ( struct aa_label * label , bool stack ) ;
int aa_set_current_hat ( struct aa_label * label , u64 token ) ;
int aa_restore_previous_label ( u64 cookie ) ;
struct aa_label * aa_get_task_label ( struct task_struct * task ) ;
2010-07-29 14:47:59 -07:00
/**
2017-06-09 08:14:28 -07:00
* aa_cred_raw_label - obtain cred ' s label
* @ cred : cred to obtain label from ( NOT NULL )
2010-07-29 14:47:59 -07:00
*
2017-06-09 08:14:28 -07:00
* Returns : confining label
2010-07-29 14:47:59 -07:00
*
* does NOT increment reference count
*/
2017-06-09 08:14:28 -07:00
static inline struct aa_label * aa_cred_raw_label ( const struct cred * cred )
2010-07-29 14:47:59 -07:00
{
2017-01-16 00:43:00 -08:00
struct aa_task_ctx * ctx = cred_ctx ( cred ) ;
2017-06-09 08:14:28 -07:00
AA_BUG ( ! ctx | | ! ctx - > label ) ;
return ctx - > label ;
2010-07-29 14:47:59 -07:00
}
2013-02-18 16:03:34 -08:00
/**
2017-06-09 08:14:28 -07:00
* aa_get_newest_cred_label - obtain the newest label on a cred
* @ cred : cred to obtain label from ( NOT NULL )
2017-06-09 02:08:28 -07:00
*
2017-06-09 08:14:28 -07:00
* Returns : newest version of confining label
2017-06-09 02:08:28 -07:00
*/
2017-06-09 08:14:28 -07:00
static inline struct aa_label * aa_get_newest_cred_label ( const struct cred * cred )
2017-06-09 02:08:28 -07:00
{
2017-06-09 08:14:28 -07:00
return aa_get_newest_label ( aa_cred_raw_label ( cred ) ) ;
2017-06-09 02:08:28 -07:00
}
/**
2017-06-09 08:14:28 -07:00
* __aa_task_raw_label - retrieve another task ' s label
2013-02-18 16:03:34 -08:00
* @ task : task to query ( NOT NULL )
*
2017-06-09 08:14:28 -07:00
* Returns : @ task ' s label without incrementing its ref count
2013-02-18 16:03:34 -08:00
*
* If @ task ! = current needs to be called in RCU safe critical section
*/
2017-06-09 08:14:28 -07:00
static inline struct aa_label * __aa_task_raw_label ( struct task_struct * task )
2013-02-18 16:03:34 -08:00
{
2017-06-09 08:14:28 -07:00
return aa_cred_raw_label ( __task_cred ( task ) ) ;
2013-02-18 16:03:34 -08:00
}
/**
* __aa_task_is_confined - determine if @ task has any confinement
* @ task : task to check confinement of ( NOT NULL )
*
* If @ task ! = current needs to be called in RCU safe critical section
*/
static inline bool __aa_task_is_confined ( struct task_struct * task )
{
2017-06-09 08:14:28 -07:00
return ! unconfined ( __aa_task_raw_label ( task ) ) ;
2013-02-18 16:03:34 -08:00
}
2010-07-29 14:47:59 -07:00
/**
2017-06-09 08:14:28 -07:00
* aa_current_raw_label - find the current tasks confining label
2010-07-29 14:47:59 -07:00
*
2017-06-09 08:14:28 -07:00
* Returns : up to date confining label or the ns unconfined label ( NOT NULL )
2010-07-29 14:47:59 -07:00
*
* This fn will not update the tasks cred to the most up to date version
2017-06-09 08:14:28 -07:00
* of the label so it is safe to call when inside of locks .
2010-07-29 14:47:59 -07:00
*/
2017-06-09 08:14:28 -07:00
static inline struct aa_label * aa_current_raw_label ( void )
2010-07-29 14:47:59 -07:00
{
2017-06-09 08:14:28 -07:00
return aa_cred_raw_label ( current_cred ( ) ) ;
2010-07-29 14:47:59 -07:00
}
/**
2017-06-09 08:14:28 -07:00
* aa_get_current_label - get the newest version of the current tasks label
2010-07-29 14:47:59 -07:00
*
2017-06-09 08:14:28 -07:00
* Returns : newest version of confining label ( NOT NULL )
2017-06-09 02:08:28 -07:00
*
* This fn will not update the tasks cred , so it is safe inside of locks
2010-07-29 14:47:59 -07:00
*
2017-06-09 08:14:28 -07:00
* The returned reference must be put with aa_put_label ( )
2010-07-29 14:47:59 -07:00
*/
2017-06-09 08:14:28 -07:00
static inline struct aa_label * aa_get_current_label ( void )
2010-07-29 14:47:59 -07:00
{
2017-06-09 08:14:28 -07:00
struct aa_label * l = aa_current_raw_label ( ) ;
2010-07-29 14:47:59 -07:00
2017-06-09 08:14:28 -07:00
if ( label_is_stale ( l ) )
return aa_get_newest_label ( l ) ;
return aa_get_label ( l ) ;
2017-06-09 02:08:28 -07:00
}
2017-01-16 00:43:00 -08:00
2017-06-09 08:14:28 -07:00
# define __end_current_label_crit_section(X) end_current_label_crit_section(X)
2017-06-09 02:08:28 -07:00
/**
2017-06-09 08:14:28 -07:00
* end_label_crit_section - put a reference found with begin_current_label . .
* @ label : label reference to put
2017-06-09 02:08:28 -07:00
*
* Should only be used with a reference obtained with
2017-06-09 08:14:28 -07:00
* begin_current_label_crit_section and never used in situations where the
2017-06-09 02:08:28 -07:00
* task cred may be updated
*/
2017-06-09 08:14:28 -07:00
static inline void end_current_label_crit_section ( struct aa_label * label )
2017-06-09 02:08:28 -07:00
{
2017-06-09 08:14:28 -07:00
if ( label ! = aa_current_raw_label ( ) )
aa_put_label ( label ) ;
2017-06-09 02:08:28 -07:00
}
/**
2017-06-09 08:14:28 -07:00
* __begin_current_label_crit_section - current ' s confining label
2017-06-09 02:08:28 -07:00
*
2017-06-09 08:14:28 -07:00
* Returns : up to date confining label or the ns unconfined label ( NOT NULL )
2017-06-09 02:08:28 -07:00
*
* safe to call inside locks
*
2017-06-09 08:14:28 -07:00
* The returned reference must be put with __end_current_label_crit_section ( )
2017-06-09 02:08:28 -07:00
* This must NOT be used if the task cred could be updated within the
2017-06-09 08:14:28 -07:00
* critical section between __begin_current_label_crit_section ( ) . .
* __end_current_label_crit_section ( )
2017-06-09 02:08:28 -07:00
*/
2017-06-09 08:14:28 -07:00
static inline struct aa_label * __begin_current_label_crit_section ( void )
2017-06-09 02:08:28 -07:00
{
2017-06-09 08:14:28 -07:00
struct aa_label * label = aa_current_raw_label ( ) ;
2017-06-09 02:08:28 -07:00
2017-06-09 08:14:28 -07:00
if ( label_is_stale ( label ) )
label = aa_get_newest_label ( label ) ;
2017-06-09 02:08:28 -07:00
2017-06-09 08:14:28 -07:00
return label ;
2017-06-09 02:08:28 -07:00
}
/**
2017-06-09 08:14:28 -07:00
* begin_current_label_crit_section - current ' s confining label and update it
2017-06-09 02:08:28 -07:00
*
2017-06-09 08:14:28 -07:00
* Returns : up to date confining label or the ns unconfined label ( NOT NULL )
2017-06-09 02:08:28 -07:00
*
* Not safe to call inside locks
*
2017-06-09 08:14:28 -07:00
* The returned reference must be put with end_current_label_crit_section ( )
2017-06-09 02:08:28 -07:00
* This must NOT be used if the task cred could be updated within the
2017-06-09 08:14:28 -07:00
* critical section between begin_current_label_crit_section ( ) . .
* end_current_label_crit_section ( )
2017-06-09 02:08:28 -07:00
*/
2017-06-09 08:14:28 -07:00
static inline struct aa_label * begin_current_label_crit_section ( void )
2017-06-09 02:08:28 -07:00
{
2017-06-09 08:14:28 -07:00
struct aa_label * label = aa_current_raw_label ( ) ;
2017-06-09 02:08:28 -07:00
2017-06-09 08:14:28 -07:00
if ( label_is_stale ( label ) ) {
label = aa_get_newest_label ( label ) ;
if ( aa_replace_current_label ( label ) = = 0 )
2017-06-09 02:08:28 -07:00
/* task cred will keep the reference */
2017-06-09 08:14:28 -07:00
aa_put_label ( label ) ;
2013-07-10 21:07:43 -07:00
}
2010-07-29 14:47:59 -07:00
2017-06-09 08:14:28 -07:00
return label ;
2010-07-29 14:47:59 -07:00
}
2017-01-16 00:42:50 -08:00
static inline struct aa_ns * aa_get_current_ns ( void )
{
2017-06-09 08:14:28 -07:00
struct aa_label * label ;
2017-06-09 02:08:28 -07:00
struct aa_ns * ns ;
2017-06-09 08:14:28 -07:00
label = __begin_current_label_crit_section ( ) ;
ns = aa_get_ns ( labels_ns ( label ) ) ;
__end_current_label_crit_section ( label ) ;
2017-06-09 02:08:28 -07:00
return ns ;
2017-01-16 00:42:50 -08:00
}
2013-02-18 16:05:34 -08:00
/**
2017-01-16 00:43:00 -08:00
* aa_clear_task_ctx_trans - clear transition tracking info from the ctx
* @ ctx : task context to clear ( NOT NULL )
2013-02-18 16:05:34 -08:00
*/
2017-01-16 00:43:00 -08:00
static inline void aa_clear_task_ctx_trans ( struct aa_task_ctx * ctx )
2013-02-18 16:05:34 -08:00
{
2017-06-09 08:14:28 -07:00
aa_put_label ( ctx - > previous ) ;
aa_put_label ( ctx - > onexec ) ;
2017-01-16 00:43:00 -08:00
ctx - > previous = NULL ;
ctx - > onexec = NULL ;
ctx - > token = 0 ;
2013-02-18 16:05:34 -08:00
}
2010-07-29 14:47:59 -07:00
# endif /* __AA_CONTEXT_H */