/* SPDX-License-Identifier: GPL-2.0-only */1/*2* AppArmor security module3*4* This file contains AppArmor contexts used to associate "labels" to objects.5*6* Copyright (C) 1998-2008 Novell/SUSE7* Copyright 2009-2010 Canonical Ltd.8*/910#ifndef __AA_CONTEXT_H11#define __AA_CONTEXT_H1213#include <linux/cred.h>14#include <linux/slab.h>15#include <linux/sched.h>1617#include "label.h"18#include "policy_ns.h"19#include "task.h"2021static inline struct aa_label *cred_label(const struct cred *cred)22{23struct aa_label **blob = cred->security + apparmor_blob_sizes.lbs_cred;2425AA_BUG(!blob);26return *blob;27}2829static inline void set_cred_label(const struct cred *cred,30struct aa_label *label)31{32struct aa_label **blob = cred->security + apparmor_blob_sizes.lbs_cred;3334AA_BUG(!blob);35*blob = label;36}3738/**39* aa_cred_raw_label - obtain cred's label40* @cred: cred to obtain label from (NOT NULL)41*42* Returns: confining label43*44* does NOT increment reference count45*/46static inline struct aa_label *aa_cred_raw_label(const struct cred *cred)47{48struct aa_label *label = cred_label(cred);4950AA_BUG(!label);51return label;52}5354/**55* aa_get_newest_cred_label - obtain the newest label on a cred56* @cred: cred to obtain label from (NOT NULL)57*58* Returns: newest version of confining label59*/60static inline struct aa_label *aa_get_newest_cred_label(const struct cred *cred)61{62return aa_get_newest_label(aa_cred_raw_label(cred));63}6465static inline struct aa_label *aa_get_newest_cred_label_condref(const struct cred *cred,66bool *needput)67{68struct aa_label *l = aa_cred_raw_label(cred);6970if (unlikely(label_is_stale(l))) {71*needput = true;72return aa_get_newest_label(l);73}7475*needput = false;76return l;77}7879static inline void aa_put_label_condref(struct aa_label *l, bool needput)80{81if (unlikely(needput))82aa_put_label(l);83}8485/**86* aa_current_raw_label - find the current tasks confining label87*88* Returns: up to date confining label or the ns unconfined label (NOT NULL)89*90* This fn will not update the tasks cred to the most up to date version91* of the label so it is safe to call when inside of locks.92*/93static inline struct aa_label *aa_current_raw_label(void)94{95return aa_cred_raw_label(current_cred());96}9798/**99* aa_get_current_label - get the newest version of the current tasks label100*101* Returns: newest version of confining label (NOT NULL)102*103* This fn will not update the tasks cred, so it is safe inside of locks104*105* The returned reference must be put with aa_put_label()106*/107static inline struct aa_label *aa_get_current_label(void)108{109struct aa_label *l = aa_current_raw_label();110111if (label_is_stale(l))112return aa_get_newest_label(l);113return aa_get_label(l);114}115116/**117* __end_current_label_crit_section - end crit section begun with __begin_...118* @label: label obtained from __begin_current_label_crit_section119* @needput: output: bool set by __begin_current_label_crit_section120*121* Returns: label to use for this crit section122*/123static inline void __end_current_label_crit_section(struct aa_label *label,124bool needput)125{126if (unlikely(needput))127aa_put_label(label);128}129130/**131* end_current_label_crit_section - put a reference found with begin_current_label..132* @label: label reference to put133*134* Should only be used with a reference obtained with135* begin_current_label_crit_section and never used in situations where the136* task cred may be updated137*/138static inline void end_current_label_crit_section(struct aa_label *label)139{140if (label != aa_current_raw_label())141aa_put_label(label);142}143144/**145* __begin_current_label_crit_section - current's confining label146* @needput: store whether the label needs to be put when ending crit section147*148* Returns: up to date confining label or the ns unconfined label (NOT NULL)149*150* safe to call inside locks151*152* The returned reference must be put with __end_current_label_crit_section()153* This must NOT be used if the task cred could be updated within the154* critical section between __begin_current_label_crit_section() ..155* __end_current_label_crit_section()156*/157static inline struct aa_label *__begin_current_label_crit_section(bool *needput)158{159struct aa_label *label = aa_current_raw_label();160161if (label_is_stale(label)) {162*needput = true;163return aa_get_newest_label(label);164}165166*needput = false;167return label;168}169170/**171* begin_current_label_crit_section - current's confining label and update it172*173* Returns: up to date confining label or the ns unconfined label (NOT NULL)174*175* Not safe to call inside locks176*177* The returned reference must be put with end_current_label_crit_section()178* This must NOT be used if the task cred could be updated within the179* critical section between begin_current_label_crit_section() ..180* end_current_label_crit_section()181*/182static inline struct aa_label *begin_current_label_crit_section(void)183{184struct aa_label *label = aa_current_raw_label();185186might_sleep();187188if (label_is_stale(label)) {189label = aa_get_newest_label(label);190if (aa_replace_current_label(label) == 0)191/* task cred will keep the reference */192aa_put_label(label);193}194195return label;196}197198static inline struct aa_ns *aa_get_current_ns(void)199{200struct aa_label *label;201struct aa_ns *ns;202bool needput;203204label = __begin_current_label_crit_section(&needput);205ns = aa_get_ns(labels_ns(label));206__end_current_label_crit_section(label, needput);207208return ns;209}210211#endif /* __AA_CONTEXT_H */212213214