Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

apparmor: refactor/cleanup cred helper fns.

aa_cred_raw_label() and cred_label() now do the same things so
consolidate to cred_label()

Document the crit section use and constraints better and refactor
__begin_current_label_crit_section() into a base fn
__begin_cred_crit_section() and a wrapper that calls the base with
current cred.

Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>

+71 -33
+71 -33
security/apparmor/include/cred.h
··· 37 37 } 38 38 39 39 /** 40 - * aa_cred_raw_label - obtain cred's label 41 - * @cred: cred to obtain label from (NOT NULL) 42 - * 43 - * Returns: confining label 44 - * 45 - * does NOT increment reference count 46 - */ 47 - static inline struct aa_label *aa_cred_raw_label(const struct cred *cred) 48 - { 49 - struct aa_label *label = cred_label(cred); 50 - 51 - AA_BUG(!label); 52 - return label; 53 - } 54 - 55 - /** 56 40 * aa_get_newest_cred_label - obtain the newest label on a cred 57 41 * @cred: cred to obtain label from (NOT NULL) 58 42 * ··· 44 60 */ 45 61 static inline struct aa_label *aa_get_newest_cred_label(const struct cred *cred) 46 62 { 47 - return aa_get_newest_label(aa_cred_raw_label(cred)); 63 + return aa_get_newest_label(cred_label(cred)); 48 64 } 49 65 50 66 static inline struct aa_label *aa_get_newest_cred_label_condref(const struct cred *cred, 51 67 bool *needput) 52 68 { 53 - struct aa_label *l = aa_cred_raw_label(cred); 69 + struct aa_label *l = cred_label(cred); 54 70 55 71 if (unlikely(label_is_stale(l))) { 56 72 *needput = true; ··· 77 93 */ 78 94 static inline struct aa_label *aa_current_raw_label(void) 79 95 { 80 - return aa_cred_raw_label(current_cred()); 96 + return cred_label(current_cred()); 81 97 } 82 98 83 99 /** ··· 99 115 } 100 116 101 117 /** 102 - * __end_current_label_crit_section - end crit section begun with __begin_... 103 - * @label: label obtained from __begin_current_label_crit_section 104 - * @needput: output: bool set by __begin_current_label_crit_section 118 + * __end_cred_crit_section - end crit section begun with __begin_... 119 + * @label: label obtained from __begin_cred_crit_section 120 + * @needput: output: bool set by __begin_cred_crit_section 105 121 * 106 - * Returns: label to use for this crit section 122 + * While the cred passed to __begin is guaranteed to not change 123 + * and the cred and label could be passed here instead of needput 124 + * using needput with a local var makes it easier for the compiler 125 + * and processor to optimize and speculatively execute the comparison 126 + * than chasing a pointer in the cred struct. 107 127 */ 108 - static inline void __end_current_label_crit_section(struct aa_label *label, 128 + static inline void __end_cred_crit_section(struct aa_label *label, 109 129 bool needput) 110 130 { 111 131 if (unlikely(needput)) 112 132 aa_put_label(label); 133 + } 134 + 135 + /** 136 + * __begin_cred_crit_section - @cred's confining label 137 + * @cred: current's cred to start a crit section on its label 138 + * @needput: store whether the label needs to be put when ending crit section 139 + * 140 + * Returns: up to date confining label or the ns unconfined label (NOT NULL) 141 + * 142 + * safe to call inside locks 143 + * 144 + * The returned reference must be put with __end_cred_crit_section() 145 + * This must NOT be used if the task cred could be updated within the 146 + * critical section between 147 + * __begin_cred_crit_section() .. __end_cred_crit_section() 148 + * 149 + * The crit section is an optimization to avoid having to get and put 150 + * the newest version of the label. While the cred won't change and 151 + * hence the label it contains won't change, the newest version of the 152 + * label can. During the crit section the newest versions of the label 153 + * will be used until the end of the crit section. 154 + * 155 + * If the label has not been updated at the start of the crit section 156 + * no refcount is taken, the cred's refcount is enough to hold the 157 + * label for the duration of the crit section. 158 + * 159 + * If the label has been updated then a refcount will be taken and the 160 + * newest version of the label will be returned. While the cred label 161 + * and the returned label could be compared at the end of the crit 162 + * section, needput is used because it allows better optimization by 163 + * the compiler and the processor's speculative execution. 164 + */ 165 + static inline struct aa_label *__begin_cred_crit_section(const struct cred *cred, 166 + bool *needput) 167 + { 168 + struct aa_label *label = cred_label(cred); 169 + 170 + if (label_is_stale(label)) { 171 + *needput = true; 172 + return aa_get_newest_label(label); 173 + } 174 + 175 + *needput = false; 176 + return label; 177 + } 178 + 179 + /** 180 + * __end_current_label_crit_section - end crit section begun with __begin_... 181 + * @label: label obtained from __begin_current_label_crit_section 182 + * @needput: output: bool set by __begin_current_label_crit_section 183 + * 184 + * wrapper around __end_cred_crit_section() to pair nicely with 185 + * __begin_current_label_crit_section() 186 + */ 187 + static inline void __end_current_label_crit_section(struct aa_label *label, 188 + bool needput) 189 + { 190 + __end_cred_crit_section(label, needput); 113 191 } 114 192 115 193 /** ··· 203 157 */ 204 158 static inline struct aa_label *__begin_current_label_crit_section(bool *needput) 205 159 { 206 - struct aa_label *label = aa_current_raw_label(); 207 - 208 - if (label_is_stale(label)) { 209 - *needput = true; 210 - return aa_get_newest_label(label); 211 - } 212 - 213 - *needput = false; 214 - return label; 160 + return __begin_cred_crit_section(current_cred(), needput); 215 161 } 216 162 217 163 /**