Blame view
security/security.c
58 KB
2874c5fd2
|
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4c
|
2 3 4 5 6 7 |
/* * Security plug functions * * Copyright (C) 2001 WireX Communications, Inc <chris@wirex.com> * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com> * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com> |
d291f1a65
|
8 |
* Copyright (C) 2016 Mellanox Technologies |
1da177e4c
|
9 |
*/ |
9b8c7c140
|
10 |
#define pr_fmt(fmt) "LSM: " fmt |
afdb09c72
|
11 |
#include <linux/bpf.h> |
c59ede7b7
|
12 |
#include <linux/capability.h> |
d47be3dfe
|
13 |
#include <linux/dcache.h> |
876979c93
|
14 |
#include <linux/export.h> |
1da177e4c
|
15 16 |
#include <linux/init.h> #include <linux/kernel.h> |
3c4ed7bdf
|
17 |
#include <linux/lsm_hooks.h> |
f381c2722
|
18 |
#include <linux/integrity.h> |
6c21a7fb4
|
19 |
#include <linux/ima.h> |
3e1be52d6
|
20 |
#include <linux/evm.h> |
404015308
|
21 |
#include <linux/fsnotify.h> |
8b3ec6814
|
22 23 24 |
#include <linux/mman.h> #include <linux/mount.h> #include <linux/personality.h> |
75331a597
|
25 |
#include <linux/backing-dev.h> |
3bb857e47
|
26 |
#include <linux/string.h> |
ecd5f82e0
|
27 |
#include <linux/msg.h> |
404015308
|
28 |
#include <net/flow.h> |
1da177e4c
|
29 |
|
823eb1ccd
|
30 |
#define MAX_LSM_EVM_XATTR 2 |
1da177e4c
|
31 |
|
2d4d51198
|
32 33 |
/* How many LSMs were built into the kernel? */ #define LSM_COUNT (__end_lsm_info - __start_lsm_info) |
3dfc9b028
|
34 |
struct security_hook_heads security_hook_heads __lsm_ro_after_init; |
42df744c4
|
35 |
static BLOCKING_NOTIFIER_HEAD(blocking_lsm_notifier_chain); |
8f408ab64
|
36 |
|
33bf60cab
|
37 |
static struct kmem_cache *lsm_file_cache; |
afb1cbe37
|
38 |
static struct kmem_cache *lsm_inode_cache; |
33bf60cab
|
39 |
|
d69dece5f
|
40 |
char *lsm_names; |
bbd3662a8
|
41 |
static struct lsm_blob_sizes blob_sizes __lsm_ro_after_init; |
076c54c5b
|
42 |
/* Boot-time LSM user choice */ |
79f7865d8
|
43 |
static __initdata const char *chosen_lsm_order; |
5ef4e4191
|
44 |
static __initdata const char *chosen_major_lsm; |
1da177e4c
|
45 |
|
13e735c0e
|
46 |
static __initconst const char * const builtin_lsm_order = CONFIG_LSM; |
2d4d51198
|
47 48 |
/* Ordered list of LSMs to initialize. */ static __initdata struct lsm_info **ordered_lsms; |
14bd99c82
|
49 |
static __initdata struct lsm_info *exclusive; |
2d4d51198
|
50 |
|
9b8c7c140
|
51 52 53 54 55 56 |
static __initdata bool debug; #define init_debug(...) \ do { \ if (debug) \ pr_info(__VA_ARGS__); \ } while (0) |
f4941d75b
|
57 58 |
static bool __init is_enabled(struct lsm_info *lsm) { |
a8027fb0d
|
59 60 |
if (!lsm->enabled) return false; |
f4941d75b
|
61 |
|
a8027fb0d
|
62 |
return *lsm->enabled; |
f4941d75b
|
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
} /* Mark an LSM's enabled flag. */ static int lsm_enabled_true __initdata = 1; static int lsm_enabled_false __initdata = 0; static void __init set_enabled(struct lsm_info *lsm, bool enabled) { /* * When an LSM hasn't configured an enable variable, we can use * a hard-coded location for storing the default enabled state. */ if (!lsm->enabled) { if (enabled) lsm->enabled = &lsm_enabled_true; else lsm->enabled = &lsm_enabled_false; } else if (lsm->enabled == &lsm_enabled_true) { if (!enabled) lsm->enabled = &lsm_enabled_false; } else if (lsm->enabled == &lsm_enabled_false) { if (enabled) lsm->enabled = &lsm_enabled_true; } else { *lsm->enabled = enabled; } } |
2d4d51198
|
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
/* Is an LSM already listed in the ordered LSMs list? */ static bool __init exists_ordered_lsm(struct lsm_info *lsm) { struct lsm_info **check; for (check = ordered_lsms; *check; check++) if (*check == lsm) return true; return false; } /* Append an LSM to the list of ordered LSMs to initialize. */ static int last_lsm __initdata; static void __init append_ordered_lsm(struct lsm_info *lsm, const char *from) { /* Ignore duplicate selections. */ if (exists_ordered_lsm(lsm)) return; if (WARN(last_lsm == LSM_COUNT, "%s: out of LSM slots!? ", from)) return; |
a8027fb0d
|
112 113 114 |
/* Enable this LSM, if it is not already set. */ if (!lsm->enabled) lsm->enabled = &lsm_enabled_true; |
2d4d51198
|
115 |
ordered_lsms[last_lsm++] = lsm; |
a8027fb0d
|
116 |
|
2d4d51198
|
117 118 119 120 |
init_debug("%s ordering: %s (%sabled) ", from, lsm->name, is_enabled(lsm) ? "en" : "dis"); } |
f4941d75b
|
121 122 123 124 125 126 |
/* Is an LSM allowed to be initialized? */ static bool __init lsm_allowed(struct lsm_info *lsm) { /* Skip if the LSM is disabled. */ if (!is_enabled(lsm)) return false; |
14bd99c82
|
127 128 129 130 131 132 |
/* Not allowed if another exclusive LSM already initialized. */ if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && exclusive) { init_debug("exclusive disabled: %s ", lsm->name); return false; } |
f4941d75b
|
133 134 |
return true; } |
bbd3662a8
|
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
static void __init lsm_set_blob_size(int *need, int *lbs) { int offset; if (*need > 0) { offset = *lbs; *lbs += *need; *need = offset; } } static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed) { if (!needed) return; lsm_set_blob_size(&needed->lbs_cred, &blob_sizes.lbs_cred); |
33bf60cab
|
152 |
lsm_set_blob_size(&needed->lbs_file, &blob_sizes.lbs_file); |
afb1cbe37
|
153 154 155 156 157 158 159 |
/* * The inode blob gets an rcu_head in addition to * what the modules might need. */ if (needed->lbs_inode && blob_sizes.lbs_inode == 0) blob_sizes.lbs_inode = sizeof(struct rcu_head); lsm_set_blob_size(&needed->lbs_inode, &blob_sizes.lbs_inode); |
ecd5f82e0
|
160 161 |
lsm_set_blob_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc); lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg); |
f4ad8f2c4
|
162 |
lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task); |
bbd3662a8
|
163 |
} |
d8e9bbd4f
|
164 165 |
/* Prepare LSM for initialization. */ static void __init prepare_lsm(struct lsm_info *lsm) |
f4941d75b
|
166 167 168 169 170 |
{ int enabled = lsm_allowed(lsm); /* Record enablement (to handle any following exclusive LSMs). */ set_enabled(lsm, enabled); |
d8e9bbd4f
|
171 |
/* If enabled, do pre-initialization work. */ |
f4941d75b
|
172 |
if (enabled) { |
14bd99c82
|
173 174 175 176 177 |
if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !exclusive) { exclusive = lsm; init_debug("exclusive chosen: %s ", lsm->name); } |
bbd3662a8
|
178 179 |
lsm_set_blob_sizes(lsm->blobs); |
d8e9bbd4f
|
180 181 182 183 184 185 186 187 |
} } /* Initialize a given LSM, if it is enabled. */ static void __init initialize_lsm(struct lsm_info *lsm) { if (is_enabled(lsm)) { int ret; |
14bd99c82
|
188 |
|
f4941d75b
|
189 190 191 192 193 194 195 |
init_debug("initializing %s ", lsm->name); ret = lsm->init(); WARN(ret, "%s failed to initialize: %d ", lsm->name, ret); } } |
13e735c0e
|
196 |
/* Populate ordered LSMs list from comma-separated LSM name list. */ |
2d4d51198
|
197 |
static void __init ordered_lsm_parse(const char *order, const char *origin) |
657d910b5
|
198 199 |
{ struct lsm_info *lsm; |
13e735c0e
|
200 |
char *sep, *name, *next; |
e2bc445b6
|
201 202 203 204 205 |
/* LSM_ORDER_FIRST is always first. */ for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { if (lsm->order == LSM_ORDER_FIRST) append_ordered_lsm(lsm, "first"); } |
7e611486d
|
206 |
/* Process "security=", if given. */ |
7e611486d
|
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
if (chosen_major_lsm) { struct lsm_info *major; /* * To match the original "security=" behavior, this * explicitly does NOT fallback to another Legacy Major * if the selected one was separately disabled: disable * all non-matching Legacy Major LSMs. */ for (major = __start_lsm_info; major < __end_lsm_info; major++) { if ((major->flags & LSM_FLAG_LEGACY_MAJOR) && strcmp(major->name, chosen_major_lsm) != 0) { set_enabled(major, false); init_debug("security=%s disabled: %s ", chosen_major_lsm, major->name); } } } |
5ef4e4191
|
227 |
|
13e735c0e
|
228 229 230 231 232 233 234 |
sep = kstrdup(order, GFP_KERNEL); next = sep; /* Walk the list, looking for matching LSMs. */ while ((name = strsep(&next, ",")) != NULL) { bool found = false; for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { |
e2bc445b6
|
235 236 |
if (lsm->order == LSM_ORDER_MUTABLE && strcmp(lsm->name, name) == 0) { |
13e735c0e
|
237 238 239 240 241 242 243 244 |
append_ordered_lsm(lsm, origin); found = true; } } if (!found) init_debug("%s ignored: %s ", origin, name); |
657d910b5
|
245 |
} |
c91d8106b
|
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
/* Process "security=", if given. */ if (chosen_major_lsm) { for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { if (exists_ordered_lsm(lsm)) continue; if (strcmp(lsm->name, chosen_major_lsm) == 0) append_ordered_lsm(lsm, "security="); } } /* Disable all LSMs not in the ordered list. */ for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { if (exists_ordered_lsm(lsm)) continue; set_enabled(lsm, false); init_debug("%s disabled: %s ", origin, lsm->name); } |
13e735c0e
|
265 |
kfree(sep); |
657d910b5
|
266 |
} |
1cfb2a512
|
267 268 |
static void __init lsm_early_cred(struct cred *cred); static void __init lsm_early_task(struct task_struct *task); |
2d4d51198
|
269 270 271 272 273 274 |
static void __init ordered_lsm_init(void) { struct lsm_info **lsm; ordered_lsms = kcalloc(LSM_COUNT + 1, sizeof(*ordered_lsms), GFP_KERNEL); |
89a9684ea
|
275 276 277 278 279 280 |
if (chosen_lsm_order) { if (chosen_major_lsm) { pr_info("security= is ignored because it is superseded by lsm= "); chosen_major_lsm = NULL; } |
79f7865d8
|
281 |
ordered_lsm_parse(chosen_lsm_order, "cmdline"); |
89a9684ea
|
282 |
} else |
79f7865d8
|
283 |
ordered_lsm_parse(builtin_lsm_order, "builtin"); |
2d4d51198
|
284 285 |
for (lsm = ordered_lsms; *lsm; lsm++) |
d8e9bbd4f
|
286 |
prepare_lsm(*lsm); |
bbd3662a8
|
287 288 |
init_debug("cred blob size = %d ", blob_sizes.lbs_cred); |
33bf60cab
|
289 290 |
init_debug("file blob size = %d ", blob_sizes.lbs_file); |
afb1cbe37
|
291 292 |
init_debug("inode blob size = %d ", blob_sizes.lbs_inode); |
ecd5f82e0
|
293 294 295 296 |
init_debug("ipc blob size = %d ", blob_sizes.lbs_ipc); init_debug("msg_msg blob size = %d ", blob_sizes.lbs_msg_msg); |
f4ad8f2c4
|
297 298 |
init_debug("task blob size = %d ", blob_sizes.lbs_task); |
33bf60cab
|
299 300 301 302 303 304 305 306 |
/* * Create any kmem_caches needed for blobs */ if (blob_sizes.lbs_file) lsm_file_cache = kmem_cache_create("lsm_file_cache", blob_sizes.lbs_file, 0, SLAB_PANIC, NULL); |
afb1cbe37
|
307 308 309 310 |
if (blob_sizes.lbs_inode) lsm_inode_cache = kmem_cache_create("lsm_inode_cache", blob_sizes.lbs_inode, 0, SLAB_PANIC, NULL); |
bbd3662a8
|
311 |
|
1cfb2a512
|
312 313 |
lsm_early_cred((struct cred *) current->cred); lsm_early_task(current); |
d8e9bbd4f
|
314 315 |
for (lsm = ordered_lsms; *lsm; lsm++) initialize_lsm(*lsm); |
2d4d51198
|
316 317 318 |
kfree(ordered_lsms); } |
1da177e4c
|
319 320 321 322 323 324 325 |
/** * security_init - initializes the security framework * * This should be called early in the kernel initialization sequence. */ int __init security_init(void) { |
3dfc9b028
|
326 |
int i; |
df0ce1733
|
327 |
struct hlist_head *list = (struct hlist_head *) &security_hook_heads; |
3dfc9b028
|
328 |
|
98d291708
|
329 330 |
pr_info("Security Framework initializing "); |
df0ce1733
|
331 |
for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct hlist_head); |
3dfc9b028
|
332 |
i++) |
df0ce1733
|
333 |
INIT_HLIST_HEAD(&list[i]); |
1da177e4c
|
334 |
|
657d910b5
|
335 336 |
/* Load LSMs in specified order. */ ordered_lsm_init(); |
1da177e4c
|
337 338 |
return 0; } |
076c54c5b
|
339 |
/* Save user chosen LSM */ |
5ef4e4191
|
340 |
static int __init choose_major_lsm(char *str) |
076c54c5b
|
341 |
{ |
5ef4e4191
|
342 |
chosen_major_lsm = str; |
076c54c5b
|
343 344 |
return 1; } |
5ef4e4191
|
345 |
__setup("security=", choose_major_lsm); |
076c54c5b
|
346 |
|
79f7865d8
|
347 348 349 350 351 352 353 |
/* Explicitly choose LSM initialization order. */ static int __init choose_lsm_order(char *str) { chosen_lsm_order = str; return 1; } __setup("lsm=", choose_lsm_order); |
9b8c7c140
|
354 355 356 357 358 359 360 |
/* Enable LSM order debugging. */ static int __init enable_debug(char *str) { debug = true; return 1; } __setup("lsm.debug", enable_debug); |
3bb857e47
|
361 362 363 364 365 366 367 368 369 370 371 372 373 374 |
static bool match_last_lsm(const char *list, const char *lsm) { const char *last; if (WARN_ON(!list || !lsm)) return false; last = strrchr(list, ','); if (last) /* Pass the comma, strcmp() will check for '\0' */ last++; else last = list; return !strcmp(last, lsm); } |
d69dece5f
|
375 376 377 378 379 380 |
static int lsm_append(char *new, char **result) { char *cp; if (*result == NULL) { *result = kstrdup(new, GFP_KERNEL); |
87ea58433
|
381 382 |
if (*result == NULL) return -ENOMEM; |
d69dece5f
|
383 |
} else { |
3bb857e47
|
384 385 386 |
/* Check if it is the last registered name */ if (match_last_lsm(*result, new)) return 0; |
d69dece5f
|
387 388 389 390 391 392 393 394 |
cp = kasprintf(GFP_KERNEL, "%s,%s", *result, new); if (cp == NULL) return -ENOMEM; kfree(*result); *result = cp; } return 0; } |
076c54c5b
|
395 |
/** |
d69dece5f
|
396 397 398 399 400 401 402 403 404 405 406 407 408 409 |
* security_add_hooks - Add a modules hooks to the hook lists. * @hooks: the hooks to add * @count: the number of hooks to add * @lsm: the name of the security module * * Each LSM has to register its hooks with the infrastructure. */ void __init security_add_hooks(struct security_hook_list *hooks, int count, char *lsm) { int i; for (i = 0; i < count; i++) { hooks[i].lsm = lsm; |
df0ce1733
|
410 |
hlist_add_tail_rcu(&hooks[i].list, hooks[i].head); |
d69dece5f
|
411 412 413 414 415 |
} if (lsm_append(lsm, &lsm_names) < 0) panic("%s - Cannot get early memory. ", __func__); } |
42df744c4
|
416 |
int call_blocking_lsm_notifier(enum lsm_event event, void *data) |
8f408ab64
|
417 |
{ |
42df744c4
|
418 419 |
return blocking_notifier_call_chain(&blocking_lsm_notifier_chain, event, data); |
8f408ab64
|
420 |
} |
42df744c4
|
421 |
EXPORT_SYMBOL(call_blocking_lsm_notifier); |
8f408ab64
|
422 |
|
42df744c4
|
423 |
int register_blocking_lsm_notifier(struct notifier_block *nb) |
8f408ab64
|
424 |
{ |
42df744c4
|
425 426 |
return blocking_notifier_chain_register(&blocking_lsm_notifier_chain, nb); |
8f408ab64
|
427 |
} |
42df744c4
|
428 |
EXPORT_SYMBOL(register_blocking_lsm_notifier); |
8f408ab64
|
429 |
|
42df744c4
|
430 |
int unregister_blocking_lsm_notifier(struct notifier_block *nb) |
8f408ab64
|
431 |
{ |
42df744c4
|
432 433 |
return blocking_notifier_chain_unregister(&blocking_lsm_notifier_chain, nb); |
8f408ab64
|
434 |
} |
42df744c4
|
435 |
EXPORT_SYMBOL(unregister_blocking_lsm_notifier); |
8f408ab64
|
436 |
|
bbd3662a8
|
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 |
/** * lsm_cred_alloc - allocate a composite cred blob * @cred: the cred that needs a blob * @gfp: allocation type * * Allocate the cred blob for all the modules * * Returns 0, or -ENOMEM if memory can't be allocated. */ static int lsm_cred_alloc(struct cred *cred, gfp_t gfp) { if (blob_sizes.lbs_cred == 0) { cred->security = NULL; return 0; } cred->security = kzalloc(blob_sizes.lbs_cred, gfp); if (cred->security == NULL) return -ENOMEM; return 0; } /** * lsm_early_cred - during initialization allocate a composite cred blob * @cred: the cred that needs a blob * |
1cfb2a512
|
463 |
* Allocate the cred blob for all the modules |
bbd3662a8
|
464 |
*/ |
1cfb2a512
|
465 |
static void __init lsm_early_cred(struct cred *cred) |
bbd3662a8
|
466 |
{ |
1cfb2a512
|
467 |
int rc = lsm_cred_alloc(cred, GFP_KERNEL); |
bbd3662a8
|
468 |
|
bbd3662a8
|
469 470 471 472 |
if (rc) panic("%s: Early cred alloc failed. ", __func__); } |
33bf60cab
|
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 |
/** * lsm_file_alloc - allocate a composite file blob * @file: the file that needs a blob * * Allocate the file blob for all the modules * * Returns 0, or -ENOMEM if memory can't be allocated. */ static int lsm_file_alloc(struct file *file) { if (!lsm_file_cache) { file->f_security = NULL; return 0; } file->f_security = kmem_cache_zalloc(lsm_file_cache, GFP_KERNEL); if (file->f_security == NULL) return -ENOMEM; return 0; } |
afb1cbe37
|
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
/** * lsm_inode_alloc - allocate a composite inode blob * @inode: the inode that needs a blob * * Allocate the inode blob for all the modules * * Returns 0, or -ENOMEM if memory can't be allocated. */ int lsm_inode_alloc(struct inode *inode) { if (!lsm_inode_cache) { inode->i_security = NULL; return 0; } inode->i_security = kmem_cache_zalloc(lsm_inode_cache, GFP_NOFS); if (inode->i_security == NULL) return -ENOMEM; return 0; } |
f4ad8f2c4
|
513 514 515 516 517 518 519 520 |
/** * lsm_task_alloc - allocate a composite task blob * @task: the task that needs a blob * * Allocate the task blob for all the modules * * Returns 0, or -ENOMEM if memory can't be allocated. */ |
3e8c73671
|
521 |
static int lsm_task_alloc(struct task_struct *task) |
f4ad8f2c4
|
522 523 524 525 526 527 528 529 530 531 532 533 534 |
{ if (blob_sizes.lbs_task == 0) { task->security = NULL; return 0; } task->security = kzalloc(blob_sizes.lbs_task, GFP_KERNEL); if (task->security == NULL) return -ENOMEM; return 0; } /** |
ecd5f82e0
|
535 536 537 538 539 540 541 |
* lsm_ipc_alloc - allocate a composite ipc blob * @kip: the ipc that needs a blob * * Allocate the ipc blob for all the modules * * Returns 0, or -ENOMEM if memory can't be allocated. */ |
3e8c73671
|
542 |
static int lsm_ipc_alloc(struct kern_ipc_perm *kip) |
ecd5f82e0
|
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 |
{ if (blob_sizes.lbs_ipc == 0) { kip->security = NULL; return 0; } kip->security = kzalloc(blob_sizes.lbs_ipc, GFP_KERNEL); if (kip->security == NULL) return -ENOMEM; return 0; } /** * lsm_msg_msg_alloc - allocate a composite msg_msg blob * @mp: the msg_msg that needs a blob * * Allocate the ipc blob for all the modules * * Returns 0, or -ENOMEM if memory can't be allocated. */ |
3e8c73671
|
563 |
static int lsm_msg_msg_alloc(struct msg_msg *mp) |
ecd5f82e0
|
564 565 566 567 568 569 570 571 572 573 574 575 576 |
{ if (blob_sizes.lbs_msg_msg == 0) { mp->security = NULL; return 0; } mp->security = kzalloc(blob_sizes.lbs_msg_msg, GFP_KERNEL); if (mp->security == NULL) return -ENOMEM; return 0; } /** |
f4ad8f2c4
|
577 578 579 |
* lsm_early_task - during initialization allocate a composite task blob * @task: the task that needs a blob * |
1cfb2a512
|
580 |
* Allocate the task blob for all the modules |
f4ad8f2c4
|
581 |
*/ |
1cfb2a512
|
582 |
static void __init lsm_early_task(struct task_struct *task) |
f4ad8f2c4
|
583 |
{ |
1cfb2a512
|
584 |
int rc = lsm_task_alloc(task); |
f4ad8f2c4
|
585 |
|
f4ad8f2c4
|
586 587 588 589 |
if (rc) panic("%s: Early task alloc failed. ", __func__); } |
f25fce3e8
|
590 |
/* |
b1d9e6b06
|
591 |
* Hook list operation macros. |
1da177e4c
|
592 |
* |
f25fce3e8
|
593 594 |
* call_void_hook: * This is a hook that does not return a value. |
1da177e4c
|
595 |
* |
f25fce3e8
|
596 597 |
* call_int_hook: * This is a hook that returns a value. |
1da177e4c
|
598 |
*/ |
1da177e4c
|
599 |
|
b1d9e6b06
|
600 601 602 603 |
#define call_void_hook(FUNC, ...) \ do { \ struct security_hook_list *P; \ \ |
df0ce1733
|
604 |
hlist_for_each_entry(P, &security_hook_heads.FUNC, list) \ |
b1d9e6b06
|
605 606 607 608 609 610 611 612 |
P->hook.FUNC(__VA_ARGS__); \ } while (0) #define call_int_hook(FUNC, IRC, ...) ({ \ int RC = IRC; \ do { \ struct security_hook_list *P; \ \ |
df0ce1733
|
613 |
hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \ |
b1d9e6b06
|
614 615 616 617 618 619 620 |
RC = P->hook.FUNC(__VA_ARGS__); \ if (RC != 0) \ break; \ } \ } while (0); \ RC; \ }) |
1da177e4c
|
621 |
|
20510f2f4
|
622 |
/* Security operations */ |
79af73079
|
623 624 |
int security_binder_set_context_mgr(struct task_struct *mgr) { |
f25fce3e8
|
625 |
return call_int_hook(binder_set_context_mgr, 0, mgr); |
79af73079
|
626 627 628 629 630 |
} int security_binder_transaction(struct task_struct *from, struct task_struct *to) { |
f25fce3e8
|
631 |
return call_int_hook(binder_transaction, 0, from, to); |
79af73079
|
632 633 634 635 636 |
} int security_binder_transfer_binder(struct task_struct *from, struct task_struct *to) { |
f25fce3e8
|
637 |
return call_int_hook(binder_transfer_binder, 0, from, to); |
79af73079
|
638 639 640 641 642 |
} int security_binder_transfer_file(struct task_struct *from, struct task_struct *to, struct file *file) { |
f25fce3e8
|
643 |
return call_int_hook(binder_transfer_file, 0, from, to, file); |
79af73079
|
644 |
} |
9e48858f7
|
645 |
int security_ptrace_access_check(struct task_struct *child, unsigned int mode) |
20510f2f4
|
646 |
{ |
f25fce3e8
|
647 |
return call_int_hook(ptrace_access_check, 0, child, mode); |
5cd9c58fb
|
648 649 650 651 |
} int security_ptrace_traceme(struct task_struct *parent) { |
f25fce3e8
|
652 |
return call_int_hook(ptrace_traceme, 0, parent); |
20510f2f4
|
653 654 655 656 657 658 659 |
} int security_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted) { |
f25fce3e8
|
660 661 |
return call_int_hook(capget, 0, target, effective, inheritable, permitted); |
20510f2f4
|
662 |
} |
d84f4f992
|
663 664 665 666 |
int security_capset(struct cred *new, const struct cred *old, const kernel_cap_t *effective, const kernel_cap_t *inheritable, const kernel_cap_t *permitted) |
20510f2f4
|
667 |
{ |
f25fce3e8
|
668 669 |
return call_int_hook(capset, 0, new, old, effective, inheritable, permitted); |
20510f2f4
|
670 |
} |
c1a85a00e
|
671 672 673 674 |
int security_capable(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts) |
20510f2f4
|
675 |
{ |
c1a85a00e
|
676 |
return call_int_hook(capable, 0, cred, ns, cap, opts); |
20510f2f4
|
677 |
} |
20510f2f4
|
678 679 |
int security_quotactl(int cmds, int type, int id, struct super_block *sb) { |
f25fce3e8
|
680 |
return call_int_hook(quotactl, 0, cmds, type, id, sb); |
20510f2f4
|
681 682 683 684 |
} int security_quota_on(struct dentry *dentry) { |
f25fce3e8
|
685 |
return call_int_hook(quota_on, 0, dentry); |
20510f2f4
|
686 |
} |
12b3052c3
|
687 |
int security_syslog(int type) |
20510f2f4
|
688 |
{ |
f25fce3e8
|
689 |
return call_int_hook(syslog, 0, type); |
20510f2f4
|
690 |
} |
457db29bf
|
691 |
int security_settime64(const struct timespec64 *ts, const struct timezone *tz) |
20510f2f4
|
692 |
{ |
f25fce3e8
|
693 |
return call_int_hook(settime, 0, ts, tz); |
20510f2f4
|
694 |
} |
20510f2f4
|
695 696 |
int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) { |
b1d9e6b06
|
697 698 699 700 701 702 703 704 705 706 707 |
struct security_hook_list *hp; int cap_sys_admin = 1; int rc; /* * The module will respond with a positive value if * it thinks the __vm_enough_memory() call should be * made with the cap_sys_admin set. If all of the modules * agree that it should be set it will. If any module * thinks it should not be set it won't. */ |
df0ce1733
|
708 |
hlist_for_each_entry(hp, &security_hook_heads.vm_enough_memory, list) { |
b1d9e6b06
|
709 710 711 712 713 714 715 |
rc = hp->hook.vm_enough_memory(mm, pages); if (rc <= 0) { cap_sys_admin = 0; break; } } return __vm_enough_memory(mm, pages, cap_sys_admin); |
20510f2f4
|
716 |
} |
a6f76f23d
|
717 |
int security_bprm_set_creds(struct linux_binprm *bprm) |
20510f2f4
|
718 |
{ |
f25fce3e8
|
719 |
return call_int_hook(bprm_set_creds, 0, bprm); |
20510f2f4
|
720 |
} |
a6f76f23d
|
721 |
int security_bprm_check(struct linux_binprm *bprm) |
20510f2f4
|
722 |
{ |
6c21a7fb4
|
723 |
int ret; |
f25fce3e8
|
724 |
ret = call_int_hook(bprm_check_security, 0, bprm); |
6c21a7fb4
|
725 726 727 |
if (ret) return ret; return ima_bprm_check(bprm); |
20510f2f4
|
728 |
} |
a6f76f23d
|
729 |
void security_bprm_committing_creds(struct linux_binprm *bprm) |
20510f2f4
|
730 |
{ |
f25fce3e8
|
731 |
call_void_hook(bprm_committing_creds, bprm); |
20510f2f4
|
732 |
} |
a6f76f23d
|
733 |
void security_bprm_committed_creds(struct linux_binprm *bprm) |
20510f2f4
|
734 |
{ |
f25fce3e8
|
735 |
call_void_hook(bprm_committed_creds, bprm); |
20510f2f4
|
736 |
} |
0b52075ee
|
737 738 739 740 |
int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc) { return call_int_hook(fs_context_dup, 0, fc, src_fc); } |
da2441fdf
|
741 742 743 744 |
int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *param) { return call_int_hook(fs_context_parse_param, -ENOPARAM, fc, param); } |
20510f2f4
|
745 746 |
int security_sb_alloc(struct super_block *sb) { |
f25fce3e8
|
747 |
return call_int_hook(sb_alloc_security, 0, sb); |
20510f2f4
|
748 749 750 751 |
} void security_sb_free(struct super_block *sb) { |
f25fce3e8
|
752 |
call_void_hook(sb_free_security, sb); |
20510f2f4
|
753 |
} |
204cc0ccf
|
754 |
void security_free_mnt_opts(void **mnt_opts) |
20510f2f4
|
755 |
{ |
204cc0ccf
|
756 757 758 759 |
if (!*mnt_opts) return; call_void_hook(sb_free_mnt_opts, *mnt_opts); *mnt_opts = NULL; |
20510f2f4
|
760 |
} |
204cc0ccf
|
761 |
EXPORT_SYMBOL(security_free_mnt_opts); |
20510f2f4
|
762 |
|
204cc0ccf
|
763 |
int security_sb_eat_lsm_opts(char *options, void **mnt_opts) |
ff36fe2c8
|
764 |
{ |
204cc0ccf
|
765 |
return call_int_hook(sb_eat_lsm_opts, 0, options, mnt_opts); |
ff36fe2c8
|
766 |
} |
f5c0c26d9
|
767 |
EXPORT_SYMBOL(security_sb_eat_lsm_opts); |
ff36fe2c8
|
768 |
|
c039bc3c2
|
769 |
int security_sb_remount(struct super_block *sb, |
204cc0ccf
|
770 |
void *mnt_opts) |
20510f2f4
|
771 |
{ |
204cc0ccf
|
772 |
return call_int_hook(sb_remount, 0, sb, mnt_opts); |
ff36fe2c8
|
773 |
} |
a65001e8a
|
774 |
EXPORT_SYMBOL(security_sb_remount); |
ff36fe2c8
|
775 |
|
a10d7c22b
|
776 |
int security_sb_kern_mount(struct super_block *sb) |
20510f2f4
|
777 |
{ |
a10d7c22b
|
778 |
return call_int_hook(sb_kern_mount, 0, sb); |
20510f2f4
|
779 |
} |
2069f4578
|
780 781 |
int security_sb_show_options(struct seq_file *m, struct super_block *sb) { |
f25fce3e8
|
782 |
return call_int_hook(sb_show_options, 0, m, sb); |
2069f4578
|
783 |
} |
20510f2f4
|
784 785 |
int security_sb_statfs(struct dentry *dentry) { |
f25fce3e8
|
786 |
return call_int_hook(sb_statfs, 0, dentry); |
20510f2f4
|
787 |
} |
8a04c43b8
|
788 |
int security_sb_mount(const char *dev_name, const struct path *path, |
808d4e3cf
|
789 |
const char *type, unsigned long flags, void *data) |
20510f2f4
|
790 |
{ |
f25fce3e8
|
791 |
return call_int_hook(sb_mount, 0, dev_name, path, type, flags, data); |
20510f2f4
|
792 |
} |
20510f2f4
|
793 794 |
int security_sb_umount(struct vfsmount *mnt, int flags) { |
f25fce3e8
|
795 |
return call_int_hook(sb_umount, 0, mnt, flags); |
20510f2f4
|
796 |
} |
3b73b68c0
|
797 |
int security_sb_pivotroot(const struct path *old_path, const struct path *new_path) |
20510f2f4
|
798 |
{ |
f25fce3e8
|
799 |
return call_int_hook(sb_pivotroot, 0, old_path, new_path); |
20510f2f4
|
800 |
} |
c9180a57a
|
801 |
int security_sb_set_mnt_opts(struct super_block *sb, |
204cc0ccf
|
802 |
void *mnt_opts, |
649f6e771
|
803 804 |
unsigned long kern_flags, unsigned long *set_kern_flags) |
c9180a57a
|
805 |
{ |
b1d9e6b06
|
806 |
return call_int_hook(sb_set_mnt_opts, |
204cc0ccf
|
807 808 |
mnt_opts ? -EOPNOTSUPP : 0, sb, mnt_opts, kern_flags, set_kern_flags); |
c9180a57a
|
809 |
} |
e00075298
|
810 |
EXPORT_SYMBOL(security_sb_set_mnt_opts); |
c9180a57a
|
811 |
|
094f7b69e
|
812 |
int security_sb_clone_mnt_opts(const struct super_block *oldsb, |
0b4d3452b
|
813 814 815 |
struct super_block *newsb, unsigned long kern_flags, unsigned long *set_kern_flags) |
c9180a57a
|
816 |
{ |
0b4d3452b
|
817 818 |
return call_int_hook(sb_clone_mnt_opts, 0, oldsb, newsb, kern_flags, set_kern_flags); |
c9180a57a
|
819 |
} |
e00075298
|
820 |
EXPORT_SYMBOL(security_sb_clone_mnt_opts); |
757cbe597
|
821 822 |
int security_add_mnt_opt(const char *option, const char *val, int len, void **mnt_opts) |
e00075298
|
823 |
{ |
757cbe597
|
824 825 |
return call_int_hook(sb_add_mnt_opt, -EINVAL, option, val, len, mnt_opts); |
e00075298
|
826 |
} |
757cbe597
|
827 |
EXPORT_SYMBOL(security_add_mnt_opt); |
c9180a57a
|
828 |
|
2db154b3e
|
829 830 831 832 |
int security_move_mount(const struct path *from_path, const struct path *to_path) { return call_int_hook(move_mount, 0, from_path, to_path); } |
20510f2f4
|
833 834 |
int security_inode_alloc(struct inode *inode) { |
afb1cbe37
|
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 |
int rc = lsm_inode_alloc(inode); if (unlikely(rc)) return rc; rc = call_int_hook(inode_alloc_security, 0, inode); if (unlikely(rc)) security_inode_free(inode); return rc; } static void inode_free_by_rcu(struct rcu_head *head) { /* * The rcu head is at the start of the inode blob */ kmem_cache_free(lsm_inode_cache, head); |
20510f2f4
|
851 852 853 854 |
} void security_inode_free(struct inode *inode) { |
f381c2722
|
855 |
integrity_inode_free(inode); |
f25fce3e8
|
856 |
call_void_hook(inode_free_security, inode); |
afb1cbe37
|
857 858 859 860 861 862 863 864 865 866 867 868 |
/* * The inode may still be referenced in a path walk and * a call to security_inode_permission() can be made * after inode_free_security() is called. Ideally, the VFS * wouldn't do this, but fixing that is a much harder * job. For now, simply free the i_security via RCU, and * leave the current inode->i_security pointer intact. * The inode will be freed after the RCU grace period too. */ if (inode->i_security) call_rcu((struct rcu_head *)inode->i_security, inode_free_by_rcu); |
20510f2f4
|
869 |
} |
d47be3dfe
|
870 |
int security_dentry_init_security(struct dentry *dentry, int mode, |
4f3ccd765
|
871 |
const struct qstr *name, void **ctx, |
d47be3dfe
|
872 873 |
u32 *ctxlen) { |
b1d9e6b06
|
874 875 |
return call_int_hook(dentry_init_security, -EOPNOTSUPP, dentry, mode, name, ctx, ctxlen); |
d47be3dfe
|
876 877 |
} EXPORT_SYMBOL(security_dentry_init_security); |
2602625b7
|
878 879 880 881 882 883 884 885 |
int security_dentry_create_files_as(struct dentry *dentry, int mode, struct qstr *name, const struct cred *old, struct cred *new) { return call_int_hook(dentry_create_files_as, 0, dentry, mode, name, old, new); } EXPORT_SYMBOL(security_dentry_create_files_as); |
20510f2f4
|
886 |
int security_inode_init_security(struct inode *inode, struct inode *dir, |
9d8f13ba3
|
887 888 |
const struct qstr *qstr, const initxattrs initxattrs, void *fs_data) |
20510f2f4
|
889 |
{ |
823eb1ccd
|
890 891 |
struct xattr new_xattrs[MAX_LSM_EVM_XATTR + 1]; struct xattr *lsm_xattr, *evm_xattr, *xattr; |
9d8f13ba3
|
892 |
int ret; |
20510f2f4
|
893 |
if (unlikely(IS_PRIVATE(inode))) |
fb88c2b6c
|
894 |
return 0; |
9d8f13ba3
|
895 |
|
9d8f13ba3
|
896 |
if (!initxattrs) |
e308fd3bb
|
897 898 |
return call_int_hook(inode_init_security, -EOPNOTSUPP, inode, dir, qstr, NULL, NULL, NULL); |
9548906b2
|
899 |
memset(new_xattrs, 0, sizeof(new_xattrs)); |
9d8f13ba3
|
900 |
lsm_xattr = new_xattrs; |
b1d9e6b06
|
901 |
ret = call_int_hook(inode_init_security, -EOPNOTSUPP, inode, dir, qstr, |
9d8f13ba3
|
902 903 904 905 906 |
&lsm_xattr->name, &lsm_xattr->value, &lsm_xattr->value_len); if (ret) goto out; |
823eb1ccd
|
907 908 909 910 911 |
evm_xattr = lsm_xattr + 1; ret = evm_inode_init_security(inode, lsm_xattr, evm_xattr); if (ret) goto out; |
9d8f13ba3
|
912 913 |
ret = initxattrs(inode, new_xattrs, fs_data); out: |
9548906b2
|
914 |
for (xattr = new_xattrs; xattr->value != NULL; xattr++) |
823eb1ccd
|
915 |
kfree(xattr->value); |
9d8f13ba3
|
916 917 918 919 920 |
return (ret == -EOPNOTSUPP) ? 0 : ret; } EXPORT_SYMBOL(security_inode_init_security); int security_old_inode_init_security(struct inode *inode, struct inode *dir, |
9548906b2
|
921 |
const struct qstr *qstr, const char **name, |
9d8f13ba3
|
922 |
void **value, size_t *len) |
20510f2f4
|
923 924 |
{ if (unlikely(IS_PRIVATE(inode))) |
30e053248
|
925 |
return -EOPNOTSUPP; |
e308fd3bb
|
926 927 |
return call_int_hook(inode_init_security, -EOPNOTSUPP, inode, dir, qstr, name, value, len); |
20510f2f4
|
928 |
} |
9d8f13ba3
|
929 |
EXPORT_SYMBOL(security_old_inode_init_security); |
20510f2f4
|
930 |
|
be6d3e56a
|
931 |
#ifdef CONFIG_SECURITY_PATH |
d36077521
|
932 |
int security_path_mknod(const struct path *dir, struct dentry *dentry, umode_t mode, |
be6d3e56a
|
933 934 |
unsigned int dev) { |
c6f493d63
|
935 |
if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) |
be6d3e56a
|
936 |
return 0; |
f25fce3e8
|
937 |
return call_int_hook(path_mknod, 0, dir, dentry, mode, dev); |
be6d3e56a
|
938 939 |
} EXPORT_SYMBOL(security_path_mknod); |
d36077521
|
940 |
int security_path_mkdir(const struct path *dir, struct dentry *dentry, umode_t mode) |
be6d3e56a
|
941 |
{ |
c6f493d63
|
942 |
if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) |
be6d3e56a
|
943 |
return 0; |
f25fce3e8
|
944 |
return call_int_hook(path_mkdir, 0, dir, dentry, mode); |
be6d3e56a
|
945 |
} |
821404434
|
946 |
EXPORT_SYMBOL(security_path_mkdir); |
be6d3e56a
|
947 |
|
989f74e05
|
948 |
int security_path_rmdir(const struct path *dir, struct dentry *dentry) |
be6d3e56a
|
949 |
{ |
c6f493d63
|
950 |
if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) |
be6d3e56a
|
951 |
return 0; |
f25fce3e8
|
952 |
return call_int_hook(path_rmdir, 0, dir, dentry); |
be6d3e56a
|
953 |
} |
989f74e05
|
954 |
int security_path_unlink(const struct path *dir, struct dentry *dentry) |
be6d3e56a
|
955 |
{ |
c6f493d63
|
956 |
if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) |
be6d3e56a
|
957 |
return 0; |
f25fce3e8
|
958 |
return call_int_hook(path_unlink, 0, dir, dentry); |
be6d3e56a
|
959 |
} |
821404434
|
960 |
EXPORT_SYMBOL(security_path_unlink); |
be6d3e56a
|
961 |
|
d36077521
|
962 |
int security_path_symlink(const struct path *dir, struct dentry *dentry, |
be6d3e56a
|
963 964 |
const char *old_name) { |
c6f493d63
|
965 |
if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) |
be6d3e56a
|
966 |
return 0; |
f25fce3e8
|
967 |
return call_int_hook(path_symlink, 0, dir, dentry, old_name); |
be6d3e56a
|
968 |
} |
3ccee46ab
|
969 |
int security_path_link(struct dentry *old_dentry, const struct path *new_dir, |
be6d3e56a
|
970 971 |
struct dentry *new_dentry) { |
c6f493d63
|
972 |
if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)))) |
be6d3e56a
|
973 |
return 0; |
f25fce3e8
|
974 |
return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry); |
be6d3e56a
|
975 |
} |
3ccee46ab
|
976 977 |
int security_path_rename(const struct path *old_dir, struct dentry *old_dentry, const struct path *new_dir, struct dentry *new_dentry, |
0b3974eb0
|
978 |
unsigned int flags) |
be6d3e56a
|
979 |
{ |
c6f493d63
|
980 981 |
if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)) || (d_is_positive(new_dentry) && IS_PRIVATE(d_backing_inode(new_dentry))))) |
be6d3e56a
|
982 |
return 0; |
da1ce0670
|
983 984 |
if (flags & RENAME_EXCHANGE) { |
f25fce3e8
|
985 986 |
int err = call_int_hook(path_rename, 0, new_dir, new_dentry, old_dir, old_dentry); |
da1ce0670
|
987 988 989 |
if (err) return err; } |
f25fce3e8
|
990 991 |
return call_int_hook(path_rename, 0, old_dir, old_dentry, new_dir, new_dentry); |
be6d3e56a
|
992 |
} |
821404434
|
993 |
EXPORT_SYMBOL(security_path_rename); |
be6d3e56a
|
994 |
|
81f4c5060
|
995 |
int security_path_truncate(const struct path *path) |
be6d3e56a
|
996 |
{ |
c6f493d63
|
997 |
if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry)))) |
be6d3e56a
|
998 |
return 0; |
f25fce3e8
|
999 |
return call_int_hook(path_truncate, 0, path); |
be6d3e56a
|
1000 |
} |
89eda0683
|
1001 |
|
be01f9f28
|
1002 |
int security_path_chmod(const struct path *path, umode_t mode) |
89eda0683
|
1003 |
{ |
c6f493d63
|
1004 |
if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry)))) |
89eda0683
|
1005 |
return 0; |
f25fce3e8
|
1006 |
return call_int_hook(path_chmod, 0, path, mode); |
89eda0683
|
1007 |
} |
7fd25dac9
|
1008 |
int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) |
89eda0683
|
1009 |
{ |
c6f493d63
|
1010 |
if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry)))) |
89eda0683
|
1011 |
return 0; |
f25fce3e8
|
1012 |
return call_int_hook(path_chown, 0, path, uid, gid); |
89eda0683
|
1013 |
} |
8b8efb440
|
1014 |
|
77b286c0d
|
1015 |
int security_path_chroot(const struct path *path) |
8b8efb440
|
1016 |
{ |
f25fce3e8
|
1017 |
return call_int_hook(path_chroot, 0, path); |
8b8efb440
|
1018 |
} |
be6d3e56a
|
1019 |
#endif |
4acdaf27e
|
1020 |
int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode) |
20510f2f4
|
1021 1022 1023 |
{ if (unlikely(IS_PRIVATE(dir))) return 0; |
f25fce3e8
|
1024 |
return call_int_hook(inode_create, 0, dir, dentry, mode); |
20510f2f4
|
1025 |
} |
800a96478
|
1026 |
EXPORT_SYMBOL_GPL(security_inode_create); |
20510f2f4
|
1027 1028 1029 1030 |
int security_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) { |
c6f493d63
|
1031 |
if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)))) |
20510f2f4
|
1032 |
return 0; |
f25fce3e8
|
1033 |
return call_int_hook(inode_link, 0, old_dentry, dir, new_dentry); |
20510f2f4
|
1034 1035 1036 1037 |
} int security_inode_unlink(struct inode *dir, struct dentry *dentry) { |
c6f493d63
|
1038 |
if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
20510f2f4
|
1039 |
return 0; |
f25fce3e8
|
1040 |
return call_int_hook(inode_unlink, 0, dir, dentry); |
20510f2f4
|
1041 1042 1043 1044 1045 1046 1047 |
} int security_inode_symlink(struct inode *dir, struct dentry *dentry, const char *old_name) { if (unlikely(IS_PRIVATE(dir))) return 0; |
f25fce3e8
|
1048 |
return call_int_hook(inode_symlink, 0, dir, dentry, old_name); |
20510f2f4
|
1049 |
} |
18bb1db3e
|
1050 |
int security_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
20510f2f4
|
1051 1052 1053 |
{ if (unlikely(IS_PRIVATE(dir))) return 0; |
f25fce3e8
|
1054 |
return call_int_hook(inode_mkdir, 0, dir, dentry, mode); |
20510f2f4
|
1055 |
} |
800a96478
|
1056 |
EXPORT_SYMBOL_GPL(security_inode_mkdir); |
20510f2f4
|
1057 1058 1059 |
int security_inode_rmdir(struct inode *dir, struct dentry *dentry) { |
c6f493d63
|
1060 |
if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
20510f2f4
|
1061 |
return 0; |
f25fce3e8
|
1062 |
return call_int_hook(inode_rmdir, 0, dir, dentry); |
20510f2f4
|
1063 |
} |
1a67aafb5
|
1064 |
int security_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) |
20510f2f4
|
1065 1066 1067 |
{ if (unlikely(IS_PRIVATE(dir))) return 0; |
f25fce3e8
|
1068 |
return call_int_hook(inode_mknod, 0, dir, dentry, mode, dev); |
20510f2f4
|
1069 1070 1071 |
} int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, |
0b3974eb0
|
1072 1073 |
struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) |
20510f2f4
|
1074 |
{ |
c6f493d63
|
1075 1076 |
if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)) || (d_is_positive(new_dentry) && IS_PRIVATE(d_backing_inode(new_dentry))))) |
20510f2f4
|
1077 |
return 0; |
da1ce0670
|
1078 1079 |
if (flags & RENAME_EXCHANGE) { |
f25fce3e8
|
1080 |
int err = call_int_hook(inode_rename, 0, new_dir, new_dentry, |
da1ce0670
|
1081 1082 1083 1084 |
old_dir, old_dentry); if (err) return err; } |
f25fce3e8
|
1085 |
return call_int_hook(inode_rename, 0, old_dir, old_dentry, |
20510f2f4
|
1086 1087 1088 1089 1090 |
new_dir, new_dentry); } int security_inode_readlink(struct dentry *dentry) { |
c6f493d63
|
1091 |
if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
20510f2f4
|
1092 |
return 0; |
f25fce3e8
|
1093 |
return call_int_hook(inode_readlink, 0, dentry); |
20510f2f4
|
1094 |
} |
bda0be7ad
|
1095 1096 |
int security_inode_follow_link(struct dentry *dentry, struct inode *inode, bool rcu) |
20510f2f4
|
1097 |
{ |
bda0be7ad
|
1098 |
if (unlikely(IS_PRIVATE(inode))) |
20510f2f4
|
1099 |
return 0; |
e22619a29
|
1100 |
return call_int_hook(inode_follow_link, 0, dentry, inode, rcu); |
20510f2f4
|
1101 |
} |
b77b0646e
|
1102 |
int security_inode_permission(struct inode *inode, int mask) |
20510f2f4
|
1103 1104 1105 |
{ if (unlikely(IS_PRIVATE(inode))) return 0; |
f25fce3e8
|
1106 |
return call_int_hook(inode_permission, 0, inode, mask); |
20510f2f4
|
1107 1108 1109 1110 |
} int security_inode_setattr(struct dentry *dentry, struct iattr *attr) { |
817b54aa4
|
1111 |
int ret; |
c6f493d63
|
1112 |
if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
20510f2f4
|
1113 |
return 0; |
f25fce3e8
|
1114 |
ret = call_int_hook(inode_setattr, 0, dentry, attr); |
817b54aa4
|
1115 1116 1117 |
if (ret) return ret; return evm_inode_setattr(dentry, attr); |
20510f2f4
|
1118 |
} |
b1da47e29
|
1119 |
EXPORT_SYMBOL_GPL(security_inode_setattr); |
20510f2f4
|
1120 |
|
3f7036a07
|
1121 |
int security_inode_getattr(const struct path *path) |
20510f2f4
|
1122 |
{ |
c6f493d63
|
1123 |
if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry)))) |
20510f2f4
|
1124 |
return 0; |
f25fce3e8
|
1125 |
return call_int_hook(inode_getattr, 0, path); |
20510f2f4
|
1126 |
} |
8f0cfa52a
|
1127 1128 |
int security_inode_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) |
20510f2f4
|
1129 |
{ |
3e1be52d6
|
1130 |
int ret; |
c6f493d63
|
1131 |
if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
20510f2f4
|
1132 |
return 0; |
b1d9e6b06
|
1133 1134 1135 1136 1137 |
/* * SELinux and Smack integrate the cap call, * so assume that all LSMs supplying this call do so. */ ret = call_int_hook(inode_setxattr, 1, dentry, name, value, size, |
f25fce3e8
|
1138 |
flags); |
b1d9e6b06
|
1139 1140 1141 |
if (ret == 1) ret = cap_inode_setxattr(dentry, name, value, size, flags); |
3e1be52d6
|
1142 1143 |
if (ret) return ret; |
42c63330f
|
1144 1145 1146 |
ret = ima_inode_setxattr(dentry, name, value, size); if (ret) return ret; |
3e1be52d6
|
1147 |
return evm_inode_setxattr(dentry, name, value, size); |
20510f2f4
|
1148 |
} |
8f0cfa52a
|
1149 1150 |
void security_inode_post_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) |
20510f2f4
|
1151 |
{ |
c6f493d63
|
1152 |
if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
20510f2f4
|
1153 |
return; |
f25fce3e8
|
1154 |
call_void_hook(inode_post_setxattr, dentry, name, value, size, flags); |
3e1be52d6
|
1155 |
evm_inode_post_setxattr(dentry, name, value, size); |
20510f2f4
|
1156 |
} |
8f0cfa52a
|
1157 |
int security_inode_getxattr(struct dentry *dentry, const char *name) |
20510f2f4
|
1158 |
{ |
c6f493d63
|
1159 |
if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
20510f2f4
|
1160 |
return 0; |
f25fce3e8
|
1161 |
return call_int_hook(inode_getxattr, 0, dentry, name); |
20510f2f4
|
1162 1163 1164 1165 |
} int security_inode_listxattr(struct dentry *dentry) { |
c6f493d63
|
1166 |
if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
20510f2f4
|
1167 |
return 0; |
f25fce3e8
|
1168 |
return call_int_hook(inode_listxattr, 0, dentry); |
20510f2f4
|
1169 |
} |
8f0cfa52a
|
1170 |
int security_inode_removexattr(struct dentry *dentry, const char *name) |
20510f2f4
|
1171 |
{ |
3e1be52d6
|
1172 |
int ret; |
c6f493d63
|
1173 |
if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
20510f2f4
|
1174 |
return 0; |
b1d9e6b06
|
1175 1176 1177 1178 1179 1180 1181 |
/* * SELinux and Smack integrate the cap call, * so assume that all LSMs supplying this call do so. */ ret = call_int_hook(inode_removexattr, 1, dentry, name); if (ret == 1) ret = cap_inode_removexattr(dentry, name); |
3e1be52d6
|
1182 1183 |
if (ret) return ret; |
42c63330f
|
1184 1185 1186 |
ret = ima_inode_removexattr(dentry, name); if (ret) return ret; |
3e1be52d6
|
1187 |
return evm_inode_removexattr(dentry, name); |
20510f2f4
|
1188 |
} |
b53767719
|
1189 1190 |
int security_inode_need_killpriv(struct dentry *dentry) { |
f25fce3e8
|
1191 |
return call_int_hook(inode_need_killpriv, 0, dentry); |
b53767719
|
1192 1193 1194 1195 |
} int security_inode_killpriv(struct dentry *dentry) { |
f25fce3e8
|
1196 |
return call_int_hook(inode_killpriv, 0, dentry); |
b53767719
|
1197 |
} |
ea861dfd9
|
1198 |
int security_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc) |
20510f2f4
|
1199 |
{ |
2885c1e3e
|
1200 1201 |
struct security_hook_list *hp; int rc; |
20510f2f4
|
1202 |
if (unlikely(IS_PRIVATE(inode))) |
8d9525048
|
1203 |
return -EOPNOTSUPP; |
2885c1e3e
|
1204 1205 1206 |
/* * Only one module will provide an attribute with a given name. */ |
df0ce1733
|
1207 |
hlist_for_each_entry(hp, &security_hook_heads.inode_getsecurity, list) { |
2885c1e3e
|
1208 1209 1210 1211 1212 |
rc = hp->hook.inode_getsecurity(inode, name, buffer, alloc); if (rc != -EOPNOTSUPP) return rc; } return -EOPNOTSUPP; |
20510f2f4
|
1213 1214 1215 1216 |
} int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags) { |
2885c1e3e
|
1217 1218 |
struct security_hook_list *hp; int rc; |
20510f2f4
|
1219 |
if (unlikely(IS_PRIVATE(inode))) |
8d9525048
|
1220 |
return -EOPNOTSUPP; |
2885c1e3e
|
1221 1222 1223 |
/* * Only one module will provide an attribute with a given name. */ |
df0ce1733
|
1224 |
hlist_for_each_entry(hp, &security_hook_heads.inode_setsecurity, list) { |
2885c1e3e
|
1225 1226 1227 1228 1229 1230 |
rc = hp->hook.inode_setsecurity(inode, name, value, size, flags); if (rc != -EOPNOTSUPP) return rc; } return -EOPNOTSUPP; |
20510f2f4
|
1231 1232 1233 1234 1235 1236 |
} int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) { if (unlikely(IS_PRIVATE(inode))) return 0; |
f25fce3e8
|
1237 |
return call_int_hook(inode_listsecurity, 0, inode, buffer, buffer_size); |
20510f2f4
|
1238 |
} |
c9bccef6b
|
1239 |
EXPORT_SYMBOL(security_inode_listsecurity); |
20510f2f4
|
1240 |
|
d6335d77a
|
1241 |
void security_inode_getsecid(struct inode *inode, u32 *secid) |
8a076191f
|
1242 |
{ |
f25fce3e8
|
1243 |
call_void_hook(inode_getsecid, inode, secid); |
8a076191f
|
1244 |
} |
d8ad8b496
|
1245 1246 1247 1248 1249 |
int security_inode_copy_up(struct dentry *src, struct cred **new) { return call_int_hook(inode_copy_up, 0, src, new); } EXPORT_SYMBOL(security_inode_copy_up); |
121ab822e
|
1250 1251 1252 1253 1254 |
int security_inode_copy_up_xattr(const char *name) { return call_int_hook(inode_copy_up_xattr, -EOPNOTSUPP, name); } EXPORT_SYMBOL(security_inode_copy_up_xattr); |
b230d5aba
|
1255 1256 1257 1258 1259 |
int security_kernfs_init_security(struct kernfs_node *kn_dir, struct kernfs_node *kn) { return call_int_hook(kernfs_init_security, 0, kn_dir, kn); } |
20510f2f4
|
1260 1261 |
int security_file_permission(struct file *file, int mask) { |
c4ec54b40
|
1262 |
int ret; |
f25fce3e8
|
1263 |
ret = call_int_hook(file_permission, 0, file, mask); |
c4ec54b40
|
1264 1265 1266 1267 |
if (ret) return ret; return fsnotify_perm(file, mask); |
20510f2f4
|
1268 1269 1270 1271 |
} int security_file_alloc(struct file *file) { |
33bf60cab
|
1272 1273 1274 1275 1276 1277 1278 1279 |
int rc = lsm_file_alloc(file); if (rc) return rc; rc = call_int_hook(file_alloc_security, 0, file); if (unlikely(rc)) security_file_free(file); return rc; |
20510f2f4
|
1280 1281 1282 1283 |
} void security_file_free(struct file *file) { |
33bf60cab
|
1284 |
void *blob; |
f25fce3e8
|
1285 |
call_void_hook(file_free_security, file); |
33bf60cab
|
1286 1287 1288 1289 1290 1291 |
blob = file->f_security; if (blob) { file->f_security = NULL; kmem_cache_free(lsm_file_cache, blob); } |
20510f2f4
|
1292 1293 1294 1295 |
} int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { |
f25fce3e8
|
1296 |
return call_int_hook(file_ioctl, 0, file, cmd, arg); |
20510f2f4
|
1297 |
} |
98de59bfe
|
1298 |
static inline unsigned long mmap_prot(struct file *file, unsigned long prot) |
20510f2f4
|
1299 |
{ |
8b3ec6814
|
1300 |
/* |
98de59bfe
|
1301 1302 |
* Does we have PROT_READ and does the application expect * it to imply PROT_EXEC? If not, nothing to talk about... |
8b3ec6814
|
1303 |
*/ |
98de59bfe
|
1304 1305 |
if ((prot & (PROT_READ | PROT_EXEC)) != PROT_READ) return prot; |
8b3ec6814
|
1306 |
if (!(current->personality & READ_IMPLIES_EXEC)) |
98de59bfe
|
1307 1308 1309 1310 1311 1312 1313 1314 |
return prot; /* * if that's an anonymous mapping, let it. */ if (!file) return prot | PROT_EXEC; /* * ditto if it's not on noexec mount, except that on !MMU we need |
b4caecd48
|
1315 |
* NOMMU_MAP_EXEC (== VM_MAYEXEC) in this case |
98de59bfe
|
1316 |
*/ |
90f8572b0
|
1317 |
if (!path_noexec(&file->f_path)) { |
8b3ec6814
|
1318 |
#ifndef CONFIG_MMU |
b4caecd48
|
1319 1320 1321 1322 1323 |
if (file->f_op->mmap_capabilities) { unsigned caps = file->f_op->mmap_capabilities(file); if (!(caps & NOMMU_MAP_EXEC)) return prot; } |
8b3ec6814
|
1324 |
#endif |
98de59bfe
|
1325 |
return prot | PROT_EXEC; |
8b3ec6814
|
1326 |
} |
98de59bfe
|
1327 1328 1329 1330 1331 1332 1333 1334 |
/* anything on noexec mount won't get PROT_EXEC */ return prot; } int security_mmap_file(struct file *file, unsigned long prot, unsigned long flags) { int ret; |
f25fce3e8
|
1335 |
ret = call_int_hook(mmap_file, 0, file, prot, |
98de59bfe
|
1336 |
mmap_prot(file, prot), flags); |
6c21a7fb4
|
1337 1338 1339 |
if (ret) return ret; return ima_file_mmap(file, prot); |
20510f2f4
|
1340 |
} |
e5467859f
|
1341 1342 |
int security_mmap_addr(unsigned long addr) { |
f25fce3e8
|
1343 |
return call_int_hook(mmap_addr, 0, addr); |
e5467859f
|
1344 |
} |
20510f2f4
|
1345 1346 1347 |
int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, unsigned long prot) { |
f25fce3e8
|
1348 |
return call_int_hook(file_mprotect, 0, vma, reqprot, prot); |
20510f2f4
|
1349 1350 1351 1352 |
} int security_file_lock(struct file *file, unsigned int cmd) { |
f25fce3e8
|
1353 |
return call_int_hook(file_lock, 0, file, cmd); |
20510f2f4
|
1354 1355 1356 1357 |
} int security_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg) { |
f25fce3e8
|
1358 |
return call_int_hook(file_fcntl, 0, file, cmd, arg); |
20510f2f4
|
1359 |
} |
e0b93eddf
|
1360 |
void security_file_set_fowner(struct file *file) |
20510f2f4
|
1361 |
{ |
f25fce3e8
|
1362 |
call_void_hook(file_set_fowner, file); |
20510f2f4
|
1363 1364 1365 1366 1367 |
} int security_file_send_sigiotask(struct task_struct *tsk, struct fown_struct *fown, int sig) { |
f25fce3e8
|
1368 |
return call_int_hook(file_send_sigiotask, 0, tsk, fown, sig); |
20510f2f4
|
1369 1370 1371 1372 |
} int security_file_receive(struct file *file) { |
f25fce3e8
|
1373 |
return call_int_hook(file_receive, 0, file); |
20510f2f4
|
1374 |
} |
e3f20ae21
|
1375 |
int security_file_open(struct file *file) |
20510f2f4
|
1376 |
{ |
c4ec54b40
|
1377 |
int ret; |
948176920
|
1378 |
ret = call_int_hook(file_open, 0, file); |
c4ec54b40
|
1379 1380 1381 1382 |
if (ret) return ret; return fsnotify_perm(file, MAY_OPEN); |
20510f2f4
|
1383 |
} |
e4e55b47e
|
1384 1385 |
int security_task_alloc(struct task_struct *task, unsigned long clone_flags) { |
f4ad8f2c4
|
1386 1387 1388 1389 1390 1391 1392 1393 |
int rc = lsm_task_alloc(task); if (rc) return rc; rc = call_int_hook(task_alloc, 0, task, clone_flags); if (unlikely(rc)) security_task_free(task); return rc; |
e4e55b47e
|
1394 |
} |
1a2a4d06e
|
1395 1396 |
void security_task_free(struct task_struct *task) { |
f25fce3e8
|
1397 |
call_void_hook(task_free, task); |
f4ad8f2c4
|
1398 1399 1400 |
kfree(task->security); task->security = NULL; |
1a2a4d06e
|
1401 |
} |
ee18d64c1
|
1402 1403 |
int security_cred_alloc_blank(struct cred *cred, gfp_t gfp) { |
bbd3662a8
|
1404 1405 1406 1407 1408 1409 |
int rc = lsm_cred_alloc(cred, gfp); if (rc) return rc; rc = call_int_hook(cred_alloc_blank, 0, cred, gfp); |
33bf60cab
|
1410 |
if (unlikely(rc)) |
bbd3662a8
|
1411 1412 |
security_cred_free(cred); return rc; |
ee18d64c1
|
1413 |
} |
d84f4f992
|
1414 |
void security_cred_free(struct cred *cred) |
20510f2f4
|
1415 |
{ |
a5795fd38
|
1416 1417 1418 1419 1420 1421 |
/* * There is a failure case in prepare_creds() that * may result in a call here with ->security being NULL. */ if (unlikely(cred->security == NULL)) return; |
f25fce3e8
|
1422 |
call_void_hook(cred_free, cred); |
bbd3662a8
|
1423 1424 1425 |
kfree(cred->security); cred->security = NULL; |
20510f2f4
|
1426 |
} |
d84f4f992
|
1427 |
int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp) |
20510f2f4
|
1428 |
{ |
bbd3662a8
|
1429 1430 1431 1432 1433 1434 |
int rc = lsm_cred_alloc(new, gfp); if (rc) return rc; rc = call_int_hook(cred_prepare, 0, new, old, gfp); |
33bf60cab
|
1435 |
if (unlikely(rc)) |
bbd3662a8
|
1436 1437 |
security_cred_free(new); return rc; |
d84f4f992
|
1438 |
} |
ee18d64c1
|
1439 1440 |
void security_transfer_creds(struct cred *new, const struct cred *old) { |
f25fce3e8
|
1441 |
call_void_hook(cred_transfer, new, old); |
ee18d64c1
|
1442 |
} |
3ec301132
|
1443 1444 1445 1446 1447 1448 |
void security_cred_getsecid(const struct cred *c, u32 *secid) { *secid = 0; call_void_hook(cred_getsecid, c, secid); } EXPORT_SYMBOL(security_cred_getsecid); |
3a3b7ce93
|
1449 1450 |
int security_kernel_act_as(struct cred *new, u32 secid) { |
f25fce3e8
|
1451 |
return call_int_hook(kernel_act_as, 0, new, secid); |
3a3b7ce93
|
1452 1453 1454 1455 |
} int security_kernel_create_files_as(struct cred *new, struct inode *inode) { |
f25fce3e8
|
1456 |
return call_int_hook(kernel_create_files_as, 0, new, inode); |
3a3b7ce93
|
1457 |
} |
dd8dbf2e6
|
1458 |
int security_kernel_module_request(char *kmod_name) |
9188499cd
|
1459 |
{ |
6eb864c1d
|
1460 1461 1462 1463 1464 1465 |
int ret; ret = call_int_hook(kernel_module_request, 0, kmod_name); if (ret) return ret; return integrity_kernel_module_request(kmod_name); |
9188499cd
|
1466 |
} |
39eeb4fb9
|
1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 |
int security_kernel_read_file(struct file *file, enum kernel_read_file_id id) { int ret; ret = call_int_hook(kernel_read_file, 0, file, id); if (ret) return ret; return ima_read_file(file, id); } EXPORT_SYMBOL_GPL(security_kernel_read_file); |
bc8ca5b92
|
1477 1478 |
int security_kernel_post_read_file(struct file *file, char *buf, loff_t size, enum kernel_read_file_id id) |
b44a7dfc6
|
1479 |
{ |
cf2222178
|
1480 1481 1482 1483 1484 1485 |
int ret; ret = call_int_hook(kernel_post_read_file, 0, file, buf, size, id); if (ret) return ret; return ima_post_read_file(file, buf, size, id); |
b44a7dfc6
|
1486 1487 |
} EXPORT_SYMBOL_GPL(security_kernel_post_read_file); |
377179cd2
|
1488 1489 |
int security_kernel_load_data(enum kernel_load_data_id id) { |
16c267aac
|
1490 1491 1492 1493 1494 1495 |
int ret; ret = call_int_hook(kernel_load_data, 0, id); if (ret) return ret; return ima_load_data(id); |
377179cd2
|
1496 |
} |
83a68a067
|
1497 |
EXPORT_SYMBOL_GPL(security_kernel_load_data); |
377179cd2
|
1498 |
|
d84f4f992
|
1499 1500 |
int security_task_fix_setuid(struct cred *new, const struct cred *old, int flags) |
20510f2f4
|
1501 |
{ |
f25fce3e8
|
1502 |
return call_int_hook(task_fix_setuid, 0, new, old, flags); |
20510f2f4
|
1503 |
} |
20510f2f4
|
1504 1505 |
int security_task_setpgid(struct task_struct *p, pid_t pgid) { |
f25fce3e8
|
1506 |
return call_int_hook(task_setpgid, 0, p, pgid); |
20510f2f4
|
1507 1508 1509 1510 |
} int security_task_getpgid(struct task_struct *p) { |
f25fce3e8
|
1511 |
return call_int_hook(task_getpgid, 0, p); |
20510f2f4
|
1512 1513 1514 1515 |
} int security_task_getsid(struct task_struct *p) { |
f25fce3e8
|
1516 |
return call_int_hook(task_getsid, 0, p); |
20510f2f4
|
1517 1518 1519 1520 |
} void security_task_getsecid(struct task_struct *p, u32 *secid) { |
b1d9e6b06
|
1521 |
*secid = 0; |
f25fce3e8
|
1522 |
call_void_hook(task_getsecid, p, secid); |
20510f2f4
|
1523 1524 |
} EXPORT_SYMBOL(security_task_getsecid); |
20510f2f4
|
1525 1526 |
int security_task_setnice(struct task_struct *p, int nice) { |
f25fce3e8
|
1527 |
return call_int_hook(task_setnice, 0, p, nice); |
20510f2f4
|
1528 1529 1530 1531 |
} int security_task_setioprio(struct task_struct *p, int ioprio) { |
f25fce3e8
|
1532 |
return call_int_hook(task_setioprio, 0, p, ioprio); |
20510f2f4
|
1533 1534 1535 1536 |
} int security_task_getioprio(struct task_struct *p) { |
f25fce3e8
|
1537 |
return call_int_hook(task_getioprio, 0, p); |
20510f2f4
|
1538 |
} |
791ec491c
|
1539 1540 1541 1542 1543 |
int security_task_prlimit(const struct cred *cred, const struct cred *tcred, unsigned int flags) { return call_int_hook(task_prlimit, 0, cred, tcred, flags); } |
8fd00b4d7
|
1544 1545 |
int security_task_setrlimit(struct task_struct *p, unsigned int resource, struct rlimit *new_rlim) |
20510f2f4
|
1546 |
{ |
f25fce3e8
|
1547 |
return call_int_hook(task_setrlimit, 0, p, resource, new_rlim); |
20510f2f4
|
1548 |
} |
b0ae19811
|
1549 |
int security_task_setscheduler(struct task_struct *p) |
20510f2f4
|
1550 |
{ |
f25fce3e8
|
1551 |
return call_int_hook(task_setscheduler, 0, p); |
20510f2f4
|
1552 1553 1554 1555 |
} int security_task_getscheduler(struct task_struct *p) { |
f25fce3e8
|
1556 |
return call_int_hook(task_getscheduler, 0, p); |
20510f2f4
|
1557 1558 1559 1560 |
} int security_task_movememory(struct task_struct *p) { |
f25fce3e8
|
1561 |
return call_int_hook(task_movememory, 0, p); |
20510f2f4
|
1562 |
} |
ae7795bc6
|
1563 |
int security_task_kill(struct task_struct *p, struct kernel_siginfo *info, |
6b4f3d010
|
1564 |
int sig, const struct cred *cred) |
20510f2f4
|
1565 |
{ |
6b4f3d010
|
1566 |
return call_int_hook(task_kill, 0, p, info, sig, cred); |
20510f2f4
|
1567 |
} |
20510f2f4
|
1568 |
int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, |
d84f4f992
|
1569 |
unsigned long arg4, unsigned long arg5) |
20510f2f4
|
1570 |
{ |
b1d9e6b06
|
1571 1572 1573 |
int thisrc; int rc = -ENOSYS; struct security_hook_list *hp; |
df0ce1733
|
1574 |
hlist_for_each_entry(hp, &security_hook_heads.task_prctl, list) { |
b1d9e6b06
|
1575 1576 1577 1578 1579 1580 1581 1582 |
thisrc = hp->hook.task_prctl(option, arg2, arg3, arg4, arg5); if (thisrc != -ENOSYS) { rc = thisrc; if (thisrc != 0) break; } } return rc; |
20510f2f4
|
1583 1584 1585 1586 |
} void security_task_to_inode(struct task_struct *p, struct inode *inode) { |
f25fce3e8
|
1587 |
call_void_hook(task_to_inode, p, inode); |
20510f2f4
|
1588 1589 1590 1591 |
} int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag) { |
f25fce3e8
|
1592 |
return call_int_hook(ipc_permission, 0, ipcp, flag); |
20510f2f4
|
1593 |
} |
8a076191f
|
1594 1595 |
void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) { |
b1d9e6b06
|
1596 |
*secid = 0; |
f25fce3e8
|
1597 |
call_void_hook(ipc_getsecid, ipcp, secid); |
8a076191f
|
1598 |
} |
20510f2f4
|
1599 1600 |
int security_msg_msg_alloc(struct msg_msg *msg) { |
ecd5f82e0
|
1601 1602 1603 1604 1605 1606 1607 1608 |
int rc = lsm_msg_msg_alloc(msg); if (unlikely(rc)) return rc; rc = call_int_hook(msg_msg_alloc_security, 0, msg); if (unlikely(rc)) security_msg_msg_free(msg); return rc; |
20510f2f4
|
1609 1610 1611 1612 |
} void security_msg_msg_free(struct msg_msg *msg) { |
f25fce3e8
|
1613 |
call_void_hook(msg_msg_free_security, msg); |
ecd5f82e0
|
1614 1615 |
kfree(msg->security); msg->security = NULL; |
20510f2f4
|
1616 |
} |
d8c6e8543
|
1617 |
int security_msg_queue_alloc(struct kern_ipc_perm *msq) |
20510f2f4
|
1618 |
{ |
ecd5f82e0
|
1619 1620 1621 1622 1623 1624 1625 1626 |
int rc = lsm_ipc_alloc(msq); if (unlikely(rc)) return rc; rc = call_int_hook(msg_queue_alloc_security, 0, msq); if (unlikely(rc)) security_msg_queue_free(msq); return rc; |
20510f2f4
|
1627 |
} |
d8c6e8543
|
1628 |
void security_msg_queue_free(struct kern_ipc_perm *msq) |
20510f2f4
|
1629 |
{ |
f25fce3e8
|
1630 |
call_void_hook(msg_queue_free_security, msq); |
ecd5f82e0
|
1631 1632 |
kfree(msq->security); msq->security = NULL; |
20510f2f4
|
1633 |
} |
d8c6e8543
|
1634 |
int security_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) |
20510f2f4
|
1635 |
{ |
f25fce3e8
|
1636 |
return call_int_hook(msg_queue_associate, 0, msq, msqflg); |
20510f2f4
|
1637 |
} |
d8c6e8543
|
1638 |
int security_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd) |
20510f2f4
|
1639 |
{ |
f25fce3e8
|
1640 |
return call_int_hook(msg_queue_msgctl, 0, msq, cmd); |
20510f2f4
|
1641 |
} |
d8c6e8543
|
1642 |
int security_msg_queue_msgsnd(struct kern_ipc_perm *msq, |
20510f2f4
|
1643 1644 |
struct msg_msg *msg, int msqflg) { |
f25fce3e8
|
1645 |
return call_int_hook(msg_queue_msgsnd, 0, msq, msg, msqflg); |
20510f2f4
|
1646 |
} |
d8c6e8543
|
1647 |
int security_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg, |
20510f2f4
|
1648 1649 |
struct task_struct *target, long type, int mode) { |
f25fce3e8
|
1650 |
return call_int_hook(msg_queue_msgrcv, 0, msq, msg, target, type, mode); |
20510f2f4
|
1651 |
} |
7191adff2
|
1652 |
int security_shm_alloc(struct kern_ipc_perm *shp) |
20510f2f4
|
1653 |
{ |
ecd5f82e0
|
1654 1655 1656 1657 1658 1659 1660 1661 |
int rc = lsm_ipc_alloc(shp); if (unlikely(rc)) return rc; rc = call_int_hook(shm_alloc_security, 0, shp); if (unlikely(rc)) security_shm_free(shp); return rc; |
20510f2f4
|
1662 |
} |
7191adff2
|
1663 |
void security_shm_free(struct kern_ipc_perm *shp) |
20510f2f4
|
1664 |
{ |
f25fce3e8
|
1665 |
call_void_hook(shm_free_security, shp); |
ecd5f82e0
|
1666 1667 |
kfree(shp->security); shp->security = NULL; |
20510f2f4
|
1668 |
} |
7191adff2
|
1669 |
int security_shm_associate(struct kern_ipc_perm *shp, int shmflg) |
20510f2f4
|
1670 |
{ |
f25fce3e8
|
1671 |
return call_int_hook(shm_associate, 0, shp, shmflg); |
20510f2f4
|
1672 |
} |
7191adff2
|
1673 |
int security_shm_shmctl(struct kern_ipc_perm *shp, int cmd) |
20510f2f4
|
1674 |
{ |
f25fce3e8
|
1675 |
return call_int_hook(shm_shmctl, 0, shp, cmd); |
20510f2f4
|
1676 |
} |
7191adff2
|
1677 |
int security_shm_shmat(struct kern_ipc_perm *shp, char __user *shmaddr, int shmflg) |
20510f2f4
|
1678 |
{ |
f25fce3e8
|
1679 |
return call_int_hook(shm_shmat, 0, shp, shmaddr, shmflg); |
20510f2f4
|
1680 |
} |
aefad9593
|
1681 |
int security_sem_alloc(struct kern_ipc_perm *sma) |
20510f2f4
|
1682 |
{ |
ecd5f82e0
|
1683 1684 1685 1686 1687 1688 1689 1690 |
int rc = lsm_ipc_alloc(sma); if (unlikely(rc)) return rc; rc = call_int_hook(sem_alloc_security, 0, sma); if (unlikely(rc)) security_sem_free(sma); return rc; |
20510f2f4
|
1691 |
} |
aefad9593
|
1692 |
void security_sem_free(struct kern_ipc_perm *sma) |
20510f2f4
|
1693 |
{ |
f25fce3e8
|
1694 |
call_void_hook(sem_free_security, sma); |
ecd5f82e0
|
1695 1696 |
kfree(sma->security); sma->security = NULL; |
20510f2f4
|
1697 |
} |
aefad9593
|
1698 |
int security_sem_associate(struct kern_ipc_perm *sma, int semflg) |
20510f2f4
|
1699 |
{ |
f25fce3e8
|
1700 |
return call_int_hook(sem_associate, 0, sma, semflg); |
20510f2f4
|
1701 |
} |
aefad9593
|
1702 |
int security_sem_semctl(struct kern_ipc_perm *sma, int cmd) |
20510f2f4
|
1703 |
{ |
f25fce3e8
|
1704 |
return call_int_hook(sem_semctl, 0, sma, cmd); |
20510f2f4
|
1705 |
} |
aefad9593
|
1706 |
int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops, |
20510f2f4
|
1707 1708 |
unsigned nsops, int alter) { |
f25fce3e8
|
1709 |
return call_int_hook(sem_semop, 0, sma, sops, nsops, alter); |
20510f2f4
|
1710 1711 1712 1713 1714 1715 |
} void security_d_instantiate(struct dentry *dentry, struct inode *inode) { if (unlikely(inode && IS_PRIVATE(inode))) return; |
f25fce3e8
|
1716 |
call_void_hook(d_instantiate, dentry, inode); |
20510f2f4
|
1717 1718 |
} EXPORT_SYMBOL(security_d_instantiate); |
6d9c939db
|
1719 1720 |
int security_getprocattr(struct task_struct *p, const char *lsm, char *name, char **value) |
20510f2f4
|
1721 |
{ |
6d9c939db
|
1722 1723 1724 1725 1726 1727 1728 1729 |
struct security_hook_list *hp; hlist_for_each_entry(hp, &security_hook_heads.getprocattr, list) { if (lsm != NULL && strcmp(lsm, hp->lsm)) continue; return hp->hook.getprocattr(p, name, value); } return -EINVAL; |
20510f2f4
|
1730 |
} |
6d9c939db
|
1731 1732 |
int security_setprocattr(const char *lsm, const char *name, void *value, size_t size) |
20510f2f4
|
1733 |
{ |
6d9c939db
|
1734 1735 1736 1737 1738 1739 1740 1741 |
struct security_hook_list *hp; hlist_for_each_entry(hp, &security_hook_heads.setprocattr, list) { if (lsm != NULL && strcmp(lsm, hp->lsm)) continue; return hp->hook.setprocattr(name, value, size); } return -EINVAL; |
20510f2f4
|
1742 1743 1744 1745 |
} int security_netlink_send(struct sock *sk, struct sk_buff *skb) { |
f25fce3e8
|
1746 |
return call_int_hook(netlink_send, 0, sk, skb); |
20510f2f4
|
1747 |
} |
20510f2f4
|
1748 |
|
746df9b59
|
1749 1750 |
int security_ismaclabel(const char *name) { |
f25fce3e8
|
1751 |
return call_int_hook(ismaclabel, 0, name); |
746df9b59
|
1752 1753 |
} EXPORT_SYMBOL(security_ismaclabel); |
20510f2f4
|
1754 1755 |
int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) { |
b1d9e6b06
|
1756 1757 |
return call_int_hook(secid_to_secctx, -EOPNOTSUPP, secid, secdata, seclen); |
20510f2f4
|
1758 1759 |
} EXPORT_SYMBOL(security_secid_to_secctx); |
7bf570dc8
|
1760 |
int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) |
63cb34492
|
1761 |
{ |
b1d9e6b06
|
1762 |
*secid = 0; |
f25fce3e8
|
1763 |
return call_int_hook(secctx_to_secid, 0, secdata, seclen, secid); |
63cb34492
|
1764 1765 |
} EXPORT_SYMBOL(security_secctx_to_secid); |
20510f2f4
|
1766 1767 |
void security_release_secctx(char *secdata, u32 seclen) { |
f25fce3e8
|
1768 |
call_void_hook(release_secctx, secdata, seclen); |
20510f2f4
|
1769 1770 |
} EXPORT_SYMBOL(security_release_secctx); |
6f3be9f56
|
1771 1772 1773 1774 1775 |
void security_inode_invalidate_secctx(struct inode *inode) { call_void_hook(inode_invalidate_secctx, inode); } EXPORT_SYMBOL(security_inode_invalidate_secctx); |
1ee65e37e
|
1776 1777 |
int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) { |
f25fce3e8
|
1778 |
return call_int_hook(inode_notifysecctx, 0, inode, ctx, ctxlen); |
1ee65e37e
|
1779 1780 1781 1782 1783 |
} EXPORT_SYMBOL(security_inode_notifysecctx); int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen) { |
f25fce3e8
|
1784 |
return call_int_hook(inode_setsecctx, 0, dentry, ctx, ctxlen); |
1ee65e37e
|
1785 1786 1787 1788 1789 |
} EXPORT_SYMBOL(security_inode_setsecctx); int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) { |
b1d9e6b06
|
1790 |
return call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, ctx, ctxlen); |
1ee65e37e
|
1791 1792 |
} EXPORT_SYMBOL(security_inode_getsecctx); |
20510f2f4
|
1793 |
#ifdef CONFIG_SECURITY_NETWORK |
3610cda53
|
1794 |
int security_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk) |
20510f2f4
|
1795 |
{ |
f25fce3e8
|
1796 |
return call_int_hook(unix_stream_connect, 0, sock, other, newsk); |
20510f2f4
|
1797 1798 1799 1800 1801 |
} EXPORT_SYMBOL(security_unix_stream_connect); int security_unix_may_send(struct socket *sock, struct socket *other) { |
f25fce3e8
|
1802 |
return call_int_hook(unix_may_send, 0, sock, other); |
20510f2f4
|
1803 1804 1805 1806 1807 |
} EXPORT_SYMBOL(security_unix_may_send); int security_socket_create(int family, int type, int protocol, int kern) { |
f25fce3e8
|
1808 |
return call_int_hook(socket_create, 0, family, type, protocol, kern); |
20510f2f4
|
1809 1810 1811 1812 1813 |
} int security_socket_post_create(struct socket *sock, int family, int type, int protocol, int kern) { |
f25fce3e8
|
1814 |
return call_int_hook(socket_post_create, 0, sock, family, type, |
20510f2f4
|
1815 1816 |
protocol, kern); } |
aae7cfcbb
|
1817 1818 1819 1820 1821 |
int security_socket_socketpair(struct socket *socka, struct socket *sockb) { return call_int_hook(socket_socketpair, 0, socka, sockb); } EXPORT_SYMBOL(security_socket_socketpair); |
20510f2f4
|
1822 1823 |
int security_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) { |
f25fce3e8
|
1824 |
return call_int_hook(socket_bind, 0, sock, address, addrlen); |
20510f2f4
|
1825 1826 1827 1828 |
} int security_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen) { |
f25fce3e8
|
1829 |
return call_int_hook(socket_connect, 0, sock, address, addrlen); |
20510f2f4
|
1830 1831 1832 1833 |
} int security_socket_listen(struct socket *sock, int backlog) { |
f25fce3e8
|
1834 |
return call_int_hook(socket_listen, 0, sock, backlog); |
20510f2f4
|
1835 1836 1837 1838 |
} int security_socket_accept(struct socket *sock, struct socket *newsock) { |
f25fce3e8
|
1839 |
return call_int_hook(socket_accept, 0, sock, newsock); |
20510f2f4
|
1840 |
} |
20510f2f4
|
1841 1842 |
int security_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size) { |
f25fce3e8
|
1843 |
return call_int_hook(socket_sendmsg, 0, sock, msg, size); |
20510f2f4
|
1844 1845 1846 1847 1848 |
} int security_socket_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags) { |
f25fce3e8
|
1849 |
return call_int_hook(socket_recvmsg, 0, sock, msg, size, flags); |
20510f2f4
|
1850 1851 1852 1853 |
} int security_socket_getsockname(struct socket *sock) { |
f25fce3e8
|
1854 |
return call_int_hook(socket_getsockname, 0, sock); |
20510f2f4
|
1855 1856 1857 1858 |
} int security_socket_getpeername(struct socket *sock) { |
f25fce3e8
|
1859 |
return call_int_hook(socket_getpeername, 0, sock); |
20510f2f4
|
1860 1861 1862 1863 |
} int security_socket_getsockopt(struct socket *sock, int level, int optname) { |
f25fce3e8
|
1864 |
return call_int_hook(socket_getsockopt, 0, sock, level, optname); |
20510f2f4
|
1865 1866 1867 1868 |
} int security_socket_setsockopt(struct socket *sock, int level, int optname) { |
f25fce3e8
|
1869 |
return call_int_hook(socket_setsockopt, 0, sock, level, optname); |
20510f2f4
|
1870 1871 1872 1873 |
} int security_socket_shutdown(struct socket *sock, int how) { |
f25fce3e8
|
1874 |
return call_int_hook(socket_shutdown, 0, sock, how); |
20510f2f4
|
1875 1876 1877 1878 |
} int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) { |
f25fce3e8
|
1879 |
return call_int_hook(socket_sock_rcv_skb, 0, sk, skb); |
20510f2f4
|
1880 1881 1882 1883 1884 1885 |
} EXPORT_SYMBOL(security_sock_rcv_skb); int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, int __user *optlen, unsigned len) { |
b1d9e6b06
|
1886 1887 |
return call_int_hook(socket_getpeersec_stream, -ENOPROTOOPT, sock, optval, optlen, len); |
20510f2f4
|
1888 1889 1890 1891 |
} int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) { |
e308fd3bb
|
1892 1893 |
return call_int_hook(socket_getpeersec_dgram, -ENOPROTOOPT, sock, skb, secid); |
20510f2f4
|
1894 1895 1896 1897 1898 |
} EXPORT_SYMBOL(security_socket_getpeersec_dgram); int security_sk_alloc(struct sock *sk, int family, gfp_t priority) { |
f25fce3e8
|
1899 |
return call_int_hook(sk_alloc_security, 0, sk, family, priority); |
20510f2f4
|
1900 1901 1902 1903 |
} void security_sk_free(struct sock *sk) { |
f25fce3e8
|
1904 |
call_void_hook(sk_free_security, sk); |
20510f2f4
|
1905 1906 1907 1908 |
} void security_sk_clone(const struct sock *sk, struct sock *newsk) { |
f25fce3e8
|
1909 |
call_void_hook(sk_clone_security, sk, newsk); |
20510f2f4
|
1910 |
} |
6230c9b4f
|
1911 |
EXPORT_SYMBOL(security_sk_clone); |
20510f2f4
|
1912 1913 1914 |
void security_sk_classify_flow(struct sock *sk, struct flowi *fl) { |
f25fce3e8
|
1915 |
call_void_hook(sk_getsecid, sk, &fl->flowi_secid); |
20510f2f4
|
1916 1917 1918 1919 1920 |
} EXPORT_SYMBOL(security_sk_classify_flow); void security_req_classify_flow(const struct request_sock *req, struct flowi *fl) { |
f25fce3e8
|
1921 |
call_void_hook(req_classify_flow, req, fl); |
20510f2f4
|
1922 1923 1924 1925 1926 |
} EXPORT_SYMBOL(security_req_classify_flow); void security_sock_graft(struct sock *sk, struct socket *parent) { |
f25fce3e8
|
1927 |
call_void_hook(sock_graft, sk, parent); |
20510f2f4
|
1928 1929 1930 1931 1932 1933 |
} EXPORT_SYMBOL(security_sock_graft); int security_inet_conn_request(struct sock *sk, struct sk_buff *skb, struct request_sock *req) { |
f25fce3e8
|
1934 |
return call_int_hook(inet_conn_request, 0, sk, skb, req); |
20510f2f4
|
1935 1936 1937 1938 1939 1940 |
} EXPORT_SYMBOL(security_inet_conn_request); void security_inet_csk_clone(struct sock *newsk, const struct request_sock *req) { |
f25fce3e8
|
1941 |
call_void_hook(inet_csk_clone, newsk, req); |
20510f2f4
|
1942 1943 1944 1945 1946 |
} void security_inet_conn_established(struct sock *sk, struct sk_buff *skb) { |
f25fce3e8
|
1947 |
call_void_hook(inet_conn_established, sk, skb); |
20510f2f4
|
1948 |
} |
72e89f500
|
1949 |
EXPORT_SYMBOL(security_inet_conn_established); |
20510f2f4
|
1950 |
|
2606fd1fa
|
1951 1952 |
int security_secmark_relabel_packet(u32 secid) { |
f25fce3e8
|
1953 |
return call_int_hook(secmark_relabel_packet, 0, secid); |
2606fd1fa
|
1954 1955 1956 1957 1958 |
} EXPORT_SYMBOL(security_secmark_relabel_packet); void security_secmark_refcount_inc(void) { |
f25fce3e8
|
1959 |
call_void_hook(secmark_refcount_inc); |
2606fd1fa
|
1960 1961 1962 1963 1964 |
} EXPORT_SYMBOL(security_secmark_refcount_inc); void security_secmark_refcount_dec(void) { |
f25fce3e8
|
1965 |
call_void_hook(secmark_refcount_dec); |
2606fd1fa
|
1966 1967 |
} EXPORT_SYMBOL(security_secmark_refcount_dec); |
5dbbaf2de
|
1968 1969 |
int security_tun_dev_alloc_security(void **security) { |
f25fce3e8
|
1970 |
return call_int_hook(tun_dev_alloc_security, 0, security); |
5dbbaf2de
|
1971 1972 1973 1974 1975 |
} EXPORT_SYMBOL(security_tun_dev_alloc_security); void security_tun_dev_free_security(void *security) { |
f25fce3e8
|
1976 |
call_void_hook(tun_dev_free_security, security); |
5dbbaf2de
|
1977 1978 |
} EXPORT_SYMBOL(security_tun_dev_free_security); |
2b980dbd7
|
1979 1980 |
int security_tun_dev_create(void) { |
f25fce3e8
|
1981 |
return call_int_hook(tun_dev_create, 0); |
2b980dbd7
|
1982 1983 |
} EXPORT_SYMBOL(security_tun_dev_create); |
5dbbaf2de
|
1984 |
int security_tun_dev_attach_queue(void *security) |
2b980dbd7
|
1985 |
{ |
f25fce3e8
|
1986 |
return call_int_hook(tun_dev_attach_queue, 0, security); |
2b980dbd7
|
1987 |
} |
5dbbaf2de
|
1988 |
EXPORT_SYMBOL(security_tun_dev_attach_queue); |
2b980dbd7
|
1989 |
|
5dbbaf2de
|
1990 |
int security_tun_dev_attach(struct sock *sk, void *security) |
2b980dbd7
|
1991 |
{ |
f25fce3e8
|
1992 |
return call_int_hook(tun_dev_attach, 0, sk, security); |
2b980dbd7
|
1993 1994 |
} EXPORT_SYMBOL(security_tun_dev_attach); |
5dbbaf2de
|
1995 1996 |
int security_tun_dev_open(void *security) { |
f25fce3e8
|
1997 |
return call_int_hook(tun_dev_open, 0, security); |
5dbbaf2de
|
1998 1999 |
} EXPORT_SYMBOL(security_tun_dev_open); |
72e89f500
|
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 |
int security_sctp_assoc_request(struct sctp_endpoint *ep, struct sk_buff *skb) { return call_int_hook(sctp_assoc_request, 0, ep, skb); } EXPORT_SYMBOL(security_sctp_assoc_request); int security_sctp_bind_connect(struct sock *sk, int optname, struct sockaddr *address, int addrlen) { return call_int_hook(sctp_bind_connect, 0, sk, optname, address, addrlen); } EXPORT_SYMBOL(security_sctp_bind_connect); void security_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk, struct sock *newsk) { call_void_hook(sctp_sk_clone, ep, sk, newsk); } EXPORT_SYMBOL(security_sctp_sk_clone); |
20510f2f4
|
2020 |
#endif /* CONFIG_SECURITY_NETWORK */ |
d291f1a65
|
2021 2022 2023 2024 2025 2026 2027 |
#ifdef CONFIG_SECURITY_INFINIBAND int security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey) { return call_int_hook(ib_pkey_access, 0, sec, subnet_prefix, pkey); } EXPORT_SYMBOL(security_ib_pkey_access); |
47a2b338f
|
2028 2029 2030 2031 2032 |
int security_ib_endport_manage_subnet(void *sec, const char *dev_name, u8 port_num) { return call_int_hook(ib_endport_manage_subnet, 0, sec, dev_name, port_num); } EXPORT_SYMBOL(security_ib_endport_manage_subnet); |
d291f1a65
|
2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 |
int security_ib_alloc_security(void **sec) { return call_int_hook(ib_alloc_security, 0, sec); } EXPORT_SYMBOL(security_ib_alloc_security); void security_ib_free_security(void *sec) { call_void_hook(ib_free_security, sec); } EXPORT_SYMBOL(security_ib_free_security); #endif /* CONFIG_SECURITY_INFINIBAND */ |
20510f2f4
|
2045 |
#ifdef CONFIG_SECURITY_NETWORK_XFRM |
52a4c6404
|
2046 2047 2048 |
int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx, gfp_t gfp) |
20510f2f4
|
2049 |
{ |
f25fce3e8
|
2050 |
return call_int_hook(xfrm_policy_alloc_security, 0, ctxp, sec_ctx, gfp); |
20510f2f4
|
2051 2052 |
} EXPORT_SYMBOL(security_xfrm_policy_alloc); |
03e1ad7b5
|
2053 2054 |
int security_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctxp) |
20510f2f4
|
2055 |
{ |
f25fce3e8
|
2056 |
return call_int_hook(xfrm_policy_clone_security, 0, old_ctx, new_ctxp); |
20510f2f4
|
2057 |
} |
03e1ad7b5
|
2058 |
void security_xfrm_policy_free(struct xfrm_sec_ctx *ctx) |
20510f2f4
|
2059 |
{ |
f25fce3e8
|
2060 |
call_void_hook(xfrm_policy_free_security, ctx); |
20510f2f4
|
2061 2062 |
} EXPORT_SYMBOL(security_xfrm_policy_free); |
03e1ad7b5
|
2063 |
int security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) |
20510f2f4
|
2064 |
{ |
f25fce3e8
|
2065 |
return call_int_hook(xfrm_policy_delete_security, 0, ctx); |
20510f2f4
|
2066 |
} |
2e5aa8660
|
2067 2068 |
int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) |
20510f2f4
|
2069 |
{ |
f25fce3e8
|
2070 |
return call_int_hook(xfrm_state_alloc, 0, x, sec_ctx); |
20510f2f4
|
2071 2072 2073 2074 2075 2076 |
} EXPORT_SYMBOL(security_xfrm_state_alloc); int security_xfrm_state_alloc_acquire(struct xfrm_state *x, struct xfrm_sec_ctx *polsec, u32 secid) { |
f25fce3e8
|
2077 |
return call_int_hook(xfrm_state_alloc_acquire, 0, x, polsec, secid); |
20510f2f4
|
2078 2079 2080 2081 |
} int security_xfrm_state_delete(struct xfrm_state *x) { |
f25fce3e8
|
2082 |
return call_int_hook(xfrm_state_delete_security, 0, x); |
20510f2f4
|
2083 2084 2085 2086 2087 |
} EXPORT_SYMBOL(security_xfrm_state_delete); void security_xfrm_state_free(struct xfrm_state *x) { |
f25fce3e8
|
2088 |
call_void_hook(xfrm_state_free_security, x); |
20510f2f4
|
2089 |
} |
03e1ad7b5
|
2090 |
int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir) |
20510f2f4
|
2091 |
{ |
f25fce3e8
|
2092 |
return call_int_hook(xfrm_policy_lookup, 0, ctx, fl_secid, dir); |
20510f2f4
|
2093 2094 2095 |
} int security_xfrm_state_pol_flow_match(struct xfrm_state *x, |
e33f77042
|
2096 2097 |
struct xfrm_policy *xp, const struct flowi *fl) |
20510f2f4
|
2098 |
{ |
b1d9e6b06
|
2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 |
struct security_hook_list *hp; int rc = 1; /* * Since this function is expected to return 0 or 1, the judgment * becomes difficult if multiple LSMs supply this call. Fortunately, * we can use the first LSM's judgment because currently only SELinux * supplies this call. * * For speed optimization, we explicitly break the loop rather than * using the macro */ |
df0ce1733
|
2111 |
hlist_for_each_entry(hp, &security_hook_heads.xfrm_state_pol_flow_match, |
b1d9e6b06
|
2112 2113 2114 2115 2116 |
list) { rc = hp->hook.xfrm_state_pol_flow_match(x, xp, fl); break; } return rc; |
20510f2f4
|
2117 2118 2119 2120 |
} int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) { |
f25fce3e8
|
2121 |
return call_int_hook(xfrm_decode_session, 0, skb, secid, 1); |
20510f2f4
|
2122 2123 2124 2125 |
} void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl) { |
f25fce3e8
|
2126 2127 |
int rc = call_int_hook(xfrm_decode_session, 0, skb, &fl->flowi_secid, 0); |
20510f2f4
|
2128 2129 2130 2131 2132 2133 2134 2135 |
BUG_ON(rc); } EXPORT_SYMBOL(security_skb_classify_flow); #endif /* CONFIG_SECURITY_NETWORK_XFRM */ #ifdef CONFIG_KEYS |
d84f4f992
|
2136 2137 |
int security_key_alloc(struct key *key, const struct cred *cred, unsigned long flags) |
20510f2f4
|
2138 |
{ |
f25fce3e8
|
2139 |
return call_int_hook(key_alloc, 0, key, cred, flags); |
20510f2f4
|
2140 2141 2142 2143 |
} void security_key_free(struct key *key) { |
f25fce3e8
|
2144 |
call_void_hook(key_free, key); |
20510f2f4
|
2145 2146 2147 |
} int security_key_permission(key_ref_t key_ref, |
f5895943d
|
2148 |
const struct cred *cred, unsigned perm) |
20510f2f4
|
2149 |
{ |
f25fce3e8
|
2150 |
return call_int_hook(key_permission, 0, key_ref, cred, perm); |
20510f2f4
|
2151 |
} |
70a5bb72b
|
2152 2153 |
int security_key_getsecurity(struct key *key, char **_buffer) { |
b1d9e6b06
|
2154 |
*_buffer = NULL; |
f25fce3e8
|
2155 |
return call_int_hook(key_getsecurity, 0, key, _buffer); |
70a5bb72b
|
2156 |
} |
20510f2f4
|
2157 |
#endif /* CONFIG_KEYS */ |
03d37d25e
|
2158 2159 2160 2161 2162 |
#ifdef CONFIG_AUDIT int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) { |
f25fce3e8
|
2163 |
return call_int_hook(audit_rule_init, 0, field, op, rulestr, lsmrule); |
03d37d25e
|
2164 2165 2166 2167 |
} int security_audit_rule_known(struct audit_krule *krule) { |
f25fce3e8
|
2168 |
return call_int_hook(audit_rule_known, 0, krule); |
03d37d25e
|
2169 2170 2171 2172 |
} void security_audit_rule_free(void *lsmrule) { |
f25fce3e8
|
2173 |
call_void_hook(audit_rule_free, lsmrule); |
03d37d25e
|
2174 |
} |
90462a5bd
|
2175 |
int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule) |
03d37d25e
|
2176 |
{ |
90462a5bd
|
2177 |
return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule); |
03d37d25e
|
2178 |
} |
b1d9e6b06
|
2179 |
#endif /* CONFIG_AUDIT */ |
afdb09c72
|
2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 |
#ifdef CONFIG_BPF_SYSCALL int security_bpf(int cmd, union bpf_attr *attr, unsigned int size) { return call_int_hook(bpf, 0, cmd, attr, size); } int security_bpf_map(struct bpf_map *map, fmode_t fmode) { return call_int_hook(bpf_map, 0, map, fmode); } int security_bpf_prog(struct bpf_prog *prog) { return call_int_hook(bpf_prog, 0, prog); } int security_bpf_map_alloc(struct bpf_map *map) { return call_int_hook(bpf_map_alloc_security, 0, map); } int security_bpf_prog_alloc(struct bpf_prog_aux *aux) { return call_int_hook(bpf_prog_alloc_security, 0, aux); } void security_bpf_map_free(struct bpf_map *map) { call_void_hook(bpf_map_free_security, map); } void security_bpf_prog_free(struct bpf_prog_aux *aux) { call_void_hook(bpf_prog_free_security, aux); } #endif /* CONFIG_BPF_SYSCALL */ |