.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Security plug functions |
---|
3 | 4 | * |
---|
.. | .. |
---|
5 | 6 | * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com> |
---|
6 | 7 | * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com> |
---|
7 | 8 | * Copyright (C) 2016 Mellanox Technologies |
---|
8 | | - * |
---|
9 | | - * This program is free software; you can redistribute it and/or modify |
---|
10 | | - * it under the terms of the GNU General Public License as published by |
---|
11 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
12 | | - * (at your option) any later version. |
---|
13 | 9 | */ |
---|
| 10 | + |
---|
| 11 | +#define pr_fmt(fmt) "LSM: " fmt |
---|
14 | 12 | |
---|
15 | 13 | #include <linux/bpf.h> |
---|
16 | 14 | #include <linux/capability.h> |
---|
17 | 15 | #include <linux/dcache.h> |
---|
18 | | -#include <linux/module.h> |
---|
| 16 | +#include <linux/export.h> |
---|
19 | 17 | #include <linux/init.h> |
---|
20 | 18 | #include <linux/kernel.h> |
---|
| 19 | +#include <linux/kernel_read_file.h> |
---|
21 | 20 | #include <linux/lsm_hooks.h> |
---|
22 | 21 | #include <linux/integrity.h> |
---|
23 | 22 | #include <linux/ima.h> |
---|
.. | .. |
---|
28 | 27 | #include <linux/personality.h> |
---|
29 | 28 | #include <linux/backing-dev.h> |
---|
30 | 29 | #include <linux/string.h> |
---|
| 30 | +#include <linux/msg.h> |
---|
31 | 31 | #include <net/flow.h> |
---|
32 | | - |
---|
33 | | -#include <trace/events/initcall.h> |
---|
34 | 32 | |
---|
35 | 33 | #define MAX_LSM_EVM_XATTR 2 |
---|
36 | 34 | |
---|
37 | | -/* Maximum number of letters for an LSM name string */ |
---|
38 | | -#define SECURITY_NAME_MAX 10 |
---|
| 35 | +/* How many LSMs were built into the kernel? */ |
---|
| 36 | +#define LSM_COUNT (__end_lsm_info - __start_lsm_info) |
---|
39 | 37 | |
---|
40 | 38 | struct security_hook_heads security_hook_heads __lsm_ro_after_init; |
---|
41 | | -static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain); |
---|
| 39 | +static BLOCKING_NOTIFIER_HEAD(blocking_lsm_notifier_chain); |
---|
| 40 | + |
---|
| 41 | +static struct kmem_cache *lsm_file_cache; |
---|
| 42 | +static struct kmem_cache *lsm_inode_cache; |
---|
42 | 43 | |
---|
43 | 44 | char *lsm_names; |
---|
| 45 | +static struct lsm_blob_sizes blob_sizes __lsm_ro_after_init; |
---|
| 46 | + |
---|
44 | 47 | /* Boot-time LSM user choice */ |
---|
45 | | -static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = |
---|
46 | | - CONFIG_DEFAULT_SECURITY; |
---|
| 48 | +static __initdata const char *chosen_lsm_order; |
---|
| 49 | +static __initdata const char *chosen_major_lsm; |
---|
47 | 50 | |
---|
48 | | -static void __init do_security_initcalls(void) |
---|
| 51 | +static __initconst const char * const builtin_lsm_order = CONFIG_LSM; |
---|
| 52 | + |
---|
| 53 | +/* Ordered list of LSMs to initialize. */ |
---|
| 54 | +static __initdata struct lsm_info **ordered_lsms; |
---|
| 55 | +static __initdata struct lsm_info *exclusive; |
---|
| 56 | + |
---|
| 57 | +static __initdata bool debug; |
---|
| 58 | +#define init_debug(...) \ |
---|
| 59 | + do { \ |
---|
| 60 | + if (debug) \ |
---|
| 61 | + pr_info(__VA_ARGS__); \ |
---|
| 62 | + } while (0) |
---|
| 63 | + |
---|
| 64 | +static bool __init is_enabled(struct lsm_info *lsm) |
---|
49 | 65 | { |
---|
50 | | - int ret; |
---|
51 | | - initcall_t call; |
---|
52 | | - initcall_entry_t *ce; |
---|
| 66 | + if (!lsm->enabled) |
---|
| 67 | + return false; |
---|
53 | 68 | |
---|
54 | | - ce = __security_initcall_start; |
---|
55 | | - trace_initcall_level("security"); |
---|
56 | | - while (ce < __security_initcall_end) { |
---|
57 | | - call = initcall_from_entry(ce); |
---|
58 | | - trace_initcall_start(call); |
---|
59 | | - ret = call(); |
---|
60 | | - trace_initcall_finish(call, ret); |
---|
61 | | - ce++; |
---|
| 69 | + return *lsm->enabled; |
---|
| 70 | +} |
---|
| 71 | + |
---|
| 72 | +/* Mark an LSM's enabled flag. */ |
---|
| 73 | +static int lsm_enabled_true __initdata = 1; |
---|
| 74 | +static int lsm_enabled_false __initdata = 0; |
---|
| 75 | +static void __init set_enabled(struct lsm_info *lsm, bool enabled) |
---|
| 76 | +{ |
---|
| 77 | + /* |
---|
| 78 | + * When an LSM hasn't configured an enable variable, we can use |
---|
| 79 | + * a hard-coded location for storing the default enabled state. |
---|
| 80 | + */ |
---|
| 81 | + if (!lsm->enabled) { |
---|
| 82 | + if (enabled) |
---|
| 83 | + lsm->enabled = &lsm_enabled_true; |
---|
| 84 | + else |
---|
| 85 | + lsm->enabled = &lsm_enabled_false; |
---|
| 86 | + } else if (lsm->enabled == &lsm_enabled_true) { |
---|
| 87 | + if (!enabled) |
---|
| 88 | + lsm->enabled = &lsm_enabled_false; |
---|
| 89 | + } else if (lsm->enabled == &lsm_enabled_false) { |
---|
| 90 | + if (enabled) |
---|
| 91 | + lsm->enabled = &lsm_enabled_true; |
---|
| 92 | + } else { |
---|
| 93 | + *lsm->enabled = enabled; |
---|
62 | 94 | } |
---|
| 95 | +} |
---|
| 96 | + |
---|
| 97 | +/* Is an LSM already listed in the ordered LSMs list? */ |
---|
| 98 | +static bool __init exists_ordered_lsm(struct lsm_info *lsm) |
---|
| 99 | +{ |
---|
| 100 | + struct lsm_info **check; |
---|
| 101 | + |
---|
| 102 | + for (check = ordered_lsms; *check; check++) |
---|
| 103 | + if (*check == lsm) |
---|
| 104 | + return true; |
---|
| 105 | + |
---|
| 106 | + return false; |
---|
| 107 | +} |
---|
| 108 | + |
---|
| 109 | +/* Append an LSM to the list of ordered LSMs to initialize. */ |
---|
| 110 | +static int last_lsm __initdata; |
---|
| 111 | +static void __init append_ordered_lsm(struct lsm_info *lsm, const char *from) |
---|
| 112 | +{ |
---|
| 113 | + /* Ignore duplicate selections. */ |
---|
| 114 | + if (exists_ordered_lsm(lsm)) |
---|
| 115 | + return; |
---|
| 116 | + |
---|
| 117 | + if (WARN(last_lsm == LSM_COUNT, "%s: out of LSM slots!?\n", from)) |
---|
| 118 | + return; |
---|
| 119 | + |
---|
| 120 | + /* Enable this LSM, if it is not already set. */ |
---|
| 121 | + if (!lsm->enabled) |
---|
| 122 | + lsm->enabled = &lsm_enabled_true; |
---|
| 123 | + ordered_lsms[last_lsm++] = lsm; |
---|
| 124 | + |
---|
| 125 | + init_debug("%s ordering: %s (%sabled)\n", from, lsm->name, |
---|
| 126 | + is_enabled(lsm) ? "en" : "dis"); |
---|
| 127 | +} |
---|
| 128 | + |
---|
| 129 | +/* Is an LSM allowed to be initialized? */ |
---|
| 130 | +static bool __init lsm_allowed(struct lsm_info *lsm) |
---|
| 131 | +{ |
---|
| 132 | + /* Skip if the LSM is disabled. */ |
---|
| 133 | + if (!is_enabled(lsm)) |
---|
| 134 | + return false; |
---|
| 135 | + |
---|
| 136 | + /* Not allowed if another exclusive LSM already initialized. */ |
---|
| 137 | + if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && exclusive) { |
---|
| 138 | + init_debug("exclusive disabled: %s\n", lsm->name); |
---|
| 139 | + return false; |
---|
| 140 | + } |
---|
| 141 | + |
---|
| 142 | + return true; |
---|
| 143 | +} |
---|
| 144 | + |
---|
| 145 | +static void __init lsm_set_blob_size(int *need, int *lbs) |
---|
| 146 | +{ |
---|
| 147 | + int offset; |
---|
| 148 | + |
---|
| 149 | + if (*need > 0) { |
---|
| 150 | + offset = *lbs; |
---|
| 151 | + *lbs += *need; |
---|
| 152 | + *need = offset; |
---|
| 153 | + } |
---|
| 154 | +} |
---|
| 155 | + |
---|
| 156 | +static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed) |
---|
| 157 | +{ |
---|
| 158 | + if (!needed) |
---|
| 159 | + return; |
---|
| 160 | + |
---|
| 161 | + lsm_set_blob_size(&needed->lbs_cred, &blob_sizes.lbs_cred); |
---|
| 162 | + lsm_set_blob_size(&needed->lbs_file, &blob_sizes.lbs_file); |
---|
| 163 | + /* |
---|
| 164 | + * The inode blob gets an rcu_head in addition to |
---|
| 165 | + * what the modules might need. |
---|
| 166 | + */ |
---|
| 167 | + if (needed->lbs_inode && blob_sizes.lbs_inode == 0) |
---|
| 168 | + blob_sizes.lbs_inode = sizeof(struct rcu_head); |
---|
| 169 | + lsm_set_blob_size(&needed->lbs_inode, &blob_sizes.lbs_inode); |
---|
| 170 | + lsm_set_blob_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc); |
---|
| 171 | + lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg); |
---|
| 172 | + lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task); |
---|
| 173 | +} |
---|
| 174 | + |
---|
| 175 | +/* Prepare LSM for initialization. */ |
---|
| 176 | +static void __init prepare_lsm(struct lsm_info *lsm) |
---|
| 177 | +{ |
---|
| 178 | + int enabled = lsm_allowed(lsm); |
---|
| 179 | + |
---|
| 180 | + /* Record enablement (to handle any following exclusive LSMs). */ |
---|
| 181 | + set_enabled(lsm, enabled); |
---|
| 182 | + |
---|
| 183 | + /* If enabled, do pre-initialization work. */ |
---|
| 184 | + if (enabled) { |
---|
| 185 | + if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !exclusive) { |
---|
| 186 | + exclusive = lsm; |
---|
| 187 | + init_debug("exclusive chosen: %s\n", lsm->name); |
---|
| 188 | + } |
---|
| 189 | + |
---|
| 190 | + lsm_set_blob_sizes(lsm->blobs); |
---|
| 191 | + } |
---|
| 192 | +} |
---|
| 193 | + |
---|
| 194 | +/* Initialize a given LSM, if it is enabled. */ |
---|
| 195 | +static void __init initialize_lsm(struct lsm_info *lsm) |
---|
| 196 | +{ |
---|
| 197 | + if (is_enabled(lsm)) { |
---|
| 198 | + int ret; |
---|
| 199 | + |
---|
| 200 | + init_debug("initializing %s\n", lsm->name); |
---|
| 201 | + ret = lsm->init(); |
---|
| 202 | + WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret); |
---|
| 203 | + } |
---|
| 204 | +} |
---|
| 205 | + |
---|
| 206 | +/* Populate ordered LSMs list from comma-separated LSM name list. */ |
---|
| 207 | +static void __init ordered_lsm_parse(const char *order, const char *origin) |
---|
| 208 | +{ |
---|
| 209 | + struct lsm_info *lsm; |
---|
| 210 | + char *sep, *name, *next; |
---|
| 211 | + |
---|
| 212 | + /* LSM_ORDER_FIRST is always first. */ |
---|
| 213 | + for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { |
---|
| 214 | + if (lsm->order == LSM_ORDER_FIRST) |
---|
| 215 | + append_ordered_lsm(lsm, "first"); |
---|
| 216 | + } |
---|
| 217 | + |
---|
| 218 | + /* Process "security=", if given. */ |
---|
| 219 | + if (chosen_major_lsm) { |
---|
| 220 | + struct lsm_info *major; |
---|
| 221 | + |
---|
| 222 | + /* |
---|
| 223 | + * To match the original "security=" behavior, this |
---|
| 224 | + * explicitly does NOT fallback to another Legacy Major |
---|
| 225 | + * if the selected one was separately disabled: disable |
---|
| 226 | + * all non-matching Legacy Major LSMs. |
---|
| 227 | + */ |
---|
| 228 | + for (major = __start_lsm_info; major < __end_lsm_info; |
---|
| 229 | + major++) { |
---|
| 230 | + if ((major->flags & LSM_FLAG_LEGACY_MAJOR) && |
---|
| 231 | + strcmp(major->name, chosen_major_lsm) != 0) { |
---|
| 232 | + set_enabled(major, false); |
---|
| 233 | + init_debug("security=%s disabled: %s\n", |
---|
| 234 | + chosen_major_lsm, major->name); |
---|
| 235 | + } |
---|
| 236 | + } |
---|
| 237 | + } |
---|
| 238 | + |
---|
| 239 | + sep = kstrdup(order, GFP_KERNEL); |
---|
| 240 | + next = sep; |
---|
| 241 | + /* Walk the list, looking for matching LSMs. */ |
---|
| 242 | + while ((name = strsep(&next, ",")) != NULL) { |
---|
| 243 | + bool found = false; |
---|
| 244 | + |
---|
| 245 | + for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { |
---|
| 246 | + if (lsm->order == LSM_ORDER_MUTABLE && |
---|
| 247 | + strcmp(lsm->name, name) == 0) { |
---|
| 248 | + append_ordered_lsm(lsm, origin); |
---|
| 249 | + found = true; |
---|
| 250 | + } |
---|
| 251 | + } |
---|
| 252 | + |
---|
| 253 | + if (!found) |
---|
| 254 | + init_debug("%s ignored: %s\n", origin, name); |
---|
| 255 | + } |
---|
| 256 | + |
---|
| 257 | + /* Process "security=", if given. */ |
---|
| 258 | + if (chosen_major_lsm) { |
---|
| 259 | + for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { |
---|
| 260 | + if (exists_ordered_lsm(lsm)) |
---|
| 261 | + continue; |
---|
| 262 | + if (strcmp(lsm->name, chosen_major_lsm) == 0) |
---|
| 263 | + append_ordered_lsm(lsm, "security="); |
---|
| 264 | + } |
---|
| 265 | + } |
---|
| 266 | + |
---|
| 267 | + /* Disable all LSMs not in the ordered list. */ |
---|
| 268 | + for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { |
---|
| 269 | + if (exists_ordered_lsm(lsm)) |
---|
| 270 | + continue; |
---|
| 271 | + set_enabled(lsm, false); |
---|
| 272 | + init_debug("%s disabled: %s\n", origin, lsm->name); |
---|
| 273 | + } |
---|
| 274 | + |
---|
| 275 | + kfree(sep); |
---|
| 276 | +} |
---|
| 277 | + |
---|
| 278 | +static void __init lsm_early_cred(struct cred *cred); |
---|
| 279 | +static void __init lsm_early_task(struct task_struct *task); |
---|
| 280 | + |
---|
| 281 | +static int lsm_append(const char *new, char **result); |
---|
| 282 | + |
---|
| 283 | +static void __init ordered_lsm_init(void) |
---|
| 284 | +{ |
---|
| 285 | + struct lsm_info **lsm; |
---|
| 286 | + |
---|
| 287 | + ordered_lsms = kcalloc(LSM_COUNT + 1, sizeof(*ordered_lsms), |
---|
| 288 | + GFP_KERNEL); |
---|
| 289 | + |
---|
| 290 | + if (chosen_lsm_order) { |
---|
| 291 | + if (chosen_major_lsm) { |
---|
| 292 | + pr_info("security= is ignored because it is superseded by lsm=\n"); |
---|
| 293 | + chosen_major_lsm = NULL; |
---|
| 294 | + } |
---|
| 295 | + ordered_lsm_parse(chosen_lsm_order, "cmdline"); |
---|
| 296 | + } else |
---|
| 297 | + ordered_lsm_parse(builtin_lsm_order, "builtin"); |
---|
| 298 | + |
---|
| 299 | + for (lsm = ordered_lsms; *lsm; lsm++) |
---|
| 300 | + prepare_lsm(*lsm); |
---|
| 301 | + |
---|
| 302 | + init_debug("cred blob size = %d\n", blob_sizes.lbs_cred); |
---|
| 303 | + init_debug("file blob size = %d\n", blob_sizes.lbs_file); |
---|
| 304 | + init_debug("inode blob size = %d\n", blob_sizes.lbs_inode); |
---|
| 305 | + init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc); |
---|
| 306 | + init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg); |
---|
| 307 | + init_debug("task blob size = %d\n", blob_sizes.lbs_task); |
---|
| 308 | + |
---|
| 309 | + /* |
---|
| 310 | + * Create any kmem_caches needed for blobs |
---|
| 311 | + */ |
---|
| 312 | + if (blob_sizes.lbs_file) |
---|
| 313 | + lsm_file_cache = kmem_cache_create("lsm_file_cache", |
---|
| 314 | + blob_sizes.lbs_file, 0, |
---|
| 315 | + SLAB_PANIC, NULL); |
---|
| 316 | + if (blob_sizes.lbs_inode) |
---|
| 317 | + lsm_inode_cache = kmem_cache_create("lsm_inode_cache", |
---|
| 318 | + blob_sizes.lbs_inode, 0, |
---|
| 319 | + SLAB_PANIC, NULL); |
---|
| 320 | + |
---|
| 321 | + lsm_early_cred((struct cred *) current->cred); |
---|
| 322 | + lsm_early_task(current); |
---|
| 323 | + for (lsm = ordered_lsms; *lsm; lsm++) |
---|
| 324 | + initialize_lsm(*lsm); |
---|
| 325 | + |
---|
| 326 | + kfree(ordered_lsms); |
---|
| 327 | +} |
---|
| 328 | + |
---|
| 329 | +int __init early_security_init(void) |
---|
| 330 | +{ |
---|
| 331 | + int i; |
---|
| 332 | + struct hlist_head *list = (struct hlist_head *) &security_hook_heads; |
---|
| 333 | + struct lsm_info *lsm; |
---|
| 334 | + |
---|
| 335 | + for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct hlist_head); |
---|
| 336 | + i++) |
---|
| 337 | + INIT_HLIST_HEAD(&list[i]); |
---|
| 338 | + |
---|
| 339 | + for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) { |
---|
| 340 | + if (!lsm->enabled) |
---|
| 341 | + lsm->enabled = &lsm_enabled_true; |
---|
| 342 | + prepare_lsm(lsm); |
---|
| 343 | + initialize_lsm(lsm); |
---|
| 344 | + } |
---|
| 345 | + |
---|
| 346 | + return 0; |
---|
63 | 347 | } |
---|
64 | 348 | |
---|
65 | 349 | /** |
---|
.. | .. |
---|
69 | 353 | */ |
---|
70 | 354 | int __init security_init(void) |
---|
71 | 355 | { |
---|
72 | | - int i; |
---|
73 | | - struct hlist_head *list = (struct hlist_head *) &security_hook_heads; |
---|
| 356 | + struct lsm_info *lsm; |
---|
74 | 357 | |
---|
75 | | - for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct hlist_head); |
---|
76 | | - i++) |
---|
77 | | - INIT_HLIST_HEAD(&list[i]); |
---|
78 | | - pr_info("Security Framework initialized\n"); |
---|
| 358 | + pr_info("Security Framework initializing\n"); |
---|
79 | 359 | |
---|
80 | 360 | /* |
---|
81 | | - * Load minor LSMs, with the capability module always first. |
---|
| 361 | + * Append the names of the early LSM modules now that kmalloc() is |
---|
| 362 | + * available |
---|
82 | 363 | */ |
---|
83 | | - capability_add_hooks(); |
---|
84 | | - yama_add_hooks(); |
---|
85 | | - loadpin_add_hooks(); |
---|
| 364 | + for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) { |
---|
| 365 | + if (lsm->enabled) |
---|
| 366 | + lsm_append(lsm->name, &lsm_names); |
---|
| 367 | + } |
---|
86 | 368 | |
---|
87 | | - /* |
---|
88 | | - * Load all the remaining security modules. |
---|
89 | | - */ |
---|
90 | | - do_security_initcalls(); |
---|
| 369 | + /* Load LSMs in specified order. */ |
---|
| 370 | + ordered_lsm_init(); |
---|
91 | 371 | |
---|
92 | 372 | return 0; |
---|
93 | 373 | } |
---|
94 | 374 | |
---|
95 | 375 | /* Save user chosen LSM */ |
---|
96 | | -static int __init choose_lsm(char *str) |
---|
| 376 | +static int __init choose_major_lsm(char *str) |
---|
97 | 377 | { |
---|
98 | | - strncpy(chosen_lsm, str, SECURITY_NAME_MAX); |
---|
| 378 | + chosen_major_lsm = str; |
---|
99 | 379 | return 1; |
---|
100 | 380 | } |
---|
101 | | -__setup("security=", choose_lsm); |
---|
| 381 | +__setup("security=", choose_major_lsm); |
---|
| 382 | + |
---|
| 383 | +/* Explicitly choose LSM initialization order. */ |
---|
| 384 | +static int __init choose_lsm_order(char *str) |
---|
| 385 | +{ |
---|
| 386 | + chosen_lsm_order = str; |
---|
| 387 | + return 1; |
---|
| 388 | +} |
---|
| 389 | +__setup("lsm=", choose_lsm_order); |
---|
| 390 | + |
---|
| 391 | +/* Enable LSM order debugging. */ |
---|
| 392 | +static int __init enable_debug(char *str) |
---|
| 393 | +{ |
---|
| 394 | + debug = true; |
---|
| 395 | + return 1; |
---|
| 396 | +} |
---|
| 397 | +__setup("lsm.debug", enable_debug); |
---|
102 | 398 | |
---|
103 | 399 | static bool match_last_lsm(const char *list, const char *lsm) |
---|
104 | 400 | { |
---|
.. | .. |
---|
115 | 411 | return !strcmp(last, lsm); |
---|
116 | 412 | } |
---|
117 | 413 | |
---|
118 | | -static int lsm_append(char *new, char **result) |
---|
| 414 | +static int lsm_append(const char *new, char **result) |
---|
119 | 415 | { |
---|
120 | 416 | char *cp; |
---|
121 | 417 | |
---|
.. | .. |
---|
137 | 433 | } |
---|
138 | 434 | |
---|
139 | 435 | /** |
---|
140 | | - * security_module_enable - Load given security module on boot ? |
---|
141 | | - * @module: the name of the module |
---|
142 | | - * |
---|
143 | | - * Each LSM must pass this method before registering its own operations |
---|
144 | | - * to avoid security registration races. This method may also be used |
---|
145 | | - * to check if your LSM is currently loaded during kernel initialization. |
---|
146 | | - * |
---|
147 | | - * Returns: |
---|
148 | | - * |
---|
149 | | - * true if: |
---|
150 | | - * |
---|
151 | | - * - The passed LSM is the one chosen by user at boot time, |
---|
152 | | - * - or the passed LSM is configured as the default and the user did not |
---|
153 | | - * choose an alternate LSM at boot time. |
---|
154 | | - * |
---|
155 | | - * Otherwise, return false. |
---|
156 | | - */ |
---|
157 | | -int __init security_module_enable(const char *module) |
---|
158 | | -{ |
---|
159 | | - return !strcmp(module, chosen_lsm); |
---|
160 | | -} |
---|
161 | | - |
---|
162 | | -/** |
---|
163 | 436 | * security_add_hooks - Add a modules hooks to the hook lists. |
---|
164 | 437 | * @hooks: the hooks to add |
---|
165 | 438 | * @count: the number of hooks to add |
---|
.. | .. |
---|
176 | 449 | hooks[i].lsm = lsm; |
---|
177 | 450 | hlist_add_tail_rcu(&hooks[i].list, hooks[i].head); |
---|
178 | 451 | } |
---|
179 | | - if (lsm_append(lsm, &lsm_names) < 0) |
---|
180 | | - panic("%s - Cannot get early memory.\n", __func__); |
---|
| 452 | + |
---|
| 453 | + /* |
---|
| 454 | + * Don't try to append during early_security_init(), we'll come back |
---|
| 455 | + * and fix this up afterwards. |
---|
| 456 | + */ |
---|
| 457 | + if (slab_is_available()) { |
---|
| 458 | + if (lsm_append(lsm, &lsm_names) < 0) |
---|
| 459 | + panic("%s - Cannot get early memory.\n", __func__); |
---|
| 460 | + } |
---|
181 | 461 | } |
---|
182 | 462 | |
---|
183 | | -int call_lsm_notifier(enum lsm_event event, void *data) |
---|
| 463 | +int call_blocking_lsm_notifier(enum lsm_event event, void *data) |
---|
184 | 464 | { |
---|
185 | | - return atomic_notifier_call_chain(&lsm_notifier_chain, event, data); |
---|
| 465 | + return blocking_notifier_call_chain(&blocking_lsm_notifier_chain, |
---|
| 466 | + event, data); |
---|
186 | 467 | } |
---|
187 | | -EXPORT_SYMBOL(call_lsm_notifier); |
---|
| 468 | +EXPORT_SYMBOL(call_blocking_lsm_notifier); |
---|
188 | 469 | |
---|
189 | | -int register_lsm_notifier(struct notifier_block *nb) |
---|
| 470 | +int register_blocking_lsm_notifier(struct notifier_block *nb) |
---|
190 | 471 | { |
---|
191 | | - return atomic_notifier_chain_register(&lsm_notifier_chain, nb); |
---|
| 472 | + return blocking_notifier_chain_register(&blocking_lsm_notifier_chain, |
---|
| 473 | + nb); |
---|
192 | 474 | } |
---|
193 | | -EXPORT_SYMBOL(register_lsm_notifier); |
---|
| 475 | +EXPORT_SYMBOL(register_blocking_lsm_notifier); |
---|
194 | 476 | |
---|
195 | | -int unregister_lsm_notifier(struct notifier_block *nb) |
---|
| 477 | +int unregister_blocking_lsm_notifier(struct notifier_block *nb) |
---|
196 | 478 | { |
---|
197 | | - return atomic_notifier_chain_unregister(&lsm_notifier_chain, nb); |
---|
| 479 | + return blocking_notifier_chain_unregister(&blocking_lsm_notifier_chain, |
---|
| 480 | + nb); |
---|
198 | 481 | } |
---|
199 | | -EXPORT_SYMBOL(unregister_lsm_notifier); |
---|
| 482 | +EXPORT_SYMBOL(unregister_blocking_lsm_notifier); |
---|
| 483 | + |
---|
| 484 | +/** |
---|
| 485 | + * lsm_cred_alloc - allocate a composite cred blob |
---|
| 486 | + * @cred: the cred that needs a blob |
---|
| 487 | + * @gfp: allocation type |
---|
| 488 | + * |
---|
| 489 | + * Allocate the cred blob for all the modules |
---|
| 490 | + * |
---|
| 491 | + * Returns 0, or -ENOMEM if memory can't be allocated. |
---|
| 492 | + */ |
---|
| 493 | +static int lsm_cred_alloc(struct cred *cred, gfp_t gfp) |
---|
| 494 | +{ |
---|
| 495 | + if (blob_sizes.lbs_cred == 0) { |
---|
| 496 | + cred->security = NULL; |
---|
| 497 | + return 0; |
---|
| 498 | + } |
---|
| 499 | + |
---|
| 500 | + cred->security = kzalloc(blob_sizes.lbs_cred, gfp); |
---|
| 501 | + if (cred->security == NULL) |
---|
| 502 | + return -ENOMEM; |
---|
| 503 | + return 0; |
---|
| 504 | +} |
---|
| 505 | + |
---|
| 506 | +/** |
---|
| 507 | + * lsm_early_cred - during initialization allocate a composite cred blob |
---|
| 508 | + * @cred: the cred that needs a blob |
---|
| 509 | + * |
---|
| 510 | + * Allocate the cred blob for all the modules |
---|
| 511 | + */ |
---|
| 512 | +static void __init lsm_early_cred(struct cred *cred) |
---|
| 513 | +{ |
---|
| 514 | + int rc = lsm_cred_alloc(cred, GFP_KERNEL); |
---|
| 515 | + |
---|
| 516 | + if (rc) |
---|
| 517 | + panic("%s: Early cred alloc failed.\n", __func__); |
---|
| 518 | +} |
---|
| 519 | + |
---|
| 520 | +/** |
---|
| 521 | + * lsm_file_alloc - allocate a composite file blob |
---|
| 522 | + * @file: the file that needs a blob |
---|
| 523 | + * |
---|
| 524 | + * Allocate the file blob for all the modules |
---|
| 525 | + * |
---|
| 526 | + * Returns 0, or -ENOMEM if memory can't be allocated. |
---|
| 527 | + */ |
---|
| 528 | +static int lsm_file_alloc(struct file *file) |
---|
| 529 | +{ |
---|
| 530 | + if (!lsm_file_cache) { |
---|
| 531 | + file->f_security = NULL; |
---|
| 532 | + return 0; |
---|
| 533 | + } |
---|
| 534 | + |
---|
| 535 | + file->f_security = kmem_cache_zalloc(lsm_file_cache, GFP_KERNEL); |
---|
| 536 | + if (file->f_security == NULL) |
---|
| 537 | + return -ENOMEM; |
---|
| 538 | + return 0; |
---|
| 539 | +} |
---|
| 540 | + |
---|
| 541 | +/** |
---|
| 542 | + * lsm_inode_alloc - allocate a composite inode blob |
---|
| 543 | + * @inode: the inode that needs a blob |
---|
| 544 | + * |
---|
| 545 | + * Allocate the inode blob for all the modules |
---|
| 546 | + * |
---|
| 547 | + * Returns 0, or -ENOMEM if memory can't be allocated. |
---|
| 548 | + */ |
---|
| 549 | +int lsm_inode_alloc(struct inode *inode) |
---|
| 550 | +{ |
---|
| 551 | + if (!lsm_inode_cache) { |
---|
| 552 | + inode->i_security = NULL; |
---|
| 553 | + return 0; |
---|
| 554 | + } |
---|
| 555 | + |
---|
| 556 | + inode->i_security = kmem_cache_zalloc(lsm_inode_cache, GFP_NOFS); |
---|
| 557 | + if (inode->i_security == NULL) |
---|
| 558 | + return -ENOMEM; |
---|
| 559 | + return 0; |
---|
| 560 | +} |
---|
| 561 | + |
---|
| 562 | +/** |
---|
| 563 | + * lsm_task_alloc - allocate a composite task blob |
---|
| 564 | + * @task: the task that needs a blob |
---|
| 565 | + * |
---|
| 566 | + * Allocate the task blob for all the modules |
---|
| 567 | + * |
---|
| 568 | + * Returns 0, or -ENOMEM if memory can't be allocated. |
---|
| 569 | + */ |
---|
| 570 | +static int lsm_task_alloc(struct task_struct *task) |
---|
| 571 | +{ |
---|
| 572 | + if (blob_sizes.lbs_task == 0) { |
---|
| 573 | + task->security = NULL; |
---|
| 574 | + return 0; |
---|
| 575 | + } |
---|
| 576 | + |
---|
| 577 | + task->security = kzalloc(blob_sizes.lbs_task, GFP_KERNEL); |
---|
| 578 | + if (task->security == NULL) |
---|
| 579 | + return -ENOMEM; |
---|
| 580 | + return 0; |
---|
| 581 | +} |
---|
| 582 | + |
---|
| 583 | +/** |
---|
| 584 | + * lsm_ipc_alloc - allocate a composite ipc blob |
---|
| 585 | + * @kip: the ipc that needs a blob |
---|
| 586 | + * |
---|
| 587 | + * Allocate the ipc blob for all the modules |
---|
| 588 | + * |
---|
| 589 | + * Returns 0, or -ENOMEM if memory can't be allocated. |
---|
| 590 | + */ |
---|
| 591 | +static int lsm_ipc_alloc(struct kern_ipc_perm *kip) |
---|
| 592 | +{ |
---|
| 593 | + if (blob_sizes.lbs_ipc == 0) { |
---|
| 594 | + kip->security = NULL; |
---|
| 595 | + return 0; |
---|
| 596 | + } |
---|
| 597 | + |
---|
| 598 | + kip->security = kzalloc(blob_sizes.lbs_ipc, GFP_KERNEL); |
---|
| 599 | + if (kip->security == NULL) |
---|
| 600 | + return -ENOMEM; |
---|
| 601 | + return 0; |
---|
| 602 | +} |
---|
| 603 | + |
---|
| 604 | +/** |
---|
| 605 | + * lsm_msg_msg_alloc - allocate a composite msg_msg blob |
---|
| 606 | + * @mp: the msg_msg that needs a blob |
---|
| 607 | + * |
---|
| 608 | + * Allocate the ipc blob for all the modules |
---|
| 609 | + * |
---|
| 610 | + * Returns 0, or -ENOMEM if memory can't be allocated. |
---|
| 611 | + */ |
---|
| 612 | +static int lsm_msg_msg_alloc(struct msg_msg *mp) |
---|
| 613 | +{ |
---|
| 614 | + if (blob_sizes.lbs_msg_msg == 0) { |
---|
| 615 | + mp->security = NULL; |
---|
| 616 | + return 0; |
---|
| 617 | + } |
---|
| 618 | + |
---|
| 619 | + mp->security = kzalloc(blob_sizes.lbs_msg_msg, GFP_KERNEL); |
---|
| 620 | + if (mp->security == NULL) |
---|
| 621 | + return -ENOMEM; |
---|
| 622 | + return 0; |
---|
| 623 | +} |
---|
| 624 | + |
---|
| 625 | +/** |
---|
| 626 | + * lsm_early_task - during initialization allocate a composite task blob |
---|
| 627 | + * @task: the task that needs a blob |
---|
| 628 | + * |
---|
| 629 | + * Allocate the task blob for all the modules |
---|
| 630 | + */ |
---|
| 631 | +static void __init lsm_early_task(struct task_struct *task) |
---|
| 632 | +{ |
---|
| 633 | + int rc = lsm_task_alloc(task); |
---|
| 634 | + |
---|
| 635 | + if (rc) |
---|
| 636 | + panic("%s: Early task alloc failed.\n", __func__); |
---|
| 637 | +} |
---|
| 638 | + |
---|
| 639 | +/* |
---|
| 640 | + * The default value of the LSM hook is defined in linux/lsm_hook_defs.h and |
---|
| 641 | + * can be accessed with: |
---|
| 642 | + * |
---|
| 643 | + * LSM_RET_DEFAULT(<hook_name>) |
---|
| 644 | + * |
---|
| 645 | + * The macros below define static constants for the default value of each |
---|
| 646 | + * LSM hook. |
---|
| 647 | + */ |
---|
| 648 | +#define LSM_RET_DEFAULT(NAME) (NAME##_default) |
---|
| 649 | +#define DECLARE_LSM_RET_DEFAULT_void(DEFAULT, NAME) |
---|
| 650 | +#define DECLARE_LSM_RET_DEFAULT_int(DEFAULT, NAME) \ |
---|
| 651 | + static const int LSM_RET_DEFAULT(NAME) = (DEFAULT); |
---|
| 652 | +#define LSM_HOOK(RET, DEFAULT, NAME, ...) \ |
---|
| 653 | + DECLARE_LSM_RET_DEFAULT_##RET(DEFAULT, NAME) |
---|
| 654 | + |
---|
| 655 | +#include <linux/lsm_hook_defs.h> |
---|
| 656 | +#undef LSM_HOOK |
---|
200 | 657 | |
---|
201 | 658 | /* |
---|
202 | 659 | * Hook list operation macros. |
---|
.. | .. |
---|
334 | 791 | return __vm_enough_memory(mm, pages, cap_sys_admin); |
---|
335 | 792 | } |
---|
336 | 793 | |
---|
337 | | -int security_bprm_set_creds(struct linux_binprm *bprm) |
---|
| 794 | +int security_bprm_creds_for_exec(struct linux_binprm *bprm) |
---|
338 | 795 | { |
---|
339 | | - return call_int_hook(bprm_set_creds, 0, bprm); |
---|
| 796 | + return call_int_hook(bprm_creds_for_exec, 0, bprm); |
---|
| 797 | +} |
---|
| 798 | + |
---|
| 799 | +int security_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file) |
---|
| 800 | +{ |
---|
| 801 | + return call_int_hook(bprm_creds_from_file, 0, bprm, file); |
---|
340 | 802 | } |
---|
341 | 803 | |
---|
342 | 804 | int security_bprm_check(struct linux_binprm *bprm) |
---|
.. | .. |
---|
359 | 821 | call_void_hook(bprm_committed_creds, bprm); |
---|
360 | 822 | } |
---|
361 | 823 | |
---|
| 824 | +int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc) |
---|
| 825 | +{ |
---|
| 826 | + return call_int_hook(fs_context_dup, 0, fc, src_fc); |
---|
| 827 | +} |
---|
| 828 | + |
---|
| 829 | +int security_fs_context_parse_param(struct fs_context *fc, |
---|
| 830 | + struct fs_parameter *param) |
---|
| 831 | +{ |
---|
| 832 | + struct security_hook_list *hp; |
---|
| 833 | + int trc; |
---|
| 834 | + int rc = -ENOPARAM; |
---|
| 835 | + |
---|
| 836 | + hlist_for_each_entry(hp, &security_hook_heads.fs_context_parse_param, |
---|
| 837 | + list) { |
---|
| 838 | + trc = hp->hook.fs_context_parse_param(fc, param); |
---|
| 839 | + if (trc == 0) |
---|
| 840 | + rc = 0; |
---|
| 841 | + else if (trc != -ENOPARAM) |
---|
| 842 | + return trc; |
---|
| 843 | + } |
---|
| 844 | + return rc; |
---|
| 845 | +} |
---|
| 846 | + |
---|
362 | 847 | int security_sb_alloc(struct super_block *sb) |
---|
363 | 848 | { |
---|
364 | 849 | return call_int_hook(sb_alloc_security, 0, sb); |
---|
.. | .. |
---|
369 | 854 | call_void_hook(sb_free_security, sb); |
---|
370 | 855 | } |
---|
371 | 856 | |
---|
372 | | -int security_sb_copy_data(char *orig, char *copy) |
---|
| 857 | +void security_free_mnt_opts(void **mnt_opts) |
---|
373 | 858 | { |
---|
374 | | - return call_int_hook(sb_copy_data, 0, orig, copy); |
---|
| 859 | + if (!*mnt_opts) |
---|
| 860 | + return; |
---|
| 861 | + call_void_hook(sb_free_mnt_opts, *mnt_opts); |
---|
| 862 | + *mnt_opts = NULL; |
---|
375 | 863 | } |
---|
376 | | -EXPORT_SYMBOL(security_sb_copy_data); |
---|
| 864 | +EXPORT_SYMBOL(security_free_mnt_opts); |
---|
377 | 865 | |
---|
378 | | -int security_sb_remount(struct super_block *sb, void *data) |
---|
| 866 | +int security_sb_eat_lsm_opts(char *options, void **mnt_opts) |
---|
379 | 867 | { |
---|
380 | | - return call_int_hook(sb_remount, 0, sb, data); |
---|
| 868 | + return call_int_hook(sb_eat_lsm_opts, 0, options, mnt_opts); |
---|
381 | 869 | } |
---|
| 870 | +EXPORT_SYMBOL(security_sb_eat_lsm_opts); |
---|
382 | 871 | |
---|
383 | | -int security_sb_kern_mount(struct super_block *sb, int flags, void *data) |
---|
| 872 | +int security_sb_remount(struct super_block *sb, |
---|
| 873 | + void *mnt_opts) |
---|
384 | 874 | { |
---|
385 | | - return call_int_hook(sb_kern_mount, 0, sb, flags, data); |
---|
| 875 | + return call_int_hook(sb_remount, 0, sb, mnt_opts); |
---|
| 876 | +} |
---|
| 877 | +EXPORT_SYMBOL(security_sb_remount); |
---|
| 878 | + |
---|
| 879 | +int security_sb_kern_mount(struct super_block *sb) |
---|
| 880 | +{ |
---|
| 881 | + return call_int_hook(sb_kern_mount, 0, sb); |
---|
386 | 882 | } |
---|
387 | 883 | |
---|
388 | 884 | int security_sb_show_options(struct seq_file *m, struct super_block *sb) |
---|
.. | .. |
---|
412 | 908 | } |
---|
413 | 909 | |
---|
414 | 910 | int security_sb_set_mnt_opts(struct super_block *sb, |
---|
415 | | - struct security_mnt_opts *opts, |
---|
| 911 | + void *mnt_opts, |
---|
416 | 912 | unsigned long kern_flags, |
---|
417 | 913 | unsigned long *set_kern_flags) |
---|
418 | 914 | { |
---|
419 | 915 | return call_int_hook(sb_set_mnt_opts, |
---|
420 | | - opts->num_mnt_opts ? -EOPNOTSUPP : 0, sb, |
---|
421 | | - opts, kern_flags, set_kern_flags); |
---|
| 916 | + mnt_opts ? -EOPNOTSUPP : 0, sb, |
---|
| 917 | + mnt_opts, kern_flags, set_kern_flags); |
---|
422 | 918 | } |
---|
423 | 919 | EXPORT_SYMBOL(security_sb_set_mnt_opts); |
---|
424 | 920 | |
---|
.. | .. |
---|
432 | 928 | } |
---|
433 | 929 | EXPORT_SYMBOL(security_sb_clone_mnt_opts); |
---|
434 | 930 | |
---|
435 | | -int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) |
---|
| 931 | +int security_add_mnt_opt(const char *option, const char *val, int len, |
---|
| 932 | + void **mnt_opts) |
---|
436 | 933 | { |
---|
437 | | - return call_int_hook(sb_parse_opts_str, 0, options, opts); |
---|
| 934 | + return call_int_hook(sb_add_mnt_opt, -EINVAL, |
---|
| 935 | + option, val, len, mnt_opts); |
---|
438 | 936 | } |
---|
439 | | -EXPORT_SYMBOL(security_sb_parse_opts_str); |
---|
| 937 | +EXPORT_SYMBOL(security_add_mnt_opt); |
---|
| 938 | + |
---|
| 939 | +int security_move_mount(const struct path *from_path, const struct path *to_path) |
---|
| 940 | +{ |
---|
| 941 | + return call_int_hook(move_mount, 0, from_path, to_path); |
---|
| 942 | +} |
---|
| 943 | + |
---|
| 944 | +int security_path_notify(const struct path *path, u64 mask, |
---|
| 945 | + unsigned int obj_type) |
---|
| 946 | +{ |
---|
| 947 | + return call_int_hook(path_notify, 0, path, mask, obj_type); |
---|
| 948 | +} |
---|
440 | 949 | |
---|
441 | 950 | int security_inode_alloc(struct inode *inode) |
---|
442 | 951 | { |
---|
443 | | - inode->i_security = NULL; |
---|
444 | | - return call_int_hook(inode_alloc_security, 0, inode); |
---|
| 952 | + int rc = lsm_inode_alloc(inode); |
---|
| 953 | + |
---|
| 954 | + if (unlikely(rc)) |
---|
| 955 | + return rc; |
---|
| 956 | + rc = call_int_hook(inode_alloc_security, 0, inode); |
---|
| 957 | + if (unlikely(rc)) |
---|
| 958 | + security_inode_free(inode); |
---|
| 959 | + return rc; |
---|
| 960 | +} |
---|
| 961 | + |
---|
| 962 | +static void inode_free_by_rcu(struct rcu_head *head) |
---|
| 963 | +{ |
---|
| 964 | + /* |
---|
| 965 | + * The rcu head is at the start of the inode blob |
---|
| 966 | + */ |
---|
| 967 | + kmem_cache_free(lsm_inode_cache, head); |
---|
445 | 968 | } |
---|
446 | 969 | |
---|
447 | 970 | void security_inode_free(struct inode *inode) |
---|
448 | 971 | { |
---|
449 | 972 | integrity_inode_free(inode); |
---|
450 | 973 | call_void_hook(inode_free_security, inode); |
---|
| 974 | + /* |
---|
| 975 | + * The inode may still be referenced in a path walk and |
---|
| 976 | + * a call to security_inode_permission() can be made |
---|
| 977 | + * after inode_free_security() is called. Ideally, the VFS |
---|
| 978 | + * wouldn't do this, but fixing that is a much harder |
---|
| 979 | + * job. For now, simply free the i_security via RCU, and |
---|
| 980 | + * leave the current inode->i_security pointer intact. |
---|
| 981 | + * The inode will be freed after the RCU grace period too. |
---|
| 982 | + */ |
---|
| 983 | + if (inode->i_security) |
---|
| 984 | + call_rcu((struct rcu_head *)inode->i_security, |
---|
| 985 | + inode_free_by_rcu); |
---|
451 | 986 | } |
---|
452 | 987 | |
---|
453 | 988 | int security_dentry_init_security(struct dentry *dentry, int mode, |
---|
.. | .. |
---|
502 | 1037 | return (ret == -EOPNOTSUPP) ? 0 : ret; |
---|
503 | 1038 | } |
---|
504 | 1039 | EXPORT_SYMBOL(security_inode_init_security); |
---|
| 1040 | + |
---|
| 1041 | +int security_inode_init_security_anon(struct inode *inode, |
---|
| 1042 | + const struct qstr *name, |
---|
| 1043 | + const struct inode *context_inode) |
---|
| 1044 | +{ |
---|
| 1045 | + return call_int_hook(inode_init_security_anon, 0, inode, name, |
---|
| 1046 | + context_inode); |
---|
| 1047 | +} |
---|
505 | 1048 | |
---|
506 | 1049 | int security_old_inode_init_security(struct inode *inode, struct inode *dir, |
---|
507 | 1050 | const struct qstr *qstr, const char **name, |
---|
.. | .. |
---|
808 | 1351 | int rc; |
---|
809 | 1352 | |
---|
810 | 1353 | if (unlikely(IS_PRIVATE(inode))) |
---|
811 | | - return -EOPNOTSUPP; |
---|
| 1354 | + return LSM_RET_DEFAULT(inode_getsecurity); |
---|
812 | 1355 | /* |
---|
813 | 1356 | * Only one module will provide an attribute with a given name. |
---|
814 | 1357 | */ |
---|
815 | 1358 | hlist_for_each_entry(hp, &security_hook_heads.inode_getsecurity, list) { |
---|
816 | 1359 | rc = hp->hook.inode_getsecurity(inode, name, buffer, alloc); |
---|
817 | | - if (rc != -EOPNOTSUPP) |
---|
| 1360 | + if (rc != LSM_RET_DEFAULT(inode_getsecurity)) |
---|
818 | 1361 | return rc; |
---|
819 | 1362 | } |
---|
820 | | - return -EOPNOTSUPP; |
---|
| 1363 | + return LSM_RET_DEFAULT(inode_getsecurity); |
---|
821 | 1364 | } |
---|
822 | 1365 | |
---|
823 | 1366 | int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags) |
---|
.. | .. |
---|
826 | 1369 | int rc; |
---|
827 | 1370 | |
---|
828 | 1371 | if (unlikely(IS_PRIVATE(inode))) |
---|
829 | | - return -EOPNOTSUPP; |
---|
| 1372 | + return LSM_RET_DEFAULT(inode_setsecurity); |
---|
830 | 1373 | /* |
---|
831 | 1374 | * Only one module will provide an attribute with a given name. |
---|
832 | 1375 | */ |
---|
833 | 1376 | hlist_for_each_entry(hp, &security_hook_heads.inode_setsecurity, list) { |
---|
834 | 1377 | rc = hp->hook.inode_setsecurity(inode, name, value, size, |
---|
835 | 1378 | flags); |
---|
836 | | - if (rc != -EOPNOTSUPP) |
---|
| 1379 | + if (rc != LSM_RET_DEFAULT(inode_setsecurity)) |
---|
837 | 1380 | return rc; |
---|
838 | 1381 | } |
---|
839 | | - return -EOPNOTSUPP; |
---|
| 1382 | + return LSM_RET_DEFAULT(inode_setsecurity); |
---|
840 | 1383 | } |
---|
841 | 1384 | |
---|
842 | 1385 | int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) |
---|
.. | .. |
---|
860 | 1403 | |
---|
861 | 1404 | int security_inode_copy_up_xattr(const char *name) |
---|
862 | 1405 | { |
---|
863 | | - return call_int_hook(inode_copy_up_xattr, -EOPNOTSUPP, name); |
---|
| 1406 | + struct security_hook_list *hp; |
---|
| 1407 | + int rc; |
---|
| 1408 | + |
---|
| 1409 | + /* |
---|
| 1410 | + * The implementation can return 0 (accept the xattr), 1 (discard the |
---|
| 1411 | + * xattr), -EOPNOTSUPP if it does not know anything about the xattr or |
---|
| 1412 | + * any other error code incase of an error. |
---|
| 1413 | + */ |
---|
| 1414 | + hlist_for_each_entry(hp, |
---|
| 1415 | + &security_hook_heads.inode_copy_up_xattr, list) { |
---|
| 1416 | + rc = hp->hook.inode_copy_up_xattr(name); |
---|
| 1417 | + if (rc != LSM_RET_DEFAULT(inode_copy_up_xattr)) |
---|
| 1418 | + return rc; |
---|
| 1419 | + } |
---|
| 1420 | + |
---|
| 1421 | + return LSM_RET_DEFAULT(inode_copy_up_xattr); |
---|
864 | 1422 | } |
---|
865 | 1423 | EXPORT_SYMBOL(security_inode_copy_up_xattr); |
---|
| 1424 | + |
---|
| 1425 | +int security_kernfs_init_security(struct kernfs_node *kn_dir, |
---|
| 1426 | + struct kernfs_node *kn) |
---|
| 1427 | +{ |
---|
| 1428 | + return call_int_hook(kernfs_init_security, 0, kn_dir, kn); |
---|
| 1429 | +} |
---|
866 | 1430 | |
---|
867 | 1431 | int security_file_permission(struct file *file, int mask) |
---|
868 | 1432 | { |
---|
.. | .. |
---|
877 | 1441 | |
---|
878 | 1442 | int security_file_alloc(struct file *file) |
---|
879 | 1443 | { |
---|
880 | | - return call_int_hook(file_alloc_security, 0, file); |
---|
| 1444 | + int rc = lsm_file_alloc(file); |
---|
| 1445 | + |
---|
| 1446 | + if (rc) |
---|
| 1447 | + return rc; |
---|
| 1448 | + rc = call_int_hook(file_alloc_security, 0, file); |
---|
| 1449 | + if (unlikely(rc)) |
---|
| 1450 | + security_file_free(file); |
---|
| 1451 | + return rc; |
---|
881 | 1452 | } |
---|
882 | 1453 | |
---|
883 | 1454 | void security_file_free(struct file *file) |
---|
884 | 1455 | { |
---|
| 1456 | + void *blob; |
---|
| 1457 | + |
---|
885 | 1458 | call_void_hook(file_free_security, file); |
---|
| 1459 | + |
---|
| 1460 | + blob = file->f_security; |
---|
| 1461 | + if (blob) { |
---|
| 1462 | + file->f_security = NULL; |
---|
| 1463 | + kmem_cache_free(lsm_file_cache, blob); |
---|
| 1464 | + } |
---|
886 | 1465 | } |
---|
887 | 1466 | |
---|
888 | 1467 | int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
---|
889 | 1468 | { |
---|
890 | 1469 | return call_int_hook(file_ioctl, 0, file, cmd, arg); |
---|
891 | 1470 | } |
---|
| 1471 | +EXPORT_SYMBOL_GPL(security_file_ioctl); |
---|
892 | 1472 | |
---|
893 | 1473 | static inline unsigned long mmap_prot(struct file *file, unsigned long prot) |
---|
894 | 1474 | { |
---|
.. | .. |
---|
926 | 1506 | int security_mmap_file(struct file *file, unsigned long prot, |
---|
927 | 1507 | unsigned long flags) |
---|
928 | 1508 | { |
---|
| 1509 | + unsigned long prot_adj = mmap_prot(file, prot); |
---|
929 | 1510 | int ret; |
---|
930 | | - ret = call_int_hook(mmap_file, 0, file, prot, |
---|
931 | | - mmap_prot(file, prot), flags); |
---|
| 1511 | + |
---|
| 1512 | + ret = call_int_hook(mmap_file, 0, file, prot, prot_adj, flags); |
---|
932 | 1513 | if (ret) |
---|
933 | 1514 | return ret; |
---|
934 | | - return ima_file_mmap(file, prot); |
---|
| 1515 | + return ima_file_mmap(file, prot, prot_adj, flags); |
---|
935 | 1516 | } |
---|
936 | 1517 | |
---|
937 | 1518 | int security_mmap_addr(unsigned long addr) |
---|
938 | 1519 | { |
---|
939 | 1520 | return call_int_hook(mmap_addr, 0, addr); |
---|
940 | 1521 | } |
---|
941 | | -EXPORT_SYMBOL_GPL(security_mmap_addr); |
---|
942 | 1522 | |
---|
943 | 1523 | int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, |
---|
944 | 1524 | unsigned long prot) |
---|
945 | 1525 | { |
---|
946 | | - return call_int_hook(file_mprotect, 0, vma, reqprot, prot); |
---|
| 1526 | + int ret; |
---|
| 1527 | + |
---|
| 1528 | + ret = call_int_hook(file_mprotect, 0, vma, reqprot, prot); |
---|
| 1529 | + if (ret) |
---|
| 1530 | + return ret; |
---|
| 1531 | + return ima_file_mprotect(vma, prot); |
---|
947 | 1532 | } |
---|
948 | 1533 | |
---|
949 | 1534 | int security_file_lock(struct file *file, unsigned int cmd) |
---|
.. | .. |
---|
985 | 1570 | |
---|
986 | 1571 | int security_task_alloc(struct task_struct *task, unsigned long clone_flags) |
---|
987 | 1572 | { |
---|
988 | | - return call_int_hook(task_alloc, 0, task, clone_flags); |
---|
| 1573 | + int rc = lsm_task_alloc(task); |
---|
| 1574 | + |
---|
| 1575 | + if (rc) |
---|
| 1576 | + return rc; |
---|
| 1577 | + rc = call_int_hook(task_alloc, 0, task, clone_flags); |
---|
| 1578 | + if (unlikely(rc)) |
---|
| 1579 | + security_task_free(task); |
---|
| 1580 | + return rc; |
---|
989 | 1581 | } |
---|
990 | 1582 | |
---|
991 | 1583 | void security_task_free(struct task_struct *task) |
---|
992 | 1584 | { |
---|
993 | 1585 | call_void_hook(task_free, task); |
---|
| 1586 | + |
---|
| 1587 | + kfree(task->security); |
---|
| 1588 | + task->security = NULL; |
---|
994 | 1589 | } |
---|
995 | 1590 | |
---|
996 | 1591 | int security_cred_alloc_blank(struct cred *cred, gfp_t gfp) |
---|
997 | 1592 | { |
---|
998 | | - return call_int_hook(cred_alloc_blank, 0, cred, gfp); |
---|
| 1593 | + int rc = lsm_cred_alloc(cred, gfp); |
---|
| 1594 | + |
---|
| 1595 | + if (rc) |
---|
| 1596 | + return rc; |
---|
| 1597 | + |
---|
| 1598 | + rc = call_int_hook(cred_alloc_blank, 0, cred, gfp); |
---|
| 1599 | + if (unlikely(rc)) |
---|
| 1600 | + security_cred_free(cred); |
---|
| 1601 | + return rc; |
---|
999 | 1602 | } |
---|
1000 | 1603 | |
---|
1001 | 1604 | void security_cred_free(struct cred *cred) |
---|
.. | .. |
---|
1008 | 1611 | return; |
---|
1009 | 1612 | |
---|
1010 | 1613 | call_void_hook(cred_free, cred); |
---|
| 1614 | + |
---|
| 1615 | + kfree(cred->security); |
---|
| 1616 | + cred->security = NULL; |
---|
1011 | 1617 | } |
---|
1012 | 1618 | |
---|
1013 | 1619 | int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp) |
---|
1014 | 1620 | { |
---|
1015 | | - return call_int_hook(cred_prepare, 0, new, old, gfp); |
---|
| 1621 | + int rc = lsm_cred_alloc(new, gfp); |
---|
| 1622 | + |
---|
| 1623 | + if (rc) |
---|
| 1624 | + return rc; |
---|
| 1625 | + |
---|
| 1626 | + rc = call_int_hook(cred_prepare, 0, new, old, gfp); |
---|
| 1627 | + if (unlikely(rc)) |
---|
| 1628 | + security_cred_free(new); |
---|
| 1629 | + return rc; |
---|
1016 | 1630 | } |
---|
1017 | 1631 | |
---|
1018 | 1632 | void security_transfer_creds(struct cred *new, const struct cred *old) |
---|
.. | .. |
---|
1047 | 1661 | return integrity_kernel_module_request(kmod_name); |
---|
1048 | 1662 | } |
---|
1049 | 1663 | |
---|
1050 | | -int security_kernel_read_file(struct file *file, enum kernel_read_file_id id) |
---|
| 1664 | +int security_kernel_read_file(struct file *file, enum kernel_read_file_id id, |
---|
| 1665 | + bool contents) |
---|
1051 | 1666 | { |
---|
1052 | 1667 | int ret; |
---|
1053 | 1668 | |
---|
1054 | | - ret = call_int_hook(kernel_read_file, 0, file, id); |
---|
| 1669 | + ret = call_int_hook(kernel_read_file, 0, file, id, contents); |
---|
1055 | 1670 | if (ret) |
---|
1056 | 1671 | return ret; |
---|
1057 | | - return ima_read_file(file, id); |
---|
| 1672 | + return ima_read_file(file, id, contents); |
---|
1058 | 1673 | } |
---|
1059 | 1674 | EXPORT_SYMBOL_GPL(security_kernel_read_file); |
---|
1060 | 1675 | |
---|
.. | .. |
---|
1070 | 1685 | } |
---|
1071 | 1686 | EXPORT_SYMBOL_GPL(security_kernel_post_read_file); |
---|
1072 | 1687 | |
---|
1073 | | -int security_kernel_load_data(enum kernel_load_data_id id) |
---|
| 1688 | +int security_kernel_load_data(enum kernel_load_data_id id, bool contents) |
---|
1074 | 1689 | { |
---|
1075 | 1690 | int ret; |
---|
1076 | 1691 | |
---|
1077 | | - ret = call_int_hook(kernel_load_data, 0, id); |
---|
| 1692 | + ret = call_int_hook(kernel_load_data, 0, id, contents); |
---|
1078 | 1693 | if (ret) |
---|
1079 | 1694 | return ret; |
---|
1080 | | - return ima_load_data(id); |
---|
| 1695 | + return ima_load_data(id, contents); |
---|
1081 | 1696 | } |
---|
1082 | 1697 | EXPORT_SYMBOL_GPL(security_kernel_load_data); |
---|
| 1698 | + |
---|
| 1699 | +int security_kernel_post_load_data(char *buf, loff_t size, |
---|
| 1700 | + enum kernel_load_data_id id, |
---|
| 1701 | + char *description) |
---|
| 1702 | +{ |
---|
| 1703 | + int ret; |
---|
| 1704 | + |
---|
| 1705 | + ret = call_int_hook(kernel_post_load_data, 0, buf, size, id, |
---|
| 1706 | + description); |
---|
| 1707 | + if (ret) |
---|
| 1708 | + return ret; |
---|
| 1709 | + return ima_post_load_data(buf, size, id, description); |
---|
| 1710 | +} |
---|
| 1711 | +EXPORT_SYMBOL_GPL(security_kernel_post_load_data); |
---|
1083 | 1712 | |
---|
1084 | 1713 | int security_task_fix_setuid(struct cred *new, const struct cred *old, |
---|
1085 | 1714 | int flags) |
---|
1086 | 1715 | { |
---|
1087 | 1716 | return call_int_hook(task_fix_setuid, 0, new, old, flags); |
---|
| 1717 | +} |
---|
| 1718 | + |
---|
| 1719 | +int security_task_fix_setgid(struct cred *new, const struct cred *old, |
---|
| 1720 | + int flags) |
---|
| 1721 | +{ |
---|
| 1722 | + return call_int_hook(task_fix_setgid, 0, new, old, flags); |
---|
1088 | 1723 | } |
---|
1089 | 1724 | |
---|
1090 | 1725 | int security_task_setpgid(struct task_struct *p, pid_t pgid) |
---|
.. | .. |
---|
1151 | 1786 | return call_int_hook(task_movememory, 0, p); |
---|
1152 | 1787 | } |
---|
1153 | 1788 | |
---|
1154 | | -int security_task_kill(struct task_struct *p, struct siginfo *info, |
---|
| 1789 | +int security_task_kill(struct task_struct *p, struct kernel_siginfo *info, |
---|
1155 | 1790 | int sig, const struct cred *cred) |
---|
1156 | 1791 | { |
---|
1157 | 1792 | return call_int_hook(task_kill, 0, p, info, sig, cred); |
---|
.. | .. |
---|
1161 | 1796 | unsigned long arg4, unsigned long arg5) |
---|
1162 | 1797 | { |
---|
1163 | 1798 | int thisrc; |
---|
1164 | | - int rc = -ENOSYS; |
---|
| 1799 | + int rc = LSM_RET_DEFAULT(task_prctl); |
---|
1165 | 1800 | struct security_hook_list *hp; |
---|
1166 | 1801 | |
---|
1167 | 1802 | hlist_for_each_entry(hp, &security_hook_heads.task_prctl, list) { |
---|
1168 | 1803 | thisrc = hp->hook.task_prctl(option, arg2, arg3, arg4, arg5); |
---|
1169 | | - if (thisrc != -ENOSYS) { |
---|
| 1804 | + if (thisrc != LSM_RET_DEFAULT(task_prctl)) { |
---|
1170 | 1805 | rc = thisrc; |
---|
1171 | 1806 | if (thisrc != 0) |
---|
1172 | 1807 | break; |
---|
.. | .. |
---|
1193 | 1828 | |
---|
1194 | 1829 | int security_msg_msg_alloc(struct msg_msg *msg) |
---|
1195 | 1830 | { |
---|
1196 | | - return call_int_hook(msg_msg_alloc_security, 0, msg); |
---|
| 1831 | + int rc = lsm_msg_msg_alloc(msg); |
---|
| 1832 | + |
---|
| 1833 | + if (unlikely(rc)) |
---|
| 1834 | + return rc; |
---|
| 1835 | + rc = call_int_hook(msg_msg_alloc_security, 0, msg); |
---|
| 1836 | + if (unlikely(rc)) |
---|
| 1837 | + security_msg_msg_free(msg); |
---|
| 1838 | + return rc; |
---|
1197 | 1839 | } |
---|
1198 | 1840 | |
---|
1199 | 1841 | void security_msg_msg_free(struct msg_msg *msg) |
---|
1200 | 1842 | { |
---|
1201 | 1843 | call_void_hook(msg_msg_free_security, msg); |
---|
| 1844 | + kfree(msg->security); |
---|
| 1845 | + msg->security = NULL; |
---|
1202 | 1846 | } |
---|
1203 | 1847 | |
---|
1204 | 1848 | int security_msg_queue_alloc(struct kern_ipc_perm *msq) |
---|
1205 | 1849 | { |
---|
1206 | | - return call_int_hook(msg_queue_alloc_security, 0, msq); |
---|
| 1850 | + int rc = lsm_ipc_alloc(msq); |
---|
| 1851 | + |
---|
| 1852 | + if (unlikely(rc)) |
---|
| 1853 | + return rc; |
---|
| 1854 | + rc = call_int_hook(msg_queue_alloc_security, 0, msq); |
---|
| 1855 | + if (unlikely(rc)) |
---|
| 1856 | + security_msg_queue_free(msq); |
---|
| 1857 | + return rc; |
---|
1207 | 1858 | } |
---|
1208 | 1859 | |
---|
1209 | 1860 | void security_msg_queue_free(struct kern_ipc_perm *msq) |
---|
1210 | 1861 | { |
---|
1211 | 1862 | call_void_hook(msg_queue_free_security, msq); |
---|
| 1863 | + kfree(msq->security); |
---|
| 1864 | + msq->security = NULL; |
---|
1212 | 1865 | } |
---|
1213 | 1866 | |
---|
1214 | 1867 | int security_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) |
---|
.. | .. |
---|
1235 | 1888 | |
---|
1236 | 1889 | int security_shm_alloc(struct kern_ipc_perm *shp) |
---|
1237 | 1890 | { |
---|
1238 | | - return call_int_hook(shm_alloc_security, 0, shp); |
---|
| 1891 | + int rc = lsm_ipc_alloc(shp); |
---|
| 1892 | + |
---|
| 1893 | + if (unlikely(rc)) |
---|
| 1894 | + return rc; |
---|
| 1895 | + rc = call_int_hook(shm_alloc_security, 0, shp); |
---|
| 1896 | + if (unlikely(rc)) |
---|
| 1897 | + security_shm_free(shp); |
---|
| 1898 | + return rc; |
---|
1239 | 1899 | } |
---|
1240 | 1900 | |
---|
1241 | 1901 | void security_shm_free(struct kern_ipc_perm *shp) |
---|
1242 | 1902 | { |
---|
1243 | 1903 | call_void_hook(shm_free_security, shp); |
---|
| 1904 | + kfree(shp->security); |
---|
| 1905 | + shp->security = NULL; |
---|
1244 | 1906 | } |
---|
1245 | 1907 | |
---|
1246 | 1908 | int security_shm_associate(struct kern_ipc_perm *shp, int shmflg) |
---|
.. | .. |
---|
1260 | 1922 | |
---|
1261 | 1923 | int security_sem_alloc(struct kern_ipc_perm *sma) |
---|
1262 | 1924 | { |
---|
1263 | | - return call_int_hook(sem_alloc_security, 0, sma); |
---|
| 1925 | + int rc = lsm_ipc_alloc(sma); |
---|
| 1926 | + |
---|
| 1927 | + if (unlikely(rc)) |
---|
| 1928 | + return rc; |
---|
| 1929 | + rc = call_int_hook(sem_alloc_security, 0, sma); |
---|
| 1930 | + if (unlikely(rc)) |
---|
| 1931 | + security_sem_free(sma); |
---|
| 1932 | + return rc; |
---|
1264 | 1933 | } |
---|
1265 | 1934 | |
---|
1266 | 1935 | void security_sem_free(struct kern_ipc_perm *sma) |
---|
1267 | 1936 | { |
---|
1268 | 1937 | call_void_hook(sem_free_security, sma); |
---|
| 1938 | + kfree(sma->security); |
---|
| 1939 | + sma->security = NULL; |
---|
1269 | 1940 | } |
---|
1270 | 1941 | |
---|
1271 | 1942 | int security_sem_associate(struct kern_ipc_perm *sma, int semflg) |
---|
.. | .. |
---|
1292 | 1963 | } |
---|
1293 | 1964 | EXPORT_SYMBOL(security_d_instantiate); |
---|
1294 | 1965 | |
---|
1295 | | -int security_getprocattr(struct task_struct *p, char *name, char **value) |
---|
| 1966 | +int security_getprocattr(struct task_struct *p, const char *lsm, char *name, |
---|
| 1967 | + char **value) |
---|
1296 | 1968 | { |
---|
1297 | | - return call_int_hook(getprocattr, -EINVAL, p, name, value); |
---|
| 1969 | + struct security_hook_list *hp; |
---|
| 1970 | + |
---|
| 1971 | + hlist_for_each_entry(hp, &security_hook_heads.getprocattr, list) { |
---|
| 1972 | + if (lsm != NULL && strcmp(lsm, hp->lsm)) |
---|
| 1973 | + continue; |
---|
| 1974 | + return hp->hook.getprocattr(p, name, value); |
---|
| 1975 | + } |
---|
| 1976 | + return LSM_RET_DEFAULT(getprocattr); |
---|
1298 | 1977 | } |
---|
1299 | 1978 | |
---|
1300 | | -int security_setprocattr(const char *name, void *value, size_t size) |
---|
| 1979 | +int security_setprocattr(const char *lsm, const char *name, void *value, |
---|
| 1980 | + size_t size) |
---|
1301 | 1981 | { |
---|
1302 | | - return call_int_hook(setprocattr, -EINVAL, name, value, size); |
---|
| 1982 | + struct security_hook_list *hp; |
---|
| 1983 | + |
---|
| 1984 | + hlist_for_each_entry(hp, &security_hook_heads.setprocattr, list) { |
---|
| 1985 | + if (lsm != NULL && strcmp(lsm, hp->lsm)) |
---|
| 1986 | + continue; |
---|
| 1987 | + return hp->hook.setprocattr(name, value, size); |
---|
| 1988 | + } |
---|
| 1989 | + return LSM_RET_DEFAULT(setprocattr); |
---|
1303 | 1990 | } |
---|
1304 | 1991 | |
---|
1305 | 1992 | int security_netlink_send(struct sock *sk, struct sk_buff *skb) |
---|
.. | .. |
---|
1315 | 2002 | |
---|
1316 | 2003 | int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) |
---|
1317 | 2004 | { |
---|
1318 | | - return call_int_hook(secid_to_secctx, -EOPNOTSUPP, secid, secdata, |
---|
1319 | | - seclen); |
---|
| 2005 | + struct security_hook_list *hp; |
---|
| 2006 | + int rc; |
---|
| 2007 | + |
---|
| 2008 | + /* |
---|
| 2009 | + * Currently, only one LSM can implement secid_to_secctx (i.e this |
---|
| 2010 | + * LSM hook is not "stackable"). |
---|
| 2011 | + */ |
---|
| 2012 | + hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { |
---|
| 2013 | + rc = hp->hook.secid_to_secctx(secid, secdata, seclen); |
---|
| 2014 | + if (rc != LSM_RET_DEFAULT(secid_to_secctx)) |
---|
| 2015 | + return rc; |
---|
| 2016 | + } |
---|
| 2017 | + |
---|
| 2018 | + return LSM_RET_DEFAULT(secid_to_secctx); |
---|
1320 | 2019 | } |
---|
1321 | 2020 | EXPORT_SYMBOL(security_secid_to_secctx); |
---|
1322 | 2021 | |
---|
.. | .. |
---|
1356 | 2055 | return call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, ctx, ctxlen); |
---|
1357 | 2056 | } |
---|
1358 | 2057 | EXPORT_SYMBOL(security_inode_getsecctx); |
---|
| 2058 | + |
---|
| 2059 | +#ifdef CONFIG_WATCH_QUEUE |
---|
| 2060 | +int security_post_notification(const struct cred *w_cred, |
---|
| 2061 | + const struct cred *cred, |
---|
| 2062 | + struct watch_notification *n) |
---|
| 2063 | +{ |
---|
| 2064 | + return call_int_hook(post_notification, 0, w_cred, cred, n); |
---|
| 2065 | +} |
---|
| 2066 | +#endif /* CONFIG_WATCH_QUEUE */ |
---|
| 2067 | + |
---|
| 2068 | +#ifdef CONFIG_KEY_NOTIFICATIONS |
---|
| 2069 | +int security_watch_key(struct key *key) |
---|
| 2070 | +{ |
---|
| 2071 | + return call_int_hook(watch_key, 0, key); |
---|
| 2072 | +} |
---|
| 2073 | +#endif |
---|
1359 | 2074 | |
---|
1360 | 2075 | #ifdef CONFIG_SECURITY_NETWORK |
---|
1361 | 2076 | |
---|
.. | .. |
---|
1481 | 2196 | } |
---|
1482 | 2197 | EXPORT_SYMBOL(security_sk_clone); |
---|
1483 | 2198 | |
---|
1484 | | -void security_sk_classify_flow(struct sock *sk, struct flowi *fl) |
---|
| 2199 | +void security_sk_classify_flow(struct sock *sk, struct flowi_common *flic) |
---|
1485 | 2200 | { |
---|
1486 | | - call_void_hook(sk_getsecid, sk, &fl->flowi_secid); |
---|
| 2201 | + call_void_hook(sk_getsecid, sk, &flic->flowic_secid); |
---|
1487 | 2202 | } |
---|
1488 | 2203 | EXPORT_SYMBOL(security_sk_classify_flow); |
---|
1489 | 2204 | |
---|
1490 | | -void security_req_classify_flow(const struct request_sock *req, struct flowi *fl) |
---|
| 2205 | +void security_req_classify_flow(const struct request_sock *req, |
---|
| 2206 | + struct flowi_common *flic) |
---|
1491 | 2207 | { |
---|
1492 | | - call_void_hook(req_classify_flow, req, fl); |
---|
| 2208 | + call_void_hook(req_classify_flow, req, flic); |
---|
1493 | 2209 | } |
---|
1494 | 2210 | EXPORT_SYMBOL(security_req_classify_flow); |
---|
1495 | 2211 | |
---|
.. | .. |
---|
1681 | 2397 | |
---|
1682 | 2398 | int security_xfrm_state_pol_flow_match(struct xfrm_state *x, |
---|
1683 | 2399 | struct xfrm_policy *xp, |
---|
1684 | | - const struct flowi *fl) |
---|
| 2400 | + const struct flowi_common *flic) |
---|
1685 | 2401 | { |
---|
1686 | 2402 | struct security_hook_list *hp; |
---|
1687 | | - int rc = 1; |
---|
| 2403 | + int rc = LSM_RET_DEFAULT(xfrm_state_pol_flow_match); |
---|
1688 | 2404 | |
---|
1689 | 2405 | /* |
---|
1690 | 2406 | * Since this function is expected to return 0 or 1, the judgment |
---|
.. | .. |
---|
1697 | 2413 | */ |
---|
1698 | 2414 | hlist_for_each_entry(hp, &security_hook_heads.xfrm_state_pol_flow_match, |
---|
1699 | 2415 | list) { |
---|
1700 | | - rc = hp->hook.xfrm_state_pol_flow_match(x, xp, fl); |
---|
| 2416 | + rc = hp->hook.xfrm_state_pol_flow_match(x, xp, flic); |
---|
1701 | 2417 | break; |
---|
1702 | 2418 | } |
---|
1703 | 2419 | return rc; |
---|
.. | .. |
---|
1708 | 2424 | return call_int_hook(xfrm_decode_session, 0, skb, secid, 1); |
---|
1709 | 2425 | } |
---|
1710 | 2426 | |
---|
1711 | | -void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl) |
---|
| 2427 | +void security_skb_classify_flow(struct sk_buff *skb, struct flowi_common *flic) |
---|
1712 | 2428 | { |
---|
1713 | | - int rc = call_int_hook(xfrm_decode_session, 0, skb, &fl->flowi_secid, |
---|
| 2429 | + int rc = call_int_hook(xfrm_decode_session, 0, skb, &flic->flowic_secid, |
---|
1714 | 2430 | 0); |
---|
1715 | 2431 | |
---|
1716 | 2432 | BUG_ON(rc); |
---|
.. | .. |
---|
1732 | 2448 | call_void_hook(key_free, key); |
---|
1733 | 2449 | } |
---|
1734 | 2450 | |
---|
1735 | | -int security_key_permission(key_ref_t key_ref, |
---|
1736 | | - const struct cred *cred, unsigned perm) |
---|
| 2451 | +int security_key_permission(key_ref_t key_ref, const struct cred *cred, |
---|
| 2452 | + enum key_need_perm need_perm) |
---|
1737 | 2453 | { |
---|
1738 | | - return call_int_hook(key_permission, 0, key_ref, cred, perm); |
---|
| 2454 | + return call_int_hook(key_permission, 0, key_ref, cred, need_perm); |
---|
1739 | 2455 | } |
---|
1740 | 2456 | |
---|
1741 | 2457 | int security_key_getsecurity(struct key *key, char **_buffer) |
---|
.. | .. |
---|
1763 | 2479 | call_void_hook(audit_rule_free, lsmrule); |
---|
1764 | 2480 | } |
---|
1765 | 2481 | |
---|
1766 | | -int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, |
---|
1767 | | - struct audit_context *actx) |
---|
| 2482 | +int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule) |
---|
1768 | 2483 | { |
---|
1769 | | - return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule, |
---|
1770 | | - actx); |
---|
| 2484 | + return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule); |
---|
1771 | 2485 | } |
---|
1772 | 2486 | #endif /* CONFIG_AUDIT */ |
---|
1773 | 2487 | |
---|
.. | .. |
---|
1802 | 2516 | } |
---|
1803 | 2517 | #endif /* CONFIG_BPF_SYSCALL */ |
---|
1804 | 2518 | |
---|
| 2519 | +int security_locked_down(enum lockdown_reason what) |
---|
| 2520 | +{ |
---|
| 2521 | + return call_int_hook(locked_down, 0, what); |
---|
| 2522 | +} |
---|
| 2523 | +EXPORT_SYMBOL(security_locked_down); |
---|
| 2524 | + |
---|
1805 | 2525 | #ifdef CONFIG_PERF_EVENTS |
---|
1806 | 2526 | int security_perf_event_open(struct perf_event_attr *attr, int type) |
---|
1807 | 2527 | { |
---|