1/* 2 * AppArmor security module 3 * 4 * This file contains AppArmor contexts used to associate "labels" to objects. 5 * 6 * Copyright (C) 1998-2008 Novell/SUSE 7 * Copyright 2009-2010 Canonical Ltd. 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation, version 2 of the 12 * License. 13 */ 14 15#ifndef __AA_CONTEXT_H 16#define __AA_CONTEXT_H 17 18#include <linux/cred.h> 19#include <linux/slab.h> 20#include <linux/sched.h> 21 22#include "label.h" 23#include "policy_ns.h" 24 25#define cred_ctx(X) ((X)->security) 26#define current_ctx() cred_ctx(current_cred()) 27 28/** 29 * struct aa_task_ctx - primary label for confined tasks 30 * @label: the current label (NOT NULL) 31 * @exec: label to transition to on next exec (MAYBE NULL) 32 * @previous: label the task may return to (MAYBE NULL) 33 * @token: magic value the task must know for returning to @previous 34 * 35 * Contains the task's current label (which could change due to 36 * change_hat). Plus the hat_magic needed during change_hat. 37 * 38 * TODO: make so a task can be confined by a stack of contexts 39 */ 40struct aa_task_ctx { 41 struct aa_label *label; 42 struct aa_label *onexec; 43 struct aa_label *previous; 44 u64 token; 45}; 46 47struct aa_task_ctx *aa_alloc_task_context(gfp_t flags); 48void aa_free_task_context(struct aa_task_ctx *ctx); 49void aa_dup_task_context(struct aa_task_ctx *new, 50 const struct aa_task_ctx *old); 51int aa_replace_current_label(struct aa_label *label); 52int aa_set_current_onexec(struct aa_label *label, bool stack); 53int aa_set_current_hat(struct aa_label *label, u64 token); 54int aa_restore_previous_label(u64 cookie); 55struct aa_label *aa_get_task_label(struct task_struct *task); 56 57 58/** 59 * aa_cred_raw_label - obtain cred's label 60 * @cred: cred to obtain label from (NOT NULL) 61 * 62 * Returns: confining label 63 * 64 * does NOT increment reference count 65 */ 66static inline struct aa_label *aa_cred_raw_label(const struct cred *cred) 67{ 68 struct aa_task_ctx *ctx = cred_ctx(cred); 69 70 AA_BUG(!ctx || !ctx->label); 71 return ctx->label; 72} 73 74/** 75 * aa_get_newest_cred_label - obtain the newest label on a cred 76 * @cred: cred to obtain label from (NOT NULL) 77 * 78 * Returns: newest version of confining label 79 */ 80static inline struct aa_label *aa_get_newest_cred_label(const struct cred *cred) 81{ 82 return aa_get_newest_label(aa_cred_raw_label(cred)); 83} 84 85/** 86 * __aa_task_raw_label - retrieve another task's label 87 * @task: task to query (NOT NULL) 88 * 89 * Returns: @task's label without incrementing its ref count 90 * 91 * If @task != current needs to be called in RCU safe critical section 92 */ 93static inline struct aa_label *__aa_task_raw_label(struct task_struct *task) 94{ 95 return aa_cred_raw_label(__task_cred(task)); 96} 97 98/** 99 * __aa_task_is_confined - determine if @task has any confinement 100 * @task: task to check confinement of (NOT NULL) 101 * 102 * If @task != current needs to be called in RCU safe critical section 103 */ 104static inline bool __aa_task_is_confined(struct task_struct *task) 105{ 106 return !unconfined(__aa_task_raw_label(task)); 107} 108 109/** 110 * aa_current_raw_label - find the current tasks confining label 111 * 112 * Returns: up to date confining label or the ns unconfined label (NOT NULL) 113 * 114 * This fn will not update the tasks cred to the most up to date version 115 * of the label so it is safe to call when inside of locks. 116 */ 117static inline struct aa_label *aa_current_raw_label(void) 118{ 119 return aa_cred_raw_label(current_cred()); 120} 121 122/** 123 * aa_get_current_label - get the newest version of the current tasks label 124 * 125 * Returns: newest version of confining label (NOT NULL) 126 * 127 * This fn will not update the tasks cred, so it is safe inside of locks 128 * 129 * The returned reference must be put with aa_put_label() 130 */ 131static inline struct aa_label *aa_get_current_label(void) 132{ 133 struct aa_label *l = aa_current_raw_label(); 134 135 if (label_is_stale(l)) 136 return aa_get_newest_label(l); 137 return aa_get_label(l); 138} 139 140#define __end_current_label_crit_section(X) end_current_label_crit_section(X) 141 142/** 143 * end_label_crit_section - put a reference found with begin_current_label.. 144 * @label: label reference to put 145 * 146 * Should only be used with a reference obtained with 147 * begin_current_label_crit_section and never used in situations where the 148 * task cred may be updated 149 */ 150static inline void end_current_label_crit_section(struct aa_label *label) 151{ 152 if (label != aa_current_raw_label()) 153 aa_put_label(label); 154} 155 156/** 157 * __begin_current_label_crit_section - current's confining label 158 * 159 * Returns: up to date confining label or the ns unconfined label (NOT NULL) 160 * 161 * safe to call inside locks 162 * 163 * The returned reference must be put with __end_current_label_crit_section() 164 * This must NOT be used if the task cred could be updated within the 165 * critical section between __begin_current_label_crit_section() .. 166 * __end_current_label_crit_section() 167 */ 168static inline struct aa_label *__begin_current_label_crit_section(void) 169{ 170 struct aa_label *label = aa_current_raw_label(); 171 172 if (label_is_stale(label)) 173 label = aa_get_newest_label(label); 174 175 return label; 176} 177 178/** 179 * begin_current_label_crit_section - current's confining label and update it 180 * 181 * Returns: up to date confining label or the ns unconfined label (NOT NULL) 182 * 183 * Not safe to call inside locks 184 * 185 * The returned reference must be put with end_current_label_crit_section() 186 * This must NOT be used if the task cred could be updated within the 187 * critical section between begin_current_label_crit_section() .. 188 * end_current_label_crit_section() 189 */ 190static inline struct aa_label *begin_current_label_crit_section(void) 191{ 192 struct aa_label *label = aa_current_raw_label(); 193 194 if (label_is_stale(label)) { 195 label = aa_get_newest_label(label); 196 if (aa_replace_current_label(label) == 0) 197 /* task cred will keep the reference */ 198 aa_put_label(label); 199 } 200 201 return label; 202} 203 204static inline struct aa_ns *aa_get_current_ns(void) 205{ 206 struct aa_label *label; 207 struct aa_ns *ns; 208 209 label = __begin_current_label_crit_section(); 210 ns = aa_get_ns(labels_ns(label)); 211 __end_current_label_crit_section(label); 212 213 return ns; 214} 215 216/** 217 * aa_clear_task_ctx_trans - clear transition tracking info from the ctx 218 * @ctx: task context to clear (NOT NULL) 219 */ 220static inline void aa_clear_task_ctx_trans(struct aa_task_ctx *ctx) 221{ 222 aa_put_label(ctx->previous); 223 aa_put_label(ctx->onexec); 224 ctx->previous = NULL; 225 ctx->onexec = NULL; 226 ctx->token = 0; 227} 228 229#endif /* __AA_CONTEXT_H */ 230