1b886d83cSThomas 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 2269b5a44aSCasey Schaufler static 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 3069b5a44aSCasey Schaufler static 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 */ 47d8889d49SJohn Johansen static 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 */ 61d8889d49SJohn Johansen static 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 66*f4fee216SMateusz Guzik static inline struct aa_label *aa_get_newest_cred_label_condref(const struct cred *cred, 67*f4fee216SMateusz Guzik bool *needput) 68*f4fee216SMateusz Guzik { 69*f4fee216SMateusz Guzik struct aa_label *l = aa_cred_raw_label(cred); 70*f4fee216SMateusz Guzik 71*f4fee216SMateusz Guzik if (unlikely(label_is_stale(l))) { 72*f4fee216SMateusz Guzik *needput = true; 73*f4fee216SMateusz Guzik return aa_get_newest_label(l); 74*f4fee216SMateusz Guzik } 75*f4fee216SMateusz Guzik 76*f4fee216SMateusz Guzik *needput = false; 77*f4fee216SMateusz Guzik return l; 78*f4fee216SMateusz Guzik } 79*f4fee216SMateusz Guzik 80*f4fee216SMateusz Guzik static inline void aa_put_label_condref(struct aa_label *l, bool needput) 81*f4fee216SMateusz Guzik { 82*f4fee216SMateusz Guzik if (unlikely(needput)) 83*f4fee216SMateusz Guzik aa_put_label(l); 84*f4fee216SMateusz Guzik } 85*f4fee216SMateusz Guzik 86d8889d49SJohn Johansen /** 87d8889d49SJohn Johansen * aa_current_raw_label - find the current tasks confining label 88d8889d49SJohn Johansen * 89d8889d49SJohn Johansen * Returns: up to date confining label or the ns unconfined label (NOT NULL) 90d8889d49SJohn Johansen * 91d8889d49SJohn Johansen * This fn will not update the tasks cred to the most up to date version 92d8889d49SJohn Johansen * of the label so it is safe to call when inside of locks. 93d8889d49SJohn Johansen */ 94d8889d49SJohn Johansen static inline struct aa_label *aa_current_raw_label(void) 95d8889d49SJohn Johansen { 96d8889d49SJohn Johansen return aa_cred_raw_label(current_cred()); 97d8889d49SJohn Johansen } 98d8889d49SJohn Johansen 99d8889d49SJohn Johansen /** 100d8889d49SJohn Johansen * aa_get_current_label - get the newest version of the current tasks label 101d8889d49SJohn Johansen * 102d8889d49SJohn Johansen * Returns: newest version of confining label (NOT NULL) 103d8889d49SJohn Johansen * 104d8889d49SJohn Johansen * This fn will not update the tasks cred, so it is safe inside of locks 105d8889d49SJohn Johansen * 106d8889d49SJohn Johansen * The returned reference must be put with aa_put_label() 107d8889d49SJohn Johansen */ 108d8889d49SJohn Johansen static inline struct aa_label *aa_get_current_label(void) 109d8889d49SJohn Johansen { 110d8889d49SJohn Johansen struct aa_label *l = aa_current_raw_label(); 111d8889d49SJohn Johansen 112d8889d49SJohn Johansen if (label_is_stale(l)) 113d8889d49SJohn Johansen return aa_get_newest_label(l); 114d8889d49SJohn Johansen return aa_get_label(l); 115d8889d49SJohn Johansen } 116d8889d49SJohn Johansen 117d8889d49SJohn Johansen #define __end_current_label_crit_section(X) end_current_label_crit_section(X) 118d8889d49SJohn Johansen 119d8889d49SJohn Johansen /** 120d8889d49SJohn Johansen * end_label_crit_section - put a reference found with begin_current_label.. 121d8889d49SJohn Johansen * @label: label reference to put 122d8889d49SJohn Johansen * 123d8889d49SJohn Johansen * Should only be used with a reference obtained with 124d8889d49SJohn Johansen * begin_current_label_crit_section and never used in situations where the 125d8889d49SJohn Johansen * task cred may be updated 126d8889d49SJohn Johansen */ 127d8889d49SJohn Johansen static inline void end_current_label_crit_section(struct aa_label *label) 128d8889d49SJohn Johansen { 129d8889d49SJohn Johansen if (label != aa_current_raw_label()) 130d8889d49SJohn Johansen aa_put_label(label); 131d8889d49SJohn Johansen } 132d8889d49SJohn Johansen 133d8889d49SJohn Johansen /** 134d8889d49SJohn Johansen * __begin_current_label_crit_section - current's confining label 135d8889d49SJohn Johansen * 136d8889d49SJohn Johansen * Returns: up to date confining label or the ns unconfined label (NOT NULL) 137d8889d49SJohn Johansen * 138d8889d49SJohn Johansen * safe to call inside locks 139d8889d49SJohn Johansen * 140d8889d49SJohn Johansen * The returned reference must be put with __end_current_label_crit_section() 141d8889d49SJohn Johansen * This must NOT be used if the task cred could be updated within the 142d8889d49SJohn Johansen * critical section between __begin_current_label_crit_section() .. 143d8889d49SJohn Johansen * __end_current_label_crit_section() 144d8889d49SJohn Johansen */ 145d8889d49SJohn Johansen static inline struct aa_label *__begin_current_label_crit_section(void) 146d8889d49SJohn Johansen { 147d8889d49SJohn Johansen struct aa_label *label = aa_current_raw_label(); 148d8889d49SJohn Johansen 149d8889d49SJohn Johansen if (label_is_stale(label)) 150d8889d49SJohn Johansen label = aa_get_newest_label(label); 151d8889d49SJohn Johansen 152d8889d49SJohn Johansen return label; 153d8889d49SJohn Johansen } 154d8889d49SJohn Johansen 155d8889d49SJohn Johansen /** 156d8889d49SJohn Johansen * begin_current_label_crit_section - current's confining label and update it 157d8889d49SJohn Johansen * 158d8889d49SJohn Johansen * Returns: up to date confining label or the ns unconfined label (NOT NULL) 159d8889d49SJohn Johansen * 160d8889d49SJohn Johansen * Not safe to call inside locks 161d8889d49SJohn Johansen * 162d8889d49SJohn Johansen * The returned reference must be put with end_current_label_crit_section() 163d8889d49SJohn Johansen * This must NOT be used if the task cred could be updated within the 164d8889d49SJohn Johansen * critical section between begin_current_label_crit_section() .. 165d8889d49SJohn Johansen * end_current_label_crit_section() 166d8889d49SJohn Johansen */ 167d8889d49SJohn Johansen static inline struct aa_label *begin_current_label_crit_section(void) 168d8889d49SJohn Johansen { 169d8889d49SJohn Johansen struct aa_label *label = aa_current_raw_label(); 170d8889d49SJohn Johansen 1711f8266ffSJann Horn might_sleep(); 1721f8266ffSJann Horn 173d8889d49SJohn Johansen if (label_is_stale(label)) { 174d8889d49SJohn Johansen label = aa_get_newest_label(label); 175d8889d49SJohn Johansen if (aa_replace_current_label(label) == 0) 176d8889d49SJohn Johansen /* task cred will keep the reference */ 177d8889d49SJohn Johansen aa_put_label(label); 178d8889d49SJohn Johansen } 179d8889d49SJohn Johansen 180d8889d49SJohn Johansen return label; 181d8889d49SJohn Johansen } 182d8889d49SJohn Johansen 183d8889d49SJohn Johansen static inline struct aa_ns *aa_get_current_ns(void) 184d8889d49SJohn Johansen { 185d8889d49SJohn Johansen struct aa_label *label; 186d8889d49SJohn Johansen struct aa_ns *ns; 187d8889d49SJohn Johansen 188d8889d49SJohn Johansen label = __begin_current_label_crit_section(); 189d8889d49SJohn Johansen ns = aa_get_ns(labels_ns(label)); 190d8889d49SJohn Johansen __end_current_label_crit_section(label); 191d8889d49SJohn Johansen 192d8889d49SJohn Johansen return ns; 193d8889d49SJohn Johansen } 194d8889d49SJohn Johansen 195d8889d49SJohn Johansen #endif /* __AA_CONTEXT_H */ 196