1*b886d83cSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 2d8889d49SJohn Johansen /* 3d8889d49SJohn Johansen * AppArmor security module 4d8889d49SJohn Johansen * 5d8889d49SJohn Johansen * This file contains AppArmor contexts used to associate "labels" to objects. 6d8889d49SJohn Johansen * 7d8889d49SJohn Johansen * Copyright (C) 1998-2008 Novell/SUSE 8d8889d49SJohn Johansen * Copyright 2009-2010 Canonical Ltd. 9d8889d49SJohn Johansen */ 10d8889d49SJohn Johansen 11d8889d49SJohn Johansen #ifndef __AA_CONTEXT_H 12d8889d49SJohn Johansen #define __AA_CONTEXT_H 13d8889d49SJohn Johansen 14d8889d49SJohn Johansen #include <linux/cred.h> 15d8889d49SJohn Johansen #include <linux/slab.h> 16d8889d49SJohn Johansen #include <linux/sched.h> 17d8889d49SJohn Johansen 18d8889d49SJohn Johansen #include "label.h" 19d8889d49SJohn Johansen #include "policy_ns.h" 20d8889d49SJohn Johansen #include "task.h" 21d8889d49SJohn Johansen cred_label(const struct cred * cred)2269b5a44aSCasey Schauflerstatic inline struct aa_label *cred_label(const struct cred *cred) 2369b5a44aSCasey Schaufler { 24bbd3662aSCasey Schaufler struct aa_label **blob = cred->security + apparmor_blob_sizes.lbs_cred; 25d8889d49SJohn Johansen 2669b5a44aSCasey Schaufler AA_BUG(!blob); 2769b5a44aSCasey Schaufler return *blob; 2869b5a44aSCasey Schaufler } 2969b5a44aSCasey Schaufler set_cred_label(const struct cred * cred,struct aa_label * label)3069b5a44aSCasey Schauflerstatic inline void set_cred_label(const struct cred *cred, 3169b5a44aSCasey Schaufler struct aa_label *label) 3269b5a44aSCasey Schaufler { 33bbd3662aSCasey Schaufler struct aa_label **blob = cred->security + apparmor_blob_sizes.lbs_cred; 3469b5a44aSCasey Schaufler 3569b5a44aSCasey Schaufler AA_BUG(!blob); 3669b5a44aSCasey Schaufler *blob = label; 3769b5a44aSCasey Schaufler } 38d8889d49SJohn Johansen 39d8889d49SJohn Johansen /** 40d8889d49SJohn Johansen * aa_cred_raw_label - obtain cred's label 41d8889d49SJohn Johansen * @cred: cred to obtain label from (NOT NULL) 42d8889d49SJohn Johansen * 43d8889d49SJohn Johansen * Returns: confining label 44d8889d49SJohn Johansen * 45d8889d49SJohn Johansen * does NOT increment reference count 46d8889d49SJohn Johansen */ aa_cred_raw_label(const struct cred * cred)47d8889d49SJohn Johansenstatic inline struct aa_label *aa_cred_raw_label(const struct cred *cred) 48d8889d49SJohn Johansen { 49d8889d49SJohn Johansen struct aa_label *label = cred_label(cred); 50d8889d49SJohn Johansen 51d8889d49SJohn Johansen AA_BUG(!label); 52d8889d49SJohn Johansen return label; 53d8889d49SJohn Johansen } 54d8889d49SJohn Johansen 55d8889d49SJohn Johansen /** 56d8889d49SJohn Johansen * aa_get_newest_cred_label - obtain the newest label on a cred 57d8889d49SJohn Johansen * @cred: cred to obtain label from (NOT NULL) 58d8889d49SJohn Johansen * 59d8889d49SJohn Johansen * Returns: newest version of confining label 60d8889d49SJohn Johansen */ aa_get_newest_cred_label(const struct cred * cred)61d8889d49SJohn Johansenstatic inline struct aa_label *aa_get_newest_cred_label(const struct cred *cred) 62d8889d49SJohn Johansen { 63d8889d49SJohn Johansen return aa_get_newest_label(aa_cred_raw_label(cred)); 64d8889d49SJohn Johansen } 65d8889d49SJohn Johansen 66d8889d49SJohn Johansen /** 67d8889d49SJohn Johansen * aa_current_raw_label - find the current tasks confining label 68d8889d49SJohn Johansen * 69d8889d49SJohn Johansen * Returns: up to date confining label or the ns unconfined label (NOT NULL) 70d8889d49SJohn Johansen * 71d8889d49SJohn Johansen * This fn will not update the tasks cred to the most up to date version 72d8889d49SJohn Johansen * of the label so it is safe to call when inside of locks. 73d8889d49SJohn Johansen */ aa_current_raw_label(void)74d8889d49SJohn Johansenstatic inline struct aa_label *aa_current_raw_label(void) 75d8889d49SJohn Johansen { 76d8889d49SJohn Johansen return aa_cred_raw_label(current_cred()); 77d8889d49SJohn Johansen } 78d8889d49SJohn Johansen 79d8889d49SJohn Johansen /** 80d8889d49SJohn Johansen * aa_get_current_label - get the newest version of the current tasks label 81d8889d49SJohn Johansen * 82d8889d49SJohn Johansen * Returns: newest version of confining label (NOT NULL) 83d8889d49SJohn Johansen * 84d8889d49SJohn Johansen * This fn will not update the tasks cred, so it is safe inside of locks 85d8889d49SJohn Johansen * 86d8889d49SJohn Johansen * The returned reference must be put with aa_put_label() 87d8889d49SJohn Johansen */ aa_get_current_label(void)88d8889d49SJohn Johansenstatic inline struct aa_label *aa_get_current_label(void) 89d8889d49SJohn Johansen { 90d8889d49SJohn Johansen struct aa_label *l = aa_current_raw_label(); 91d8889d49SJohn Johansen 92d8889d49SJohn Johansen if (label_is_stale(l)) 93d8889d49SJohn Johansen return aa_get_newest_label(l); 94d8889d49SJohn Johansen return aa_get_label(l); 95d8889d49SJohn Johansen } 96d8889d49SJohn Johansen 97d8889d49SJohn Johansen #define __end_current_label_crit_section(X) end_current_label_crit_section(X) 98d8889d49SJohn Johansen 99d8889d49SJohn Johansen /** 100d8889d49SJohn Johansen * end_label_crit_section - put a reference found with begin_current_label.. 101d8889d49SJohn Johansen * @label: label reference to put 102d8889d49SJohn Johansen * 103d8889d49SJohn Johansen * Should only be used with a reference obtained with 104d8889d49SJohn Johansen * begin_current_label_crit_section and never used in situations where the 105d8889d49SJohn Johansen * task cred may be updated 106d8889d49SJohn Johansen */ end_current_label_crit_section(struct aa_label * label)107d8889d49SJohn Johansenstatic inline void end_current_label_crit_section(struct aa_label *label) 108d8889d49SJohn Johansen { 109d8889d49SJohn Johansen if (label != aa_current_raw_label()) 110d8889d49SJohn Johansen aa_put_label(label); 111d8889d49SJohn Johansen } 112d8889d49SJohn Johansen 113d8889d49SJohn Johansen /** 114d8889d49SJohn Johansen * __begin_current_label_crit_section - current's confining label 115d8889d49SJohn Johansen * 116d8889d49SJohn Johansen * Returns: up to date confining label or the ns unconfined label (NOT NULL) 117d8889d49SJohn Johansen * 118d8889d49SJohn Johansen * safe to call inside locks 119d8889d49SJohn Johansen * 120d8889d49SJohn Johansen * The returned reference must be put with __end_current_label_crit_section() 121d8889d49SJohn Johansen * This must NOT be used if the task cred could be updated within the 122d8889d49SJohn Johansen * critical section between __begin_current_label_crit_section() .. 123d8889d49SJohn Johansen * __end_current_label_crit_section() 124d8889d49SJohn Johansen */ __begin_current_label_crit_section(void)125d8889d49SJohn Johansenstatic inline struct aa_label *__begin_current_label_crit_section(void) 126d8889d49SJohn Johansen { 127d8889d49SJohn Johansen struct aa_label *label = aa_current_raw_label(); 128d8889d49SJohn Johansen 129d8889d49SJohn Johansen if (label_is_stale(label)) 130d8889d49SJohn Johansen label = aa_get_newest_label(label); 131d8889d49SJohn Johansen 132d8889d49SJohn Johansen return label; 133d8889d49SJohn Johansen } 134d8889d49SJohn Johansen 135d8889d49SJohn Johansen /** 136d8889d49SJohn Johansen * begin_current_label_crit_section - current's confining label and update it 137d8889d49SJohn Johansen * 138d8889d49SJohn Johansen * Returns: up to date confining label or the ns unconfined label (NOT NULL) 139d8889d49SJohn Johansen * 140d8889d49SJohn Johansen * Not safe to call inside locks 141d8889d49SJohn Johansen * 142d8889d49SJohn Johansen * The returned reference must be put with end_current_label_crit_section() 143d8889d49SJohn Johansen * This must NOT be used if the task cred could be updated within the 144d8889d49SJohn Johansen * critical section between begin_current_label_crit_section() .. 145d8889d49SJohn Johansen * end_current_label_crit_section() 146d8889d49SJohn Johansen */ begin_current_label_crit_section(void)147d8889d49SJohn Johansenstatic inline struct aa_label *begin_current_label_crit_section(void) 148d8889d49SJohn Johansen { 149d8889d49SJohn Johansen struct aa_label *label = aa_current_raw_label(); 150d8889d49SJohn Johansen 1511f8266ffSJann Horn might_sleep(); 1521f8266ffSJann Horn 153d8889d49SJohn Johansen if (label_is_stale(label)) { 154d8889d49SJohn Johansen label = aa_get_newest_label(label); 155d8889d49SJohn Johansen if (aa_replace_current_label(label) == 0) 156d8889d49SJohn Johansen /* task cred will keep the reference */ 157d8889d49SJohn Johansen aa_put_label(label); 158d8889d49SJohn Johansen } 159d8889d49SJohn Johansen 160d8889d49SJohn Johansen return label; 161d8889d49SJohn Johansen } 162d8889d49SJohn Johansen aa_get_current_ns(void)163d8889d49SJohn Johansenstatic inline struct aa_ns *aa_get_current_ns(void) 164d8889d49SJohn Johansen { 165d8889d49SJohn Johansen struct aa_label *label; 166d8889d49SJohn Johansen struct aa_ns *ns; 167d8889d49SJohn Johansen 168d8889d49SJohn Johansen label = __begin_current_label_crit_section(); 169d8889d49SJohn Johansen ns = aa_get_ns(labels_ns(label)); 170d8889d49SJohn Johansen __end_current_label_crit_section(label); 171d8889d49SJohn Johansen 172d8889d49SJohn Johansen return ns; 173d8889d49SJohn Johansen } 174d8889d49SJohn Johansen 175d8889d49SJohn Johansen #endif /* __AA_CONTEXT_H */ 176