162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Security plug functions 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2001 WireX Communications, Inc <chris@wirex.com> 662306a36Sopenharmony_ci * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com> 762306a36Sopenharmony_ci * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com> 862306a36Sopenharmony_ci * Copyright (C) 2016 Mellanox Technologies 962306a36Sopenharmony_ci * Copyright (C) 2023 Microsoft Corporation <paul@paul-moore.com> 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#define pr_fmt(fmt) "LSM: " fmt 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <linux/bpf.h> 1562306a36Sopenharmony_ci#include <linux/capability.h> 1662306a36Sopenharmony_ci#include <linux/dcache.h> 1762306a36Sopenharmony_ci#include <linux/export.h> 1862306a36Sopenharmony_ci#include <linux/init.h> 1962306a36Sopenharmony_ci#include <linux/kernel.h> 2062306a36Sopenharmony_ci#include <linux/kernel_read_file.h> 2162306a36Sopenharmony_ci#include <linux/lsm_hooks.h> 2262306a36Sopenharmony_ci#include <linux/integrity.h> 2362306a36Sopenharmony_ci#include <linux/ima.h> 2462306a36Sopenharmony_ci#include <linux/evm.h> 2562306a36Sopenharmony_ci#include <linux/fsnotify.h> 2662306a36Sopenharmony_ci#include <linux/mman.h> 2762306a36Sopenharmony_ci#include <linux/mount.h> 2862306a36Sopenharmony_ci#include <linux/personality.h> 2962306a36Sopenharmony_ci#include <linux/backing-dev.h> 3062306a36Sopenharmony_ci#include <linux/string.h> 3162306a36Sopenharmony_ci#include <linux/msg.h> 3262306a36Sopenharmony_ci#include <net/flow.h> 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci/* How many LSMs were built into the kernel? */ 3562306a36Sopenharmony_ci#define LSM_COUNT (__end_lsm_info - __start_lsm_info) 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/* 3862306a36Sopenharmony_ci * These are descriptions of the reasons that can be passed to the 3962306a36Sopenharmony_ci * security_locked_down() LSM hook. Placing this array here allows 4062306a36Sopenharmony_ci * all security modules to use the same descriptions for auditing 4162306a36Sopenharmony_ci * purposes. 4262306a36Sopenharmony_ci */ 4362306a36Sopenharmony_ciconst char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX + 1] = { 4462306a36Sopenharmony_ci [LOCKDOWN_NONE] = "none", 4562306a36Sopenharmony_ci [LOCKDOWN_MODULE_SIGNATURE] = "unsigned module loading", 4662306a36Sopenharmony_ci [LOCKDOWN_DEV_MEM] = "/dev/mem,kmem,port", 4762306a36Sopenharmony_ci [LOCKDOWN_EFI_TEST] = "/dev/efi_test access", 4862306a36Sopenharmony_ci [LOCKDOWN_KEXEC] = "kexec of unsigned images", 4962306a36Sopenharmony_ci [LOCKDOWN_HIBERNATION] = "hibernation", 5062306a36Sopenharmony_ci [LOCKDOWN_PCI_ACCESS] = "direct PCI access", 5162306a36Sopenharmony_ci [LOCKDOWN_IOPORT] = "raw io port access", 5262306a36Sopenharmony_ci [LOCKDOWN_MSR] = "raw MSR access", 5362306a36Sopenharmony_ci [LOCKDOWN_ACPI_TABLES] = "modifying ACPI tables", 5462306a36Sopenharmony_ci [LOCKDOWN_DEVICE_TREE] = "modifying device tree contents", 5562306a36Sopenharmony_ci [LOCKDOWN_PCMCIA_CIS] = "direct PCMCIA CIS storage", 5662306a36Sopenharmony_ci [LOCKDOWN_TIOCSSERIAL] = "reconfiguration of serial port IO", 5762306a36Sopenharmony_ci [LOCKDOWN_MODULE_PARAMETERS] = "unsafe module parameters", 5862306a36Sopenharmony_ci [LOCKDOWN_MMIOTRACE] = "unsafe mmio", 5962306a36Sopenharmony_ci [LOCKDOWN_DEBUGFS] = "debugfs access", 6062306a36Sopenharmony_ci [LOCKDOWN_XMON_WR] = "xmon write access", 6162306a36Sopenharmony_ci [LOCKDOWN_BPF_WRITE_USER] = "use of bpf to write user RAM", 6262306a36Sopenharmony_ci [LOCKDOWN_DBG_WRITE_KERNEL] = "use of kgdb/kdb to write kernel RAM", 6362306a36Sopenharmony_ci [LOCKDOWN_RTAS_ERROR_INJECTION] = "RTAS error injection", 6462306a36Sopenharmony_ci [LOCKDOWN_INTEGRITY_MAX] = "integrity", 6562306a36Sopenharmony_ci [LOCKDOWN_KCORE] = "/proc/kcore access", 6662306a36Sopenharmony_ci [LOCKDOWN_KPROBES] = "use of kprobes", 6762306a36Sopenharmony_ci [LOCKDOWN_BPF_READ_KERNEL] = "use of bpf to read kernel RAM", 6862306a36Sopenharmony_ci [LOCKDOWN_DBG_READ_KERNEL] = "use of kgdb/kdb to read kernel RAM", 6962306a36Sopenharmony_ci [LOCKDOWN_PERF] = "unsafe use of perf", 7062306a36Sopenharmony_ci [LOCKDOWN_TRACEFS] = "use of tracefs", 7162306a36Sopenharmony_ci [LOCKDOWN_XMON_RW] = "xmon read and write access", 7262306a36Sopenharmony_ci [LOCKDOWN_XFRM_SECRET] = "xfrm SA secret", 7362306a36Sopenharmony_ci [LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality", 7462306a36Sopenharmony_ci}; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistruct security_hook_heads security_hook_heads __ro_after_init; 7762306a36Sopenharmony_cistatic BLOCKING_NOTIFIER_HEAD(blocking_lsm_notifier_chain); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic struct kmem_cache *lsm_file_cache; 8062306a36Sopenharmony_cistatic struct kmem_cache *lsm_inode_cache; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cichar *lsm_names; 8362306a36Sopenharmony_cistatic struct lsm_blob_sizes blob_sizes __ro_after_init; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci/* Boot-time LSM user choice */ 8662306a36Sopenharmony_cistatic __initdata const char *chosen_lsm_order; 8762306a36Sopenharmony_cistatic __initdata const char *chosen_major_lsm; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cistatic __initconst const char *const builtin_lsm_order = CONFIG_LSM; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci/* Ordered list of LSMs to initialize. */ 9262306a36Sopenharmony_cistatic __initdata struct lsm_info **ordered_lsms; 9362306a36Sopenharmony_cistatic __initdata struct lsm_info *exclusive; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_cistatic __initdata bool debug; 9662306a36Sopenharmony_ci#define init_debug(...) \ 9762306a36Sopenharmony_ci do { \ 9862306a36Sopenharmony_ci if (debug) \ 9962306a36Sopenharmony_ci pr_info(__VA_ARGS__); \ 10062306a36Sopenharmony_ci } while (0) 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_cistatic bool __init is_enabled(struct lsm_info *lsm) 10362306a36Sopenharmony_ci{ 10462306a36Sopenharmony_ci if (!lsm->enabled) 10562306a36Sopenharmony_ci return false; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci return *lsm->enabled; 10862306a36Sopenharmony_ci} 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci/* Mark an LSM's enabled flag. */ 11162306a36Sopenharmony_cistatic int lsm_enabled_true __initdata = 1; 11262306a36Sopenharmony_cistatic int lsm_enabled_false __initdata = 0; 11362306a36Sopenharmony_cistatic void __init set_enabled(struct lsm_info *lsm, bool enabled) 11462306a36Sopenharmony_ci{ 11562306a36Sopenharmony_ci /* 11662306a36Sopenharmony_ci * When an LSM hasn't configured an enable variable, we can use 11762306a36Sopenharmony_ci * a hard-coded location for storing the default enabled state. 11862306a36Sopenharmony_ci */ 11962306a36Sopenharmony_ci if (!lsm->enabled) { 12062306a36Sopenharmony_ci if (enabled) 12162306a36Sopenharmony_ci lsm->enabled = &lsm_enabled_true; 12262306a36Sopenharmony_ci else 12362306a36Sopenharmony_ci lsm->enabled = &lsm_enabled_false; 12462306a36Sopenharmony_ci } else if (lsm->enabled == &lsm_enabled_true) { 12562306a36Sopenharmony_ci if (!enabled) 12662306a36Sopenharmony_ci lsm->enabled = &lsm_enabled_false; 12762306a36Sopenharmony_ci } else if (lsm->enabled == &lsm_enabled_false) { 12862306a36Sopenharmony_ci if (enabled) 12962306a36Sopenharmony_ci lsm->enabled = &lsm_enabled_true; 13062306a36Sopenharmony_ci } else { 13162306a36Sopenharmony_ci *lsm->enabled = enabled; 13262306a36Sopenharmony_ci } 13362306a36Sopenharmony_ci} 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci/* Is an LSM already listed in the ordered LSMs list? */ 13662306a36Sopenharmony_cistatic bool __init exists_ordered_lsm(struct lsm_info *lsm) 13762306a36Sopenharmony_ci{ 13862306a36Sopenharmony_ci struct lsm_info **check; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci for (check = ordered_lsms; *check; check++) 14162306a36Sopenharmony_ci if (*check == lsm) 14262306a36Sopenharmony_ci return true; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci return false; 14562306a36Sopenharmony_ci} 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci/* Append an LSM to the list of ordered LSMs to initialize. */ 14862306a36Sopenharmony_cistatic int last_lsm __initdata; 14962306a36Sopenharmony_cistatic void __init append_ordered_lsm(struct lsm_info *lsm, const char *from) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci /* Ignore duplicate selections. */ 15262306a36Sopenharmony_ci if (exists_ordered_lsm(lsm)) 15362306a36Sopenharmony_ci return; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci if (WARN(last_lsm == LSM_COUNT, "%s: out of LSM slots!?\n", from)) 15662306a36Sopenharmony_ci return; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci /* Enable this LSM, if it is not already set. */ 15962306a36Sopenharmony_ci if (!lsm->enabled) 16062306a36Sopenharmony_ci lsm->enabled = &lsm_enabled_true; 16162306a36Sopenharmony_ci ordered_lsms[last_lsm++] = lsm; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci init_debug("%s ordered: %s (%s)\n", from, lsm->name, 16462306a36Sopenharmony_ci is_enabled(lsm) ? "enabled" : "disabled"); 16562306a36Sopenharmony_ci} 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci/* Is an LSM allowed to be initialized? */ 16862306a36Sopenharmony_cistatic bool __init lsm_allowed(struct lsm_info *lsm) 16962306a36Sopenharmony_ci{ 17062306a36Sopenharmony_ci /* Skip if the LSM is disabled. */ 17162306a36Sopenharmony_ci if (!is_enabled(lsm)) 17262306a36Sopenharmony_ci return false; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci /* Not allowed if another exclusive LSM already initialized. */ 17562306a36Sopenharmony_ci if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && exclusive) { 17662306a36Sopenharmony_ci init_debug("exclusive disabled: %s\n", lsm->name); 17762306a36Sopenharmony_ci return false; 17862306a36Sopenharmony_ci } 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci return true; 18162306a36Sopenharmony_ci} 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_cistatic void __init lsm_set_blob_size(int *need, int *lbs) 18462306a36Sopenharmony_ci{ 18562306a36Sopenharmony_ci int offset; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci if (*need <= 0) 18862306a36Sopenharmony_ci return; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci offset = ALIGN(*lbs, sizeof(void *)); 19162306a36Sopenharmony_ci *lbs = offset + *need; 19262306a36Sopenharmony_ci *need = offset; 19362306a36Sopenharmony_ci} 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_cistatic void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed) 19662306a36Sopenharmony_ci{ 19762306a36Sopenharmony_ci if (!needed) 19862306a36Sopenharmony_ci return; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci lsm_set_blob_size(&needed->lbs_cred, &blob_sizes.lbs_cred); 20162306a36Sopenharmony_ci lsm_set_blob_size(&needed->lbs_file, &blob_sizes.lbs_file); 20262306a36Sopenharmony_ci /* 20362306a36Sopenharmony_ci * The inode blob gets an rcu_head in addition to 20462306a36Sopenharmony_ci * what the modules might need. 20562306a36Sopenharmony_ci */ 20662306a36Sopenharmony_ci if (needed->lbs_inode && blob_sizes.lbs_inode == 0) 20762306a36Sopenharmony_ci blob_sizes.lbs_inode = sizeof(struct rcu_head); 20862306a36Sopenharmony_ci lsm_set_blob_size(&needed->lbs_inode, &blob_sizes.lbs_inode); 20962306a36Sopenharmony_ci lsm_set_blob_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc); 21062306a36Sopenharmony_ci lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg); 21162306a36Sopenharmony_ci lsm_set_blob_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock); 21262306a36Sopenharmony_ci lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task); 21362306a36Sopenharmony_ci lsm_set_blob_size(&needed->lbs_xattr_count, 21462306a36Sopenharmony_ci &blob_sizes.lbs_xattr_count); 21562306a36Sopenharmony_ci} 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci/* Prepare LSM for initialization. */ 21862306a36Sopenharmony_cistatic void __init prepare_lsm(struct lsm_info *lsm) 21962306a36Sopenharmony_ci{ 22062306a36Sopenharmony_ci int enabled = lsm_allowed(lsm); 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci /* Record enablement (to handle any following exclusive LSMs). */ 22362306a36Sopenharmony_ci set_enabled(lsm, enabled); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci /* If enabled, do pre-initialization work. */ 22662306a36Sopenharmony_ci if (enabled) { 22762306a36Sopenharmony_ci if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !exclusive) { 22862306a36Sopenharmony_ci exclusive = lsm; 22962306a36Sopenharmony_ci init_debug("exclusive chosen: %s\n", lsm->name); 23062306a36Sopenharmony_ci } 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci lsm_set_blob_sizes(lsm->blobs); 23362306a36Sopenharmony_ci } 23462306a36Sopenharmony_ci} 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci/* Initialize a given LSM, if it is enabled. */ 23762306a36Sopenharmony_cistatic void __init initialize_lsm(struct lsm_info *lsm) 23862306a36Sopenharmony_ci{ 23962306a36Sopenharmony_ci if (is_enabled(lsm)) { 24062306a36Sopenharmony_ci int ret; 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci init_debug("initializing %s\n", lsm->name); 24362306a36Sopenharmony_ci ret = lsm->init(); 24462306a36Sopenharmony_ci WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret); 24562306a36Sopenharmony_ci } 24662306a36Sopenharmony_ci} 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci/* Populate ordered LSMs list from comma-separated LSM name list. */ 24962306a36Sopenharmony_cistatic void __init ordered_lsm_parse(const char *order, const char *origin) 25062306a36Sopenharmony_ci{ 25162306a36Sopenharmony_ci struct lsm_info *lsm; 25262306a36Sopenharmony_ci char *sep, *name, *next; 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci /* LSM_ORDER_FIRST is always first. */ 25562306a36Sopenharmony_ci for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { 25662306a36Sopenharmony_ci if (lsm->order == LSM_ORDER_FIRST) 25762306a36Sopenharmony_ci append_ordered_lsm(lsm, " first"); 25862306a36Sopenharmony_ci } 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci /* Process "security=", if given. */ 26162306a36Sopenharmony_ci if (chosen_major_lsm) { 26262306a36Sopenharmony_ci struct lsm_info *major; 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci /* 26562306a36Sopenharmony_ci * To match the original "security=" behavior, this 26662306a36Sopenharmony_ci * explicitly does NOT fallback to another Legacy Major 26762306a36Sopenharmony_ci * if the selected one was separately disabled: disable 26862306a36Sopenharmony_ci * all non-matching Legacy Major LSMs. 26962306a36Sopenharmony_ci */ 27062306a36Sopenharmony_ci for (major = __start_lsm_info; major < __end_lsm_info; 27162306a36Sopenharmony_ci major++) { 27262306a36Sopenharmony_ci if ((major->flags & LSM_FLAG_LEGACY_MAJOR) && 27362306a36Sopenharmony_ci strcmp(major->name, chosen_major_lsm) != 0) { 27462306a36Sopenharmony_ci set_enabled(major, false); 27562306a36Sopenharmony_ci init_debug("security=%s disabled: %s (only one legacy major LSM)\n", 27662306a36Sopenharmony_ci chosen_major_lsm, major->name); 27762306a36Sopenharmony_ci } 27862306a36Sopenharmony_ci } 27962306a36Sopenharmony_ci } 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci sep = kstrdup(order, GFP_KERNEL); 28262306a36Sopenharmony_ci next = sep; 28362306a36Sopenharmony_ci /* Walk the list, looking for matching LSMs. */ 28462306a36Sopenharmony_ci while ((name = strsep(&next, ",")) != NULL) { 28562306a36Sopenharmony_ci bool found = false; 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { 28862306a36Sopenharmony_ci if (strcmp(lsm->name, name) == 0) { 28962306a36Sopenharmony_ci if (lsm->order == LSM_ORDER_MUTABLE) 29062306a36Sopenharmony_ci append_ordered_lsm(lsm, origin); 29162306a36Sopenharmony_ci found = true; 29262306a36Sopenharmony_ci } 29362306a36Sopenharmony_ci } 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci if (!found) 29662306a36Sopenharmony_ci init_debug("%s ignored: %s (not built into kernel)\n", 29762306a36Sopenharmony_ci origin, name); 29862306a36Sopenharmony_ci } 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci /* Process "security=", if given. */ 30162306a36Sopenharmony_ci if (chosen_major_lsm) { 30262306a36Sopenharmony_ci for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { 30362306a36Sopenharmony_ci if (exists_ordered_lsm(lsm)) 30462306a36Sopenharmony_ci continue; 30562306a36Sopenharmony_ci if (strcmp(lsm->name, chosen_major_lsm) == 0) 30662306a36Sopenharmony_ci append_ordered_lsm(lsm, "security="); 30762306a36Sopenharmony_ci } 30862306a36Sopenharmony_ci } 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci /* LSM_ORDER_LAST is always last. */ 31162306a36Sopenharmony_ci for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { 31262306a36Sopenharmony_ci if (lsm->order == LSM_ORDER_LAST) 31362306a36Sopenharmony_ci append_ordered_lsm(lsm, " last"); 31462306a36Sopenharmony_ci } 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci /* Disable all LSMs not in the ordered list. */ 31762306a36Sopenharmony_ci for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) { 31862306a36Sopenharmony_ci if (exists_ordered_lsm(lsm)) 31962306a36Sopenharmony_ci continue; 32062306a36Sopenharmony_ci set_enabled(lsm, false); 32162306a36Sopenharmony_ci init_debug("%s skipped: %s (not in requested order)\n", 32262306a36Sopenharmony_ci origin, lsm->name); 32362306a36Sopenharmony_ci } 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci kfree(sep); 32662306a36Sopenharmony_ci} 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_cistatic void __init lsm_early_cred(struct cred *cred); 32962306a36Sopenharmony_cistatic void __init lsm_early_task(struct task_struct *task); 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_cistatic int lsm_append(const char *new, char **result); 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_cistatic void __init report_lsm_order(void) 33462306a36Sopenharmony_ci{ 33562306a36Sopenharmony_ci struct lsm_info **lsm, *early; 33662306a36Sopenharmony_ci int first = 0; 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci pr_info("initializing lsm="); 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci /* Report each enabled LSM name, comma separated. */ 34162306a36Sopenharmony_ci for (early = __start_early_lsm_info; 34262306a36Sopenharmony_ci early < __end_early_lsm_info; early++) 34362306a36Sopenharmony_ci if (is_enabled(early)) 34462306a36Sopenharmony_ci pr_cont("%s%s", first++ == 0 ? "" : ",", early->name); 34562306a36Sopenharmony_ci for (lsm = ordered_lsms; *lsm; lsm++) 34662306a36Sopenharmony_ci if (is_enabled(*lsm)) 34762306a36Sopenharmony_ci pr_cont("%s%s", first++ == 0 ? "" : ",", (*lsm)->name); 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci pr_cont("\n"); 35062306a36Sopenharmony_ci} 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_cistatic void __init ordered_lsm_init(void) 35362306a36Sopenharmony_ci{ 35462306a36Sopenharmony_ci struct lsm_info **lsm; 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ci ordered_lsms = kcalloc(LSM_COUNT + 1, sizeof(*ordered_lsms), 35762306a36Sopenharmony_ci GFP_KERNEL); 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci if (chosen_lsm_order) { 36062306a36Sopenharmony_ci if (chosen_major_lsm) { 36162306a36Sopenharmony_ci pr_warn("security=%s is ignored because it is superseded by lsm=%s\n", 36262306a36Sopenharmony_ci chosen_major_lsm, chosen_lsm_order); 36362306a36Sopenharmony_ci chosen_major_lsm = NULL; 36462306a36Sopenharmony_ci } 36562306a36Sopenharmony_ci ordered_lsm_parse(chosen_lsm_order, "cmdline"); 36662306a36Sopenharmony_ci } else 36762306a36Sopenharmony_ci ordered_lsm_parse(builtin_lsm_order, "builtin"); 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci for (lsm = ordered_lsms; *lsm; lsm++) 37062306a36Sopenharmony_ci prepare_lsm(*lsm); 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci report_lsm_order(); 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci init_debug("cred blob size = %d\n", blob_sizes.lbs_cred); 37562306a36Sopenharmony_ci init_debug("file blob size = %d\n", blob_sizes.lbs_file); 37662306a36Sopenharmony_ci init_debug("inode blob size = %d\n", blob_sizes.lbs_inode); 37762306a36Sopenharmony_ci init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc); 37862306a36Sopenharmony_ci init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg); 37962306a36Sopenharmony_ci init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock); 38062306a36Sopenharmony_ci init_debug("task blob size = %d\n", blob_sizes.lbs_task); 38162306a36Sopenharmony_ci init_debug("xattr slots = %d\n", blob_sizes.lbs_xattr_count); 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci /* 38462306a36Sopenharmony_ci * Create any kmem_caches needed for blobs 38562306a36Sopenharmony_ci */ 38662306a36Sopenharmony_ci if (blob_sizes.lbs_file) 38762306a36Sopenharmony_ci lsm_file_cache = kmem_cache_create("lsm_file_cache", 38862306a36Sopenharmony_ci blob_sizes.lbs_file, 0, 38962306a36Sopenharmony_ci SLAB_PANIC, NULL); 39062306a36Sopenharmony_ci if (blob_sizes.lbs_inode) 39162306a36Sopenharmony_ci lsm_inode_cache = kmem_cache_create("lsm_inode_cache", 39262306a36Sopenharmony_ci blob_sizes.lbs_inode, 0, 39362306a36Sopenharmony_ci SLAB_PANIC, NULL); 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci lsm_early_cred((struct cred *) current->cred); 39662306a36Sopenharmony_ci lsm_early_task(current); 39762306a36Sopenharmony_ci for (lsm = ordered_lsms; *lsm; lsm++) 39862306a36Sopenharmony_ci initialize_lsm(*lsm); 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci kfree(ordered_lsms); 40162306a36Sopenharmony_ci} 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ciint __init early_security_init(void) 40462306a36Sopenharmony_ci{ 40562306a36Sopenharmony_ci struct lsm_info *lsm; 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci#define LSM_HOOK(RET, DEFAULT, NAME, ...) \ 40862306a36Sopenharmony_ci INIT_HLIST_HEAD(&security_hook_heads.NAME); 40962306a36Sopenharmony_ci#include "linux/lsm_hook_defs.h" 41062306a36Sopenharmony_ci#undef LSM_HOOK 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) { 41362306a36Sopenharmony_ci if (!lsm->enabled) 41462306a36Sopenharmony_ci lsm->enabled = &lsm_enabled_true; 41562306a36Sopenharmony_ci prepare_lsm(lsm); 41662306a36Sopenharmony_ci initialize_lsm(lsm); 41762306a36Sopenharmony_ci } 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci return 0; 42062306a36Sopenharmony_ci} 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci/** 42362306a36Sopenharmony_ci * security_init - initializes the security framework 42462306a36Sopenharmony_ci * 42562306a36Sopenharmony_ci * This should be called early in the kernel initialization sequence. 42662306a36Sopenharmony_ci */ 42762306a36Sopenharmony_ciint __init security_init(void) 42862306a36Sopenharmony_ci{ 42962306a36Sopenharmony_ci struct lsm_info *lsm; 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci init_debug("legacy security=%s\n", chosen_major_lsm ? : " *unspecified*"); 43262306a36Sopenharmony_ci init_debug(" CONFIG_LSM=%s\n", builtin_lsm_order); 43362306a36Sopenharmony_ci init_debug("boot arg lsm=%s\n", chosen_lsm_order ? : " *unspecified*"); 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci /* 43662306a36Sopenharmony_ci * Append the names of the early LSM modules now that kmalloc() is 43762306a36Sopenharmony_ci * available 43862306a36Sopenharmony_ci */ 43962306a36Sopenharmony_ci for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) { 44062306a36Sopenharmony_ci init_debug(" early started: %s (%s)\n", lsm->name, 44162306a36Sopenharmony_ci is_enabled(lsm) ? "enabled" : "disabled"); 44262306a36Sopenharmony_ci if (lsm->enabled) 44362306a36Sopenharmony_ci lsm_append(lsm->name, &lsm_names); 44462306a36Sopenharmony_ci } 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci /* Load LSMs in specified order. */ 44762306a36Sopenharmony_ci ordered_lsm_init(); 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci return 0; 45062306a36Sopenharmony_ci} 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci/* Save user chosen LSM */ 45362306a36Sopenharmony_cistatic int __init choose_major_lsm(char *str) 45462306a36Sopenharmony_ci{ 45562306a36Sopenharmony_ci chosen_major_lsm = str; 45662306a36Sopenharmony_ci return 1; 45762306a36Sopenharmony_ci} 45862306a36Sopenharmony_ci__setup("security=", choose_major_lsm); 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci/* Explicitly choose LSM initialization order. */ 46162306a36Sopenharmony_cistatic int __init choose_lsm_order(char *str) 46262306a36Sopenharmony_ci{ 46362306a36Sopenharmony_ci chosen_lsm_order = str; 46462306a36Sopenharmony_ci return 1; 46562306a36Sopenharmony_ci} 46662306a36Sopenharmony_ci__setup("lsm=", choose_lsm_order); 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci/* Enable LSM order debugging. */ 46962306a36Sopenharmony_cistatic int __init enable_debug(char *str) 47062306a36Sopenharmony_ci{ 47162306a36Sopenharmony_ci debug = true; 47262306a36Sopenharmony_ci return 1; 47362306a36Sopenharmony_ci} 47462306a36Sopenharmony_ci__setup("lsm.debug", enable_debug); 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_cistatic bool match_last_lsm(const char *list, const char *lsm) 47762306a36Sopenharmony_ci{ 47862306a36Sopenharmony_ci const char *last; 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci if (WARN_ON(!list || !lsm)) 48162306a36Sopenharmony_ci return false; 48262306a36Sopenharmony_ci last = strrchr(list, ','); 48362306a36Sopenharmony_ci if (last) 48462306a36Sopenharmony_ci /* Pass the comma, strcmp() will check for '\0' */ 48562306a36Sopenharmony_ci last++; 48662306a36Sopenharmony_ci else 48762306a36Sopenharmony_ci last = list; 48862306a36Sopenharmony_ci return !strcmp(last, lsm); 48962306a36Sopenharmony_ci} 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_cistatic int lsm_append(const char *new, char **result) 49262306a36Sopenharmony_ci{ 49362306a36Sopenharmony_ci char *cp; 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci if (*result == NULL) { 49662306a36Sopenharmony_ci *result = kstrdup(new, GFP_KERNEL); 49762306a36Sopenharmony_ci if (*result == NULL) 49862306a36Sopenharmony_ci return -ENOMEM; 49962306a36Sopenharmony_ci } else { 50062306a36Sopenharmony_ci /* Check if it is the last registered name */ 50162306a36Sopenharmony_ci if (match_last_lsm(*result, new)) 50262306a36Sopenharmony_ci return 0; 50362306a36Sopenharmony_ci cp = kasprintf(GFP_KERNEL, "%s,%s", *result, new); 50462306a36Sopenharmony_ci if (cp == NULL) 50562306a36Sopenharmony_ci return -ENOMEM; 50662306a36Sopenharmony_ci kfree(*result); 50762306a36Sopenharmony_ci *result = cp; 50862306a36Sopenharmony_ci } 50962306a36Sopenharmony_ci return 0; 51062306a36Sopenharmony_ci} 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci/** 51362306a36Sopenharmony_ci * security_add_hooks - Add a modules hooks to the hook lists. 51462306a36Sopenharmony_ci * @hooks: the hooks to add 51562306a36Sopenharmony_ci * @count: the number of hooks to add 51662306a36Sopenharmony_ci * @lsm: the name of the security module 51762306a36Sopenharmony_ci * 51862306a36Sopenharmony_ci * Each LSM has to register its hooks with the infrastructure. 51962306a36Sopenharmony_ci */ 52062306a36Sopenharmony_civoid __init security_add_hooks(struct security_hook_list *hooks, int count, 52162306a36Sopenharmony_ci const char *lsm) 52262306a36Sopenharmony_ci{ 52362306a36Sopenharmony_ci int i; 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci for (i = 0; i < count; i++) { 52662306a36Sopenharmony_ci hooks[i].lsm = lsm; 52762306a36Sopenharmony_ci hlist_add_tail_rcu(&hooks[i].list, hooks[i].head); 52862306a36Sopenharmony_ci } 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_ci /* 53162306a36Sopenharmony_ci * Don't try to append during early_security_init(), we'll come back 53262306a36Sopenharmony_ci * and fix this up afterwards. 53362306a36Sopenharmony_ci */ 53462306a36Sopenharmony_ci if (slab_is_available()) { 53562306a36Sopenharmony_ci if (lsm_append(lsm, &lsm_names) < 0) 53662306a36Sopenharmony_ci panic("%s - Cannot get early memory.\n", __func__); 53762306a36Sopenharmony_ci } 53862306a36Sopenharmony_ci} 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ciint call_blocking_lsm_notifier(enum lsm_event event, void *data) 54162306a36Sopenharmony_ci{ 54262306a36Sopenharmony_ci return blocking_notifier_call_chain(&blocking_lsm_notifier_chain, 54362306a36Sopenharmony_ci event, data); 54462306a36Sopenharmony_ci} 54562306a36Sopenharmony_ciEXPORT_SYMBOL(call_blocking_lsm_notifier); 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_ciint register_blocking_lsm_notifier(struct notifier_block *nb) 54862306a36Sopenharmony_ci{ 54962306a36Sopenharmony_ci return blocking_notifier_chain_register(&blocking_lsm_notifier_chain, 55062306a36Sopenharmony_ci nb); 55162306a36Sopenharmony_ci} 55262306a36Sopenharmony_ciEXPORT_SYMBOL(register_blocking_lsm_notifier); 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_ciint unregister_blocking_lsm_notifier(struct notifier_block *nb) 55562306a36Sopenharmony_ci{ 55662306a36Sopenharmony_ci return blocking_notifier_chain_unregister(&blocking_lsm_notifier_chain, 55762306a36Sopenharmony_ci nb); 55862306a36Sopenharmony_ci} 55962306a36Sopenharmony_ciEXPORT_SYMBOL(unregister_blocking_lsm_notifier); 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci/** 56262306a36Sopenharmony_ci * lsm_cred_alloc - allocate a composite cred blob 56362306a36Sopenharmony_ci * @cred: the cred that needs a blob 56462306a36Sopenharmony_ci * @gfp: allocation type 56562306a36Sopenharmony_ci * 56662306a36Sopenharmony_ci * Allocate the cred blob for all the modules 56762306a36Sopenharmony_ci * 56862306a36Sopenharmony_ci * Returns 0, or -ENOMEM if memory can't be allocated. 56962306a36Sopenharmony_ci */ 57062306a36Sopenharmony_cistatic int lsm_cred_alloc(struct cred *cred, gfp_t gfp) 57162306a36Sopenharmony_ci{ 57262306a36Sopenharmony_ci if (blob_sizes.lbs_cred == 0) { 57362306a36Sopenharmony_ci cred->security = NULL; 57462306a36Sopenharmony_ci return 0; 57562306a36Sopenharmony_ci } 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_ci cred->security = kzalloc(blob_sizes.lbs_cred, gfp); 57862306a36Sopenharmony_ci if (cred->security == NULL) 57962306a36Sopenharmony_ci return -ENOMEM; 58062306a36Sopenharmony_ci return 0; 58162306a36Sopenharmony_ci} 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci/** 58462306a36Sopenharmony_ci * lsm_early_cred - during initialization allocate a composite cred blob 58562306a36Sopenharmony_ci * @cred: the cred that needs a blob 58662306a36Sopenharmony_ci * 58762306a36Sopenharmony_ci * Allocate the cred blob for all the modules 58862306a36Sopenharmony_ci */ 58962306a36Sopenharmony_cistatic void __init lsm_early_cred(struct cred *cred) 59062306a36Sopenharmony_ci{ 59162306a36Sopenharmony_ci int rc = lsm_cred_alloc(cred, GFP_KERNEL); 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci if (rc) 59462306a36Sopenharmony_ci panic("%s: Early cred alloc failed.\n", __func__); 59562306a36Sopenharmony_ci} 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci/** 59862306a36Sopenharmony_ci * lsm_file_alloc - allocate a composite file blob 59962306a36Sopenharmony_ci * @file: the file that needs a blob 60062306a36Sopenharmony_ci * 60162306a36Sopenharmony_ci * Allocate the file blob for all the modules 60262306a36Sopenharmony_ci * 60362306a36Sopenharmony_ci * Returns 0, or -ENOMEM if memory can't be allocated. 60462306a36Sopenharmony_ci */ 60562306a36Sopenharmony_cistatic int lsm_file_alloc(struct file *file) 60662306a36Sopenharmony_ci{ 60762306a36Sopenharmony_ci if (!lsm_file_cache) { 60862306a36Sopenharmony_ci file->f_security = NULL; 60962306a36Sopenharmony_ci return 0; 61062306a36Sopenharmony_ci } 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci file->f_security = kmem_cache_zalloc(lsm_file_cache, GFP_KERNEL); 61362306a36Sopenharmony_ci if (file->f_security == NULL) 61462306a36Sopenharmony_ci return -ENOMEM; 61562306a36Sopenharmony_ci return 0; 61662306a36Sopenharmony_ci} 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci/** 61962306a36Sopenharmony_ci * lsm_inode_alloc - allocate a composite inode blob 62062306a36Sopenharmony_ci * @inode: the inode that needs a blob 62162306a36Sopenharmony_ci * 62262306a36Sopenharmony_ci * Allocate the inode blob for all the modules 62362306a36Sopenharmony_ci * 62462306a36Sopenharmony_ci * Returns 0, or -ENOMEM if memory can't be allocated. 62562306a36Sopenharmony_ci */ 62662306a36Sopenharmony_ciint lsm_inode_alloc(struct inode *inode) 62762306a36Sopenharmony_ci{ 62862306a36Sopenharmony_ci if (!lsm_inode_cache) { 62962306a36Sopenharmony_ci inode->i_security = NULL; 63062306a36Sopenharmony_ci return 0; 63162306a36Sopenharmony_ci } 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci inode->i_security = kmem_cache_zalloc(lsm_inode_cache, GFP_NOFS); 63462306a36Sopenharmony_ci if (inode->i_security == NULL) 63562306a36Sopenharmony_ci return -ENOMEM; 63662306a36Sopenharmony_ci return 0; 63762306a36Sopenharmony_ci} 63862306a36Sopenharmony_ci 63962306a36Sopenharmony_ci/** 64062306a36Sopenharmony_ci * lsm_task_alloc - allocate a composite task blob 64162306a36Sopenharmony_ci * @task: the task that needs a blob 64262306a36Sopenharmony_ci * 64362306a36Sopenharmony_ci * Allocate the task blob for all the modules 64462306a36Sopenharmony_ci * 64562306a36Sopenharmony_ci * Returns 0, or -ENOMEM if memory can't be allocated. 64662306a36Sopenharmony_ci */ 64762306a36Sopenharmony_cistatic int lsm_task_alloc(struct task_struct *task) 64862306a36Sopenharmony_ci{ 64962306a36Sopenharmony_ci if (blob_sizes.lbs_task == 0) { 65062306a36Sopenharmony_ci task->security = NULL; 65162306a36Sopenharmony_ci return 0; 65262306a36Sopenharmony_ci } 65362306a36Sopenharmony_ci 65462306a36Sopenharmony_ci task->security = kzalloc(blob_sizes.lbs_task, GFP_KERNEL); 65562306a36Sopenharmony_ci if (task->security == NULL) 65662306a36Sopenharmony_ci return -ENOMEM; 65762306a36Sopenharmony_ci return 0; 65862306a36Sopenharmony_ci} 65962306a36Sopenharmony_ci 66062306a36Sopenharmony_ci/** 66162306a36Sopenharmony_ci * lsm_ipc_alloc - allocate a composite ipc blob 66262306a36Sopenharmony_ci * @kip: the ipc that needs a blob 66362306a36Sopenharmony_ci * 66462306a36Sopenharmony_ci * Allocate the ipc blob for all the modules 66562306a36Sopenharmony_ci * 66662306a36Sopenharmony_ci * Returns 0, or -ENOMEM if memory can't be allocated. 66762306a36Sopenharmony_ci */ 66862306a36Sopenharmony_cistatic int lsm_ipc_alloc(struct kern_ipc_perm *kip) 66962306a36Sopenharmony_ci{ 67062306a36Sopenharmony_ci if (blob_sizes.lbs_ipc == 0) { 67162306a36Sopenharmony_ci kip->security = NULL; 67262306a36Sopenharmony_ci return 0; 67362306a36Sopenharmony_ci } 67462306a36Sopenharmony_ci 67562306a36Sopenharmony_ci kip->security = kzalloc(blob_sizes.lbs_ipc, GFP_KERNEL); 67662306a36Sopenharmony_ci if (kip->security == NULL) 67762306a36Sopenharmony_ci return -ENOMEM; 67862306a36Sopenharmony_ci return 0; 67962306a36Sopenharmony_ci} 68062306a36Sopenharmony_ci 68162306a36Sopenharmony_ci/** 68262306a36Sopenharmony_ci * lsm_msg_msg_alloc - allocate a composite msg_msg blob 68362306a36Sopenharmony_ci * @mp: the msg_msg that needs a blob 68462306a36Sopenharmony_ci * 68562306a36Sopenharmony_ci * Allocate the ipc blob for all the modules 68662306a36Sopenharmony_ci * 68762306a36Sopenharmony_ci * Returns 0, or -ENOMEM if memory can't be allocated. 68862306a36Sopenharmony_ci */ 68962306a36Sopenharmony_cistatic int lsm_msg_msg_alloc(struct msg_msg *mp) 69062306a36Sopenharmony_ci{ 69162306a36Sopenharmony_ci if (blob_sizes.lbs_msg_msg == 0) { 69262306a36Sopenharmony_ci mp->security = NULL; 69362306a36Sopenharmony_ci return 0; 69462306a36Sopenharmony_ci } 69562306a36Sopenharmony_ci 69662306a36Sopenharmony_ci mp->security = kzalloc(blob_sizes.lbs_msg_msg, GFP_KERNEL); 69762306a36Sopenharmony_ci if (mp->security == NULL) 69862306a36Sopenharmony_ci return -ENOMEM; 69962306a36Sopenharmony_ci return 0; 70062306a36Sopenharmony_ci} 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci/** 70362306a36Sopenharmony_ci * lsm_early_task - during initialization allocate a composite task blob 70462306a36Sopenharmony_ci * @task: the task that needs a blob 70562306a36Sopenharmony_ci * 70662306a36Sopenharmony_ci * Allocate the task blob for all the modules 70762306a36Sopenharmony_ci */ 70862306a36Sopenharmony_cistatic void __init lsm_early_task(struct task_struct *task) 70962306a36Sopenharmony_ci{ 71062306a36Sopenharmony_ci int rc = lsm_task_alloc(task); 71162306a36Sopenharmony_ci 71262306a36Sopenharmony_ci if (rc) 71362306a36Sopenharmony_ci panic("%s: Early task alloc failed.\n", __func__); 71462306a36Sopenharmony_ci} 71562306a36Sopenharmony_ci 71662306a36Sopenharmony_ci/** 71762306a36Sopenharmony_ci * lsm_superblock_alloc - allocate a composite superblock blob 71862306a36Sopenharmony_ci * @sb: the superblock that needs a blob 71962306a36Sopenharmony_ci * 72062306a36Sopenharmony_ci * Allocate the superblock blob for all the modules 72162306a36Sopenharmony_ci * 72262306a36Sopenharmony_ci * Returns 0, or -ENOMEM if memory can't be allocated. 72362306a36Sopenharmony_ci */ 72462306a36Sopenharmony_cistatic int lsm_superblock_alloc(struct super_block *sb) 72562306a36Sopenharmony_ci{ 72662306a36Sopenharmony_ci if (blob_sizes.lbs_superblock == 0) { 72762306a36Sopenharmony_ci sb->s_security = NULL; 72862306a36Sopenharmony_ci return 0; 72962306a36Sopenharmony_ci } 73062306a36Sopenharmony_ci 73162306a36Sopenharmony_ci sb->s_security = kzalloc(blob_sizes.lbs_superblock, GFP_KERNEL); 73262306a36Sopenharmony_ci if (sb->s_security == NULL) 73362306a36Sopenharmony_ci return -ENOMEM; 73462306a36Sopenharmony_ci return 0; 73562306a36Sopenharmony_ci} 73662306a36Sopenharmony_ci 73762306a36Sopenharmony_ci/* 73862306a36Sopenharmony_ci * The default value of the LSM hook is defined in linux/lsm_hook_defs.h and 73962306a36Sopenharmony_ci * can be accessed with: 74062306a36Sopenharmony_ci * 74162306a36Sopenharmony_ci * LSM_RET_DEFAULT(<hook_name>) 74262306a36Sopenharmony_ci * 74362306a36Sopenharmony_ci * The macros below define static constants for the default value of each 74462306a36Sopenharmony_ci * LSM hook. 74562306a36Sopenharmony_ci */ 74662306a36Sopenharmony_ci#define LSM_RET_DEFAULT(NAME) (NAME##_default) 74762306a36Sopenharmony_ci#define DECLARE_LSM_RET_DEFAULT_void(DEFAULT, NAME) 74862306a36Sopenharmony_ci#define DECLARE_LSM_RET_DEFAULT_int(DEFAULT, NAME) \ 74962306a36Sopenharmony_ci static const int __maybe_unused LSM_RET_DEFAULT(NAME) = (DEFAULT); 75062306a36Sopenharmony_ci#define LSM_HOOK(RET, DEFAULT, NAME, ...) \ 75162306a36Sopenharmony_ci DECLARE_LSM_RET_DEFAULT_##RET(DEFAULT, NAME) 75262306a36Sopenharmony_ci 75362306a36Sopenharmony_ci#include <linux/lsm_hook_defs.h> 75462306a36Sopenharmony_ci#undef LSM_HOOK 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_ci/* 75762306a36Sopenharmony_ci * Hook list operation macros. 75862306a36Sopenharmony_ci * 75962306a36Sopenharmony_ci * call_void_hook: 76062306a36Sopenharmony_ci * This is a hook that does not return a value. 76162306a36Sopenharmony_ci * 76262306a36Sopenharmony_ci * call_int_hook: 76362306a36Sopenharmony_ci * This is a hook that returns a value. 76462306a36Sopenharmony_ci */ 76562306a36Sopenharmony_ci 76662306a36Sopenharmony_ci#define call_void_hook(FUNC, ...) \ 76762306a36Sopenharmony_ci do { \ 76862306a36Sopenharmony_ci struct security_hook_list *P; \ 76962306a36Sopenharmony_ci \ 77062306a36Sopenharmony_ci hlist_for_each_entry(P, &security_hook_heads.FUNC, list) \ 77162306a36Sopenharmony_ci P->hook.FUNC(__VA_ARGS__); \ 77262306a36Sopenharmony_ci } while (0) 77362306a36Sopenharmony_ci 77462306a36Sopenharmony_ci#define call_int_hook(FUNC, IRC, ...) ({ \ 77562306a36Sopenharmony_ci int RC = IRC; \ 77662306a36Sopenharmony_ci do { \ 77762306a36Sopenharmony_ci struct security_hook_list *P; \ 77862306a36Sopenharmony_ci \ 77962306a36Sopenharmony_ci hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \ 78062306a36Sopenharmony_ci RC = P->hook.FUNC(__VA_ARGS__); \ 78162306a36Sopenharmony_ci if (RC != 0) \ 78262306a36Sopenharmony_ci break; \ 78362306a36Sopenharmony_ci } \ 78462306a36Sopenharmony_ci } while (0); \ 78562306a36Sopenharmony_ci RC; \ 78662306a36Sopenharmony_ci}) 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_ci/* Security operations */ 78962306a36Sopenharmony_ci 79062306a36Sopenharmony_ci/** 79162306a36Sopenharmony_ci * security_binder_set_context_mgr() - Check if becoming binder ctx mgr is ok 79262306a36Sopenharmony_ci * @mgr: task credentials of current binder process 79362306a36Sopenharmony_ci * 79462306a36Sopenharmony_ci * Check whether @mgr is allowed to be the binder context manager. 79562306a36Sopenharmony_ci * 79662306a36Sopenharmony_ci * Return: Return 0 if permission is granted. 79762306a36Sopenharmony_ci */ 79862306a36Sopenharmony_ciint security_binder_set_context_mgr(const struct cred *mgr) 79962306a36Sopenharmony_ci{ 80062306a36Sopenharmony_ci return call_int_hook(binder_set_context_mgr, 0, mgr); 80162306a36Sopenharmony_ci} 80262306a36Sopenharmony_ci 80362306a36Sopenharmony_ci/** 80462306a36Sopenharmony_ci * security_binder_transaction() - Check if a binder transaction is allowed 80562306a36Sopenharmony_ci * @from: sending process 80662306a36Sopenharmony_ci * @to: receiving process 80762306a36Sopenharmony_ci * 80862306a36Sopenharmony_ci * Check whether @from is allowed to invoke a binder transaction call to @to. 80962306a36Sopenharmony_ci * 81062306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 81162306a36Sopenharmony_ci */ 81262306a36Sopenharmony_ciint security_binder_transaction(const struct cred *from, 81362306a36Sopenharmony_ci const struct cred *to) 81462306a36Sopenharmony_ci{ 81562306a36Sopenharmony_ci return call_int_hook(binder_transaction, 0, from, to); 81662306a36Sopenharmony_ci} 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_ci/** 81962306a36Sopenharmony_ci * security_binder_transfer_binder() - Check if a binder transfer is allowed 82062306a36Sopenharmony_ci * @from: sending process 82162306a36Sopenharmony_ci * @to: receiving process 82262306a36Sopenharmony_ci * 82362306a36Sopenharmony_ci * Check whether @from is allowed to transfer a binder reference to @to. 82462306a36Sopenharmony_ci * 82562306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 82662306a36Sopenharmony_ci */ 82762306a36Sopenharmony_ciint security_binder_transfer_binder(const struct cred *from, 82862306a36Sopenharmony_ci const struct cred *to) 82962306a36Sopenharmony_ci{ 83062306a36Sopenharmony_ci return call_int_hook(binder_transfer_binder, 0, from, to); 83162306a36Sopenharmony_ci} 83262306a36Sopenharmony_ci 83362306a36Sopenharmony_ci/** 83462306a36Sopenharmony_ci * security_binder_transfer_file() - Check if a binder file xfer is allowed 83562306a36Sopenharmony_ci * @from: sending process 83662306a36Sopenharmony_ci * @to: receiving process 83762306a36Sopenharmony_ci * @file: file being transferred 83862306a36Sopenharmony_ci * 83962306a36Sopenharmony_ci * Check whether @from is allowed to transfer @file to @to. 84062306a36Sopenharmony_ci * 84162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 84262306a36Sopenharmony_ci */ 84362306a36Sopenharmony_ciint security_binder_transfer_file(const struct cred *from, 84462306a36Sopenharmony_ci const struct cred *to, const struct file *file) 84562306a36Sopenharmony_ci{ 84662306a36Sopenharmony_ci return call_int_hook(binder_transfer_file, 0, from, to, file); 84762306a36Sopenharmony_ci} 84862306a36Sopenharmony_ci 84962306a36Sopenharmony_ci/** 85062306a36Sopenharmony_ci * security_ptrace_access_check() - Check if tracing is allowed 85162306a36Sopenharmony_ci * @child: target process 85262306a36Sopenharmony_ci * @mode: PTRACE_MODE flags 85362306a36Sopenharmony_ci * 85462306a36Sopenharmony_ci * Check permission before allowing the current process to trace the @child 85562306a36Sopenharmony_ci * process. Security modules may also want to perform a process tracing check 85662306a36Sopenharmony_ci * during an execve in the set_security or apply_creds hooks of tracing check 85762306a36Sopenharmony_ci * during an execve in the bprm_set_creds hook of binprm_security_ops if the 85862306a36Sopenharmony_ci * process is being traced and its security attributes would be changed by the 85962306a36Sopenharmony_ci * execve. 86062306a36Sopenharmony_ci * 86162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 86262306a36Sopenharmony_ci */ 86362306a36Sopenharmony_ciint security_ptrace_access_check(struct task_struct *child, unsigned int mode) 86462306a36Sopenharmony_ci{ 86562306a36Sopenharmony_ci return call_int_hook(ptrace_access_check, 0, child, mode); 86662306a36Sopenharmony_ci} 86762306a36Sopenharmony_ci 86862306a36Sopenharmony_ci/** 86962306a36Sopenharmony_ci * security_ptrace_traceme() - Check if tracing is allowed 87062306a36Sopenharmony_ci * @parent: tracing process 87162306a36Sopenharmony_ci * 87262306a36Sopenharmony_ci * Check that the @parent process has sufficient permission to trace the 87362306a36Sopenharmony_ci * current process before allowing the current process to present itself to the 87462306a36Sopenharmony_ci * @parent process for tracing. 87562306a36Sopenharmony_ci * 87662306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 87762306a36Sopenharmony_ci */ 87862306a36Sopenharmony_ciint security_ptrace_traceme(struct task_struct *parent) 87962306a36Sopenharmony_ci{ 88062306a36Sopenharmony_ci return call_int_hook(ptrace_traceme, 0, parent); 88162306a36Sopenharmony_ci} 88262306a36Sopenharmony_ci 88362306a36Sopenharmony_ci/** 88462306a36Sopenharmony_ci * security_capget() - Get the capability sets for a process 88562306a36Sopenharmony_ci * @target: target process 88662306a36Sopenharmony_ci * @effective: effective capability set 88762306a36Sopenharmony_ci * @inheritable: inheritable capability set 88862306a36Sopenharmony_ci * @permitted: permitted capability set 88962306a36Sopenharmony_ci * 89062306a36Sopenharmony_ci * Get the @effective, @inheritable, and @permitted capability sets for the 89162306a36Sopenharmony_ci * @target process. The hook may also perform permission checking to determine 89262306a36Sopenharmony_ci * if the current process is allowed to see the capability sets of the @target 89362306a36Sopenharmony_ci * process. 89462306a36Sopenharmony_ci * 89562306a36Sopenharmony_ci * Return: Returns 0 if the capability sets were successfully obtained. 89662306a36Sopenharmony_ci */ 89762306a36Sopenharmony_ciint security_capget(const struct task_struct *target, 89862306a36Sopenharmony_ci kernel_cap_t *effective, 89962306a36Sopenharmony_ci kernel_cap_t *inheritable, 90062306a36Sopenharmony_ci kernel_cap_t *permitted) 90162306a36Sopenharmony_ci{ 90262306a36Sopenharmony_ci return call_int_hook(capget, 0, target, 90362306a36Sopenharmony_ci effective, inheritable, permitted); 90462306a36Sopenharmony_ci} 90562306a36Sopenharmony_ci 90662306a36Sopenharmony_ci/** 90762306a36Sopenharmony_ci * security_capset() - Set the capability sets for a process 90862306a36Sopenharmony_ci * @new: new credentials for the target process 90962306a36Sopenharmony_ci * @old: current credentials of the target process 91062306a36Sopenharmony_ci * @effective: effective capability set 91162306a36Sopenharmony_ci * @inheritable: inheritable capability set 91262306a36Sopenharmony_ci * @permitted: permitted capability set 91362306a36Sopenharmony_ci * 91462306a36Sopenharmony_ci * Set the @effective, @inheritable, and @permitted capability sets for the 91562306a36Sopenharmony_ci * current process. 91662306a36Sopenharmony_ci * 91762306a36Sopenharmony_ci * Return: Returns 0 and update @new if permission is granted. 91862306a36Sopenharmony_ci */ 91962306a36Sopenharmony_ciint security_capset(struct cred *new, const struct cred *old, 92062306a36Sopenharmony_ci const kernel_cap_t *effective, 92162306a36Sopenharmony_ci const kernel_cap_t *inheritable, 92262306a36Sopenharmony_ci const kernel_cap_t *permitted) 92362306a36Sopenharmony_ci{ 92462306a36Sopenharmony_ci return call_int_hook(capset, 0, new, old, 92562306a36Sopenharmony_ci effective, inheritable, permitted); 92662306a36Sopenharmony_ci} 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_ci/** 92962306a36Sopenharmony_ci * security_capable() - Check if a process has the necessary capability 93062306a36Sopenharmony_ci * @cred: credentials to examine 93162306a36Sopenharmony_ci * @ns: user namespace 93262306a36Sopenharmony_ci * @cap: capability requested 93362306a36Sopenharmony_ci * @opts: capability check options 93462306a36Sopenharmony_ci * 93562306a36Sopenharmony_ci * Check whether the @tsk process has the @cap capability in the indicated 93662306a36Sopenharmony_ci * credentials. @cap contains the capability <include/linux/capability.h>. 93762306a36Sopenharmony_ci * @opts contains options for the capable check <include/linux/security.h>. 93862306a36Sopenharmony_ci * 93962306a36Sopenharmony_ci * Return: Returns 0 if the capability is granted. 94062306a36Sopenharmony_ci */ 94162306a36Sopenharmony_ciint security_capable(const struct cred *cred, 94262306a36Sopenharmony_ci struct user_namespace *ns, 94362306a36Sopenharmony_ci int cap, 94462306a36Sopenharmony_ci unsigned int opts) 94562306a36Sopenharmony_ci{ 94662306a36Sopenharmony_ci return call_int_hook(capable, 0, cred, ns, cap, opts); 94762306a36Sopenharmony_ci} 94862306a36Sopenharmony_ci 94962306a36Sopenharmony_ci/** 95062306a36Sopenharmony_ci * security_quotactl() - Check if a quotactl() syscall is allowed for this fs 95162306a36Sopenharmony_ci * @cmds: commands 95262306a36Sopenharmony_ci * @type: type 95362306a36Sopenharmony_ci * @id: id 95462306a36Sopenharmony_ci * @sb: filesystem 95562306a36Sopenharmony_ci * 95662306a36Sopenharmony_ci * Check whether the quotactl syscall is allowed for this @sb. 95762306a36Sopenharmony_ci * 95862306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 95962306a36Sopenharmony_ci */ 96062306a36Sopenharmony_ciint security_quotactl(int cmds, int type, int id, struct super_block *sb) 96162306a36Sopenharmony_ci{ 96262306a36Sopenharmony_ci return call_int_hook(quotactl, 0, cmds, type, id, sb); 96362306a36Sopenharmony_ci} 96462306a36Sopenharmony_ci 96562306a36Sopenharmony_ci/** 96662306a36Sopenharmony_ci * security_quota_on() - Check if QUOTAON is allowed for a dentry 96762306a36Sopenharmony_ci * @dentry: dentry 96862306a36Sopenharmony_ci * 96962306a36Sopenharmony_ci * Check whether QUOTAON is allowed for @dentry. 97062306a36Sopenharmony_ci * 97162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 97262306a36Sopenharmony_ci */ 97362306a36Sopenharmony_ciint security_quota_on(struct dentry *dentry) 97462306a36Sopenharmony_ci{ 97562306a36Sopenharmony_ci return call_int_hook(quota_on, 0, dentry); 97662306a36Sopenharmony_ci} 97762306a36Sopenharmony_ci 97862306a36Sopenharmony_ci/** 97962306a36Sopenharmony_ci * security_syslog() - Check if accessing the kernel message ring is allowed 98062306a36Sopenharmony_ci * @type: SYSLOG_ACTION_* type 98162306a36Sopenharmony_ci * 98262306a36Sopenharmony_ci * Check permission before accessing the kernel message ring or changing 98362306a36Sopenharmony_ci * logging to the console. See the syslog(2) manual page for an explanation of 98462306a36Sopenharmony_ci * the @type values. 98562306a36Sopenharmony_ci * 98662306a36Sopenharmony_ci * Return: Return 0 if permission is granted. 98762306a36Sopenharmony_ci */ 98862306a36Sopenharmony_ciint security_syslog(int type) 98962306a36Sopenharmony_ci{ 99062306a36Sopenharmony_ci return call_int_hook(syslog, 0, type); 99162306a36Sopenharmony_ci} 99262306a36Sopenharmony_ci 99362306a36Sopenharmony_ci/** 99462306a36Sopenharmony_ci * security_settime64() - Check if changing the system time is allowed 99562306a36Sopenharmony_ci * @ts: new time 99662306a36Sopenharmony_ci * @tz: timezone 99762306a36Sopenharmony_ci * 99862306a36Sopenharmony_ci * Check permission to change the system time, struct timespec64 is defined in 99962306a36Sopenharmony_ci * <include/linux/time64.h> and timezone is defined in <include/linux/time.h>. 100062306a36Sopenharmony_ci * 100162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 100262306a36Sopenharmony_ci */ 100362306a36Sopenharmony_ciint security_settime64(const struct timespec64 *ts, const struct timezone *tz) 100462306a36Sopenharmony_ci{ 100562306a36Sopenharmony_ci return call_int_hook(settime, 0, ts, tz); 100662306a36Sopenharmony_ci} 100762306a36Sopenharmony_ci 100862306a36Sopenharmony_ci/** 100962306a36Sopenharmony_ci * security_vm_enough_memory_mm() - Check if allocating a new mem map is allowed 101062306a36Sopenharmony_ci * @mm: mm struct 101162306a36Sopenharmony_ci * @pages: number of pages 101262306a36Sopenharmony_ci * 101362306a36Sopenharmony_ci * Check permissions for allocating a new virtual mapping. If all LSMs return 101462306a36Sopenharmony_ci * a positive value, __vm_enough_memory() will be called with cap_sys_admin 101562306a36Sopenharmony_ci * set. If at least one LSM returns 0 or negative, __vm_enough_memory() will be 101662306a36Sopenharmony_ci * called with cap_sys_admin cleared. 101762306a36Sopenharmony_ci * 101862306a36Sopenharmony_ci * Return: Returns 0 if permission is granted by the LSM infrastructure to the 101962306a36Sopenharmony_ci * caller. 102062306a36Sopenharmony_ci */ 102162306a36Sopenharmony_ciint security_vm_enough_memory_mm(struct mm_struct *mm, long pages) 102262306a36Sopenharmony_ci{ 102362306a36Sopenharmony_ci struct security_hook_list *hp; 102462306a36Sopenharmony_ci int cap_sys_admin = 1; 102562306a36Sopenharmony_ci int rc; 102662306a36Sopenharmony_ci 102762306a36Sopenharmony_ci /* 102862306a36Sopenharmony_ci * The module will respond with a positive value if 102962306a36Sopenharmony_ci * it thinks the __vm_enough_memory() call should be 103062306a36Sopenharmony_ci * made with the cap_sys_admin set. If all of the modules 103162306a36Sopenharmony_ci * agree that it should be set it will. If any module 103262306a36Sopenharmony_ci * thinks it should not be set it won't. 103362306a36Sopenharmony_ci */ 103462306a36Sopenharmony_ci hlist_for_each_entry(hp, &security_hook_heads.vm_enough_memory, list) { 103562306a36Sopenharmony_ci rc = hp->hook.vm_enough_memory(mm, pages); 103662306a36Sopenharmony_ci if (rc <= 0) { 103762306a36Sopenharmony_ci cap_sys_admin = 0; 103862306a36Sopenharmony_ci break; 103962306a36Sopenharmony_ci } 104062306a36Sopenharmony_ci } 104162306a36Sopenharmony_ci return __vm_enough_memory(mm, pages, cap_sys_admin); 104262306a36Sopenharmony_ci} 104362306a36Sopenharmony_ci 104462306a36Sopenharmony_ci/** 104562306a36Sopenharmony_ci * security_bprm_creds_for_exec() - Prepare the credentials for exec() 104662306a36Sopenharmony_ci * @bprm: binary program information 104762306a36Sopenharmony_ci * 104862306a36Sopenharmony_ci * If the setup in prepare_exec_creds did not setup @bprm->cred->security 104962306a36Sopenharmony_ci * properly for executing @bprm->file, update the LSM's portion of 105062306a36Sopenharmony_ci * @bprm->cred->security to be what commit_creds needs to install for the new 105162306a36Sopenharmony_ci * program. This hook may also optionally check permissions (e.g. for 105262306a36Sopenharmony_ci * transitions between security domains). The hook must set @bprm->secureexec 105362306a36Sopenharmony_ci * to 1 if AT_SECURE should be set to request libc enable secure mode. @bprm 105462306a36Sopenharmony_ci * contains the linux_binprm structure. 105562306a36Sopenharmony_ci * 105662306a36Sopenharmony_ci * Return: Returns 0 if the hook is successful and permission is granted. 105762306a36Sopenharmony_ci */ 105862306a36Sopenharmony_ciint security_bprm_creds_for_exec(struct linux_binprm *bprm) 105962306a36Sopenharmony_ci{ 106062306a36Sopenharmony_ci return call_int_hook(bprm_creds_for_exec, 0, bprm); 106162306a36Sopenharmony_ci} 106262306a36Sopenharmony_ci 106362306a36Sopenharmony_ci/** 106462306a36Sopenharmony_ci * security_bprm_creds_from_file() - Update linux_binprm creds based on file 106562306a36Sopenharmony_ci * @bprm: binary program information 106662306a36Sopenharmony_ci * @file: associated file 106762306a36Sopenharmony_ci * 106862306a36Sopenharmony_ci * If @file is setpcap, suid, sgid or otherwise marked to change privilege upon 106962306a36Sopenharmony_ci * exec, update @bprm->cred to reflect that change. This is called after 107062306a36Sopenharmony_ci * finding the binary that will be executed without an interpreter. This 107162306a36Sopenharmony_ci * ensures that the credentials will not be derived from a script that the 107262306a36Sopenharmony_ci * binary will need to reopen, which when reopend may end up being a completely 107362306a36Sopenharmony_ci * different file. This hook may also optionally check permissions (e.g. for 107462306a36Sopenharmony_ci * transitions between security domains). The hook must set @bprm->secureexec 107562306a36Sopenharmony_ci * to 1 if AT_SECURE should be set to request libc enable secure mode. The 107662306a36Sopenharmony_ci * hook must add to @bprm->per_clear any personality flags that should be 107762306a36Sopenharmony_ci * cleared from current->personality. @bprm contains the linux_binprm 107862306a36Sopenharmony_ci * structure. 107962306a36Sopenharmony_ci * 108062306a36Sopenharmony_ci * Return: Returns 0 if the hook is successful and permission is granted. 108162306a36Sopenharmony_ci */ 108262306a36Sopenharmony_ciint security_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file) 108362306a36Sopenharmony_ci{ 108462306a36Sopenharmony_ci return call_int_hook(bprm_creds_from_file, 0, bprm, file); 108562306a36Sopenharmony_ci} 108662306a36Sopenharmony_ci 108762306a36Sopenharmony_ci/** 108862306a36Sopenharmony_ci * security_bprm_check() - Mediate binary handler search 108962306a36Sopenharmony_ci * @bprm: binary program information 109062306a36Sopenharmony_ci * 109162306a36Sopenharmony_ci * This hook mediates the point when a search for a binary handler will begin. 109262306a36Sopenharmony_ci * It allows a check against the @bprm->cred->security value which was set in 109362306a36Sopenharmony_ci * the preceding creds_for_exec call. The argv list and envp list are reliably 109462306a36Sopenharmony_ci * available in @bprm. This hook may be called multiple times during a single 109562306a36Sopenharmony_ci * execve. @bprm contains the linux_binprm structure. 109662306a36Sopenharmony_ci * 109762306a36Sopenharmony_ci * Return: Returns 0 if the hook is successful and permission is granted. 109862306a36Sopenharmony_ci */ 109962306a36Sopenharmony_ciint security_bprm_check(struct linux_binprm *bprm) 110062306a36Sopenharmony_ci{ 110162306a36Sopenharmony_ci int ret; 110262306a36Sopenharmony_ci 110362306a36Sopenharmony_ci ret = call_int_hook(bprm_check_security, 0, bprm); 110462306a36Sopenharmony_ci if (ret) 110562306a36Sopenharmony_ci return ret; 110662306a36Sopenharmony_ci return ima_bprm_check(bprm); 110762306a36Sopenharmony_ci} 110862306a36Sopenharmony_ci 110962306a36Sopenharmony_ci/** 111062306a36Sopenharmony_ci * security_bprm_committing_creds() - Install creds for a process during exec() 111162306a36Sopenharmony_ci * @bprm: binary program information 111262306a36Sopenharmony_ci * 111362306a36Sopenharmony_ci * Prepare to install the new security attributes of a process being 111462306a36Sopenharmony_ci * transformed by an execve operation, based on the old credentials pointed to 111562306a36Sopenharmony_ci * by @current->cred and the information set in @bprm->cred by the 111662306a36Sopenharmony_ci * bprm_creds_for_exec hook. @bprm points to the linux_binprm structure. This 111762306a36Sopenharmony_ci * hook is a good place to perform state changes on the process such as closing 111862306a36Sopenharmony_ci * open file descriptors to which access will no longer be granted when the 111962306a36Sopenharmony_ci * attributes are changed. This is called immediately before commit_creds(). 112062306a36Sopenharmony_ci */ 112162306a36Sopenharmony_civoid security_bprm_committing_creds(struct linux_binprm *bprm) 112262306a36Sopenharmony_ci{ 112362306a36Sopenharmony_ci call_void_hook(bprm_committing_creds, bprm); 112462306a36Sopenharmony_ci} 112562306a36Sopenharmony_ci 112662306a36Sopenharmony_ci/** 112762306a36Sopenharmony_ci * security_bprm_committed_creds() - Tidy up after cred install during exec() 112862306a36Sopenharmony_ci * @bprm: binary program information 112962306a36Sopenharmony_ci * 113062306a36Sopenharmony_ci * Tidy up after the installation of the new security attributes of a process 113162306a36Sopenharmony_ci * being transformed by an execve operation. The new credentials have, by this 113262306a36Sopenharmony_ci * point, been set to @current->cred. @bprm points to the linux_binprm 113362306a36Sopenharmony_ci * structure. This hook is a good place to perform state changes on the 113462306a36Sopenharmony_ci * process such as clearing out non-inheritable signal state. This is called 113562306a36Sopenharmony_ci * immediately after commit_creds(). 113662306a36Sopenharmony_ci */ 113762306a36Sopenharmony_civoid security_bprm_committed_creds(struct linux_binprm *bprm) 113862306a36Sopenharmony_ci{ 113962306a36Sopenharmony_ci call_void_hook(bprm_committed_creds, bprm); 114062306a36Sopenharmony_ci} 114162306a36Sopenharmony_ci 114262306a36Sopenharmony_ci/** 114362306a36Sopenharmony_ci * security_fs_context_submount() - Initialise fc->security 114462306a36Sopenharmony_ci * @fc: new filesystem context 114562306a36Sopenharmony_ci * @reference: dentry reference for submount/remount 114662306a36Sopenharmony_ci * 114762306a36Sopenharmony_ci * Fill out the ->security field for a new fs_context. 114862306a36Sopenharmony_ci * 114962306a36Sopenharmony_ci * Return: Returns 0 on success or negative error code on failure. 115062306a36Sopenharmony_ci */ 115162306a36Sopenharmony_ciint security_fs_context_submount(struct fs_context *fc, struct super_block *reference) 115262306a36Sopenharmony_ci{ 115362306a36Sopenharmony_ci return call_int_hook(fs_context_submount, 0, fc, reference); 115462306a36Sopenharmony_ci} 115562306a36Sopenharmony_ci 115662306a36Sopenharmony_ci/** 115762306a36Sopenharmony_ci * security_fs_context_dup() - Duplicate a fs_context LSM blob 115862306a36Sopenharmony_ci * @fc: destination filesystem context 115962306a36Sopenharmony_ci * @src_fc: source filesystem context 116062306a36Sopenharmony_ci * 116162306a36Sopenharmony_ci * Allocate and attach a security structure to sc->security. This pointer is 116262306a36Sopenharmony_ci * initialised to NULL by the caller. @fc indicates the new filesystem context. 116362306a36Sopenharmony_ci * @src_fc indicates the original filesystem context. 116462306a36Sopenharmony_ci * 116562306a36Sopenharmony_ci * Return: Returns 0 on success or a negative error code on failure. 116662306a36Sopenharmony_ci */ 116762306a36Sopenharmony_ciint security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc) 116862306a36Sopenharmony_ci{ 116962306a36Sopenharmony_ci return call_int_hook(fs_context_dup, 0, fc, src_fc); 117062306a36Sopenharmony_ci} 117162306a36Sopenharmony_ci 117262306a36Sopenharmony_ci/** 117362306a36Sopenharmony_ci * security_fs_context_parse_param() - Configure a filesystem context 117462306a36Sopenharmony_ci * @fc: filesystem context 117562306a36Sopenharmony_ci * @param: filesystem parameter 117662306a36Sopenharmony_ci * 117762306a36Sopenharmony_ci * Userspace provided a parameter to configure a superblock. The LSM can 117862306a36Sopenharmony_ci * consume the parameter or return it to the caller for use elsewhere. 117962306a36Sopenharmony_ci * 118062306a36Sopenharmony_ci * Return: If the parameter is used by the LSM it should return 0, if it is 118162306a36Sopenharmony_ci * returned to the caller -ENOPARAM is returned, otherwise a negative 118262306a36Sopenharmony_ci * error code is returned. 118362306a36Sopenharmony_ci */ 118462306a36Sopenharmony_ciint security_fs_context_parse_param(struct fs_context *fc, 118562306a36Sopenharmony_ci struct fs_parameter *param) 118662306a36Sopenharmony_ci{ 118762306a36Sopenharmony_ci struct security_hook_list *hp; 118862306a36Sopenharmony_ci int trc; 118962306a36Sopenharmony_ci int rc = -ENOPARAM; 119062306a36Sopenharmony_ci 119162306a36Sopenharmony_ci hlist_for_each_entry(hp, &security_hook_heads.fs_context_parse_param, 119262306a36Sopenharmony_ci list) { 119362306a36Sopenharmony_ci trc = hp->hook.fs_context_parse_param(fc, param); 119462306a36Sopenharmony_ci if (trc == 0) 119562306a36Sopenharmony_ci rc = 0; 119662306a36Sopenharmony_ci else if (trc != -ENOPARAM) 119762306a36Sopenharmony_ci return trc; 119862306a36Sopenharmony_ci } 119962306a36Sopenharmony_ci return rc; 120062306a36Sopenharmony_ci} 120162306a36Sopenharmony_ci 120262306a36Sopenharmony_ci/** 120362306a36Sopenharmony_ci * security_sb_alloc() - Allocate a super_block LSM blob 120462306a36Sopenharmony_ci * @sb: filesystem superblock 120562306a36Sopenharmony_ci * 120662306a36Sopenharmony_ci * Allocate and attach a security structure to the sb->s_security field. The 120762306a36Sopenharmony_ci * s_security field is initialized to NULL when the structure is allocated. 120862306a36Sopenharmony_ci * @sb contains the super_block structure to be modified. 120962306a36Sopenharmony_ci * 121062306a36Sopenharmony_ci * Return: Returns 0 if operation was successful. 121162306a36Sopenharmony_ci */ 121262306a36Sopenharmony_ciint security_sb_alloc(struct super_block *sb) 121362306a36Sopenharmony_ci{ 121462306a36Sopenharmony_ci int rc = lsm_superblock_alloc(sb); 121562306a36Sopenharmony_ci 121662306a36Sopenharmony_ci if (unlikely(rc)) 121762306a36Sopenharmony_ci return rc; 121862306a36Sopenharmony_ci rc = call_int_hook(sb_alloc_security, 0, sb); 121962306a36Sopenharmony_ci if (unlikely(rc)) 122062306a36Sopenharmony_ci security_sb_free(sb); 122162306a36Sopenharmony_ci return rc; 122262306a36Sopenharmony_ci} 122362306a36Sopenharmony_ci 122462306a36Sopenharmony_ci/** 122562306a36Sopenharmony_ci * security_sb_delete() - Release super_block LSM associated objects 122662306a36Sopenharmony_ci * @sb: filesystem superblock 122762306a36Sopenharmony_ci * 122862306a36Sopenharmony_ci * Release objects tied to a superblock (e.g. inodes). @sb contains the 122962306a36Sopenharmony_ci * super_block structure being released. 123062306a36Sopenharmony_ci */ 123162306a36Sopenharmony_civoid security_sb_delete(struct super_block *sb) 123262306a36Sopenharmony_ci{ 123362306a36Sopenharmony_ci call_void_hook(sb_delete, sb); 123462306a36Sopenharmony_ci} 123562306a36Sopenharmony_ci 123662306a36Sopenharmony_ci/** 123762306a36Sopenharmony_ci * security_sb_free() - Free a super_block LSM blob 123862306a36Sopenharmony_ci * @sb: filesystem superblock 123962306a36Sopenharmony_ci * 124062306a36Sopenharmony_ci * Deallocate and clear the sb->s_security field. @sb contains the super_block 124162306a36Sopenharmony_ci * structure to be modified. 124262306a36Sopenharmony_ci */ 124362306a36Sopenharmony_civoid security_sb_free(struct super_block *sb) 124462306a36Sopenharmony_ci{ 124562306a36Sopenharmony_ci call_void_hook(sb_free_security, sb); 124662306a36Sopenharmony_ci kfree(sb->s_security); 124762306a36Sopenharmony_ci sb->s_security = NULL; 124862306a36Sopenharmony_ci} 124962306a36Sopenharmony_ci 125062306a36Sopenharmony_ci/** 125162306a36Sopenharmony_ci * security_free_mnt_opts() - Free memory associated with mount options 125262306a36Sopenharmony_ci * @mnt_opts: LSM processed mount options 125362306a36Sopenharmony_ci * 125462306a36Sopenharmony_ci * Free memory associated with @mnt_ops. 125562306a36Sopenharmony_ci */ 125662306a36Sopenharmony_civoid security_free_mnt_opts(void **mnt_opts) 125762306a36Sopenharmony_ci{ 125862306a36Sopenharmony_ci if (!*mnt_opts) 125962306a36Sopenharmony_ci return; 126062306a36Sopenharmony_ci call_void_hook(sb_free_mnt_opts, *mnt_opts); 126162306a36Sopenharmony_ci *mnt_opts = NULL; 126262306a36Sopenharmony_ci} 126362306a36Sopenharmony_ciEXPORT_SYMBOL(security_free_mnt_opts); 126462306a36Sopenharmony_ci 126562306a36Sopenharmony_ci/** 126662306a36Sopenharmony_ci * security_sb_eat_lsm_opts() - Consume LSM mount options 126762306a36Sopenharmony_ci * @options: mount options 126862306a36Sopenharmony_ci * @mnt_opts: LSM processed mount options 126962306a36Sopenharmony_ci * 127062306a36Sopenharmony_ci * Eat (scan @options) and save them in @mnt_opts. 127162306a36Sopenharmony_ci * 127262306a36Sopenharmony_ci * Return: Returns 0 on success, negative values on failure. 127362306a36Sopenharmony_ci */ 127462306a36Sopenharmony_ciint security_sb_eat_lsm_opts(char *options, void **mnt_opts) 127562306a36Sopenharmony_ci{ 127662306a36Sopenharmony_ci return call_int_hook(sb_eat_lsm_opts, 0, options, mnt_opts); 127762306a36Sopenharmony_ci} 127862306a36Sopenharmony_ciEXPORT_SYMBOL(security_sb_eat_lsm_opts); 127962306a36Sopenharmony_ci 128062306a36Sopenharmony_ci/** 128162306a36Sopenharmony_ci * security_sb_mnt_opts_compat() - Check if new mount options are allowed 128262306a36Sopenharmony_ci * @sb: filesystem superblock 128362306a36Sopenharmony_ci * @mnt_opts: new mount options 128462306a36Sopenharmony_ci * 128562306a36Sopenharmony_ci * Determine if the new mount options in @mnt_opts are allowed given the 128662306a36Sopenharmony_ci * existing mounted filesystem at @sb. @sb superblock being compared. 128762306a36Sopenharmony_ci * 128862306a36Sopenharmony_ci * Return: Returns 0 if options are compatible. 128962306a36Sopenharmony_ci */ 129062306a36Sopenharmony_ciint security_sb_mnt_opts_compat(struct super_block *sb, 129162306a36Sopenharmony_ci void *mnt_opts) 129262306a36Sopenharmony_ci{ 129362306a36Sopenharmony_ci return call_int_hook(sb_mnt_opts_compat, 0, sb, mnt_opts); 129462306a36Sopenharmony_ci} 129562306a36Sopenharmony_ciEXPORT_SYMBOL(security_sb_mnt_opts_compat); 129662306a36Sopenharmony_ci 129762306a36Sopenharmony_ci/** 129862306a36Sopenharmony_ci * security_sb_remount() - Verify no incompatible mount changes during remount 129962306a36Sopenharmony_ci * @sb: filesystem superblock 130062306a36Sopenharmony_ci * @mnt_opts: (re)mount options 130162306a36Sopenharmony_ci * 130262306a36Sopenharmony_ci * Extracts security system specific mount options and verifies no changes are 130362306a36Sopenharmony_ci * being made to those options. 130462306a36Sopenharmony_ci * 130562306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 130662306a36Sopenharmony_ci */ 130762306a36Sopenharmony_ciint security_sb_remount(struct super_block *sb, 130862306a36Sopenharmony_ci void *mnt_opts) 130962306a36Sopenharmony_ci{ 131062306a36Sopenharmony_ci return call_int_hook(sb_remount, 0, sb, mnt_opts); 131162306a36Sopenharmony_ci} 131262306a36Sopenharmony_ciEXPORT_SYMBOL(security_sb_remount); 131362306a36Sopenharmony_ci 131462306a36Sopenharmony_ci/** 131562306a36Sopenharmony_ci * security_sb_kern_mount() - Check if a kernel mount is allowed 131662306a36Sopenharmony_ci * @sb: filesystem superblock 131762306a36Sopenharmony_ci * 131862306a36Sopenharmony_ci * Mount this @sb if allowed by permissions. 131962306a36Sopenharmony_ci * 132062306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 132162306a36Sopenharmony_ci */ 132262306a36Sopenharmony_ciint security_sb_kern_mount(struct super_block *sb) 132362306a36Sopenharmony_ci{ 132462306a36Sopenharmony_ci return call_int_hook(sb_kern_mount, 0, sb); 132562306a36Sopenharmony_ci} 132662306a36Sopenharmony_ci 132762306a36Sopenharmony_ci/** 132862306a36Sopenharmony_ci * security_sb_show_options() - Output the mount options for a superblock 132962306a36Sopenharmony_ci * @m: output file 133062306a36Sopenharmony_ci * @sb: filesystem superblock 133162306a36Sopenharmony_ci * 133262306a36Sopenharmony_ci * Show (print on @m) mount options for this @sb. 133362306a36Sopenharmony_ci * 133462306a36Sopenharmony_ci * Return: Returns 0 on success, negative values on failure. 133562306a36Sopenharmony_ci */ 133662306a36Sopenharmony_ciint security_sb_show_options(struct seq_file *m, struct super_block *sb) 133762306a36Sopenharmony_ci{ 133862306a36Sopenharmony_ci return call_int_hook(sb_show_options, 0, m, sb); 133962306a36Sopenharmony_ci} 134062306a36Sopenharmony_ci 134162306a36Sopenharmony_ci/** 134262306a36Sopenharmony_ci * security_sb_statfs() - Check if accessing fs stats is allowed 134362306a36Sopenharmony_ci * @dentry: superblock handle 134462306a36Sopenharmony_ci * 134562306a36Sopenharmony_ci * Check permission before obtaining filesystem statistics for the @mnt 134662306a36Sopenharmony_ci * mountpoint. @dentry is a handle on the superblock for the filesystem. 134762306a36Sopenharmony_ci * 134862306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 134962306a36Sopenharmony_ci */ 135062306a36Sopenharmony_ciint security_sb_statfs(struct dentry *dentry) 135162306a36Sopenharmony_ci{ 135262306a36Sopenharmony_ci return call_int_hook(sb_statfs, 0, dentry); 135362306a36Sopenharmony_ci} 135462306a36Sopenharmony_ci 135562306a36Sopenharmony_ci/** 135662306a36Sopenharmony_ci * security_sb_mount() - Check permission for mounting a filesystem 135762306a36Sopenharmony_ci * @dev_name: filesystem backing device 135862306a36Sopenharmony_ci * @path: mount point 135962306a36Sopenharmony_ci * @type: filesystem type 136062306a36Sopenharmony_ci * @flags: mount flags 136162306a36Sopenharmony_ci * @data: filesystem specific data 136262306a36Sopenharmony_ci * 136362306a36Sopenharmony_ci * Check permission before an object specified by @dev_name is mounted on the 136462306a36Sopenharmony_ci * mount point named by @nd. For an ordinary mount, @dev_name identifies a 136562306a36Sopenharmony_ci * device if the file system type requires a device. For a remount 136662306a36Sopenharmony_ci * (@flags & MS_REMOUNT), @dev_name is irrelevant. For a loopback/bind mount 136762306a36Sopenharmony_ci * (@flags & MS_BIND), @dev_name identifies the pathname of the object being 136862306a36Sopenharmony_ci * mounted. 136962306a36Sopenharmony_ci * 137062306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 137162306a36Sopenharmony_ci */ 137262306a36Sopenharmony_ciint security_sb_mount(const char *dev_name, const struct path *path, 137362306a36Sopenharmony_ci const char *type, unsigned long flags, void *data) 137462306a36Sopenharmony_ci{ 137562306a36Sopenharmony_ci return call_int_hook(sb_mount, 0, dev_name, path, type, flags, data); 137662306a36Sopenharmony_ci} 137762306a36Sopenharmony_ci 137862306a36Sopenharmony_ci/** 137962306a36Sopenharmony_ci * security_sb_umount() - Check permission for unmounting a filesystem 138062306a36Sopenharmony_ci * @mnt: mounted filesystem 138162306a36Sopenharmony_ci * @flags: unmount flags 138262306a36Sopenharmony_ci * 138362306a36Sopenharmony_ci * Check permission before the @mnt file system is unmounted. 138462306a36Sopenharmony_ci * 138562306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 138662306a36Sopenharmony_ci */ 138762306a36Sopenharmony_ciint security_sb_umount(struct vfsmount *mnt, int flags) 138862306a36Sopenharmony_ci{ 138962306a36Sopenharmony_ci return call_int_hook(sb_umount, 0, mnt, flags); 139062306a36Sopenharmony_ci} 139162306a36Sopenharmony_ci 139262306a36Sopenharmony_ci/** 139362306a36Sopenharmony_ci * security_sb_pivotroot() - Check permissions for pivoting the rootfs 139462306a36Sopenharmony_ci * @old_path: new location for current rootfs 139562306a36Sopenharmony_ci * @new_path: location of the new rootfs 139662306a36Sopenharmony_ci * 139762306a36Sopenharmony_ci * Check permission before pivoting the root filesystem. 139862306a36Sopenharmony_ci * 139962306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 140062306a36Sopenharmony_ci */ 140162306a36Sopenharmony_ciint security_sb_pivotroot(const struct path *old_path, 140262306a36Sopenharmony_ci const struct path *new_path) 140362306a36Sopenharmony_ci{ 140462306a36Sopenharmony_ci return call_int_hook(sb_pivotroot, 0, old_path, new_path); 140562306a36Sopenharmony_ci} 140662306a36Sopenharmony_ci 140762306a36Sopenharmony_ci/** 140862306a36Sopenharmony_ci * security_sb_set_mnt_opts() - Set the mount options for a filesystem 140962306a36Sopenharmony_ci * @sb: filesystem superblock 141062306a36Sopenharmony_ci * @mnt_opts: binary mount options 141162306a36Sopenharmony_ci * @kern_flags: kernel flags (in) 141262306a36Sopenharmony_ci * @set_kern_flags: kernel flags (out) 141362306a36Sopenharmony_ci * 141462306a36Sopenharmony_ci * Set the security relevant mount options used for a superblock. 141562306a36Sopenharmony_ci * 141662306a36Sopenharmony_ci * Return: Returns 0 on success, error on failure. 141762306a36Sopenharmony_ci */ 141862306a36Sopenharmony_ciint security_sb_set_mnt_opts(struct super_block *sb, 141962306a36Sopenharmony_ci void *mnt_opts, 142062306a36Sopenharmony_ci unsigned long kern_flags, 142162306a36Sopenharmony_ci unsigned long *set_kern_flags) 142262306a36Sopenharmony_ci{ 142362306a36Sopenharmony_ci return call_int_hook(sb_set_mnt_opts, 142462306a36Sopenharmony_ci mnt_opts ? -EOPNOTSUPP : 0, sb, 142562306a36Sopenharmony_ci mnt_opts, kern_flags, set_kern_flags); 142662306a36Sopenharmony_ci} 142762306a36Sopenharmony_ciEXPORT_SYMBOL(security_sb_set_mnt_opts); 142862306a36Sopenharmony_ci 142962306a36Sopenharmony_ci/** 143062306a36Sopenharmony_ci * security_sb_clone_mnt_opts() - Duplicate superblock mount options 143162306a36Sopenharmony_ci * @oldsb: source superblock 143262306a36Sopenharmony_ci * @newsb: destination superblock 143362306a36Sopenharmony_ci * @kern_flags: kernel flags (in) 143462306a36Sopenharmony_ci * @set_kern_flags: kernel flags (out) 143562306a36Sopenharmony_ci * 143662306a36Sopenharmony_ci * Copy all security options from a given superblock to another. 143762306a36Sopenharmony_ci * 143862306a36Sopenharmony_ci * Return: Returns 0 on success, error on failure. 143962306a36Sopenharmony_ci */ 144062306a36Sopenharmony_ciint security_sb_clone_mnt_opts(const struct super_block *oldsb, 144162306a36Sopenharmony_ci struct super_block *newsb, 144262306a36Sopenharmony_ci unsigned long kern_flags, 144362306a36Sopenharmony_ci unsigned long *set_kern_flags) 144462306a36Sopenharmony_ci{ 144562306a36Sopenharmony_ci return call_int_hook(sb_clone_mnt_opts, 0, oldsb, newsb, 144662306a36Sopenharmony_ci kern_flags, set_kern_flags); 144762306a36Sopenharmony_ci} 144862306a36Sopenharmony_ciEXPORT_SYMBOL(security_sb_clone_mnt_opts); 144962306a36Sopenharmony_ci 145062306a36Sopenharmony_ci/** 145162306a36Sopenharmony_ci * security_move_mount() - Check permissions for moving a mount 145262306a36Sopenharmony_ci * @from_path: source mount point 145362306a36Sopenharmony_ci * @to_path: destination mount point 145462306a36Sopenharmony_ci * 145562306a36Sopenharmony_ci * Check permission before a mount is moved. 145662306a36Sopenharmony_ci * 145762306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 145862306a36Sopenharmony_ci */ 145962306a36Sopenharmony_ciint security_move_mount(const struct path *from_path, 146062306a36Sopenharmony_ci const struct path *to_path) 146162306a36Sopenharmony_ci{ 146262306a36Sopenharmony_ci return call_int_hook(move_mount, 0, from_path, to_path); 146362306a36Sopenharmony_ci} 146462306a36Sopenharmony_ci 146562306a36Sopenharmony_ci/** 146662306a36Sopenharmony_ci * security_path_notify() - Check if setting a watch is allowed 146762306a36Sopenharmony_ci * @path: file path 146862306a36Sopenharmony_ci * @mask: event mask 146962306a36Sopenharmony_ci * @obj_type: file path type 147062306a36Sopenharmony_ci * 147162306a36Sopenharmony_ci * Check permissions before setting a watch on events as defined by @mask, on 147262306a36Sopenharmony_ci * an object at @path, whose type is defined by @obj_type. 147362306a36Sopenharmony_ci * 147462306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 147562306a36Sopenharmony_ci */ 147662306a36Sopenharmony_ciint security_path_notify(const struct path *path, u64 mask, 147762306a36Sopenharmony_ci unsigned int obj_type) 147862306a36Sopenharmony_ci{ 147962306a36Sopenharmony_ci return call_int_hook(path_notify, 0, path, mask, obj_type); 148062306a36Sopenharmony_ci} 148162306a36Sopenharmony_ci 148262306a36Sopenharmony_ci/** 148362306a36Sopenharmony_ci * security_inode_alloc() - Allocate an inode LSM blob 148462306a36Sopenharmony_ci * @inode: the inode 148562306a36Sopenharmony_ci * 148662306a36Sopenharmony_ci * Allocate and attach a security structure to @inode->i_security. The 148762306a36Sopenharmony_ci * i_security field is initialized to NULL when the inode structure is 148862306a36Sopenharmony_ci * allocated. 148962306a36Sopenharmony_ci * 149062306a36Sopenharmony_ci * Return: Return 0 if operation was successful. 149162306a36Sopenharmony_ci */ 149262306a36Sopenharmony_ciint security_inode_alloc(struct inode *inode) 149362306a36Sopenharmony_ci{ 149462306a36Sopenharmony_ci int rc = lsm_inode_alloc(inode); 149562306a36Sopenharmony_ci 149662306a36Sopenharmony_ci if (unlikely(rc)) 149762306a36Sopenharmony_ci return rc; 149862306a36Sopenharmony_ci rc = call_int_hook(inode_alloc_security, 0, inode); 149962306a36Sopenharmony_ci if (unlikely(rc)) 150062306a36Sopenharmony_ci security_inode_free(inode); 150162306a36Sopenharmony_ci return rc; 150262306a36Sopenharmony_ci} 150362306a36Sopenharmony_ci 150462306a36Sopenharmony_cistatic void inode_free_by_rcu(struct rcu_head *head) 150562306a36Sopenharmony_ci{ 150662306a36Sopenharmony_ci /* 150762306a36Sopenharmony_ci * The rcu head is at the start of the inode blob 150862306a36Sopenharmony_ci */ 150962306a36Sopenharmony_ci kmem_cache_free(lsm_inode_cache, head); 151062306a36Sopenharmony_ci} 151162306a36Sopenharmony_ci 151262306a36Sopenharmony_ci/** 151362306a36Sopenharmony_ci * security_inode_free() - Free an inode's LSM blob 151462306a36Sopenharmony_ci * @inode: the inode 151562306a36Sopenharmony_ci * 151662306a36Sopenharmony_ci * Deallocate the inode security structure and set @inode->i_security to NULL. 151762306a36Sopenharmony_ci */ 151862306a36Sopenharmony_civoid security_inode_free(struct inode *inode) 151962306a36Sopenharmony_ci{ 152062306a36Sopenharmony_ci integrity_inode_free(inode); 152162306a36Sopenharmony_ci call_void_hook(inode_free_security, inode); 152262306a36Sopenharmony_ci /* 152362306a36Sopenharmony_ci * The inode may still be referenced in a path walk and 152462306a36Sopenharmony_ci * a call to security_inode_permission() can be made 152562306a36Sopenharmony_ci * after inode_free_security() is called. Ideally, the VFS 152662306a36Sopenharmony_ci * wouldn't do this, but fixing that is a much harder 152762306a36Sopenharmony_ci * job. For now, simply free the i_security via RCU, and 152862306a36Sopenharmony_ci * leave the current inode->i_security pointer intact. 152962306a36Sopenharmony_ci * The inode will be freed after the RCU grace period too. 153062306a36Sopenharmony_ci */ 153162306a36Sopenharmony_ci if (inode->i_security) 153262306a36Sopenharmony_ci call_rcu((struct rcu_head *)inode->i_security, 153362306a36Sopenharmony_ci inode_free_by_rcu); 153462306a36Sopenharmony_ci} 153562306a36Sopenharmony_ci 153662306a36Sopenharmony_ci/** 153762306a36Sopenharmony_ci * security_dentry_init_security() - Perform dentry initialization 153862306a36Sopenharmony_ci * @dentry: the dentry to initialize 153962306a36Sopenharmony_ci * @mode: mode used to determine resource type 154062306a36Sopenharmony_ci * @name: name of the last path component 154162306a36Sopenharmony_ci * @xattr_name: name of the security/LSM xattr 154262306a36Sopenharmony_ci * @ctx: pointer to the resulting LSM context 154362306a36Sopenharmony_ci * @ctxlen: length of @ctx 154462306a36Sopenharmony_ci * 154562306a36Sopenharmony_ci * Compute a context for a dentry as the inode is not yet available since NFSv4 154662306a36Sopenharmony_ci * has no label backed by an EA anyway. It is important to note that 154762306a36Sopenharmony_ci * @xattr_name does not need to be free'd by the caller, it is a static string. 154862306a36Sopenharmony_ci * 154962306a36Sopenharmony_ci * Return: Returns 0 on success, negative values on failure. 155062306a36Sopenharmony_ci */ 155162306a36Sopenharmony_ciint security_dentry_init_security(struct dentry *dentry, int mode, 155262306a36Sopenharmony_ci const struct qstr *name, 155362306a36Sopenharmony_ci const char **xattr_name, void **ctx, 155462306a36Sopenharmony_ci u32 *ctxlen) 155562306a36Sopenharmony_ci{ 155662306a36Sopenharmony_ci struct security_hook_list *hp; 155762306a36Sopenharmony_ci int rc; 155862306a36Sopenharmony_ci 155962306a36Sopenharmony_ci /* 156062306a36Sopenharmony_ci * Only one module will provide a security context. 156162306a36Sopenharmony_ci */ 156262306a36Sopenharmony_ci hlist_for_each_entry(hp, &security_hook_heads.dentry_init_security, 156362306a36Sopenharmony_ci list) { 156462306a36Sopenharmony_ci rc = hp->hook.dentry_init_security(dentry, mode, name, 156562306a36Sopenharmony_ci xattr_name, ctx, ctxlen); 156662306a36Sopenharmony_ci if (rc != LSM_RET_DEFAULT(dentry_init_security)) 156762306a36Sopenharmony_ci return rc; 156862306a36Sopenharmony_ci } 156962306a36Sopenharmony_ci return LSM_RET_DEFAULT(dentry_init_security); 157062306a36Sopenharmony_ci} 157162306a36Sopenharmony_ciEXPORT_SYMBOL(security_dentry_init_security); 157262306a36Sopenharmony_ci 157362306a36Sopenharmony_ci/** 157462306a36Sopenharmony_ci * security_dentry_create_files_as() - Perform dentry initialization 157562306a36Sopenharmony_ci * @dentry: the dentry to initialize 157662306a36Sopenharmony_ci * @mode: mode used to determine resource type 157762306a36Sopenharmony_ci * @name: name of the last path component 157862306a36Sopenharmony_ci * @old: creds to use for LSM context calculations 157962306a36Sopenharmony_ci * @new: creds to modify 158062306a36Sopenharmony_ci * 158162306a36Sopenharmony_ci * Compute a context for a dentry as the inode is not yet available and set 158262306a36Sopenharmony_ci * that context in passed in creds so that new files are created using that 158362306a36Sopenharmony_ci * context. Context is calculated using the passed in creds and not the creds 158462306a36Sopenharmony_ci * of the caller. 158562306a36Sopenharmony_ci * 158662306a36Sopenharmony_ci * Return: Returns 0 on success, error on failure. 158762306a36Sopenharmony_ci */ 158862306a36Sopenharmony_ciint security_dentry_create_files_as(struct dentry *dentry, int mode, 158962306a36Sopenharmony_ci struct qstr *name, 159062306a36Sopenharmony_ci const struct cred *old, struct cred *new) 159162306a36Sopenharmony_ci{ 159262306a36Sopenharmony_ci return call_int_hook(dentry_create_files_as, 0, dentry, mode, 159362306a36Sopenharmony_ci name, old, new); 159462306a36Sopenharmony_ci} 159562306a36Sopenharmony_ciEXPORT_SYMBOL(security_dentry_create_files_as); 159662306a36Sopenharmony_ci 159762306a36Sopenharmony_ci/** 159862306a36Sopenharmony_ci * security_inode_init_security() - Initialize an inode's LSM context 159962306a36Sopenharmony_ci * @inode: the inode 160062306a36Sopenharmony_ci * @dir: parent directory 160162306a36Sopenharmony_ci * @qstr: last component of the pathname 160262306a36Sopenharmony_ci * @initxattrs: callback function to write xattrs 160362306a36Sopenharmony_ci * @fs_data: filesystem specific data 160462306a36Sopenharmony_ci * 160562306a36Sopenharmony_ci * Obtain the security attribute name suffix and value to set on a newly 160662306a36Sopenharmony_ci * created inode and set up the incore security field for the new inode. This 160762306a36Sopenharmony_ci * hook is called by the fs code as part of the inode creation transaction and 160862306a36Sopenharmony_ci * provides for atomic labeling of the inode, unlike the post_create/mkdir/... 160962306a36Sopenharmony_ci * hooks called by the VFS. 161062306a36Sopenharmony_ci * 161162306a36Sopenharmony_ci * The hook function is expected to populate the xattrs array, by calling 161262306a36Sopenharmony_ci * lsm_get_xattr_slot() to retrieve the slots reserved by the security module 161362306a36Sopenharmony_ci * with the lbs_xattr_count field of the lsm_blob_sizes structure. For each 161462306a36Sopenharmony_ci * slot, the hook function should set ->name to the attribute name suffix 161562306a36Sopenharmony_ci * (e.g. selinux), to allocate ->value (will be freed by the caller) and set it 161662306a36Sopenharmony_ci * to the attribute value, to set ->value_len to the length of the value. If 161762306a36Sopenharmony_ci * the security module does not use security attributes or does not wish to put 161862306a36Sopenharmony_ci * a security attribute on this particular inode, then it should return 161962306a36Sopenharmony_ci * -EOPNOTSUPP to skip this processing. 162062306a36Sopenharmony_ci * 162162306a36Sopenharmony_ci * Return: Returns 0 if the LSM successfully initialized all of the inode 162262306a36Sopenharmony_ci * security attributes that are required, negative values otherwise. 162362306a36Sopenharmony_ci */ 162462306a36Sopenharmony_ciint security_inode_init_security(struct inode *inode, struct inode *dir, 162562306a36Sopenharmony_ci const struct qstr *qstr, 162662306a36Sopenharmony_ci const initxattrs initxattrs, void *fs_data) 162762306a36Sopenharmony_ci{ 162862306a36Sopenharmony_ci struct security_hook_list *hp; 162962306a36Sopenharmony_ci struct xattr *new_xattrs = NULL; 163062306a36Sopenharmony_ci int ret = -EOPNOTSUPP, xattr_count = 0; 163162306a36Sopenharmony_ci 163262306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(inode))) 163362306a36Sopenharmony_ci return 0; 163462306a36Sopenharmony_ci 163562306a36Sopenharmony_ci if (!blob_sizes.lbs_xattr_count) 163662306a36Sopenharmony_ci return 0; 163762306a36Sopenharmony_ci 163862306a36Sopenharmony_ci if (initxattrs) { 163962306a36Sopenharmony_ci /* Allocate +1 for EVM and +1 as terminator. */ 164062306a36Sopenharmony_ci new_xattrs = kcalloc(blob_sizes.lbs_xattr_count + 2, 164162306a36Sopenharmony_ci sizeof(*new_xattrs), GFP_NOFS); 164262306a36Sopenharmony_ci if (!new_xattrs) 164362306a36Sopenharmony_ci return -ENOMEM; 164462306a36Sopenharmony_ci } 164562306a36Sopenharmony_ci 164662306a36Sopenharmony_ci hlist_for_each_entry(hp, &security_hook_heads.inode_init_security, 164762306a36Sopenharmony_ci list) { 164862306a36Sopenharmony_ci ret = hp->hook.inode_init_security(inode, dir, qstr, new_xattrs, 164962306a36Sopenharmony_ci &xattr_count); 165062306a36Sopenharmony_ci if (ret && ret != -EOPNOTSUPP) 165162306a36Sopenharmony_ci goto out; 165262306a36Sopenharmony_ci /* 165362306a36Sopenharmony_ci * As documented in lsm_hooks.h, -EOPNOTSUPP in this context 165462306a36Sopenharmony_ci * means that the LSM is not willing to provide an xattr, not 165562306a36Sopenharmony_ci * that it wants to signal an error. Thus, continue to invoke 165662306a36Sopenharmony_ci * the remaining LSMs. 165762306a36Sopenharmony_ci */ 165862306a36Sopenharmony_ci } 165962306a36Sopenharmony_ci 166062306a36Sopenharmony_ci /* If initxattrs() is NULL, xattr_count is zero, skip the call. */ 166162306a36Sopenharmony_ci if (!xattr_count) 166262306a36Sopenharmony_ci goto out; 166362306a36Sopenharmony_ci 166462306a36Sopenharmony_ci ret = evm_inode_init_security(inode, dir, qstr, new_xattrs, 166562306a36Sopenharmony_ci &xattr_count); 166662306a36Sopenharmony_ci if (ret) 166762306a36Sopenharmony_ci goto out; 166862306a36Sopenharmony_ci ret = initxattrs(inode, new_xattrs, fs_data); 166962306a36Sopenharmony_ciout: 167062306a36Sopenharmony_ci for (; xattr_count > 0; xattr_count--) 167162306a36Sopenharmony_ci kfree(new_xattrs[xattr_count - 1].value); 167262306a36Sopenharmony_ci kfree(new_xattrs); 167362306a36Sopenharmony_ci return (ret == -EOPNOTSUPP) ? 0 : ret; 167462306a36Sopenharmony_ci} 167562306a36Sopenharmony_ciEXPORT_SYMBOL(security_inode_init_security); 167662306a36Sopenharmony_ci 167762306a36Sopenharmony_ci/** 167862306a36Sopenharmony_ci * security_inode_init_security_anon() - Initialize an anonymous inode 167962306a36Sopenharmony_ci * @inode: the inode 168062306a36Sopenharmony_ci * @name: the anonymous inode class 168162306a36Sopenharmony_ci * @context_inode: an optional related inode 168262306a36Sopenharmony_ci * 168362306a36Sopenharmony_ci * Set up the incore security field for the new anonymous inode and return 168462306a36Sopenharmony_ci * whether the inode creation is permitted by the security module or not. 168562306a36Sopenharmony_ci * 168662306a36Sopenharmony_ci * Return: Returns 0 on success, -EACCES if the security module denies the 168762306a36Sopenharmony_ci * creation of this inode, or another -errno upon other errors. 168862306a36Sopenharmony_ci */ 168962306a36Sopenharmony_ciint security_inode_init_security_anon(struct inode *inode, 169062306a36Sopenharmony_ci const struct qstr *name, 169162306a36Sopenharmony_ci const struct inode *context_inode) 169262306a36Sopenharmony_ci{ 169362306a36Sopenharmony_ci return call_int_hook(inode_init_security_anon, 0, inode, name, 169462306a36Sopenharmony_ci context_inode); 169562306a36Sopenharmony_ci} 169662306a36Sopenharmony_ci 169762306a36Sopenharmony_ci#ifdef CONFIG_SECURITY_PATH 169862306a36Sopenharmony_ci/** 169962306a36Sopenharmony_ci * security_path_mknod() - Check if creating a special file is allowed 170062306a36Sopenharmony_ci * @dir: parent directory 170162306a36Sopenharmony_ci * @dentry: new file 170262306a36Sopenharmony_ci * @mode: new file mode 170362306a36Sopenharmony_ci * @dev: device number 170462306a36Sopenharmony_ci * 170562306a36Sopenharmony_ci * Check permissions when creating a file. Note that this hook is called even 170662306a36Sopenharmony_ci * if mknod operation is being done for a regular file. 170762306a36Sopenharmony_ci * 170862306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 170962306a36Sopenharmony_ci */ 171062306a36Sopenharmony_ciint security_path_mknod(const struct path *dir, struct dentry *dentry, 171162306a36Sopenharmony_ci umode_t mode, unsigned int dev) 171262306a36Sopenharmony_ci{ 171362306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) 171462306a36Sopenharmony_ci return 0; 171562306a36Sopenharmony_ci return call_int_hook(path_mknod, 0, dir, dentry, mode, dev); 171662306a36Sopenharmony_ci} 171762306a36Sopenharmony_ciEXPORT_SYMBOL(security_path_mknod); 171862306a36Sopenharmony_ci 171962306a36Sopenharmony_ci/** 172062306a36Sopenharmony_ci * security_path_mkdir() - Check if creating a new directory is allowed 172162306a36Sopenharmony_ci * @dir: parent directory 172262306a36Sopenharmony_ci * @dentry: new directory 172362306a36Sopenharmony_ci * @mode: new directory mode 172462306a36Sopenharmony_ci * 172562306a36Sopenharmony_ci * Check permissions to create a new directory in the existing directory. 172662306a36Sopenharmony_ci * 172762306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 172862306a36Sopenharmony_ci */ 172962306a36Sopenharmony_ciint security_path_mkdir(const struct path *dir, struct dentry *dentry, 173062306a36Sopenharmony_ci umode_t mode) 173162306a36Sopenharmony_ci{ 173262306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) 173362306a36Sopenharmony_ci return 0; 173462306a36Sopenharmony_ci return call_int_hook(path_mkdir, 0, dir, dentry, mode); 173562306a36Sopenharmony_ci} 173662306a36Sopenharmony_ciEXPORT_SYMBOL(security_path_mkdir); 173762306a36Sopenharmony_ci 173862306a36Sopenharmony_ci/** 173962306a36Sopenharmony_ci * security_path_rmdir() - Check if removing a directory is allowed 174062306a36Sopenharmony_ci * @dir: parent directory 174162306a36Sopenharmony_ci * @dentry: directory to remove 174262306a36Sopenharmony_ci * 174362306a36Sopenharmony_ci * Check the permission to remove a directory. 174462306a36Sopenharmony_ci * 174562306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 174662306a36Sopenharmony_ci */ 174762306a36Sopenharmony_ciint security_path_rmdir(const struct path *dir, struct dentry *dentry) 174862306a36Sopenharmony_ci{ 174962306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) 175062306a36Sopenharmony_ci return 0; 175162306a36Sopenharmony_ci return call_int_hook(path_rmdir, 0, dir, dentry); 175262306a36Sopenharmony_ci} 175362306a36Sopenharmony_ci 175462306a36Sopenharmony_ci/** 175562306a36Sopenharmony_ci * security_path_unlink() - Check if removing a hard link is allowed 175662306a36Sopenharmony_ci * @dir: parent directory 175762306a36Sopenharmony_ci * @dentry: file 175862306a36Sopenharmony_ci * 175962306a36Sopenharmony_ci * Check the permission to remove a hard link to a file. 176062306a36Sopenharmony_ci * 176162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 176262306a36Sopenharmony_ci */ 176362306a36Sopenharmony_ciint security_path_unlink(const struct path *dir, struct dentry *dentry) 176462306a36Sopenharmony_ci{ 176562306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) 176662306a36Sopenharmony_ci return 0; 176762306a36Sopenharmony_ci return call_int_hook(path_unlink, 0, dir, dentry); 176862306a36Sopenharmony_ci} 176962306a36Sopenharmony_ciEXPORT_SYMBOL(security_path_unlink); 177062306a36Sopenharmony_ci 177162306a36Sopenharmony_ci/** 177262306a36Sopenharmony_ci * security_path_symlink() - Check if creating a symbolic link is allowed 177362306a36Sopenharmony_ci * @dir: parent directory 177462306a36Sopenharmony_ci * @dentry: symbolic link 177562306a36Sopenharmony_ci * @old_name: file pathname 177662306a36Sopenharmony_ci * 177762306a36Sopenharmony_ci * Check the permission to create a symbolic link to a file. 177862306a36Sopenharmony_ci * 177962306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 178062306a36Sopenharmony_ci */ 178162306a36Sopenharmony_ciint security_path_symlink(const struct path *dir, struct dentry *dentry, 178262306a36Sopenharmony_ci const char *old_name) 178362306a36Sopenharmony_ci{ 178462306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) 178562306a36Sopenharmony_ci return 0; 178662306a36Sopenharmony_ci return call_int_hook(path_symlink, 0, dir, dentry, old_name); 178762306a36Sopenharmony_ci} 178862306a36Sopenharmony_ci 178962306a36Sopenharmony_ci/** 179062306a36Sopenharmony_ci * security_path_link - Check if creating a hard link is allowed 179162306a36Sopenharmony_ci * @old_dentry: existing file 179262306a36Sopenharmony_ci * @new_dir: new parent directory 179362306a36Sopenharmony_ci * @new_dentry: new link 179462306a36Sopenharmony_ci * 179562306a36Sopenharmony_ci * Check permission before creating a new hard link to a file. 179662306a36Sopenharmony_ci * 179762306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 179862306a36Sopenharmony_ci */ 179962306a36Sopenharmony_ciint security_path_link(struct dentry *old_dentry, const struct path *new_dir, 180062306a36Sopenharmony_ci struct dentry *new_dentry) 180162306a36Sopenharmony_ci{ 180262306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)))) 180362306a36Sopenharmony_ci return 0; 180462306a36Sopenharmony_ci return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry); 180562306a36Sopenharmony_ci} 180662306a36Sopenharmony_ci 180762306a36Sopenharmony_ci/** 180862306a36Sopenharmony_ci * security_path_rename() - Check if renaming a file is allowed 180962306a36Sopenharmony_ci * @old_dir: parent directory of the old file 181062306a36Sopenharmony_ci * @old_dentry: the old file 181162306a36Sopenharmony_ci * @new_dir: parent directory of the new file 181262306a36Sopenharmony_ci * @new_dentry: the new file 181362306a36Sopenharmony_ci * @flags: flags 181462306a36Sopenharmony_ci * 181562306a36Sopenharmony_ci * Check for permission to rename a file or directory. 181662306a36Sopenharmony_ci * 181762306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 181862306a36Sopenharmony_ci */ 181962306a36Sopenharmony_ciint security_path_rename(const struct path *old_dir, struct dentry *old_dentry, 182062306a36Sopenharmony_ci const struct path *new_dir, struct dentry *new_dentry, 182162306a36Sopenharmony_ci unsigned int flags) 182262306a36Sopenharmony_ci{ 182362306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)) || 182462306a36Sopenharmony_ci (d_is_positive(new_dentry) && 182562306a36Sopenharmony_ci IS_PRIVATE(d_backing_inode(new_dentry))))) 182662306a36Sopenharmony_ci return 0; 182762306a36Sopenharmony_ci 182862306a36Sopenharmony_ci return call_int_hook(path_rename, 0, old_dir, old_dentry, new_dir, 182962306a36Sopenharmony_ci new_dentry, flags); 183062306a36Sopenharmony_ci} 183162306a36Sopenharmony_ciEXPORT_SYMBOL(security_path_rename); 183262306a36Sopenharmony_ci 183362306a36Sopenharmony_ci/** 183462306a36Sopenharmony_ci * security_path_truncate() - Check if truncating a file is allowed 183562306a36Sopenharmony_ci * @path: file 183662306a36Sopenharmony_ci * 183762306a36Sopenharmony_ci * Check permission before truncating the file indicated by path. Note that 183862306a36Sopenharmony_ci * truncation permissions may also be checked based on already opened files, 183962306a36Sopenharmony_ci * using the security_file_truncate() hook. 184062306a36Sopenharmony_ci * 184162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 184262306a36Sopenharmony_ci */ 184362306a36Sopenharmony_ciint security_path_truncate(const struct path *path) 184462306a36Sopenharmony_ci{ 184562306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry)))) 184662306a36Sopenharmony_ci return 0; 184762306a36Sopenharmony_ci return call_int_hook(path_truncate, 0, path); 184862306a36Sopenharmony_ci} 184962306a36Sopenharmony_ci 185062306a36Sopenharmony_ci/** 185162306a36Sopenharmony_ci * security_path_chmod() - Check if changing the file's mode is allowed 185262306a36Sopenharmony_ci * @path: file 185362306a36Sopenharmony_ci * @mode: new mode 185462306a36Sopenharmony_ci * 185562306a36Sopenharmony_ci * Check for permission to change a mode of the file @path. The new mode is 185662306a36Sopenharmony_ci * specified in @mode which is a bitmask of constants from 185762306a36Sopenharmony_ci * <include/uapi/linux/stat.h>. 185862306a36Sopenharmony_ci * 185962306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 186062306a36Sopenharmony_ci */ 186162306a36Sopenharmony_ciint security_path_chmod(const struct path *path, umode_t mode) 186262306a36Sopenharmony_ci{ 186362306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry)))) 186462306a36Sopenharmony_ci return 0; 186562306a36Sopenharmony_ci return call_int_hook(path_chmod, 0, path, mode); 186662306a36Sopenharmony_ci} 186762306a36Sopenharmony_ci 186862306a36Sopenharmony_ci/** 186962306a36Sopenharmony_ci * security_path_chown() - Check if changing the file's owner/group is allowed 187062306a36Sopenharmony_ci * @path: file 187162306a36Sopenharmony_ci * @uid: file owner 187262306a36Sopenharmony_ci * @gid: file group 187362306a36Sopenharmony_ci * 187462306a36Sopenharmony_ci * Check for permission to change owner/group of a file or directory. 187562306a36Sopenharmony_ci * 187662306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 187762306a36Sopenharmony_ci */ 187862306a36Sopenharmony_ciint security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) 187962306a36Sopenharmony_ci{ 188062306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry)))) 188162306a36Sopenharmony_ci return 0; 188262306a36Sopenharmony_ci return call_int_hook(path_chown, 0, path, uid, gid); 188362306a36Sopenharmony_ci} 188462306a36Sopenharmony_ci 188562306a36Sopenharmony_ci/** 188662306a36Sopenharmony_ci * security_path_chroot() - Check if changing the root directory is allowed 188762306a36Sopenharmony_ci * @path: directory 188862306a36Sopenharmony_ci * 188962306a36Sopenharmony_ci * Check for permission to change root directory. 189062306a36Sopenharmony_ci * 189162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 189262306a36Sopenharmony_ci */ 189362306a36Sopenharmony_ciint security_path_chroot(const struct path *path) 189462306a36Sopenharmony_ci{ 189562306a36Sopenharmony_ci return call_int_hook(path_chroot, 0, path); 189662306a36Sopenharmony_ci} 189762306a36Sopenharmony_ci#endif /* CONFIG_SECURITY_PATH */ 189862306a36Sopenharmony_ci 189962306a36Sopenharmony_ci/** 190062306a36Sopenharmony_ci * security_inode_create() - Check if creating a file is allowed 190162306a36Sopenharmony_ci * @dir: the parent directory 190262306a36Sopenharmony_ci * @dentry: the file being created 190362306a36Sopenharmony_ci * @mode: requested file mode 190462306a36Sopenharmony_ci * 190562306a36Sopenharmony_ci * Check permission to create a regular file. 190662306a36Sopenharmony_ci * 190762306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 190862306a36Sopenharmony_ci */ 190962306a36Sopenharmony_ciint security_inode_create(struct inode *dir, struct dentry *dentry, 191062306a36Sopenharmony_ci umode_t mode) 191162306a36Sopenharmony_ci{ 191262306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(dir))) 191362306a36Sopenharmony_ci return 0; 191462306a36Sopenharmony_ci return call_int_hook(inode_create, 0, dir, dentry, mode); 191562306a36Sopenharmony_ci} 191662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(security_inode_create); 191762306a36Sopenharmony_ci 191862306a36Sopenharmony_ci/** 191962306a36Sopenharmony_ci * security_inode_link() - Check if creating a hard link is allowed 192062306a36Sopenharmony_ci * @old_dentry: existing file 192162306a36Sopenharmony_ci * @dir: new parent directory 192262306a36Sopenharmony_ci * @new_dentry: new link 192362306a36Sopenharmony_ci * 192462306a36Sopenharmony_ci * Check permission before creating a new hard link to a file. 192562306a36Sopenharmony_ci * 192662306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 192762306a36Sopenharmony_ci */ 192862306a36Sopenharmony_ciint security_inode_link(struct dentry *old_dentry, struct inode *dir, 192962306a36Sopenharmony_ci struct dentry *new_dentry) 193062306a36Sopenharmony_ci{ 193162306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)))) 193262306a36Sopenharmony_ci return 0; 193362306a36Sopenharmony_ci return call_int_hook(inode_link, 0, old_dentry, dir, new_dentry); 193462306a36Sopenharmony_ci} 193562306a36Sopenharmony_ci 193662306a36Sopenharmony_ci/** 193762306a36Sopenharmony_ci * security_inode_unlink() - Check if removing a hard link is allowed 193862306a36Sopenharmony_ci * @dir: parent directory 193962306a36Sopenharmony_ci * @dentry: file 194062306a36Sopenharmony_ci * 194162306a36Sopenharmony_ci * Check the permission to remove a hard link to a file. 194262306a36Sopenharmony_ci * 194362306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 194462306a36Sopenharmony_ci */ 194562306a36Sopenharmony_ciint security_inode_unlink(struct inode *dir, struct dentry *dentry) 194662306a36Sopenharmony_ci{ 194762306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) 194862306a36Sopenharmony_ci return 0; 194962306a36Sopenharmony_ci return call_int_hook(inode_unlink, 0, dir, dentry); 195062306a36Sopenharmony_ci} 195162306a36Sopenharmony_ci 195262306a36Sopenharmony_ci/** 195362306a36Sopenharmony_ci * security_inode_symlink() - Check if creating a symbolic link is allowed 195462306a36Sopenharmony_ci * @dir: parent directory 195562306a36Sopenharmony_ci * @dentry: symbolic link 195662306a36Sopenharmony_ci * @old_name: existing filename 195762306a36Sopenharmony_ci * 195862306a36Sopenharmony_ci * Check the permission to create a symbolic link to a file. 195962306a36Sopenharmony_ci * 196062306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 196162306a36Sopenharmony_ci */ 196262306a36Sopenharmony_ciint security_inode_symlink(struct inode *dir, struct dentry *dentry, 196362306a36Sopenharmony_ci const char *old_name) 196462306a36Sopenharmony_ci{ 196562306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(dir))) 196662306a36Sopenharmony_ci return 0; 196762306a36Sopenharmony_ci return call_int_hook(inode_symlink, 0, dir, dentry, old_name); 196862306a36Sopenharmony_ci} 196962306a36Sopenharmony_ci 197062306a36Sopenharmony_ci/** 197162306a36Sopenharmony_ci * security_inode_mkdir() - Check if creation a new director is allowed 197262306a36Sopenharmony_ci * @dir: parent directory 197362306a36Sopenharmony_ci * @dentry: new directory 197462306a36Sopenharmony_ci * @mode: new directory mode 197562306a36Sopenharmony_ci * 197662306a36Sopenharmony_ci * Check permissions to create a new directory in the existing directory 197762306a36Sopenharmony_ci * associated with inode structure @dir. 197862306a36Sopenharmony_ci * 197962306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 198062306a36Sopenharmony_ci */ 198162306a36Sopenharmony_ciint security_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) 198262306a36Sopenharmony_ci{ 198362306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(dir))) 198462306a36Sopenharmony_ci return 0; 198562306a36Sopenharmony_ci return call_int_hook(inode_mkdir, 0, dir, dentry, mode); 198662306a36Sopenharmony_ci} 198762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(security_inode_mkdir); 198862306a36Sopenharmony_ci 198962306a36Sopenharmony_ci/** 199062306a36Sopenharmony_ci * security_inode_rmdir() - Check if removing a directory is allowed 199162306a36Sopenharmony_ci * @dir: parent directory 199262306a36Sopenharmony_ci * @dentry: directory to be removed 199362306a36Sopenharmony_ci * 199462306a36Sopenharmony_ci * Check the permission to remove a directory. 199562306a36Sopenharmony_ci * 199662306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 199762306a36Sopenharmony_ci */ 199862306a36Sopenharmony_ciint security_inode_rmdir(struct inode *dir, struct dentry *dentry) 199962306a36Sopenharmony_ci{ 200062306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) 200162306a36Sopenharmony_ci return 0; 200262306a36Sopenharmony_ci return call_int_hook(inode_rmdir, 0, dir, dentry); 200362306a36Sopenharmony_ci} 200462306a36Sopenharmony_ci 200562306a36Sopenharmony_ci/** 200662306a36Sopenharmony_ci * security_inode_mknod() - Check if creating a special file is allowed 200762306a36Sopenharmony_ci * @dir: parent directory 200862306a36Sopenharmony_ci * @dentry: new file 200962306a36Sopenharmony_ci * @mode: new file mode 201062306a36Sopenharmony_ci * @dev: device number 201162306a36Sopenharmony_ci * 201262306a36Sopenharmony_ci * Check permissions when creating a special file (or a socket or a fifo file 201362306a36Sopenharmony_ci * created via the mknod system call). Note that if mknod operation is being 201462306a36Sopenharmony_ci * done for a regular file, then the create hook will be called and not this 201562306a36Sopenharmony_ci * hook. 201662306a36Sopenharmony_ci * 201762306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 201862306a36Sopenharmony_ci */ 201962306a36Sopenharmony_ciint security_inode_mknod(struct inode *dir, struct dentry *dentry, 202062306a36Sopenharmony_ci umode_t mode, dev_t dev) 202162306a36Sopenharmony_ci{ 202262306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(dir))) 202362306a36Sopenharmony_ci return 0; 202462306a36Sopenharmony_ci return call_int_hook(inode_mknod, 0, dir, dentry, mode, dev); 202562306a36Sopenharmony_ci} 202662306a36Sopenharmony_ci 202762306a36Sopenharmony_ci/** 202862306a36Sopenharmony_ci * security_inode_rename() - Check if renaming a file is allowed 202962306a36Sopenharmony_ci * @old_dir: parent directory of the old file 203062306a36Sopenharmony_ci * @old_dentry: the old file 203162306a36Sopenharmony_ci * @new_dir: parent directory of the new file 203262306a36Sopenharmony_ci * @new_dentry: the new file 203362306a36Sopenharmony_ci * @flags: flags 203462306a36Sopenharmony_ci * 203562306a36Sopenharmony_ci * Check for permission to rename a file or directory. 203662306a36Sopenharmony_ci * 203762306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 203862306a36Sopenharmony_ci */ 203962306a36Sopenharmony_ciint security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, 204062306a36Sopenharmony_ci struct inode *new_dir, struct dentry *new_dentry, 204162306a36Sopenharmony_ci unsigned int flags) 204262306a36Sopenharmony_ci{ 204362306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)) || 204462306a36Sopenharmony_ci (d_is_positive(new_dentry) && 204562306a36Sopenharmony_ci IS_PRIVATE(d_backing_inode(new_dentry))))) 204662306a36Sopenharmony_ci return 0; 204762306a36Sopenharmony_ci 204862306a36Sopenharmony_ci if (flags & RENAME_EXCHANGE) { 204962306a36Sopenharmony_ci int err = call_int_hook(inode_rename, 0, new_dir, new_dentry, 205062306a36Sopenharmony_ci old_dir, old_dentry); 205162306a36Sopenharmony_ci if (err) 205262306a36Sopenharmony_ci return err; 205362306a36Sopenharmony_ci } 205462306a36Sopenharmony_ci 205562306a36Sopenharmony_ci return call_int_hook(inode_rename, 0, old_dir, old_dentry, 205662306a36Sopenharmony_ci new_dir, new_dentry); 205762306a36Sopenharmony_ci} 205862306a36Sopenharmony_ci 205962306a36Sopenharmony_ci/** 206062306a36Sopenharmony_ci * security_inode_readlink() - Check if reading a symbolic link is allowed 206162306a36Sopenharmony_ci * @dentry: link 206262306a36Sopenharmony_ci * 206362306a36Sopenharmony_ci * Check the permission to read the symbolic link. 206462306a36Sopenharmony_ci * 206562306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 206662306a36Sopenharmony_ci */ 206762306a36Sopenharmony_ciint security_inode_readlink(struct dentry *dentry) 206862306a36Sopenharmony_ci{ 206962306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) 207062306a36Sopenharmony_ci return 0; 207162306a36Sopenharmony_ci return call_int_hook(inode_readlink, 0, dentry); 207262306a36Sopenharmony_ci} 207362306a36Sopenharmony_ci 207462306a36Sopenharmony_ci/** 207562306a36Sopenharmony_ci * security_inode_follow_link() - Check if following a symbolic link is allowed 207662306a36Sopenharmony_ci * @dentry: link dentry 207762306a36Sopenharmony_ci * @inode: link inode 207862306a36Sopenharmony_ci * @rcu: true if in RCU-walk mode 207962306a36Sopenharmony_ci * 208062306a36Sopenharmony_ci * Check permission to follow a symbolic link when looking up a pathname. If 208162306a36Sopenharmony_ci * @rcu is true, @inode is not stable. 208262306a36Sopenharmony_ci * 208362306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 208462306a36Sopenharmony_ci */ 208562306a36Sopenharmony_ciint security_inode_follow_link(struct dentry *dentry, struct inode *inode, 208662306a36Sopenharmony_ci bool rcu) 208762306a36Sopenharmony_ci{ 208862306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(inode))) 208962306a36Sopenharmony_ci return 0; 209062306a36Sopenharmony_ci return call_int_hook(inode_follow_link, 0, dentry, inode, rcu); 209162306a36Sopenharmony_ci} 209262306a36Sopenharmony_ci 209362306a36Sopenharmony_ci/** 209462306a36Sopenharmony_ci * security_inode_permission() - Check if accessing an inode is allowed 209562306a36Sopenharmony_ci * @inode: inode 209662306a36Sopenharmony_ci * @mask: access mask 209762306a36Sopenharmony_ci * 209862306a36Sopenharmony_ci * Check permission before accessing an inode. This hook is called by the 209962306a36Sopenharmony_ci * existing Linux permission function, so a security module can use it to 210062306a36Sopenharmony_ci * provide additional checking for existing Linux permission checks. Notice 210162306a36Sopenharmony_ci * that this hook is called when a file is opened (as well as many other 210262306a36Sopenharmony_ci * operations), whereas the file_security_ops permission hook is called when 210362306a36Sopenharmony_ci * the actual read/write operations are performed. 210462306a36Sopenharmony_ci * 210562306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 210662306a36Sopenharmony_ci */ 210762306a36Sopenharmony_ciint security_inode_permission(struct inode *inode, int mask) 210862306a36Sopenharmony_ci{ 210962306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(inode))) 211062306a36Sopenharmony_ci return 0; 211162306a36Sopenharmony_ci return call_int_hook(inode_permission, 0, inode, mask); 211262306a36Sopenharmony_ci} 211362306a36Sopenharmony_ci 211462306a36Sopenharmony_ci/** 211562306a36Sopenharmony_ci * security_inode_setattr() - Check if setting file attributes is allowed 211662306a36Sopenharmony_ci * @idmap: idmap of the mount 211762306a36Sopenharmony_ci * @dentry: file 211862306a36Sopenharmony_ci * @attr: new attributes 211962306a36Sopenharmony_ci * 212062306a36Sopenharmony_ci * Check permission before setting file attributes. Note that the kernel call 212162306a36Sopenharmony_ci * to notify_change is performed from several locations, whenever file 212262306a36Sopenharmony_ci * attributes change (such as when a file is truncated, chown/chmod operations, 212362306a36Sopenharmony_ci * transferring disk quotas, etc). 212462306a36Sopenharmony_ci * 212562306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 212662306a36Sopenharmony_ci */ 212762306a36Sopenharmony_ciint security_inode_setattr(struct mnt_idmap *idmap, 212862306a36Sopenharmony_ci struct dentry *dentry, struct iattr *attr) 212962306a36Sopenharmony_ci{ 213062306a36Sopenharmony_ci int ret; 213162306a36Sopenharmony_ci 213262306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) 213362306a36Sopenharmony_ci return 0; 213462306a36Sopenharmony_ci ret = call_int_hook(inode_setattr, 0, dentry, attr); 213562306a36Sopenharmony_ci if (ret) 213662306a36Sopenharmony_ci return ret; 213762306a36Sopenharmony_ci return evm_inode_setattr(idmap, dentry, attr); 213862306a36Sopenharmony_ci} 213962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(security_inode_setattr); 214062306a36Sopenharmony_ci 214162306a36Sopenharmony_ci/** 214262306a36Sopenharmony_ci * security_inode_getattr() - Check if getting file attributes is allowed 214362306a36Sopenharmony_ci * @path: file 214462306a36Sopenharmony_ci * 214562306a36Sopenharmony_ci * Check permission before obtaining file attributes. 214662306a36Sopenharmony_ci * 214762306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 214862306a36Sopenharmony_ci */ 214962306a36Sopenharmony_ciint security_inode_getattr(const struct path *path) 215062306a36Sopenharmony_ci{ 215162306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry)))) 215262306a36Sopenharmony_ci return 0; 215362306a36Sopenharmony_ci return call_int_hook(inode_getattr, 0, path); 215462306a36Sopenharmony_ci} 215562306a36Sopenharmony_ci 215662306a36Sopenharmony_ci/** 215762306a36Sopenharmony_ci * security_inode_setxattr() - Check if setting file xattrs is allowed 215862306a36Sopenharmony_ci * @idmap: idmap of the mount 215962306a36Sopenharmony_ci * @dentry: file 216062306a36Sopenharmony_ci * @name: xattr name 216162306a36Sopenharmony_ci * @value: xattr value 216262306a36Sopenharmony_ci * @size: size of xattr value 216362306a36Sopenharmony_ci * @flags: flags 216462306a36Sopenharmony_ci * 216562306a36Sopenharmony_ci * Check permission before setting the extended attributes. 216662306a36Sopenharmony_ci * 216762306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 216862306a36Sopenharmony_ci */ 216962306a36Sopenharmony_ciint security_inode_setxattr(struct mnt_idmap *idmap, 217062306a36Sopenharmony_ci struct dentry *dentry, const char *name, 217162306a36Sopenharmony_ci const void *value, size_t size, int flags) 217262306a36Sopenharmony_ci{ 217362306a36Sopenharmony_ci int ret; 217462306a36Sopenharmony_ci 217562306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) 217662306a36Sopenharmony_ci return 0; 217762306a36Sopenharmony_ci /* 217862306a36Sopenharmony_ci * SELinux and Smack integrate the cap call, 217962306a36Sopenharmony_ci * so assume that all LSMs supplying this call do so. 218062306a36Sopenharmony_ci */ 218162306a36Sopenharmony_ci ret = call_int_hook(inode_setxattr, 1, idmap, dentry, name, value, 218262306a36Sopenharmony_ci size, flags); 218362306a36Sopenharmony_ci 218462306a36Sopenharmony_ci if (ret == 1) 218562306a36Sopenharmony_ci ret = cap_inode_setxattr(dentry, name, value, size, flags); 218662306a36Sopenharmony_ci if (ret) 218762306a36Sopenharmony_ci return ret; 218862306a36Sopenharmony_ci ret = ima_inode_setxattr(dentry, name, value, size); 218962306a36Sopenharmony_ci if (ret) 219062306a36Sopenharmony_ci return ret; 219162306a36Sopenharmony_ci return evm_inode_setxattr(idmap, dentry, name, value, size); 219262306a36Sopenharmony_ci} 219362306a36Sopenharmony_ci 219462306a36Sopenharmony_ci/** 219562306a36Sopenharmony_ci * security_inode_set_acl() - Check if setting posix acls is allowed 219662306a36Sopenharmony_ci * @idmap: idmap of the mount 219762306a36Sopenharmony_ci * @dentry: file 219862306a36Sopenharmony_ci * @acl_name: acl name 219962306a36Sopenharmony_ci * @kacl: acl struct 220062306a36Sopenharmony_ci * 220162306a36Sopenharmony_ci * Check permission before setting posix acls, the posix acls in @kacl are 220262306a36Sopenharmony_ci * identified by @acl_name. 220362306a36Sopenharmony_ci * 220462306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 220562306a36Sopenharmony_ci */ 220662306a36Sopenharmony_ciint security_inode_set_acl(struct mnt_idmap *idmap, 220762306a36Sopenharmony_ci struct dentry *dentry, const char *acl_name, 220862306a36Sopenharmony_ci struct posix_acl *kacl) 220962306a36Sopenharmony_ci{ 221062306a36Sopenharmony_ci int ret; 221162306a36Sopenharmony_ci 221262306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) 221362306a36Sopenharmony_ci return 0; 221462306a36Sopenharmony_ci ret = call_int_hook(inode_set_acl, 0, idmap, dentry, acl_name, 221562306a36Sopenharmony_ci kacl); 221662306a36Sopenharmony_ci if (ret) 221762306a36Sopenharmony_ci return ret; 221862306a36Sopenharmony_ci ret = ima_inode_set_acl(idmap, dentry, acl_name, kacl); 221962306a36Sopenharmony_ci if (ret) 222062306a36Sopenharmony_ci return ret; 222162306a36Sopenharmony_ci return evm_inode_set_acl(idmap, dentry, acl_name, kacl); 222262306a36Sopenharmony_ci} 222362306a36Sopenharmony_ci 222462306a36Sopenharmony_ci/** 222562306a36Sopenharmony_ci * security_inode_get_acl() - Check if reading posix acls is allowed 222662306a36Sopenharmony_ci * @idmap: idmap of the mount 222762306a36Sopenharmony_ci * @dentry: file 222862306a36Sopenharmony_ci * @acl_name: acl name 222962306a36Sopenharmony_ci * 223062306a36Sopenharmony_ci * Check permission before getting osix acls, the posix acls are identified by 223162306a36Sopenharmony_ci * @acl_name. 223262306a36Sopenharmony_ci * 223362306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 223462306a36Sopenharmony_ci */ 223562306a36Sopenharmony_ciint security_inode_get_acl(struct mnt_idmap *idmap, 223662306a36Sopenharmony_ci struct dentry *dentry, const char *acl_name) 223762306a36Sopenharmony_ci{ 223862306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) 223962306a36Sopenharmony_ci return 0; 224062306a36Sopenharmony_ci return call_int_hook(inode_get_acl, 0, idmap, dentry, acl_name); 224162306a36Sopenharmony_ci} 224262306a36Sopenharmony_ci 224362306a36Sopenharmony_ci/** 224462306a36Sopenharmony_ci * security_inode_remove_acl() - Check if removing a posix acl is allowed 224562306a36Sopenharmony_ci * @idmap: idmap of the mount 224662306a36Sopenharmony_ci * @dentry: file 224762306a36Sopenharmony_ci * @acl_name: acl name 224862306a36Sopenharmony_ci * 224962306a36Sopenharmony_ci * Check permission before removing posix acls, the posix acls are identified 225062306a36Sopenharmony_ci * by @acl_name. 225162306a36Sopenharmony_ci * 225262306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 225362306a36Sopenharmony_ci */ 225462306a36Sopenharmony_ciint security_inode_remove_acl(struct mnt_idmap *idmap, 225562306a36Sopenharmony_ci struct dentry *dentry, const char *acl_name) 225662306a36Sopenharmony_ci{ 225762306a36Sopenharmony_ci int ret; 225862306a36Sopenharmony_ci 225962306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) 226062306a36Sopenharmony_ci return 0; 226162306a36Sopenharmony_ci ret = call_int_hook(inode_remove_acl, 0, idmap, dentry, acl_name); 226262306a36Sopenharmony_ci if (ret) 226362306a36Sopenharmony_ci return ret; 226462306a36Sopenharmony_ci ret = ima_inode_remove_acl(idmap, dentry, acl_name); 226562306a36Sopenharmony_ci if (ret) 226662306a36Sopenharmony_ci return ret; 226762306a36Sopenharmony_ci return evm_inode_remove_acl(idmap, dentry, acl_name); 226862306a36Sopenharmony_ci} 226962306a36Sopenharmony_ci 227062306a36Sopenharmony_ci/** 227162306a36Sopenharmony_ci * security_inode_post_setxattr() - Update the inode after a setxattr operation 227262306a36Sopenharmony_ci * @dentry: file 227362306a36Sopenharmony_ci * @name: xattr name 227462306a36Sopenharmony_ci * @value: xattr value 227562306a36Sopenharmony_ci * @size: xattr value size 227662306a36Sopenharmony_ci * @flags: flags 227762306a36Sopenharmony_ci * 227862306a36Sopenharmony_ci * Update inode security field after successful setxattr operation. 227962306a36Sopenharmony_ci */ 228062306a36Sopenharmony_civoid security_inode_post_setxattr(struct dentry *dentry, const char *name, 228162306a36Sopenharmony_ci const void *value, size_t size, int flags) 228262306a36Sopenharmony_ci{ 228362306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) 228462306a36Sopenharmony_ci return; 228562306a36Sopenharmony_ci call_void_hook(inode_post_setxattr, dentry, name, value, size, flags); 228662306a36Sopenharmony_ci evm_inode_post_setxattr(dentry, name, value, size); 228762306a36Sopenharmony_ci} 228862306a36Sopenharmony_ci 228962306a36Sopenharmony_ci/** 229062306a36Sopenharmony_ci * security_inode_getxattr() - Check if xattr access is allowed 229162306a36Sopenharmony_ci * @dentry: file 229262306a36Sopenharmony_ci * @name: xattr name 229362306a36Sopenharmony_ci * 229462306a36Sopenharmony_ci * Check permission before obtaining the extended attributes identified by 229562306a36Sopenharmony_ci * @name for @dentry. 229662306a36Sopenharmony_ci * 229762306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 229862306a36Sopenharmony_ci */ 229962306a36Sopenharmony_ciint security_inode_getxattr(struct dentry *dentry, const char *name) 230062306a36Sopenharmony_ci{ 230162306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) 230262306a36Sopenharmony_ci return 0; 230362306a36Sopenharmony_ci return call_int_hook(inode_getxattr, 0, dentry, name); 230462306a36Sopenharmony_ci} 230562306a36Sopenharmony_ci 230662306a36Sopenharmony_ci/** 230762306a36Sopenharmony_ci * security_inode_listxattr() - Check if listing xattrs is allowed 230862306a36Sopenharmony_ci * @dentry: file 230962306a36Sopenharmony_ci * 231062306a36Sopenharmony_ci * Check permission before obtaining the list of extended attribute names for 231162306a36Sopenharmony_ci * @dentry. 231262306a36Sopenharmony_ci * 231362306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 231462306a36Sopenharmony_ci */ 231562306a36Sopenharmony_ciint security_inode_listxattr(struct dentry *dentry) 231662306a36Sopenharmony_ci{ 231762306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) 231862306a36Sopenharmony_ci return 0; 231962306a36Sopenharmony_ci return call_int_hook(inode_listxattr, 0, dentry); 232062306a36Sopenharmony_ci} 232162306a36Sopenharmony_ci 232262306a36Sopenharmony_ci/** 232362306a36Sopenharmony_ci * security_inode_removexattr() - Check if removing an xattr is allowed 232462306a36Sopenharmony_ci * @idmap: idmap of the mount 232562306a36Sopenharmony_ci * @dentry: file 232662306a36Sopenharmony_ci * @name: xattr name 232762306a36Sopenharmony_ci * 232862306a36Sopenharmony_ci * Check permission before removing the extended attribute identified by @name 232962306a36Sopenharmony_ci * for @dentry. 233062306a36Sopenharmony_ci * 233162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 233262306a36Sopenharmony_ci */ 233362306a36Sopenharmony_ciint security_inode_removexattr(struct mnt_idmap *idmap, 233462306a36Sopenharmony_ci struct dentry *dentry, const char *name) 233562306a36Sopenharmony_ci{ 233662306a36Sopenharmony_ci int ret; 233762306a36Sopenharmony_ci 233862306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) 233962306a36Sopenharmony_ci return 0; 234062306a36Sopenharmony_ci /* 234162306a36Sopenharmony_ci * SELinux and Smack integrate the cap call, 234262306a36Sopenharmony_ci * so assume that all LSMs supplying this call do so. 234362306a36Sopenharmony_ci */ 234462306a36Sopenharmony_ci ret = call_int_hook(inode_removexattr, 1, idmap, dentry, name); 234562306a36Sopenharmony_ci if (ret == 1) 234662306a36Sopenharmony_ci ret = cap_inode_removexattr(idmap, dentry, name); 234762306a36Sopenharmony_ci if (ret) 234862306a36Sopenharmony_ci return ret; 234962306a36Sopenharmony_ci ret = ima_inode_removexattr(dentry, name); 235062306a36Sopenharmony_ci if (ret) 235162306a36Sopenharmony_ci return ret; 235262306a36Sopenharmony_ci return evm_inode_removexattr(idmap, dentry, name); 235362306a36Sopenharmony_ci} 235462306a36Sopenharmony_ci 235562306a36Sopenharmony_ci/** 235662306a36Sopenharmony_ci * security_inode_need_killpriv() - Check if security_inode_killpriv() required 235762306a36Sopenharmony_ci * @dentry: associated dentry 235862306a36Sopenharmony_ci * 235962306a36Sopenharmony_ci * Called when an inode has been changed to determine if 236062306a36Sopenharmony_ci * security_inode_killpriv() should be called. 236162306a36Sopenharmony_ci * 236262306a36Sopenharmony_ci * Return: Return <0 on error to abort the inode change operation, return 0 if 236362306a36Sopenharmony_ci * security_inode_killpriv() does not need to be called, return >0 if 236462306a36Sopenharmony_ci * security_inode_killpriv() does need to be called. 236562306a36Sopenharmony_ci */ 236662306a36Sopenharmony_ciint security_inode_need_killpriv(struct dentry *dentry) 236762306a36Sopenharmony_ci{ 236862306a36Sopenharmony_ci return call_int_hook(inode_need_killpriv, 0, dentry); 236962306a36Sopenharmony_ci} 237062306a36Sopenharmony_ci 237162306a36Sopenharmony_ci/** 237262306a36Sopenharmony_ci * security_inode_killpriv() - The setuid bit is removed, update LSM state 237362306a36Sopenharmony_ci * @idmap: idmap of the mount 237462306a36Sopenharmony_ci * @dentry: associated dentry 237562306a36Sopenharmony_ci * 237662306a36Sopenharmony_ci * The @dentry's setuid bit is being removed. Remove similar security labels. 237762306a36Sopenharmony_ci * Called with the dentry->d_inode->i_mutex held. 237862306a36Sopenharmony_ci * 237962306a36Sopenharmony_ci * Return: Return 0 on success. If error is returned, then the operation 238062306a36Sopenharmony_ci * causing setuid bit removal is failed. 238162306a36Sopenharmony_ci */ 238262306a36Sopenharmony_ciint security_inode_killpriv(struct mnt_idmap *idmap, 238362306a36Sopenharmony_ci struct dentry *dentry) 238462306a36Sopenharmony_ci{ 238562306a36Sopenharmony_ci return call_int_hook(inode_killpriv, 0, idmap, dentry); 238662306a36Sopenharmony_ci} 238762306a36Sopenharmony_ci 238862306a36Sopenharmony_ci/** 238962306a36Sopenharmony_ci * security_inode_getsecurity() - Get the xattr security label of an inode 239062306a36Sopenharmony_ci * @idmap: idmap of the mount 239162306a36Sopenharmony_ci * @inode: inode 239262306a36Sopenharmony_ci * @name: xattr name 239362306a36Sopenharmony_ci * @buffer: security label buffer 239462306a36Sopenharmony_ci * @alloc: allocation flag 239562306a36Sopenharmony_ci * 239662306a36Sopenharmony_ci * Retrieve a copy of the extended attribute representation of the security 239762306a36Sopenharmony_ci * label associated with @name for @inode via @buffer. Note that @name is the 239862306a36Sopenharmony_ci * remainder of the attribute name after the security prefix has been removed. 239962306a36Sopenharmony_ci * @alloc is used to specify if the call should return a value via the buffer 240062306a36Sopenharmony_ci * or just the value length. 240162306a36Sopenharmony_ci * 240262306a36Sopenharmony_ci * Return: Returns size of buffer on success. 240362306a36Sopenharmony_ci */ 240462306a36Sopenharmony_ciint security_inode_getsecurity(struct mnt_idmap *idmap, 240562306a36Sopenharmony_ci struct inode *inode, const char *name, 240662306a36Sopenharmony_ci void **buffer, bool alloc) 240762306a36Sopenharmony_ci{ 240862306a36Sopenharmony_ci struct security_hook_list *hp; 240962306a36Sopenharmony_ci int rc; 241062306a36Sopenharmony_ci 241162306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(inode))) 241262306a36Sopenharmony_ci return LSM_RET_DEFAULT(inode_getsecurity); 241362306a36Sopenharmony_ci /* 241462306a36Sopenharmony_ci * Only one module will provide an attribute with a given name. 241562306a36Sopenharmony_ci */ 241662306a36Sopenharmony_ci hlist_for_each_entry(hp, &security_hook_heads.inode_getsecurity, list) { 241762306a36Sopenharmony_ci rc = hp->hook.inode_getsecurity(idmap, inode, name, buffer, 241862306a36Sopenharmony_ci alloc); 241962306a36Sopenharmony_ci if (rc != LSM_RET_DEFAULT(inode_getsecurity)) 242062306a36Sopenharmony_ci return rc; 242162306a36Sopenharmony_ci } 242262306a36Sopenharmony_ci return LSM_RET_DEFAULT(inode_getsecurity); 242362306a36Sopenharmony_ci} 242462306a36Sopenharmony_ci 242562306a36Sopenharmony_ci/** 242662306a36Sopenharmony_ci * security_inode_setsecurity() - Set the xattr security label of an inode 242762306a36Sopenharmony_ci * @inode: inode 242862306a36Sopenharmony_ci * @name: xattr name 242962306a36Sopenharmony_ci * @value: security label 243062306a36Sopenharmony_ci * @size: length of security label 243162306a36Sopenharmony_ci * @flags: flags 243262306a36Sopenharmony_ci * 243362306a36Sopenharmony_ci * Set the security label associated with @name for @inode from the extended 243462306a36Sopenharmony_ci * attribute value @value. @size indicates the size of the @value in bytes. 243562306a36Sopenharmony_ci * @flags may be XATTR_CREATE, XATTR_REPLACE, or 0. Note that @name is the 243662306a36Sopenharmony_ci * remainder of the attribute name after the security. prefix has been removed. 243762306a36Sopenharmony_ci * 243862306a36Sopenharmony_ci * Return: Returns 0 on success. 243962306a36Sopenharmony_ci */ 244062306a36Sopenharmony_ciint security_inode_setsecurity(struct inode *inode, const char *name, 244162306a36Sopenharmony_ci const void *value, size_t size, int flags) 244262306a36Sopenharmony_ci{ 244362306a36Sopenharmony_ci struct security_hook_list *hp; 244462306a36Sopenharmony_ci int rc; 244562306a36Sopenharmony_ci 244662306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(inode))) 244762306a36Sopenharmony_ci return LSM_RET_DEFAULT(inode_setsecurity); 244862306a36Sopenharmony_ci /* 244962306a36Sopenharmony_ci * Only one module will provide an attribute with a given name. 245062306a36Sopenharmony_ci */ 245162306a36Sopenharmony_ci hlist_for_each_entry(hp, &security_hook_heads.inode_setsecurity, list) { 245262306a36Sopenharmony_ci rc = hp->hook.inode_setsecurity(inode, name, value, size, 245362306a36Sopenharmony_ci flags); 245462306a36Sopenharmony_ci if (rc != LSM_RET_DEFAULT(inode_setsecurity)) 245562306a36Sopenharmony_ci return rc; 245662306a36Sopenharmony_ci } 245762306a36Sopenharmony_ci return LSM_RET_DEFAULT(inode_setsecurity); 245862306a36Sopenharmony_ci} 245962306a36Sopenharmony_ci 246062306a36Sopenharmony_ci/** 246162306a36Sopenharmony_ci * security_inode_listsecurity() - List the xattr security label names 246262306a36Sopenharmony_ci * @inode: inode 246362306a36Sopenharmony_ci * @buffer: buffer 246462306a36Sopenharmony_ci * @buffer_size: size of buffer 246562306a36Sopenharmony_ci * 246662306a36Sopenharmony_ci * Copy the extended attribute names for the security labels associated with 246762306a36Sopenharmony_ci * @inode into @buffer. The maximum size of @buffer is specified by 246862306a36Sopenharmony_ci * @buffer_size. @buffer may be NULL to request the size of the buffer 246962306a36Sopenharmony_ci * required. 247062306a36Sopenharmony_ci * 247162306a36Sopenharmony_ci * Return: Returns number of bytes used/required on success. 247262306a36Sopenharmony_ci */ 247362306a36Sopenharmony_ciint security_inode_listsecurity(struct inode *inode, 247462306a36Sopenharmony_ci char *buffer, size_t buffer_size) 247562306a36Sopenharmony_ci{ 247662306a36Sopenharmony_ci if (unlikely(IS_PRIVATE(inode))) 247762306a36Sopenharmony_ci return 0; 247862306a36Sopenharmony_ci return call_int_hook(inode_listsecurity, 0, inode, buffer, buffer_size); 247962306a36Sopenharmony_ci} 248062306a36Sopenharmony_ciEXPORT_SYMBOL(security_inode_listsecurity); 248162306a36Sopenharmony_ci 248262306a36Sopenharmony_ci/** 248362306a36Sopenharmony_ci * security_inode_getsecid() - Get an inode's secid 248462306a36Sopenharmony_ci * @inode: inode 248562306a36Sopenharmony_ci * @secid: secid to return 248662306a36Sopenharmony_ci * 248762306a36Sopenharmony_ci * Get the secid associated with the node. In case of failure, @secid will be 248862306a36Sopenharmony_ci * set to zero. 248962306a36Sopenharmony_ci */ 249062306a36Sopenharmony_civoid security_inode_getsecid(struct inode *inode, u32 *secid) 249162306a36Sopenharmony_ci{ 249262306a36Sopenharmony_ci call_void_hook(inode_getsecid, inode, secid); 249362306a36Sopenharmony_ci} 249462306a36Sopenharmony_ci 249562306a36Sopenharmony_ci/** 249662306a36Sopenharmony_ci * security_inode_copy_up() - Create new creds for an overlayfs copy-up op 249762306a36Sopenharmony_ci * @src: union dentry of copy-up file 249862306a36Sopenharmony_ci * @new: newly created creds 249962306a36Sopenharmony_ci * 250062306a36Sopenharmony_ci * A file is about to be copied up from lower layer to upper layer of overlay 250162306a36Sopenharmony_ci * filesystem. Security module can prepare a set of new creds and modify as 250262306a36Sopenharmony_ci * need be and return new creds. Caller will switch to new creds temporarily to 250362306a36Sopenharmony_ci * create new file and release newly allocated creds. 250462306a36Sopenharmony_ci * 250562306a36Sopenharmony_ci * Return: Returns 0 on success or a negative error code on error. 250662306a36Sopenharmony_ci */ 250762306a36Sopenharmony_ciint security_inode_copy_up(struct dentry *src, struct cred **new) 250862306a36Sopenharmony_ci{ 250962306a36Sopenharmony_ci return call_int_hook(inode_copy_up, 0, src, new); 251062306a36Sopenharmony_ci} 251162306a36Sopenharmony_ciEXPORT_SYMBOL(security_inode_copy_up); 251262306a36Sopenharmony_ci 251362306a36Sopenharmony_ci/** 251462306a36Sopenharmony_ci * security_inode_copy_up_xattr() - Filter xattrs in an overlayfs copy-up op 251562306a36Sopenharmony_ci * @name: xattr name 251662306a36Sopenharmony_ci * 251762306a36Sopenharmony_ci * Filter the xattrs being copied up when a unioned file is copied up from a 251862306a36Sopenharmony_ci * lower layer to the union/overlay layer. The caller is responsible for 251962306a36Sopenharmony_ci * reading and writing the xattrs, this hook is merely a filter. 252062306a36Sopenharmony_ci * 252162306a36Sopenharmony_ci * Return: Returns 0 to accept the xattr, 1 to discard the xattr, -EOPNOTSUPP 252262306a36Sopenharmony_ci * if the security module does not know about attribute, or a negative 252362306a36Sopenharmony_ci * error code to abort the copy up. 252462306a36Sopenharmony_ci */ 252562306a36Sopenharmony_ciint security_inode_copy_up_xattr(const char *name) 252662306a36Sopenharmony_ci{ 252762306a36Sopenharmony_ci struct security_hook_list *hp; 252862306a36Sopenharmony_ci int rc; 252962306a36Sopenharmony_ci 253062306a36Sopenharmony_ci /* 253162306a36Sopenharmony_ci * The implementation can return 0 (accept the xattr), 1 (discard the 253262306a36Sopenharmony_ci * xattr), -EOPNOTSUPP if it does not know anything about the xattr or 253362306a36Sopenharmony_ci * any other error code in case of an error. 253462306a36Sopenharmony_ci */ 253562306a36Sopenharmony_ci hlist_for_each_entry(hp, 253662306a36Sopenharmony_ci &security_hook_heads.inode_copy_up_xattr, list) { 253762306a36Sopenharmony_ci rc = hp->hook.inode_copy_up_xattr(name); 253862306a36Sopenharmony_ci if (rc != LSM_RET_DEFAULT(inode_copy_up_xattr)) 253962306a36Sopenharmony_ci return rc; 254062306a36Sopenharmony_ci } 254162306a36Sopenharmony_ci 254262306a36Sopenharmony_ci return LSM_RET_DEFAULT(inode_copy_up_xattr); 254362306a36Sopenharmony_ci} 254462306a36Sopenharmony_ciEXPORT_SYMBOL(security_inode_copy_up_xattr); 254562306a36Sopenharmony_ci 254662306a36Sopenharmony_ci/** 254762306a36Sopenharmony_ci * security_kernfs_init_security() - Init LSM context for a kernfs node 254862306a36Sopenharmony_ci * @kn_dir: parent kernfs node 254962306a36Sopenharmony_ci * @kn: the kernfs node to initialize 255062306a36Sopenharmony_ci * 255162306a36Sopenharmony_ci * Initialize the security context of a newly created kernfs node based on its 255262306a36Sopenharmony_ci * own and its parent's attributes. 255362306a36Sopenharmony_ci * 255462306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 255562306a36Sopenharmony_ci */ 255662306a36Sopenharmony_ciint security_kernfs_init_security(struct kernfs_node *kn_dir, 255762306a36Sopenharmony_ci struct kernfs_node *kn) 255862306a36Sopenharmony_ci{ 255962306a36Sopenharmony_ci return call_int_hook(kernfs_init_security, 0, kn_dir, kn); 256062306a36Sopenharmony_ci} 256162306a36Sopenharmony_ci 256262306a36Sopenharmony_ci/** 256362306a36Sopenharmony_ci * security_file_permission() - Check file permissions 256462306a36Sopenharmony_ci * @file: file 256562306a36Sopenharmony_ci * @mask: requested permissions 256662306a36Sopenharmony_ci * 256762306a36Sopenharmony_ci * Check file permissions before accessing an open file. This hook is called 256862306a36Sopenharmony_ci * by various operations that read or write files. A security module can use 256962306a36Sopenharmony_ci * this hook to perform additional checking on these operations, e.g. to 257062306a36Sopenharmony_ci * revalidate permissions on use to support privilege bracketing or policy 257162306a36Sopenharmony_ci * changes. Notice that this hook is used when the actual read/write 257262306a36Sopenharmony_ci * operations are performed, whereas the inode_security_ops hook is called when 257362306a36Sopenharmony_ci * a file is opened (as well as many other operations). Although this hook can 257462306a36Sopenharmony_ci * be used to revalidate permissions for various system call operations that 257562306a36Sopenharmony_ci * read or write files, it does not address the revalidation of permissions for 257662306a36Sopenharmony_ci * memory-mapped files. Security modules must handle this separately if they 257762306a36Sopenharmony_ci * need such revalidation. 257862306a36Sopenharmony_ci * 257962306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 258062306a36Sopenharmony_ci */ 258162306a36Sopenharmony_ciint security_file_permission(struct file *file, int mask) 258262306a36Sopenharmony_ci{ 258362306a36Sopenharmony_ci int ret; 258462306a36Sopenharmony_ci 258562306a36Sopenharmony_ci ret = call_int_hook(file_permission, 0, file, mask); 258662306a36Sopenharmony_ci if (ret) 258762306a36Sopenharmony_ci return ret; 258862306a36Sopenharmony_ci 258962306a36Sopenharmony_ci return fsnotify_perm(file, mask); 259062306a36Sopenharmony_ci} 259162306a36Sopenharmony_ci 259262306a36Sopenharmony_ci/** 259362306a36Sopenharmony_ci * security_file_alloc() - Allocate and init a file's LSM blob 259462306a36Sopenharmony_ci * @file: the file 259562306a36Sopenharmony_ci * 259662306a36Sopenharmony_ci * Allocate and attach a security structure to the file->f_security field. The 259762306a36Sopenharmony_ci * security field is initialized to NULL when the structure is first created. 259862306a36Sopenharmony_ci * 259962306a36Sopenharmony_ci * Return: Return 0 if the hook is successful and permission is granted. 260062306a36Sopenharmony_ci */ 260162306a36Sopenharmony_ciint security_file_alloc(struct file *file) 260262306a36Sopenharmony_ci{ 260362306a36Sopenharmony_ci int rc = lsm_file_alloc(file); 260462306a36Sopenharmony_ci 260562306a36Sopenharmony_ci if (rc) 260662306a36Sopenharmony_ci return rc; 260762306a36Sopenharmony_ci rc = call_int_hook(file_alloc_security, 0, file); 260862306a36Sopenharmony_ci if (unlikely(rc)) 260962306a36Sopenharmony_ci security_file_free(file); 261062306a36Sopenharmony_ci return rc; 261162306a36Sopenharmony_ci} 261262306a36Sopenharmony_ci 261362306a36Sopenharmony_ci/** 261462306a36Sopenharmony_ci * security_file_free() - Free a file's LSM blob 261562306a36Sopenharmony_ci * @file: the file 261662306a36Sopenharmony_ci * 261762306a36Sopenharmony_ci * Deallocate and free any security structures stored in file->f_security. 261862306a36Sopenharmony_ci */ 261962306a36Sopenharmony_civoid security_file_free(struct file *file) 262062306a36Sopenharmony_ci{ 262162306a36Sopenharmony_ci void *blob; 262262306a36Sopenharmony_ci 262362306a36Sopenharmony_ci call_void_hook(file_free_security, file); 262462306a36Sopenharmony_ci 262562306a36Sopenharmony_ci blob = file->f_security; 262662306a36Sopenharmony_ci if (blob) { 262762306a36Sopenharmony_ci file->f_security = NULL; 262862306a36Sopenharmony_ci kmem_cache_free(lsm_file_cache, blob); 262962306a36Sopenharmony_ci } 263062306a36Sopenharmony_ci} 263162306a36Sopenharmony_ci 263262306a36Sopenharmony_ci/** 263362306a36Sopenharmony_ci * security_file_ioctl() - Check if an ioctl is allowed 263462306a36Sopenharmony_ci * @file: associated file 263562306a36Sopenharmony_ci * @cmd: ioctl cmd 263662306a36Sopenharmony_ci * @arg: ioctl arguments 263762306a36Sopenharmony_ci * 263862306a36Sopenharmony_ci * Check permission for an ioctl operation on @file. Note that @arg sometimes 263962306a36Sopenharmony_ci * represents a user space pointer; in other cases, it may be a simple integer 264062306a36Sopenharmony_ci * value. When @arg represents a user space pointer, it should never be used 264162306a36Sopenharmony_ci * by the security module. 264262306a36Sopenharmony_ci * 264362306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 264462306a36Sopenharmony_ci */ 264562306a36Sopenharmony_ciint security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 264662306a36Sopenharmony_ci{ 264762306a36Sopenharmony_ci return call_int_hook(file_ioctl, 0, file, cmd, arg); 264862306a36Sopenharmony_ci} 264962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(security_file_ioctl); 265062306a36Sopenharmony_ci 265162306a36Sopenharmony_ci/** 265262306a36Sopenharmony_ci * security_file_ioctl_compat() - Check if an ioctl is allowed in compat mode 265362306a36Sopenharmony_ci * @file: associated file 265462306a36Sopenharmony_ci * @cmd: ioctl cmd 265562306a36Sopenharmony_ci * @arg: ioctl arguments 265662306a36Sopenharmony_ci * 265762306a36Sopenharmony_ci * Compat version of security_file_ioctl() that correctly handles 32-bit 265862306a36Sopenharmony_ci * processes running on 64-bit kernels. 265962306a36Sopenharmony_ci * 266062306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 266162306a36Sopenharmony_ci */ 266262306a36Sopenharmony_ciint security_file_ioctl_compat(struct file *file, unsigned int cmd, 266362306a36Sopenharmony_ci unsigned long arg) 266462306a36Sopenharmony_ci{ 266562306a36Sopenharmony_ci return call_int_hook(file_ioctl_compat, 0, file, cmd, arg); 266662306a36Sopenharmony_ci} 266762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(security_file_ioctl_compat); 266862306a36Sopenharmony_ci 266962306a36Sopenharmony_cistatic inline unsigned long mmap_prot(struct file *file, unsigned long prot) 267062306a36Sopenharmony_ci{ 267162306a36Sopenharmony_ci /* 267262306a36Sopenharmony_ci * Does we have PROT_READ and does the application expect 267362306a36Sopenharmony_ci * it to imply PROT_EXEC? If not, nothing to talk about... 267462306a36Sopenharmony_ci */ 267562306a36Sopenharmony_ci if ((prot & (PROT_READ | PROT_EXEC)) != PROT_READ) 267662306a36Sopenharmony_ci return prot; 267762306a36Sopenharmony_ci if (!(current->personality & READ_IMPLIES_EXEC)) 267862306a36Sopenharmony_ci return prot; 267962306a36Sopenharmony_ci /* 268062306a36Sopenharmony_ci * if that's an anonymous mapping, let it. 268162306a36Sopenharmony_ci */ 268262306a36Sopenharmony_ci if (!file) 268362306a36Sopenharmony_ci return prot | PROT_EXEC; 268462306a36Sopenharmony_ci /* 268562306a36Sopenharmony_ci * ditto if it's not on noexec mount, except that on !MMU we need 268662306a36Sopenharmony_ci * NOMMU_MAP_EXEC (== VM_MAYEXEC) in this case 268762306a36Sopenharmony_ci */ 268862306a36Sopenharmony_ci if (!path_noexec(&file->f_path)) { 268962306a36Sopenharmony_ci#ifndef CONFIG_MMU 269062306a36Sopenharmony_ci if (file->f_op->mmap_capabilities) { 269162306a36Sopenharmony_ci unsigned caps = file->f_op->mmap_capabilities(file); 269262306a36Sopenharmony_ci if (!(caps & NOMMU_MAP_EXEC)) 269362306a36Sopenharmony_ci return prot; 269462306a36Sopenharmony_ci } 269562306a36Sopenharmony_ci#endif 269662306a36Sopenharmony_ci return prot | PROT_EXEC; 269762306a36Sopenharmony_ci } 269862306a36Sopenharmony_ci /* anything on noexec mount won't get PROT_EXEC */ 269962306a36Sopenharmony_ci return prot; 270062306a36Sopenharmony_ci} 270162306a36Sopenharmony_ci 270262306a36Sopenharmony_ci/** 270362306a36Sopenharmony_ci * security_mmap_file() - Check if mmap'ing a file is allowed 270462306a36Sopenharmony_ci * @file: file 270562306a36Sopenharmony_ci * @prot: protection applied by the kernel 270662306a36Sopenharmony_ci * @flags: flags 270762306a36Sopenharmony_ci * 270862306a36Sopenharmony_ci * Check permissions for a mmap operation. The @file may be NULL, e.g. if 270962306a36Sopenharmony_ci * mapping anonymous memory. 271062306a36Sopenharmony_ci * 271162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 271262306a36Sopenharmony_ci */ 271362306a36Sopenharmony_ciint security_mmap_file(struct file *file, unsigned long prot, 271462306a36Sopenharmony_ci unsigned long flags) 271562306a36Sopenharmony_ci{ 271662306a36Sopenharmony_ci unsigned long prot_adj = mmap_prot(file, prot); 271762306a36Sopenharmony_ci int ret; 271862306a36Sopenharmony_ci 271962306a36Sopenharmony_ci ret = call_int_hook(mmap_file, 0, file, prot, prot_adj, flags); 272062306a36Sopenharmony_ci if (ret) 272162306a36Sopenharmony_ci return ret; 272262306a36Sopenharmony_ci return ima_file_mmap(file, prot, prot_adj, flags); 272362306a36Sopenharmony_ci} 272462306a36Sopenharmony_ci 272562306a36Sopenharmony_ci/** 272662306a36Sopenharmony_ci * security_mmap_addr() - Check if mmap'ing an address is allowed 272762306a36Sopenharmony_ci * @addr: address 272862306a36Sopenharmony_ci * 272962306a36Sopenharmony_ci * Check permissions for a mmap operation at @addr. 273062306a36Sopenharmony_ci * 273162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 273262306a36Sopenharmony_ci */ 273362306a36Sopenharmony_ciint security_mmap_addr(unsigned long addr) 273462306a36Sopenharmony_ci{ 273562306a36Sopenharmony_ci return call_int_hook(mmap_addr, 0, addr); 273662306a36Sopenharmony_ci} 273762306a36Sopenharmony_ci 273862306a36Sopenharmony_ci/** 273962306a36Sopenharmony_ci * security_file_mprotect() - Check if changing memory protections is allowed 274062306a36Sopenharmony_ci * @vma: memory region 274162306a36Sopenharmony_ci * @reqprot: application requested protection 274262306a36Sopenharmony_ci * @prot: protection applied by the kernel 274362306a36Sopenharmony_ci * 274462306a36Sopenharmony_ci * Check permissions before changing memory access permissions. 274562306a36Sopenharmony_ci * 274662306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 274762306a36Sopenharmony_ci */ 274862306a36Sopenharmony_ciint security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, 274962306a36Sopenharmony_ci unsigned long prot) 275062306a36Sopenharmony_ci{ 275162306a36Sopenharmony_ci int ret; 275262306a36Sopenharmony_ci 275362306a36Sopenharmony_ci ret = call_int_hook(file_mprotect, 0, vma, reqprot, prot); 275462306a36Sopenharmony_ci if (ret) 275562306a36Sopenharmony_ci return ret; 275662306a36Sopenharmony_ci return ima_file_mprotect(vma, prot); 275762306a36Sopenharmony_ci} 275862306a36Sopenharmony_ci 275962306a36Sopenharmony_ci/** 276062306a36Sopenharmony_ci * security_file_lock() - Check if a file lock is allowed 276162306a36Sopenharmony_ci * @file: file 276262306a36Sopenharmony_ci * @cmd: lock operation (e.g. F_RDLCK, F_WRLCK) 276362306a36Sopenharmony_ci * 276462306a36Sopenharmony_ci * Check permission before performing file locking operations. Note the hook 276562306a36Sopenharmony_ci * mediates both flock and fcntl style locks. 276662306a36Sopenharmony_ci * 276762306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 276862306a36Sopenharmony_ci */ 276962306a36Sopenharmony_ciint security_file_lock(struct file *file, unsigned int cmd) 277062306a36Sopenharmony_ci{ 277162306a36Sopenharmony_ci return call_int_hook(file_lock, 0, file, cmd); 277262306a36Sopenharmony_ci} 277362306a36Sopenharmony_ci 277462306a36Sopenharmony_ci/** 277562306a36Sopenharmony_ci * security_file_fcntl() - Check if fcntl() op is allowed 277662306a36Sopenharmony_ci * @file: file 277762306a36Sopenharmony_ci * @cmd: fcntl command 277862306a36Sopenharmony_ci * @arg: command argument 277962306a36Sopenharmony_ci * 278062306a36Sopenharmony_ci * Check permission before allowing the file operation specified by @cmd from 278162306a36Sopenharmony_ci * being performed on the file @file. Note that @arg sometimes represents a 278262306a36Sopenharmony_ci * user space pointer; in other cases, it may be a simple integer value. When 278362306a36Sopenharmony_ci * @arg represents a user space pointer, it should never be used by the 278462306a36Sopenharmony_ci * security module. 278562306a36Sopenharmony_ci * 278662306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 278762306a36Sopenharmony_ci */ 278862306a36Sopenharmony_ciint security_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg) 278962306a36Sopenharmony_ci{ 279062306a36Sopenharmony_ci return call_int_hook(file_fcntl, 0, file, cmd, arg); 279162306a36Sopenharmony_ci} 279262306a36Sopenharmony_ci 279362306a36Sopenharmony_ci/** 279462306a36Sopenharmony_ci * security_file_set_fowner() - Set the file owner info in the LSM blob 279562306a36Sopenharmony_ci * @file: the file 279662306a36Sopenharmony_ci * 279762306a36Sopenharmony_ci * Save owner security information (typically from current->security) in 279862306a36Sopenharmony_ci * file->f_security for later use by the send_sigiotask hook. 279962306a36Sopenharmony_ci * 280062306a36Sopenharmony_ci * Return: Returns 0 on success. 280162306a36Sopenharmony_ci */ 280262306a36Sopenharmony_civoid security_file_set_fowner(struct file *file) 280362306a36Sopenharmony_ci{ 280462306a36Sopenharmony_ci call_void_hook(file_set_fowner, file); 280562306a36Sopenharmony_ci} 280662306a36Sopenharmony_ci 280762306a36Sopenharmony_ci/** 280862306a36Sopenharmony_ci * security_file_send_sigiotask() - Check if sending SIGIO/SIGURG is allowed 280962306a36Sopenharmony_ci * @tsk: target task 281062306a36Sopenharmony_ci * @fown: signal sender 281162306a36Sopenharmony_ci * @sig: signal to be sent, SIGIO is sent if 0 281262306a36Sopenharmony_ci * 281362306a36Sopenharmony_ci * Check permission for the file owner @fown to send SIGIO or SIGURG to the 281462306a36Sopenharmony_ci * process @tsk. Note that this hook is sometimes called from interrupt. Note 281562306a36Sopenharmony_ci * that the fown_struct, @fown, is never outside the context of a struct file, 281662306a36Sopenharmony_ci * so the file structure (and associated security information) can always be 281762306a36Sopenharmony_ci * obtained: container_of(fown, struct file, f_owner). 281862306a36Sopenharmony_ci * 281962306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 282062306a36Sopenharmony_ci */ 282162306a36Sopenharmony_ciint security_file_send_sigiotask(struct task_struct *tsk, 282262306a36Sopenharmony_ci struct fown_struct *fown, int sig) 282362306a36Sopenharmony_ci{ 282462306a36Sopenharmony_ci return call_int_hook(file_send_sigiotask, 0, tsk, fown, sig); 282562306a36Sopenharmony_ci} 282662306a36Sopenharmony_ci 282762306a36Sopenharmony_ci/** 282862306a36Sopenharmony_ci * security_file_receive() - Check is receiving a file via IPC is allowed 282962306a36Sopenharmony_ci * @file: file being received 283062306a36Sopenharmony_ci * 283162306a36Sopenharmony_ci * This hook allows security modules to control the ability of a process to 283262306a36Sopenharmony_ci * receive an open file descriptor via socket IPC. 283362306a36Sopenharmony_ci * 283462306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 283562306a36Sopenharmony_ci */ 283662306a36Sopenharmony_ciint security_file_receive(struct file *file) 283762306a36Sopenharmony_ci{ 283862306a36Sopenharmony_ci return call_int_hook(file_receive, 0, file); 283962306a36Sopenharmony_ci} 284062306a36Sopenharmony_ci 284162306a36Sopenharmony_ci/** 284262306a36Sopenharmony_ci * security_file_open() - Save open() time state for late use by the LSM 284362306a36Sopenharmony_ci * @file: 284462306a36Sopenharmony_ci * 284562306a36Sopenharmony_ci * Save open-time permission checking state for later use upon file_permission, 284662306a36Sopenharmony_ci * and recheck access if anything has changed since inode_permission. 284762306a36Sopenharmony_ci * 284862306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 284962306a36Sopenharmony_ci */ 285062306a36Sopenharmony_ciint security_file_open(struct file *file) 285162306a36Sopenharmony_ci{ 285262306a36Sopenharmony_ci int ret; 285362306a36Sopenharmony_ci 285462306a36Sopenharmony_ci ret = call_int_hook(file_open, 0, file); 285562306a36Sopenharmony_ci if (ret) 285662306a36Sopenharmony_ci return ret; 285762306a36Sopenharmony_ci 285862306a36Sopenharmony_ci return fsnotify_perm(file, MAY_OPEN); 285962306a36Sopenharmony_ci} 286062306a36Sopenharmony_ci 286162306a36Sopenharmony_ci/** 286262306a36Sopenharmony_ci * security_file_truncate() - Check if truncating a file is allowed 286362306a36Sopenharmony_ci * @file: file 286462306a36Sopenharmony_ci * 286562306a36Sopenharmony_ci * Check permission before truncating a file, i.e. using ftruncate. Note that 286662306a36Sopenharmony_ci * truncation permission may also be checked based on the path, using the 286762306a36Sopenharmony_ci * @path_truncate hook. 286862306a36Sopenharmony_ci * 286962306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 287062306a36Sopenharmony_ci */ 287162306a36Sopenharmony_ciint security_file_truncate(struct file *file) 287262306a36Sopenharmony_ci{ 287362306a36Sopenharmony_ci return call_int_hook(file_truncate, 0, file); 287462306a36Sopenharmony_ci} 287562306a36Sopenharmony_ci 287662306a36Sopenharmony_ci/** 287762306a36Sopenharmony_ci * security_task_alloc() - Allocate a task's LSM blob 287862306a36Sopenharmony_ci * @task: the task 287962306a36Sopenharmony_ci * @clone_flags: flags indicating what is being shared 288062306a36Sopenharmony_ci * 288162306a36Sopenharmony_ci * Handle allocation of task-related resources. 288262306a36Sopenharmony_ci * 288362306a36Sopenharmony_ci * Return: Returns a zero on success, negative values on failure. 288462306a36Sopenharmony_ci */ 288562306a36Sopenharmony_ciint security_task_alloc(struct task_struct *task, unsigned long clone_flags) 288662306a36Sopenharmony_ci{ 288762306a36Sopenharmony_ci int rc = lsm_task_alloc(task); 288862306a36Sopenharmony_ci 288962306a36Sopenharmony_ci if (rc) 289062306a36Sopenharmony_ci return rc; 289162306a36Sopenharmony_ci rc = call_int_hook(task_alloc, 0, task, clone_flags); 289262306a36Sopenharmony_ci if (unlikely(rc)) 289362306a36Sopenharmony_ci security_task_free(task); 289462306a36Sopenharmony_ci return rc; 289562306a36Sopenharmony_ci} 289662306a36Sopenharmony_ci 289762306a36Sopenharmony_ci/** 289862306a36Sopenharmony_ci * security_task_free() - Free a task's LSM blob and related resources 289962306a36Sopenharmony_ci * @task: task 290062306a36Sopenharmony_ci * 290162306a36Sopenharmony_ci * Handle release of task-related resources. Note that this can be called from 290262306a36Sopenharmony_ci * interrupt context. 290362306a36Sopenharmony_ci */ 290462306a36Sopenharmony_civoid security_task_free(struct task_struct *task) 290562306a36Sopenharmony_ci{ 290662306a36Sopenharmony_ci call_void_hook(task_free, task); 290762306a36Sopenharmony_ci 290862306a36Sopenharmony_ci kfree(task->security); 290962306a36Sopenharmony_ci task->security = NULL; 291062306a36Sopenharmony_ci} 291162306a36Sopenharmony_ci 291262306a36Sopenharmony_ci/** 291362306a36Sopenharmony_ci * security_cred_alloc_blank() - Allocate the min memory to allow cred_transfer 291462306a36Sopenharmony_ci * @cred: credentials 291562306a36Sopenharmony_ci * @gfp: gfp flags 291662306a36Sopenharmony_ci * 291762306a36Sopenharmony_ci * Only allocate sufficient memory and attach to @cred such that 291862306a36Sopenharmony_ci * cred_transfer() will not get ENOMEM. 291962306a36Sopenharmony_ci * 292062306a36Sopenharmony_ci * Return: Returns 0 on success, negative values on failure. 292162306a36Sopenharmony_ci */ 292262306a36Sopenharmony_ciint security_cred_alloc_blank(struct cred *cred, gfp_t gfp) 292362306a36Sopenharmony_ci{ 292462306a36Sopenharmony_ci int rc = lsm_cred_alloc(cred, gfp); 292562306a36Sopenharmony_ci 292662306a36Sopenharmony_ci if (rc) 292762306a36Sopenharmony_ci return rc; 292862306a36Sopenharmony_ci 292962306a36Sopenharmony_ci rc = call_int_hook(cred_alloc_blank, 0, cred, gfp); 293062306a36Sopenharmony_ci if (unlikely(rc)) 293162306a36Sopenharmony_ci security_cred_free(cred); 293262306a36Sopenharmony_ci return rc; 293362306a36Sopenharmony_ci} 293462306a36Sopenharmony_ci 293562306a36Sopenharmony_ci/** 293662306a36Sopenharmony_ci * security_cred_free() - Free the cred's LSM blob and associated resources 293762306a36Sopenharmony_ci * @cred: credentials 293862306a36Sopenharmony_ci * 293962306a36Sopenharmony_ci * Deallocate and clear the cred->security field in a set of credentials. 294062306a36Sopenharmony_ci */ 294162306a36Sopenharmony_civoid security_cred_free(struct cred *cred) 294262306a36Sopenharmony_ci{ 294362306a36Sopenharmony_ci /* 294462306a36Sopenharmony_ci * There is a failure case in prepare_creds() that 294562306a36Sopenharmony_ci * may result in a call here with ->security being NULL. 294662306a36Sopenharmony_ci */ 294762306a36Sopenharmony_ci if (unlikely(cred->security == NULL)) 294862306a36Sopenharmony_ci return; 294962306a36Sopenharmony_ci 295062306a36Sopenharmony_ci call_void_hook(cred_free, cred); 295162306a36Sopenharmony_ci 295262306a36Sopenharmony_ci kfree(cred->security); 295362306a36Sopenharmony_ci cred->security = NULL; 295462306a36Sopenharmony_ci} 295562306a36Sopenharmony_ci 295662306a36Sopenharmony_ci/** 295762306a36Sopenharmony_ci * security_prepare_creds() - Prepare a new set of credentials 295862306a36Sopenharmony_ci * @new: new credentials 295962306a36Sopenharmony_ci * @old: original credentials 296062306a36Sopenharmony_ci * @gfp: gfp flags 296162306a36Sopenharmony_ci * 296262306a36Sopenharmony_ci * Prepare a new set of credentials by copying the data from the old set. 296362306a36Sopenharmony_ci * 296462306a36Sopenharmony_ci * Return: Returns 0 on success, negative values on failure. 296562306a36Sopenharmony_ci */ 296662306a36Sopenharmony_ciint security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp) 296762306a36Sopenharmony_ci{ 296862306a36Sopenharmony_ci int rc = lsm_cred_alloc(new, gfp); 296962306a36Sopenharmony_ci 297062306a36Sopenharmony_ci if (rc) 297162306a36Sopenharmony_ci return rc; 297262306a36Sopenharmony_ci 297362306a36Sopenharmony_ci rc = call_int_hook(cred_prepare, 0, new, old, gfp); 297462306a36Sopenharmony_ci if (unlikely(rc)) 297562306a36Sopenharmony_ci security_cred_free(new); 297662306a36Sopenharmony_ci return rc; 297762306a36Sopenharmony_ci} 297862306a36Sopenharmony_ci 297962306a36Sopenharmony_ci/** 298062306a36Sopenharmony_ci * security_transfer_creds() - Transfer creds 298162306a36Sopenharmony_ci * @new: target credentials 298262306a36Sopenharmony_ci * @old: original credentials 298362306a36Sopenharmony_ci * 298462306a36Sopenharmony_ci * Transfer data from original creds to new creds. 298562306a36Sopenharmony_ci */ 298662306a36Sopenharmony_civoid security_transfer_creds(struct cred *new, const struct cred *old) 298762306a36Sopenharmony_ci{ 298862306a36Sopenharmony_ci call_void_hook(cred_transfer, new, old); 298962306a36Sopenharmony_ci} 299062306a36Sopenharmony_ci 299162306a36Sopenharmony_ci/** 299262306a36Sopenharmony_ci * security_cred_getsecid() - Get the secid from a set of credentials 299362306a36Sopenharmony_ci * @c: credentials 299462306a36Sopenharmony_ci * @secid: secid value 299562306a36Sopenharmony_ci * 299662306a36Sopenharmony_ci * Retrieve the security identifier of the cred structure @c. In case of 299762306a36Sopenharmony_ci * failure, @secid will be set to zero. 299862306a36Sopenharmony_ci */ 299962306a36Sopenharmony_civoid security_cred_getsecid(const struct cred *c, u32 *secid) 300062306a36Sopenharmony_ci{ 300162306a36Sopenharmony_ci *secid = 0; 300262306a36Sopenharmony_ci call_void_hook(cred_getsecid, c, secid); 300362306a36Sopenharmony_ci} 300462306a36Sopenharmony_ciEXPORT_SYMBOL(security_cred_getsecid); 300562306a36Sopenharmony_ci 300662306a36Sopenharmony_ci/** 300762306a36Sopenharmony_ci * security_kernel_act_as() - Set the kernel credentials to act as secid 300862306a36Sopenharmony_ci * @new: credentials 300962306a36Sopenharmony_ci * @secid: secid 301062306a36Sopenharmony_ci * 301162306a36Sopenharmony_ci * Set the credentials for a kernel service to act as (subjective context). 301262306a36Sopenharmony_ci * The current task must be the one that nominated @secid. 301362306a36Sopenharmony_ci * 301462306a36Sopenharmony_ci * Return: Returns 0 if successful. 301562306a36Sopenharmony_ci */ 301662306a36Sopenharmony_ciint security_kernel_act_as(struct cred *new, u32 secid) 301762306a36Sopenharmony_ci{ 301862306a36Sopenharmony_ci return call_int_hook(kernel_act_as, 0, new, secid); 301962306a36Sopenharmony_ci} 302062306a36Sopenharmony_ci 302162306a36Sopenharmony_ci/** 302262306a36Sopenharmony_ci * security_kernel_create_files_as() - Set file creation context using an inode 302362306a36Sopenharmony_ci * @new: target credentials 302462306a36Sopenharmony_ci * @inode: reference inode 302562306a36Sopenharmony_ci * 302662306a36Sopenharmony_ci * Set the file creation context in a set of credentials to be the same as the 302762306a36Sopenharmony_ci * objective context of the specified inode. The current task must be the one 302862306a36Sopenharmony_ci * that nominated @inode. 302962306a36Sopenharmony_ci * 303062306a36Sopenharmony_ci * Return: Returns 0 if successful. 303162306a36Sopenharmony_ci */ 303262306a36Sopenharmony_ciint security_kernel_create_files_as(struct cred *new, struct inode *inode) 303362306a36Sopenharmony_ci{ 303462306a36Sopenharmony_ci return call_int_hook(kernel_create_files_as, 0, new, inode); 303562306a36Sopenharmony_ci} 303662306a36Sopenharmony_ci 303762306a36Sopenharmony_ci/** 303862306a36Sopenharmony_ci * security_kernel_module_request() - Check is loading a module is allowed 303962306a36Sopenharmony_ci * @kmod_name: module name 304062306a36Sopenharmony_ci * 304162306a36Sopenharmony_ci * Ability to trigger the kernel to automatically upcall to userspace for 304262306a36Sopenharmony_ci * userspace to load a kernel module with the given name. 304362306a36Sopenharmony_ci * 304462306a36Sopenharmony_ci * Return: Returns 0 if successful. 304562306a36Sopenharmony_ci */ 304662306a36Sopenharmony_ciint security_kernel_module_request(char *kmod_name) 304762306a36Sopenharmony_ci{ 304862306a36Sopenharmony_ci int ret; 304962306a36Sopenharmony_ci 305062306a36Sopenharmony_ci ret = call_int_hook(kernel_module_request, 0, kmod_name); 305162306a36Sopenharmony_ci if (ret) 305262306a36Sopenharmony_ci return ret; 305362306a36Sopenharmony_ci return integrity_kernel_module_request(kmod_name); 305462306a36Sopenharmony_ci} 305562306a36Sopenharmony_ci 305662306a36Sopenharmony_ci/** 305762306a36Sopenharmony_ci * security_kernel_read_file() - Read a file specified by userspace 305862306a36Sopenharmony_ci * @file: file 305962306a36Sopenharmony_ci * @id: file identifier 306062306a36Sopenharmony_ci * @contents: trust if security_kernel_post_read_file() will be called 306162306a36Sopenharmony_ci * 306262306a36Sopenharmony_ci * Read a file specified by userspace. 306362306a36Sopenharmony_ci * 306462306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 306562306a36Sopenharmony_ci */ 306662306a36Sopenharmony_ciint security_kernel_read_file(struct file *file, enum kernel_read_file_id id, 306762306a36Sopenharmony_ci bool contents) 306862306a36Sopenharmony_ci{ 306962306a36Sopenharmony_ci int ret; 307062306a36Sopenharmony_ci 307162306a36Sopenharmony_ci ret = call_int_hook(kernel_read_file, 0, file, id, contents); 307262306a36Sopenharmony_ci if (ret) 307362306a36Sopenharmony_ci return ret; 307462306a36Sopenharmony_ci return ima_read_file(file, id, contents); 307562306a36Sopenharmony_ci} 307662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(security_kernel_read_file); 307762306a36Sopenharmony_ci 307862306a36Sopenharmony_ci/** 307962306a36Sopenharmony_ci * security_kernel_post_read_file() - Read a file specified by userspace 308062306a36Sopenharmony_ci * @file: file 308162306a36Sopenharmony_ci * @buf: file contents 308262306a36Sopenharmony_ci * @size: size of file contents 308362306a36Sopenharmony_ci * @id: file identifier 308462306a36Sopenharmony_ci * 308562306a36Sopenharmony_ci * Read a file specified by userspace. This must be paired with a prior call 308662306a36Sopenharmony_ci * to security_kernel_read_file() call that indicated this hook would also be 308762306a36Sopenharmony_ci * called, see security_kernel_read_file() for more information. 308862306a36Sopenharmony_ci * 308962306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 309062306a36Sopenharmony_ci */ 309162306a36Sopenharmony_ciint security_kernel_post_read_file(struct file *file, char *buf, loff_t size, 309262306a36Sopenharmony_ci enum kernel_read_file_id id) 309362306a36Sopenharmony_ci{ 309462306a36Sopenharmony_ci int ret; 309562306a36Sopenharmony_ci 309662306a36Sopenharmony_ci ret = call_int_hook(kernel_post_read_file, 0, file, buf, size, id); 309762306a36Sopenharmony_ci if (ret) 309862306a36Sopenharmony_ci return ret; 309962306a36Sopenharmony_ci return ima_post_read_file(file, buf, size, id); 310062306a36Sopenharmony_ci} 310162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(security_kernel_post_read_file); 310262306a36Sopenharmony_ci 310362306a36Sopenharmony_ci/** 310462306a36Sopenharmony_ci * security_kernel_load_data() - Load data provided by userspace 310562306a36Sopenharmony_ci * @id: data identifier 310662306a36Sopenharmony_ci * @contents: true if security_kernel_post_load_data() will be called 310762306a36Sopenharmony_ci * 310862306a36Sopenharmony_ci * Load data provided by userspace. 310962306a36Sopenharmony_ci * 311062306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 311162306a36Sopenharmony_ci */ 311262306a36Sopenharmony_ciint security_kernel_load_data(enum kernel_load_data_id id, bool contents) 311362306a36Sopenharmony_ci{ 311462306a36Sopenharmony_ci int ret; 311562306a36Sopenharmony_ci 311662306a36Sopenharmony_ci ret = call_int_hook(kernel_load_data, 0, id, contents); 311762306a36Sopenharmony_ci if (ret) 311862306a36Sopenharmony_ci return ret; 311962306a36Sopenharmony_ci return ima_load_data(id, contents); 312062306a36Sopenharmony_ci} 312162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(security_kernel_load_data); 312262306a36Sopenharmony_ci 312362306a36Sopenharmony_ci/** 312462306a36Sopenharmony_ci * security_kernel_post_load_data() - Load userspace data from a non-file source 312562306a36Sopenharmony_ci * @buf: data 312662306a36Sopenharmony_ci * @size: size of data 312762306a36Sopenharmony_ci * @id: data identifier 312862306a36Sopenharmony_ci * @description: text description of data, specific to the id value 312962306a36Sopenharmony_ci * 313062306a36Sopenharmony_ci * Load data provided by a non-file source (usually userspace buffer). This 313162306a36Sopenharmony_ci * must be paired with a prior security_kernel_load_data() call that indicated 313262306a36Sopenharmony_ci * this hook would also be called, see security_kernel_load_data() for more 313362306a36Sopenharmony_ci * information. 313462306a36Sopenharmony_ci * 313562306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 313662306a36Sopenharmony_ci */ 313762306a36Sopenharmony_ciint security_kernel_post_load_data(char *buf, loff_t size, 313862306a36Sopenharmony_ci enum kernel_load_data_id id, 313962306a36Sopenharmony_ci char *description) 314062306a36Sopenharmony_ci{ 314162306a36Sopenharmony_ci int ret; 314262306a36Sopenharmony_ci 314362306a36Sopenharmony_ci ret = call_int_hook(kernel_post_load_data, 0, buf, size, id, 314462306a36Sopenharmony_ci description); 314562306a36Sopenharmony_ci if (ret) 314662306a36Sopenharmony_ci return ret; 314762306a36Sopenharmony_ci return ima_post_load_data(buf, size, id, description); 314862306a36Sopenharmony_ci} 314962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(security_kernel_post_load_data); 315062306a36Sopenharmony_ci 315162306a36Sopenharmony_ci/** 315262306a36Sopenharmony_ci * security_task_fix_setuid() - Update LSM with new user id attributes 315362306a36Sopenharmony_ci * @new: updated credentials 315462306a36Sopenharmony_ci * @old: credentials being replaced 315562306a36Sopenharmony_ci * @flags: LSM_SETID_* flag values 315662306a36Sopenharmony_ci * 315762306a36Sopenharmony_ci * Update the module's state after setting one or more of the user identity 315862306a36Sopenharmony_ci * attributes of the current process. The @flags parameter indicates which of 315962306a36Sopenharmony_ci * the set*uid system calls invoked this hook. If @new is the set of 316062306a36Sopenharmony_ci * credentials that will be installed. Modifications should be made to this 316162306a36Sopenharmony_ci * rather than to @current->cred. 316262306a36Sopenharmony_ci * 316362306a36Sopenharmony_ci * Return: Returns 0 on success. 316462306a36Sopenharmony_ci */ 316562306a36Sopenharmony_ciint security_task_fix_setuid(struct cred *new, const struct cred *old, 316662306a36Sopenharmony_ci int flags) 316762306a36Sopenharmony_ci{ 316862306a36Sopenharmony_ci return call_int_hook(task_fix_setuid, 0, new, old, flags); 316962306a36Sopenharmony_ci} 317062306a36Sopenharmony_ci 317162306a36Sopenharmony_ci/** 317262306a36Sopenharmony_ci * security_task_fix_setgid() - Update LSM with new group id attributes 317362306a36Sopenharmony_ci * @new: updated credentials 317462306a36Sopenharmony_ci * @old: credentials being replaced 317562306a36Sopenharmony_ci * @flags: LSM_SETID_* flag value 317662306a36Sopenharmony_ci * 317762306a36Sopenharmony_ci * Update the module's state after setting one or more of the group identity 317862306a36Sopenharmony_ci * attributes of the current process. The @flags parameter indicates which of 317962306a36Sopenharmony_ci * the set*gid system calls invoked this hook. @new is the set of credentials 318062306a36Sopenharmony_ci * that will be installed. Modifications should be made to this rather than to 318162306a36Sopenharmony_ci * @current->cred. 318262306a36Sopenharmony_ci * 318362306a36Sopenharmony_ci * Return: Returns 0 on success. 318462306a36Sopenharmony_ci */ 318562306a36Sopenharmony_ciint security_task_fix_setgid(struct cred *new, const struct cred *old, 318662306a36Sopenharmony_ci int flags) 318762306a36Sopenharmony_ci{ 318862306a36Sopenharmony_ci return call_int_hook(task_fix_setgid, 0, new, old, flags); 318962306a36Sopenharmony_ci} 319062306a36Sopenharmony_ci 319162306a36Sopenharmony_ci/** 319262306a36Sopenharmony_ci * security_task_fix_setgroups() - Update LSM with new supplementary groups 319362306a36Sopenharmony_ci * @new: updated credentials 319462306a36Sopenharmony_ci * @old: credentials being replaced 319562306a36Sopenharmony_ci * 319662306a36Sopenharmony_ci * Update the module's state after setting the supplementary group identity 319762306a36Sopenharmony_ci * attributes of the current process. @new is the set of credentials that will 319862306a36Sopenharmony_ci * be installed. Modifications should be made to this rather than to 319962306a36Sopenharmony_ci * @current->cred. 320062306a36Sopenharmony_ci * 320162306a36Sopenharmony_ci * Return: Returns 0 on success. 320262306a36Sopenharmony_ci */ 320362306a36Sopenharmony_ciint security_task_fix_setgroups(struct cred *new, const struct cred *old) 320462306a36Sopenharmony_ci{ 320562306a36Sopenharmony_ci return call_int_hook(task_fix_setgroups, 0, new, old); 320662306a36Sopenharmony_ci} 320762306a36Sopenharmony_ci 320862306a36Sopenharmony_ci/** 320962306a36Sopenharmony_ci * security_task_setpgid() - Check if setting the pgid is allowed 321062306a36Sopenharmony_ci * @p: task being modified 321162306a36Sopenharmony_ci * @pgid: new pgid 321262306a36Sopenharmony_ci * 321362306a36Sopenharmony_ci * Check permission before setting the process group identifier of the process 321462306a36Sopenharmony_ci * @p to @pgid. 321562306a36Sopenharmony_ci * 321662306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 321762306a36Sopenharmony_ci */ 321862306a36Sopenharmony_ciint security_task_setpgid(struct task_struct *p, pid_t pgid) 321962306a36Sopenharmony_ci{ 322062306a36Sopenharmony_ci return call_int_hook(task_setpgid, 0, p, pgid); 322162306a36Sopenharmony_ci} 322262306a36Sopenharmony_ci 322362306a36Sopenharmony_ci/** 322462306a36Sopenharmony_ci * security_task_getpgid() - Check if getting the pgid is allowed 322562306a36Sopenharmony_ci * @p: task 322662306a36Sopenharmony_ci * 322762306a36Sopenharmony_ci * Check permission before getting the process group identifier of the process 322862306a36Sopenharmony_ci * @p. 322962306a36Sopenharmony_ci * 323062306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 323162306a36Sopenharmony_ci */ 323262306a36Sopenharmony_ciint security_task_getpgid(struct task_struct *p) 323362306a36Sopenharmony_ci{ 323462306a36Sopenharmony_ci return call_int_hook(task_getpgid, 0, p); 323562306a36Sopenharmony_ci} 323662306a36Sopenharmony_ci 323762306a36Sopenharmony_ci/** 323862306a36Sopenharmony_ci * security_task_getsid() - Check if getting the session id is allowed 323962306a36Sopenharmony_ci * @p: task 324062306a36Sopenharmony_ci * 324162306a36Sopenharmony_ci * Check permission before getting the session identifier of the process @p. 324262306a36Sopenharmony_ci * 324362306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 324462306a36Sopenharmony_ci */ 324562306a36Sopenharmony_ciint security_task_getsid(struct task_struct *p) 324662306a36Sopenharmony_ci{ 324762306a36Sopenharmony_ci return call_int_hook(task_getsid, 0, p); 324862306a36Sopenharmony_ci} 324962306a36Sopenharmony_ci 325062306a36Sopenharmony_ci/** 325162306a36Sopenharmony_ci * security_current_getsecid_subj() - Get the current task's subjective secid 325262306a36Sopenharmony_ci * @secid: secid value 325362306a36Sopenharmony_ci * 325462306a36Sopenharmony_ci * Retrieve the subjective security identifier of the current task and return 325562306a36Sopenharmony_ci * it in @secid. In case of failure, @secid will be set to zero. 325662306a36Sopenharmony_ci */ 325762306a36Sopenharmony_civoid security_current_getsecid_subj(u32 *secid) 325862306a36Sopenharmony_ci{ 325962306a36Sopenharmony_ci *secid = 0; 326062306a36Sopenharmony_ci call_void_hook(current_getsecid_subj, secid); 326162306a36Sopenharmony_ci} 326262306a36Sopenharmony_ciEXPORT_SYMBOL(security_current_getsecid_subj); 326362306a36Sopenharmony_ci 326462306a36Sopenharmony_ci/** 326562306a36Sopenharmony_ci * security_task_getsecid_obj() - Get a task's objective secid 326662306a36Sopenharmony_ci * @p: target task 326762306a36Sopenharmony_ci * @secid: secid value 326862306a36Sopenharmony_ci * 326962306a36Sopenharmony_ci * Retrieve the objective security identifier of the task_struct in @p and 327062306a36Sopenharmony_ci * return it in @secid. In case of failure, @secid will be set to zero. 327162306a36Sopenharmony_ci */ 327262306a36Sopenharmony_civoid security_task_getsecid_obj(struct task_struct *p, u32 *secid) 327362306a36Sopenharmony_ci{ 327462306a36Sopenharmony_ci *secid = 0; 327562306a36Sopenharmony_ci call_void_hook(task_getsecid_obj, p, secid); 327662306a36Sopenharmony_ci} 327762306a36Sopenharmony_ciEXPORT_SYMBOL(security_task_getsecid_obj); 327862306a36Sopenharmony_ci 327962306a36Sopenharmony_ci/** 328062306a36Sopenharmony_ci * security_task_setnice() - Check if setting a task's nice value is allowed 328162306a36Sopenharmony_ci * @p: target task 328262306a36Sopenharmony_ci * @nice: nice value 328362306a36Sopenharmony_ci * 328462306a36Sopenharmony_ci * Check permission before setting the nice value of @p to @nice. 328562306a36Sopenharmony_ci * 328662306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 328762306a36Sopenharmony_ci */ 328862306a36Sopenharmony_ciint security_task_setnice(struct task_struct *p, int nice) 328962306a36Sopenharmony_ci{ 329062306a36Sopenharmony_ci return call_int_hook(task_setnice, 0, p, nice); 329162306a36Sopenharmony_ci} 329262306a36Sopenharmony_ci 329362306a36Sopenharmony_ci/** 329462306a36Sopenharmony_ci * security_task_setioprio() - Check if setting a task's ioprio is allowed 329562306a36Sopenharmony_ci * @p: target task 329662306a36Sopenharmony_ci * @ioprio: ioprio value 329762306a36Sopenharmony_ci * 329862306a36Sopenharmony_ci * Check permission before setting the ioprio value of @p to @ioprio. 329962306a36Sopenharmony_ci * 330062306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 330162306a36Sopenharmony_ci */ 330262306a36Sopenharmony_ciint security_task_setioprio(struct task_struct *p, int ioprio) 330362306a36Sopenharmony_ci{ 330462306a36Sopenharmony_ci return call_int_hook(task_setioprio, 0, p, ioprio); 330562306a36Sopenharmony_ci} 330662306a36Sopenharmony_ci 330762306a36Sopenharmony_ci/** 330862306a36Sopenharmony_ci * security_task_getioprio() - Check if getting a task's ioprio is allowed 330962306a36Sopenharmony_ci * @p: task 331062306a36Sopenharmony_ci * 331162306a36Sopenharmony_ci * Check permission before getting the ioprio value of @p. 331262306a36Sopenharmony_ci * 331362306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 331462306a36Sopenharmony_ci */ 331562306a36Sopenharmony_ciint security_task_getioprio(struct task_struct *p) 331662306a36Sopenharmony_ci{ 331762306a36Sopenharmony_ci return call_int_hook(task_getioprio, 0, p); 331862306a36Sopenharmony_ci} 331962306a36Sopenharmony_ci 332062306a36Sopenharmony_ci/** 332162306a36Sopenharmony_ci * security_task_prlimit() - Check if get/setting resources limits is allowed 332262306a36Sopenharmony_ci * @cred: current task credentials 332362306a36Sopenharmony_ci * @tcred: target task credentials 332462306a36Sopenharmony_ci * @flags: LSM_PRLIMIT_* flag bits indicating a get/set/both 332562306a36Sopenharmony_ci * 332662306a36Sopenharmony_ci * Check permission before getting and/or setting the resource limits of 332762306a36Sopenharmony_ci * another task. 332862306a36Sopenharmony_ci * 332962306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 333062306a36Sopenharmony_ci */ 333162306a36Sopenharmony_ciint security_task_prlimit(const struct cred *cred, const struct cred *tcred, 333262306a36Sopenharmony_ci unsigned int flags) 333362306a36Sopenharmony_ci{ 333462306a36Sopenharmony_ci return call_int_hook(task_prlimit, 0, cred, tcred, flags); 333562306a36Sopenharmony_ci} 333662306a36Sopenharmony_ci 333762306a36Sopenharmony_ci/** 333862306a36Sopenharmony_ci * security_task_setrlimit() - Check if setting a new rlimit value is allowed 333962306a36Sopenharmony_ci * @p: target task's group leader 334062306a36Sopenharmony_ci * @resource: resource whose limit is being set 334162306a36Sopenharmony_ci * @new_rlim: new resource limit 334262306a36Sopenharmony_ci * 334362306a36Sopenharmony_ci * Check permission before setting the resource limits of process @p for 334462306a36Sopenharmony_ci * @resource to @new_rlim. The old resource limit values can be examined by 334562306a36Sopenharmony_ci * dereferencing (p->signal->rlim + resource). 334662306a36Sopenharmony_ci * 334762306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 334862306a36Sopenharmony_ci */ 334962306a36Sopenharmony_ciint security_task_setrlimit(struct task_struct *p, unsigned int resource, 335062306a36Sopenharmony_ci struct rlimit *new_rlim) 335162306a36Sopenharmony_ci{ 335262306a36Sopenharmony_ci return call_int_hook(task_setrlimit, 0, p, resource, new_rlim); 335362306a36Sopenharmony_ci} 335462306a36Sopenharmony_ci 335562306a36Sopenharmony_ci/** 335662306a36Sopenharmony_ci * security_task_setscheduler() - Check if setting sched policy/param is allowed 335762306a36Sopenharmony_ci * @p: target task 335862306a36Sopenharmony_ci * 335962306a36Sopenharmony_ci * Check permission before setting scheduling policy and/or parameters of 336062306a36Sopenharmony_ci * process @p. 336162306a36Sopenharmony_ci * 336262306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 336362306a36Sopenharmony_ci */ 336462306a36Sopenharmony_ciint security_task_setscheduler(struct task_struct *p) 336562306a36Sopenharmony_ci{ 336662306a36Sopenharmony_ci return call_int_hook(task_setscheduler, 0, p); 336762306a36Sopenharmony_ci} 336862306a36Sopenharmony_ci 336962306a36Sopenharmony_ci/** 337062306a36Sopenharmony_ci * security_task_getscheduler() - Check if getting scheduling info is allowed 337162306a36Sopenharmony_ci * @p: target task 337262306a36Sopenharmony_ci * 337362306a36Sopenharmony_ci * Check permission before obtaining scheduling information for process @p. 337462306a36Sopenharmony_ci * 337562306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 337662306a36Sopenharmony_ci */ 337762306a36Sopenharmony_ciint security_task_getscheduler(struct task_struct *p) 337862306a36Sopenharmony_ci{ 337962306a36Sopenharmony_ci return call_int_hook(task_getscheduler, 0, p); 338062306a36Sopenharmony_ci} 338162306a36Sopenharmony_ci 338262306a36Sopenharmony_ci/** 338362306a36Sopenharmony_ci * security_task_movememory() - Check if moving memory is allowed 338462306a36Sopenharmony_ci * @p: task 338562306a36Sopenharmony_ci * 338662306a36Sopenharmony_ci * Check permission before moving memory owned by process @p. 338762306a36Sopenharmony_ci * 338862306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 338962306a36Sopenharmony_ci */ 339062306a36Sopenharmony_ciint security_task_movememory(struct task_struct *p) 339162306a36Sopenharmony_ci{ 339262306a36Sopenharmony_ci return call_int_hook(task_movememory, 0, p); 339362306a36Sopenharmony_ci} 339462306a36Sopenharmony_ci 339562306a36Sopenharmony_ci/** 339662306a36Sopenharmony_ci * security_task_kill() - Check if sending a signal is allowed 339762306a36Sopenharmony_ci * @p: target process 339862306a36Sopenharmony_ci * @info: signal information 339962306a36Sopenharmony_ci * @sig: signal value 340062306a36Sopenharmony_ci * @cred: credentials of the signal sender, NULL if @current 340162306a36Sopenharmony_ci * 340262306a36Sopenharmony_ci * Check permission before sending signal @sig to @p. @info can be NULL, the 340362306a36Sopenharmony_ci * constant 1, or a pointer to a kernel_siginfo structure. If @info is 1 or 340462306a36Sopenharmony_ci * SI_FROMKERNEL(info) is true, then the signal should be viewed as coming from 340562306a36Sopenharmony_ci * the kernel and should typically be permitted. SIGIO signals are handled 340662306a36Sopenharmony_ci * separately by the send_sigiotask hook in file_security_ops. 340762306a36Sopenharmony_ci * 340862306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 340962306a36Sopenharmony_ci */ 341062306a36Sopenharmony_ciint security_task_kill(struct task_struct *p, struct kernel_siginfo *info, 341162306a36Sopenharmony_ci int sig, const struct cred *cred) 341262306a36Sopenharmony_ci{ 341362306a36Sopenharmony_ci return call_int_hook(task_kill, 0, p, info, sig, cred); 341462306a36Sopenharmony_ci} 341562306a36Sopenharmony_ci 341662306a36Sopenharmony_ci/** 341762306a36Sopenharmony_ci * security_task_prctl() - Check if a prctl op is allowed 341862306a36Sopenharmony_ci * @option: operation 341962306a36Sopenharmony_ci * @arg2: argument 342062306a36Sopenharmony_ci * @arg3: argument 342162306a36Sopenharmony_ci * @arg4: argument 342262306a36Sopenharmony_ci * @arg5: argument 342362306a36Sopenharmony_ci * 342462306a36Sopenharmony_ci * Check permission before performing a process control operation on the 342562306a36Sopenharmony_ci * current process. 342662306a36Sopenharmony_ci * 342762306a36Sopenharmony_ci * Return: Return -ENOSYS if no-one wanted to handle this op, any other value 342862306a36Sopenharmony_ci * to cause prctl() to return immediately with that value. 342962306a36Sopenharmony_ci */ 343062306a36Sopenharmony_ciint security_task_prctl(int option, unsigned long arg2, unsigned long arg3, 343162306a36Sopenharmony_ci unsigned long arg4, unsigned long arg5) 343262306a36Sopenharmony_ci{ 343362306a36Sopenharmony_ci int thisrc; 343462306a36Sopenharmony_ci int rc = LSM_RET_DEFAULT(task_prctl); 343562306a36Sopenharmony_ci struct security_hook_list *hp; 343662306a36Sopenharmony_ci 343762306a36Sopenharmony_ci hlist_for_each_entry(hp, &security_hook_heads.task_prctl, list) { 343862306a36Sopenharmony_ci thisrc = hp->hook.task_prctl(option, arg2, arg3, arg4, arg5); 343962306a36Sopenharmony_ci if (thisrc != LSM_RET_DEFAULT(task_prctl)) { 344062306a36Sopenharmony_ci rc = thisrc; 344162306a36Sopenharmony_ci if (thisrc != 0) 344262306a36Sopenharmony_ci break; 344362306a36Sopenharmony_ci } 344462306a36Sopenharmony_ci } 344562306a36Sopenharmony_ci return rc; 344662306a36Sopenharmony_ci} 344762306a36Sopenharmony_ci 344862306a36Sopenharmony_ci/** 344962306a36Sopenharmony_ci * security_task_to_inode() - Set the security attributes of a task's inode 345062306a36Sopenharmony_ci * @p: task 345162306a36Sopenharmony_ci * @inode: inode 345262306a36Sopenharmony_ci * 345362306a36Sopenharmony_ci * Set the security attributes for an inode based on an associated task's 345462306a36Sopenharmony_ci * security attributes, e.g. for /proc/pid inodes. 345562306a36Sopenharmony_ci */ 345662306a36Sopenharmony_civoid security_task_to_inode(struct task_struct *p, struct inode *inode) 345762306a36Sopenharmony_ci{ 345862306a36Sopenharmony_ci call_void_hook(task_to_inode, p, inode); 345962306a36Sopenharmony_ci} 346062306a36Sopenharmony_ci 346162306a36Sopenharmony_ci/** 346262306a36Sopenharmony_ci * security_create_user_ns() - Check if creating a new userns is allowed 346362306a36Sopenharmony_ci * @cred: prepared creds 346462306a36Sopenharmony_ci * 346562306a36Sopenharmony_ci * Check permission prior to creating a new user namespace. 346662306a36Sopenharmony_ci * 346762306a36Sopenharmony_ci * Return: Returns 0 if successful, otherwise < 0 error code. 346862306a36Sopenharmony_ci */ 346962306a36Sopenharmony_ciint security_create_user_ns(const struct cred *cred) 347062306a36Sopenharmony_ci{ 347162306a36Sopenharmony_ci return call_int_hook(userns_create, 0, cred); 347262306a36Sopenharmony_ci} 347362306a36Sopenharmony_ci 347462306a36Sopenharmony_ci/** 347562306a36Sopenharmony_ci * security_ipc_permission() - Check if sysv ipc access is allowed 347662306a36Sopenharmony_ci * @ipcp: ipc permission structure 347762306a36Sopenharmony_ci * @flag: requested permissions 347862306a36Sopenharmony_ci * 347962306a36Sopenharmony_ci * Check permissions for access to IPC. 348062306a36Sopenharmony_ci * 348162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 348262306a36Sopenharmony_ci */ 348362306a36Sopenharmony_ciint security_ipc_permission(struct kern_ipc_perm *ipcp, short flag) 348462306a36Sopenharmony_ci{ 348562306a36Sopenharmony_ci return call_int_hook(ipc_permission, 0, ipcp, flag); 348662306a36Sopenharmony_ci} 348762306a36Sopenharmony_ci 348862306a36Sopenharmony_ci/** 348962306a36Sopenharmony_ci * security_ipc_getsecid() - Get the sysv ipc object's secid 349062306a36Sopenharmony_ci * @ipcp: ipc permission structure 349162306a36Sopenharmony_ci * @secid: secid pointer 349262306a36Sopenharmony_ci * 349362306a36Sopenharmony_ci * Get the secid associated with the ipc object. In case of failure, @secid 349462306a36Sopenharmony_ci * will be set to zero. 349562306a36Sopenharmony_ci */ 349662306a36Sopenharmony_civoid security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) 349762306a36Sopenharmony_ci{ 349862306a36Sopenharmony_ci *secid = 0; 349962306a36Sopenharmony_ci call_void_hook(ipc_getsecid, ipcp, secid); 350062306a36Sopenharmony_ci} 350162306a36Sopenharmony_ci 350262306a36Sopenharmony_ci/** 350362306a36Sopenharmony_ci * security_msg_msg_alloc() - Allocate a sysv ipc message LSM blob 350462306a36Sopenharmony_ci * @msg: message structure 350562306a36Sopenharmony_ci * 350662306a36Sopenharmony_ci * Allocate and attach a security structure to the msg->security field. The 350762306a36Sopenharmony_ci * security field is initialized to NULL when the structure is first created. 350862306a36Sopenharmony_ci * 350962306a36Sopenharmony_ci * Return: Return 0 if operation was successful and permission is granted. 351062306a36Sopenharmony_ci */ 351162306a36Sopenharmony_ciint security_msg_msg_alloc(struct msg_msg *msg) 351262306a36Sopenharmony_ci{ 351362306a36Sopenharmony_ci int rc = lsm_msg_msg_alloc(msg); 351462306a36Sopenharmony_ci 351562306a36Sopenharmony_ci if (unlikely(rc)) 351662306a36Sopenharmony_ci return rc; 351762306a36Sopenharmony_ci rc = call_int_hook(msg_msg_alloc_security, 0, msg); 351862306a36Sopenharmony_ci if (unlikely(rc)) 351962306a36Sopenharmony_ci security_msg_msg_free(msg); 352062306a36Sopenharmony_ci return rc; 352162306a36Sopenharmony_ci} 352262306a36Sopenharmony_ci 352362306a36Sopenharmony_ci/** 352462306a36Sopenharmony_ci * security_msg_msg_free() - Free a sysv ipc message LSM blob 352562306a36Sopenharmony_ci * @msg: message structure 352662306a36Sopenharmony_ci * 352762306a36Sopenharmony_ci * Deallocate the security structure for this message. 352862306a36Sopenharmony_ci */ 352962306a36Sopenharmony_civoid security_msg_msg_free(struct msg_msg *msg) 353062306a36Sopenharmony_ci{ 353162306a36Sopenharmony_ci call_void_hook(msg_msg_free_security, msg); 353262306a36Sopenharmony_ci kfree(msg->security); 353362306a36Sopenharmony_ci msg->security = NULL; 353462306a36Sopenharmony_ci} 353562306a36Sopenharmony_ci 353662306a36Sopenharmony_ci/** 353762306a36Sopenharmony_ci * security_msg_queue_alloc() - Allocate a sysv ipc msg queue LSM blob 353862306a36Sopenharmony_ci * @msq: sysv ipc permission structure 353962306a36Sopenharmony_ci * 354062306a36Sopenharmony_ci * Allocate and attach a security structure to @msg. The security field is 354162306a36Sopenharmony_ci * initialized to NULL when the structure is first created. 354262306a36Sopenharmony_ci * 354362306a36Sopenharmony_ci * Return: Returns 0 if operation was successful and permission is granted. 354462306a36Sopenharmony_ci */ 354562306a36Sopenharmony_ciint security_msg_queue_alloc(struct kern_ipc_perm *msq) 354662306a36Sopenharmony_ci{ 354762306a36Sopenharmony_ci int rc = lsm_ipc_alloc(msq); 354862306a36Sopenharmony_ci 354962306a36Sopenharmony_ci if (unlikely(rc)) 355062306a36Sopenharmony_ci return rc; 355162306a36Sopenharmony_ci rc = call_int_hook(msg_queue_alloc_security, 0, msq); 355262306a36Sopenharmony_ci if (unlikely(rc)) 355362306a36Sopenharmony_ci security_msg_queue_free(msq); 355462306a36Sopenharmony_ci return rc; 355562306a36Sopenharmony_ci} 355662306a36Sopenharmony_ci 355762306a36Sopenharmony_ci/** 355862306a36Sopenharmony_ci * security_msg_queue_free() - Free a sysv ipc msg queue LSM blob 355962306a36Sopenharmony_ci * @msq: sysv ipc permission structure 356062306a36Sopenharmony_ci * 356162306a36Sopenharmony_ci * Deallocate security field @perm->security for the message queue. 356262306a36Sopenharmony_ci */ 356362306a36Sopenharmony_civoid security_msg_queue_free(struct kern_ipc_perm *msq) 356462306a36Sopenharmony_ci{ 356562306a36Sopenharmony_ci call_void_hook(msg_queue_free_security, msq); 356662306a36Sopenharmony_ci kfree(msq->security); 356762306a36Sopenharmony_ci msq->security = NULL; 356862306a36Sopenharmony_ci} 356962306a36Sopenharmony_ci 357062306a36Sopenharmony_ci/** 357162306a36Sopenharmony_ci * security_msg_queue_associate() - Check if a msg queue operation is allowed 357262306a36Sopenharmony_ci * @msq: sysv ipc permission structure 357362306a36Sopenharmony_ci * @msqflg: operation flags 357462306a36Sopenharmony_ci * 357562306a36Sopenharmony_ci * Check permission when a message queue is requested through the msgget system 357662306a36Sopenharmony_ci * call. This hook is only called when returning the message queue identifier 357762306a36Sopenharmony_ci * for an existing message queue, not when a new message queue is created. 357862306a36Sopenharmony_ci * 357962306a36Sopenharmony_ci * Return: Return 0 if permission is granted. 358062306a36Sopenharmony_ci */ 358162306a36Sopenharmony_ciint security_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) 358262306a36Sopenharmony_ci{ 358362306a36Sopenharmony_ci return call_int_hook(msg_queue_associate, 0, msq, msqflg); 358462306a36Sopenharmony_ci} 358562306a36Sopenharmony_ci 358662306a36Sopenharmony_ci/** 358762306a36Sopenharmony_ci * security_msg_queue_msgctl() - Check if a msg queue operation is allowed 358862306a36Sopenharmony_ci * @msq: sysv ipc permission structure 358962306a36Sopenharmony_ci * @cmd: operation 359062306a36Sopenharmony_ci * 359162306a36Sopenharmony_ci * Check permission when a message control operation specified by @cmd is to be 359262306a36Sopenharmony_ci * performed on the message queue with permissions. 359362306a36Sopenharmony_ci * 359462306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 359562306a36Sopenharmony_ci */ 359662306a36Sopenharmony_ciint security_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd) 359762306a36Sopenharmony_ci{ 359862306a36Sopenharmony_ci return call_int_hook(msg_queue_msgctl, 0, msq, cmd); 359962306a36Sopenharmony_ci} 360062306a36Sopenharmony_ci 360162306a36Sopenharmony_ci/** 360262306a36Sopenharmony_ci * security_msg_queue_msgsnd() - Check if sending a sysv ipc message is allowed 360362306a36Sopenharmony_ci * @msq: sysv ipc permission structure 360462306a36Sopenharmony_ci * @msg: message 360562306a36Sopenharmony_ci * @msqflg: operation flags 360662306a36Sopenharmony_ci * 360762306a36Sopenharmony_ci * Check permission before a message, @msg, is enqueued on the message queue 360862306a36Sopenharmony_ci * with permissions specified in @msq. 360962306a36Sopenharmony_ci * 361062306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 361162306a36Sopenharmony_ci */ 361262306a36Sopenharmony_ciint security_msg_queue_msgsnd(struct kern_ipc_perm *msq, 361362306a36Sopenharmony_ci struct msg_msg *msg, int msqflg) 361462306a36Sopenharmony_ci{ 361562306a36Sopenharmony_ci return call_int_hook(msg_queue_msgsnd, 0, msq, msg, msqflg); 361662306a36Sopenharmony_ci} 361762306a36Sopenharmony_ci 361862306a36Sopenharmony_ci/** 361962306a36Sopenharmony_ci * security_msg_queue_msgrcv() - Check if receiving a sysv ipc msg is allowed 362062306a36Sopenharmony_ci * @msq: sysv ipc permission structure 362162306a36Sopenharmony_ci * @msg: message 362262306a36Sopenharmony_ci * @target: target task 362362306a36Sopenharmony_ci * @type: type of message requested 362462306a36Sopenharmony_ci * @mode: operation flags 362562306a36Sopenharmony_ci * 362662306a36Sopenharmony_ci * Check permission before a message, @msg, is removed from the message queue. 362762306a36Sopenharmony_ci * The @target task structure contains a pointer to the process that will be 362862306a36Sopenharmony_ci * receiving the message (not equal to the current process when inline receives 362962306a36Sopenharmony_ci * are being performed). 363062306a36Sopenharmony_ci * 363162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 363262306a36Sopenharmony_ci */ 363362306a36Sopenharmony_ciint security_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg, 363462306a36Sopenharmony_ci struct task_struct *target, long type, int mode) 363562306a36Sopenharmony_ci{ 363662306a36Sopenharmony_ci return call_int_hook(msg_queue_msgrcv, 0, msq, msg, target, type, mode); 363762306a36Sopenharmony_ci} 363862306a36Sopenharmony_ci 363962306a36Sopenharmony_ci/** 364062306a36Sopenharmony_ci * security_shm_alloc() - Allocate a sysv shm LSM blob 364162306a36Sopenharmony_ci * @shp: sysv ipc permission structure 364262306a36Sopenharmony_ci * 364362306a36Sopenharmony_ci * Allocate and attach a security structure to the @shp security field. The 364462306a36Sopenharmony_ci * security field is initialized to NULL when the structure is first created. 364562306a36Sopenharmony_ci * 364662306a36Sopenharmony_ci * Return: Returns 0 if operation was successful and permission is granted. 364762306a36Sopenharmony_ci */ 364862306a36Sopenharmony_ciint security_shm_alloc(struct kern_ipc_perm *shp) 364962306a36Sopenharmony_ci{ 365062306a36Sopenharmony_ci int rc = lsm_ipc_alloc(shp); 365162306a36Sopenharmony_ci 365262306a36Sopenharmony_ci if (unlikely(rc)) 365362306a36Sopenharmony_ci return rc; 365462306a36Sopenharmony_ci rc = call_int_hook(shm_alloc_security, 0, shp); 365562306a36Sopenharmony_ci if (unlikely(rc)) 365662306a36Sopenharmony_ci security_shm_free(shp); 365762306a36Sopenharmony_ci return rc; 365862306a36Sopenharmony_ci} 365962306a36Sopenharmony_ci 366062306a36Sopenharmony_ci/** 366162306a36Sopenharmony_ci * security_shm_free() - Free a sysv shm LSM blob 366262306a36Sopenharmony_ci * @shp: sysv ipc permission structure 366362306a36Sopenharmony_ci * 366462306a36Sopenharmony_ci * Deallocate the security structure @perm->security for the memory segment. 366562306a36Sopenharmony_ci */ 366662306a36Sopenharmony_civoid security_shm_free(struct kern_ipc_perm *shp) 366762306a36Sopenharmony_ci{ 366862306a36Sopenharmony_ci call_void_hook(shm_free_security, shp); 366962306a36Sopenharmony_ci kfree(shp->security); 367062306a36Sopenharmony_ci shp->security = NULL; 367162306a36Sopenharmony_ci} 367262306a36Sopenharmony_ci 367362306a36Sopenharmony_ci/** 367462306a36Sopenharmony_ci * security_shm_associate() - Check if a sysv shm operation is allowed 367562306a36Sopenharmony_ci * @shp: sysv ipc permission structure 367662306a36Sopenharmony_ci * @shmflg: operation flags 367762306a36Sopenharmony_ci * 367862306a36Sopenharmony_ci * Check permission when a shared memory region is requested through the shmget 367962306a36Sopenharmony_ci * system call. This hook is only called when returning the shared memory 368062306a36Sopenharmony_ci * region identifier for an existing region, not when a new shared memory 368162306a36Sopenharmony_ci * region is created. 368262306a36Sopenharmony_ci * 368362306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 368462306a36Sopenharmony_ci */ 368562306a36Sopenharmony_ciint security_shm_associate(struct kern_ipc_perm *shp, int shmflg) 368662306a36Sopenharmony_ci{ 368762306a36Sopenharmony_ci return call_int_hook(shm_associate, 0, shp, shmflg); 368862306a36Sopenharmony_ci} 368962306a36Sopenharmony_ci 369062306a36Sopenharmony_ci/** 369162306a36Sopenharmony_ci * security_shm_shmctl() - Check if a sysv shm operation is allowed 369262306a36Sopenharmony_ci * @shp: sysv ipc permission structure 369362306a36Sopenharmony_ci * @cmd: operation 369462306a36Sopenharmony_ci * 369562306a36Sopenharmony_ci * Check permission when a shared memory control operation specified by @cmd is 369662306a36Sopenharmony_ci * to be performed on the shared memory region with permissions in @shp. 369762306a36Sopenharmony_ci * 369862306a36Sopenharmony_ci * Return: Return 0 if permission is granted. 369962306a36Sopenharmony_ci */ 370062306a36Sopenharmony_ciint security_shm_shmctl(struct kern_ipc_perm *shp, int cmd) 370162306a36Sopenharmony_ci{ 370262306a36Sopenharmony_ci return call_int_hook(shm_shmctl, 0, shp, cmd); 370362306a36Sopenharmony_ci} 370462306a36Sopenharmony_ci 370562306a36Sopenharmony_ci/** 370662306a36Sopenharmony_ci * security_shm_shmat() - Check if a sysv shm attach operation is allowed 370762306a36Sopenharmony_ci * @shp: sysv ipc permission structure 370862306a36Sopenharmony_ci * @shmaddr: address of memory region to attach 370962306a36Sopenharmony_ci * @shmflg: operation flags 371062306a36Sopenharmony_ci * 371162306a36Sopenharmony_ci * Check permissions prior to allowing the shmat system call to attach the 371262306a36Sopenharmony_ci * shared memory segment with permissions @shp to the data segment of the 371362306a36Sopenharmony_ci * calling process. The attaching address is specified by @shmaddr. 371462306a36Sopenharmony_ci * 371562306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 371662306a36Sopenharmony_ci */ 371762306a36Sopenharmony_ciint security_shm_shmat(struct kern_ipc_perm *shp, 371862306a36Sopenharmony_ci char __user *shmaddr, int shmflg) 371962306a36Sopenharmony_ci{ 372062306a36Sopenharmony_ci return call_int_hook(shm_shmat, 0, shp, shmaddr, shmflg); 372162306a36Sopenharmony_ci} 372262306a36Sopenharmony_ci 372362306a36Sopenharmony_ci/** 372462306a36Sopenharmony_ci * security_sem_alloc() - Allocate a sysv semaphore LSM blob 372562306a36Sopenharmony_ci * @sma: sysv ipc permission structure 372662306a36Sopenharmony_ci * 372762306a36Sopenharmony_ci * Allocate and attach a security structure to the @sma security field. The 372862306a36Sopenharmony_ci * security field is initialized to NULL when the structure is first created. 372962306a36Sopenharmony_ci * 373062306a36Sopenharmony_ci * Return: Returns 0 if operation was successful and permission is granted. 373162306a36Sopenharmony_ci */ 373262306a36Sopenharmony_ciint security_sem_alloc(struct kern_ipc_perm *sma) 373362306a36Sopenharmony_ci{ 373462306a36Sopenharmony_ci int rc = lsm_ipc_alloc(sma); 373562306a36Sopenharmony_ci 373662306a36Sopenharmony_ci if (unlikely(rc)) 373762306a36Sopenharmony_ci return rc; 373862306a36Sopenharmony_ci rc = call_int_hook(sem_alloc_security, 0, sma); 373962306a36Sopenharmony_ci if (unlikely(rc)) 374062306a36Sopenharmony_ci security_sem_free(sma); 374162306a36Sopenharmony_ci return rc; 374262306a36Sopenharmony_ci} 374362306a36Sopenharmony_ci 374462306a36Sopenharmony_ci/** 374562306a36Sopenharmony_ci * security_sem_free() - Free a sysv semaphore LSM blob 374662306a36Sopenharmony_ci * @sma: sysv ipc permission structure 374762306a36Sopenharmony_ci * 374862306a36Sopenharmony_ci * Deallocate security structure @sma->security for the semaphore. 374962306a36Sopenharmony_ci */ 375062306a36Sopenharmony_civoid security_sem_free(struct kern_ipc_perm *sma) 375162306a36Sopenharmony_ci{ 375262306a36Sopenharmony_ci call_void_hook(sem_free_security, sma); 375362306a36Sopenharmony_ci kfree(sma->security); 375462306a36Sopenharmony_ci sma->security = NULL; 375562306a36Sopenharmony_ci} 375662306a36Sopenharmony_ci 375762306a36Sopenharmony_ci/** 375862306a36Sopenharmony_ci * security_sem_associate() - Check if a sysv semaphore operation is allowed 375962306a36Sopenharmony_ci * @sma: sysv ipc permission structure 376062306a36Sopenharmony_ci * @semflg: operation flags 376162306a36Sopenharmony_ci * 376262306a36Sopenharmony_ci * Check permission when a semaphore is requested through the semget system 376362306a36Sopenharmony_ci * call. This hook is only called when returning the semaphore identifier for 376462306a36Sopenharmony_ci * an existing semaphore, not when a new one must be created. 376562306a36Sopenharmony_ci * 376662306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 376762306a36Sopenharmony_ci */ 376862306a36Sopenharmony_ciint security_sem_associate(struct kern_ipc_perm *sma, int semflg) 376962306a36Sopenharmony_ci{ 377062306a36Sopenharmony_ci return call_int_hook(sem_associate, 0, sma, semflg); 377162306a36Sopenharmony_ci} 377262306a36Sopenharmony_ci 377362306a36Sopenharmony_ci/** 377462306a36Sopenharmony_ci * security_sem_semctl() - Check if a sysv semaphore operation is allowed 377562306a36Sopenharmony_ci * @sma: sysv ipc permission structure 377662306a36Sopenharmony_ci * @cmd: operation 377762306a36Sopenharmony_ci * 377862306a36Sopenharmony_ci * Check permission when a semaphore operation specified by @cmd is to be 377962306a36Sopenharmony_ci * performed on the semaphore. 378062306a36Sopenharmony_ci * 378162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 378262306a36Sopenharmony_ci */ 378362306a36Sopenharmony_ciint security_sem_semctl(struct kern_ipc_perm *sma, int cmd) 378462306a36Sopenharmony_ci{ 378562306a36Sopenharmony_ci return call_int_hook(sem_semctl, 0, sma, cmd); 378662306a36Sopenharmony_ci} 378762306a36Sopenharmony_ci 378862306a36Sopenharmony_ci/** 378962306a36Sopenharmony_ci * security_sem_semop() - Check if a sysv semaphore operation is allowed 379062306a36Sopenharmony_ci * @sma: sysv ipc permission structure 379162306a36Sopenharmony_ci * @sops: operations to perform 379262306a36Sopenharmony_ci * @nsops: number of operations 379362306a36Sopenharmony_ci * @alter: flag indicating changes will be made 379462306a36Sopenharmony_ci * 379562306a36Sopenharmony_ci * Check permissions before performing operations on members of the semaphore 379662306a36Sopenharmony_ci * set. If the @alter flag is nonzero, the semaphore set may be modified. 379762306a36Sopenharmony_ci * 379862306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 379962306a36Sopenharmony_ci */ 380062306a36Sopenharmony_ciint security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops, 380162306a36Sopenharmony_ci unsigned nsops, int alter) 380262306a36Sopenharmony_ci{ 380362306a36Sopenharmony_ci return call_int_hook(sem_semop, 0, sma, sops, nsops, alter); 380462306a36Sopenharmony_ci} 380562306a36Sopenharmony_ci 380662306a36Sopenharmony_ci/** 380762306a36Sopenharmony_ci * security_d_instantiate() - Populate an inode's LSM state based on a dentry 380862306a36Sopenharmony_ci * @dentry: dentry 380962306a36Sopenharmony_ci * @inode: inode 381062306a36Sopenharmony_ci * 381162306a36Sopenharmony_ci * Fill in @inode security information for a @dentry if allowed. 381262306a36Sopenharmony_ci */ 381362306a36Sopenharmony_civoid security_d_instantiate(struct dentry *dentry, struct inode *inode) 381462306a36Sopenharmony_ci{ 381562306a36Sopenharmony_ci if (unlikely(inode && IS_PRIVATE(inode))) 381662306a36Sopenharmony_ci return; 381762306a36Sopenharmony_ci call_void_hook(d_instantiate, dentry, inode); 381862306a36Sopenharmony_ci} 381962306a36Sopenharmony_ciEXPORT_SYMBOL(security_d_instantiate); 382062306a36Sopenharmony_ci 382162306a36Sopenharmony_ci/** 382262306a36Sopenharmony_ci * security_getprocattr() - Read an attribute for a task 382362306a36Sopenharmony_ci * @p: the task 382462306a36Sopenharmony_ci * @lsm: LSM name 382562306a36Sopenharmony_ci * @name: attribute name 382662306a36Sopenharmony_ci * @value: attribute value 382762306a36Sopenharmony_ci * 382862306a36Sopenharmony_ci * Read attribute @name for task @p and store it into @value if allowed. 382962306a36Sopenharmony_ci * 383062306a36Sopenharmony_ci * Return: Returns the length of @value on success, a negative value otherwise. 383162306a36Sopenharmony_ci */ 383262306a36Sopenharmony_ciint security_getprocattr(struct task_struct *p, const char *lsm, 383362306a36Sopenharmony_ci const char *name, char **value) 383462306a36Sopenharmony_ci{ 383562306a36Sopenharmony_ci struct security_hook_list *hp; 383662306a36Sopenharmony_ci 383762306a36Sopenharmony_ci hlist_for_each_entry(hp, &security_hook_heads.getprocattr, list) { 383862306a36Sopenharmony_ci if (lsm != NULL && strcmp(lsm, hp->lsm)) 383962306a36Sopenharmony_ci continue; 384062306a36Sopenharmony_ci return hp->hook.getprocattr(p, name, value); 384162306a36Sopenharmony_ci } 384262306a36Sopenharmony_ci return LSM_RET_DEFAULT(getprocattr); 384362306a36Sopenharmony_ci} 384462306a36Sopenharmony_ci 384562306a36Sopenharmony_ci/** 384662306a36Sopenharmony_ci * security_setprocattr() - Set an attribute for a task 384762306a36Sopenharmony_ci * @lsm: LSM name 384862306a36Sopenharmony_ci * @name: attribute name 384962306a36Sopenharmony_ci * @value: attribute value 385062306a36Sopenharmony_ci * @size: attribute value size 385162306a36Sopenharmony_ci * 385262306a36Sopenharmony_ci * Write (set) the current task's attribute @name to @value, size @size if 385362306a36Sopenharmony_ci * allowed. 385462306a36Sopenharmony_ci * 385562306a36Sopenharmony_ci * Return: Returns bytes written on success, a negative value otherwise. 385662306a36Sopenharmony_ci */ 385762306a36Sopenharmony_ciint security_setprocattr(const char *lsm, const char *name, void *value, 385862306a36Sopenharmony_ci size_t size) 385962306a36Sopenharmony_ci{ 386062306a36Sopenharmony_ci struct security_hook_list *hp; 386162306a36Sopenharmony_ci 386262306a36Sopenharmony_ci hlist_for_each_entry(hp, &security_hook_heads.setprocattr, list) { 386362306a36Sopenharmony_ci if (lsm != NULL && strcmp(lsm, hp->lsm)) 386462306a36Sopenharmony_ci continue; 386562306a36Sopenharmony_ci return hp->hook.setprocattr(name, value, size); 386662306a36Sopenharmony_ci } 386762306a36Sopenharmony_ci return LSM_RET_DEFAULT(setprocattr); 386862306a36Sopenharmony_ci} 386962306a36Sopenharmony_ci 387062306a36Sopenharmony_ci/** 387162306a36Sopenharmony_ci * security_netlink_send() - Save info and check if netlink sending is allowed 387262306a36Sopenharmony_ci * @sk: sending socket 387362306a36Sopenharmony_ci * @skb: netlink message 387462306a36Sopenharmony_ci * 387562306a36Sopenharmony_ci * Save security information for a netlink message so that permission checking 387662306a36Sopenharmony_ci * can be performed when the message is processed. The security information 387762306a36Sopenharmony_ci * can be saved using the eff_cap field of the netlink_skb_parms structure. 387862306a36Sopenharmony_ci * Also may be used to provide fine grained control over message transmission. 387962306a36Sopenharmony_ci * 388062306a36Sopenharmony_ci * Return: Returns 0 if the information was successfully saved and message is 388162306a36Sopenharmony_ci * allowed to be transmitted. 388262306a36Sopenharmony_ci */ 388362306a36Sopenharmony_ciint security_netlink_send(struct sock *sk, struct sk_buff *skb) 388462306a36Sopenharmony_ci{ 388562306a36Sopenharmony_ci return call_int_hook(netlink_send, 0, sk, skb); 388662306a36Sopenharmony_ci} 388762306a36Sopenharmony_ci 388862306a36Sopenharmony_ci/** 388962306a36Sopenharmony_ci * security_ismaclabel() - Check is the named attribute is a MAC label 389062306a36Sopenharmony_ci * @name: full extended attribute name 389162306a36Sopenharmony_ci * 389262306a36Sopenharmony_ci * Check if the extended attribute specified by @name represents a MAC label. 389362306a36Sopenharmony_ci * 389462306a36Sopenharmony_ci * Return: Returns 1 if name is a MAC attribute otherwise returns 0. 389562306a36Sopenharmony_ci */ 389662306a36Sopenharmony_ciint security_ismaclabel(const char *name) 389762306a36Sopenharmony_ci{ 389862306a36Sopenharmony_ci return call_int_hook(ismaclabel, 0, name); 389962306a36Sopenharmony_ci} 390062306a36Sopenharmony_ciEXPORT_SYMBOL(security_ismaclabel); 390162306a36Sopenharmony_ci 390262306a36Sopenharmony_ci/** 390362306a36Sopenharmony_ci * security_secid_to_secctx() - Convert a secid to a secctx 390462306a36Sopenharmony_ci * @secid: secid 390562306a36Sopenharmony_ci * @secdata: secctx 390662306a36Sopenharmony_ci * @seclen: secctx length 390762306a36Sopenharmony_ci * 390862306a36Sopenharmony_ci * Convert secid to security context. If @secdata is NULL the length of the 390962306a36Sopenharmony_ci * result will be returned in @seclen, but no @secdata will be returned. This 391062306a36Sopenharmony_ci * does mean that the length could change between calls to check the length and 391162306a36Sopenharmony_ci * the next call which actually allocates and returns the @secdata. 391262306a36Sopenharmony_ci * 391362306a36Sopenharmony_ci * Return: Return 0 on success, error on failure. 391462306a36Sopenharmony_ci */ 391562306a36Sopenharmony_ciint security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 391662306a36Sopenharmony_ci{ 391762306a36Sopenharmony_ci struct security_hook_list *hp; 391862306a36Sopenharmony_ci int rc; 391962306a36Sopenharmony_ci 392062306a36Sopenharmony_ci /* 392162306a36Sopenharmony_ci * Currently, only one LSM can implement secid_to_secctx (i.e this 392262306a36Sopenharmony_ci * LSM hook is not "stackable"). 392362306a36Sopenharmony_ci */ 392462306a36Sopenharmony_ci hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { 392562306a36Sopenharmony_ci rc = hp->hook.secid_to_secctx(secid, secdata, seclen); 392662306a36Sopenharmony_ci if (rc != LSM_RET_DEFAULT(secid_to_secctx)) 392762306a36Sopenharmony_ci return rc; 392862306a36Sopenharmony_ci } 392962306a36Sopenharmony_ci 393062306a36Sopenharmony_ci return LSM_RET_DEFAULT(secid_to_secctx); 393162306a36Sopenharmony_ci} 393262306a36Sopenharmony_ciEXPORT_SYMBOL(security_secid_to_secctx); 393362306a36Sopenharmony_ci 393462306a36Sopenharmony_ci/** 393562306a36Sopenharmony_ci * security_secctx_to_secid() - Convert a secctx to a secid 393662306a36Sopenharmony_ci * @secdata: secctx 393762306a36Sopenharmony_ci * @seclen: length of secctx 393862306a36Sopenharmony_ci * @secid: secid 393962306a36Sopenharmony_ci * 394062306a36Sopenharmony_ci * Convert security context to secid. 394162306a36Sopenharmony_ci * 394262306a36Sopenharmony_ci * Return: Returns 0 on success, error on failure. 394362306a36Sopenharmony_ci */ 394462306a36Sopenharmony_ciint security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) 394562306a36Sopenharmony_ci{ 394662306a36Sopenharmony_ci *secid = 0; 394762306a36Sopenharmony_ci return call_int_hook(secctx_to_secid, 0, secdata, seclen, secid); 394862306a36Sopenharmony_ci} 394962306a36Sopenharmony_ciEXPORT_SYMBOL(security_secctx_to_secid); 395062306a36Sopenharmony_ci 395162306a36Sopenharmony_ci/** 395262306a36Sopenharmony_ci * security_release_secctx() - Free a secctx buffer 395362306a36Sopenharmony_ci * @secdata: secctx 395462306a36Sopenharmony_ci * @seclen: length of secctx 395562306a36Sopenharmony_ci * 395662306a36Sopenharmony_ci * Release the security context. 395762306a36Sopenharmony_ci */ 395862306a36Sopenharmony_civoid security_release_secctx(char *secdata, u32 seclen) 395962306a36Sopenharmony_ci{ 396062306a36Sopenharmony_ci call_void_hook(release_secctx, secdata, seclen); 396162306a36Sopenharmony_ci} 396262306a36Sopenharmony_ciEXPORT_SYMBOL(security_release_secctx); 396362306a36Sopenharmony_ci 396462306a36Sopenharmony_ci/** 396562306a36Sopenharmony_ci * security_inode_invalidate_secctx() - Invalidate an inode's security label 396662306a36Sopenharmony_ci * @inode: inode 396762306a36Sopenharmony_ci * 396862306a36Sopenharmony_ci * Notify the security module that it must revalidate the security context of 396962306a36Sopenharmony_ci * an inode. 397062306a36Sopenharmony_ci */ 397162306a36Sopenharmony_civoid security_inode_invalidate_secctx(struct inode *inode) 397262306a36Sopenharmony_ci{ 397362306a36Sopenharmony_ci call_void_hook(inode_invalidate_secctx, inode); 397462306a36Sopenharmony_ci} 397562306a36Sopenharmony_ciEXPORT_SYMBOL(security_inode_invalidate_secctx); 397662306a36Sopenharmony_ci 397762306a36Sopenharmony_ci/** 397862306a36Sopenharmony_ci * security_inode_notifysecctx() - Nofify the LSM of an inode's security label 397962306a36Sopenharmony_ci * @inode: inode 398062306a36Sopenharmony_ci * @ctx: secctx 398162306a36Sopenharmony_ci * @ctxlen: length of secctx 398262306a36Sopenharmony_ci * 398362306a36Sopenharmony_ci * Notify the security module of what the security context of an inode should 398462306a36Sopenharmony_ci * be. Initializes the incore security context managed by the security module 398562306a36Sopenharmony_ci * for this inode. Example usage: NFS client invokes this hook to initialize 398662306a36Sopenharmony_ci * the security context in its incore inode to the value provided by the server 398762306a36Sopenharmony_ci * for the file when the server returned the file's attributes to the client. 398862306a36Sopenharmony_ci * Must be called with inode->i_mutex locked. 398962306a36Sopenharmony_ci * 399062306a36Sopenharmony_ci * Return: Returns 0 on success, error on failure. 399162306a36Sopenharmony_ci */ 399262306a36Sopenharmony_ciint security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) 399362306a36Sopenharmony_ci{ 399462306a36Sopenharmony_ci return call_int_hook(inode_notifysecctx, 0, inode, ctx, ctxlen); 399562306a36Sopenharmony_ci} 399662306a36Sopenharmony_ciEXPORT_SYMBOL(security_inode_notifysecctx); 399762306a36Sopenharmony_ci 399862306a36Sopenharmony_ci/** 399962306a36Sopenharmony_ci * security_inode_setsecctx() - Change the security label of an inode 400062306a36Sopenharmony_ci * @dentry: inode 400162306a36Sopenharmony_ci * @ctx: secctx 400262306a36Sopenharmony_ci * @ctxlen: length of secctx 400362306a36Sopenharmony_ci * 400462306a36Sopenharmony_ci * Change the security context of an inode. Updates the incore security 400562306a36Sopenharmony_ci * context managed by the security module and invokes the fs code as needed 400662306a36Sopenharmony_ci * (via __vfs_setxattr_noperm) to update any backing xattrs that represent the 400762306a36Sopenharmony_ci * context. Example usage: NFS server invokes this hook to change the security 400862306a36Sopenharmony_ci * context in its incore inode and on the backing filesystem to a value 400962306a36Sopenharmony_ci * provided by the client on a SETATTR operation. Must be called with 401062306a36Sopenharmony_ci * inode->i_mutex locked. 401162306a36Sopenharmony_ci * 401262306a36Sopenharmony_ci * Return: Returns 0 on success, error on failure. 401362306a36Sopenharmony_ci */ 401462306a36Sopenharmony_ciint security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen) 401562306a36Sopenharmony_ci{ 401662306a36Sopenharmony_ci return call_int_hook(inode_setsecctx, 0, dentry, ctx, ctxlen); 401762306a36Sopenharmony_ci} 401862306a36Sopenharmony_ciEXPORT_SYMBOL(security_inode_setsecctx); 401962306a36Sopenharmony_ci 402062306a36Sopenharmony_ci/** 402162306a36Sopenharmony_ci * security_inode_getsecctx() - Get the security label of an inode 402262306a36Sopenharmony_ci * @inode: inode 402362306a36Sopenharmony_ci * @ctx: secctx 402462306a36Sopenharmony_ci * @ctxlen: length of secctx 402562306a36Sopenharmony_ci * 402662306a36Sopenharmony_ci * On success, returns 0 and fills out @ctx and @ctxlen with the security 402762306a36Sopenharmony_ci * context for the given @inode. 402862306a36Sopenharmony_ci * 402962306a36Sopenharmony_ci * Return: Returns 0 on success, error on failure. 403062306a36Sopenharmony_ci */ 403162306a36Sopenharmony_ciint security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) 403262306a36Sopenharmony_ci{ 403362306a36Sopenharmony_ci struct security_hook_list *hp; 403462306a36Sopenharmony_ci int rc; 403562306a36Sopenharmony_ci 403662306a36Sopenharmony_ci /* 403762306a36Sopenharmony_ci * Only one module will provide a security context. 403862306a36Sopenharmony_ci */ 403962306a36Sopenharmony_ci hlist_for_each_entry(hp, &security_hook_heads.inode_getsecctx, list) { 404062306a36Sopenharmony_ci rc = hp->hook.inode_getsecctx(inode, ctx, ctxlen); 404162306a36Sopenharmony_ci if (rc != LSM_RET_DEFAULT(inode_getsecctx)) 404262306a36Sopenharmony_ci return rc; 404362306a36Sopenharmony_ci } 404462306a36Sopenharmony_ci 404562306a36Sopenharmony_ci return LSM_RET_DEFAULT(inode_getsecctx); 404662306a36Sopenharmony_ci} 404762306a36Sopenharmony_ciEXPORT_SYMBOL(security_inode_getsecctx); 404862306a36Sopenharmony_ci 404962306a36Sopenharmony_ci#ifdef CONFIG_WATCH_QUEUE 405062306a36Sopenharmony_ci/** 405162306a36Sopenharmony_ci * security_post_notification() - Check if a watch notification can be posted 405262306a36Sopenharmony_ci * @w_cred: credentials of the task that set the watch 405362306a36Sopenharmony_ci * @cred: credentials of the task which triggered the watch 405462306a36Sopenharmony_ci * @n: the notification 405562306a36Sopenharmony_ci * 405662306a36Sopenharmony_ci * Check to see if a watch notification can be posted to a particular queue. 405762306a36Sopenharmony_ci * 405862306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 405962306a36Sopenharmony_ci */ 406062306a36Sopenharmony_ciint security_post_notification(const struct cred *w_cred, 406162306a36Sopenharmony_ci const struct cred *cred, 406262306a36Sopenharmony_ci struct watch_notification *n) 406362306a36Sopenharmony_ci{ 406462306a36Sopenharmony_ci return call_int_hook(post_notification, 0, w_cred, cred, n); 406562306a36Sopenharmony_ci} 406662306a36Sopenharmony_ci#endif /* CONFIG_WATCH_QUEUE */ 406762306a36Sopenharmony_ci 406862306a36Sopenharmony_ci#ifdef CONFIG_KEY_NOTIFICATIONS 406962306a36Sopenharmony_ci/** 407062306a36Sopenharmony_ci * security_watch_key() - Check if a task is allowed to watch for key events 407162306a36Sopenharmony_ci * @key: the key to watch 407262306a36Sopenharmony_ci * 407362306a36Sopenharmony_ci * Check to see if a process is allowed to watch for event notifications from 407462306a36Sopenharmony_ci * a key or keyring. 407562306a36Sopenharmony_ci * 407662306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 407762306a36Sopenharmony_ci */ 407862306a36Sopenharmony_ciint security_watch_key(struct key *key) 407962306a36Sopenharmony_ci{ 408062306a36Sopenharmony_ci return call_int_hook(watch_key, 0, key); 408162306a36Sopenharmony_ci} 408262306a36Sopenharmony_ci#endif /* CONFIG_KEY_NOTIFICATIONS */ 408362306a36Sopenharmony_ci 408462306a36Sopenharmony_ci#ifdef CONFIG_SECURITY_NETWORK 408562306a36Sopenharmony_ci/** 408662306a36Sopenharmony_ci * security_unix_stream_connect() - Check if a AF_UNIX stream is allowed 408762306a36Sopenharmony_ci * @sock: originating sock 408862306a36Sopenharmony_ci * @other: peer sock 408962306a36Sopenharmony_ci * @newsk: new sock 409062306a36Sopenharmony_ci * 409162306a36Sopenharmony_ci * Check permissions before establishing a Unix domain stream connection 409262306a36Sopenharmony_ci * between @sock and @other. 409362306a36Sopenharmony_ci * 409462306a36Sopenharmony_ci * The @unix_stream_connect and @unix_may_send hooks were necessary because 409562306a36Sopenharmony_ci * Linux provides an alternative to the conventional file name space for Unix 409662306a36Sopenharmony_ci * domain sockets. Whereas binding and connecting to sockets in the file name 409762306a36Sopenharmony_ci * space is mediated by the typical file permissions (and caught by the mknod 409862306a36Sopenharmony_ci * and permission hooks in inode_security_ops), binding and connecting to 409962306a36Sopenharmony_ci * sockets in the abstract name space is completely unmediated. Sufficient 410062306a36Sopenharmony_ci * control of Unix domain sockets in the abstract name space isn't possible 410162306a36Sopenharmony_ci * using only the socket layer hooks, since we need to know the actual target 410262306a36Sopenharmony_ci * socket, which is not looked up until we are inside the af_unix code. 410362306a36Sopenharmony_ci * 410462306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 410562306a36Sopenharmony_ci */ 410662306a36Sopenharmony_ciint security_unix_stream_connect(struct sock *sock, struct sock *other, 410762306a36Sopenharmony_ci struct sock *newsk) 410862306a36Sopenharmony_ci{ 410962306a36Sopenharmony_ci return call_int_hook(unix_stream_connect, 0, sock, other, newsk); 411062306a36Sopenharmony_ci} 411162306a36Sopenharmony_ciEXPORT_SYMBOL(security_unix_stream_connect); 411262306a36Sopenharmony_ci 411362306a36Sopenharmony_ci/** 411462306a36Sopenharmony_ci * security_unix_may_send() - Check if AF_UNIX socket can send datagrams 411562306a36Sopenharmony_ci * @sock: originating sock 411662306a36Sopenharmony_ci * @other: peer sock 411762306a36Sopenharmony_ci * 411862306a36Sopenharmony_ci * Check permissions before connecting or sending datagrams from @sock to 411962306a36Sopenharmony_ci * @other. 412062306a36Sopenharmony_ci * 412162306a36Sopenharmony_ci * The @unix_stream_connect and @unix_may_send hooks were necessary because 412262306a36Sopenharmony_ci * Linux provides an alternative to the conventional file name space for Unix 412362306a36Sopenharmony_ci * domain sockets. Whereas binding and connecting to sockets in the file name 412462306a36Sopenharmony_ci * space is mediated by the typical file permissions (and caught by the mknod 412562306a36Sopenharmony_ci * and permission hooks in inode_security_ops), binding and connecting to 412662306a36Sopenharmony_ci * sockets in the abstract name space is completely unmediated. Sufficient 412762306a36Sopenharmony_ci * control of Unix domain sockets in the abstract name space isn't possible 412862306a36Sopenharmony_ci * using only the socket layer hooks, since we need to know the actual target 412962306a36Sopenharmony_ci * socket, which is not looked up until we are inside the af_unix code. 413062306a36Sopenharmony_ci * 413162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 413262306a36Sopenharmony_ci */ 413362306a36Sopenharmony_ciint security_unix_may_send(struct socket *sock, struct socket *other) 413462306a36Sopenharmony_ci{ 413562306a36Sopenharmony_ci return call_int_hook(unix_may_send, 0, sock, other); 413662306a36Sopenharmony_ci} 413762306a36Sopenharmony_ciEXPORT_SYMBOL(security_unix_may_send); 413862306a36Sopenharmony_ci 413962306a36Sopenharmony_ci/** 414062306a36Sopenharmony_ci * security_socket_create() - Check if creating a new socket is allowed 414162306a36Sopenharmony_ci * @family: protocol family 414262306a36Sopenharmony_ci * @type: communications type 414362306a36Sopenharmony_ci * @protocol: requested protocol 414462306a36Sopenharmony_ci * @kern: set to 1 if a kernel socket is requested 414562306a36Sopenharmony_ci * 414662306a36Sopenharmony_ci * Check permissions prior to creating a new socket. 414762306a36Sopenharmony_ci * 414862306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 414962306a36Sopenharmony_ci */ 415062306a36Sopenharmony_ciint security_socket_create(int family, int type, int protocol, int kern) 415162306a36Sopenharmony_ci{ 415262306a36Sopenharmony_ci return call_int_hook(socket_create, 0, family, type, protocol, kern); 415362306a36Sopenharmony_ci} 415462306a36Sopenharmony_ci 415562306a36Sopenharmony_ci/** 415662306a36Sopenharmony_ci * security_socket_post_create() - Initialize a newly created socket 415762306a36Sopenharmony_ci * @sock: socket 415862306a36Sopenharmony_ci * @family: protocol family 415962306a36Sopenharmony_ci * @type: communications type 416062306a36Sopenharmony_ci * @protocol: requested protocol 416162306a36Sopenharmony_ci * @kern: set to 1 if a kernel socket is requested 416262306a36Sopenharmony_ci * 416362306a36Sopenharmony_ci * This hook allows a module to update or allocate a per-socket security 416462306a36Sopenharmony_ci * structure. Note that the security field was not added directly to the socket 416562306a36Sopenharmony_ci * structure, but rather, the socket security information is stored in the 416662306a36Sopenharmony_ci * associated inode. Typically, the inode alloc_security hook will allocate 416762306a36Sopenharmony_ci * and attach security information to SOCK_INODE(sock)->i_security. This hook 416862306a36Sopenharmony_ci * may be used to update the SOCK_INODE(sock)->i_security field with additional 416962306a36Sopenharmony_ci * information that wasn't available when the inode was allocated. 417062306a36Sopenharmony_ci * 417162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 417262306a36Sopenharmony_ci */ 417362306a36Sopenharmony_ciint security_socket_post_create(struct socket *sock, int family, 417462306a36Sopenharmony_ci int type, int protocol, int kern) 417562306a36Sopenharmony_ci{ 417662306a36Sopenharmony_ci return call_int_hook(socket_post_create, 0, sock, family, type, 417762306a36Sopenharmony_ci protocol, kern); 417862306a36Sopenharmony_ci} 417962306a36Sopenharmony_ci 418062306a36Sopenharmony_ci/** 418162306a36Sopenharmony_ci * security_socket_socketpair() - Check if creating a socketpair is allowed 418262306a36Sopenharmony_ci * @socka: first socket 418362306a36Sopenharmony_ci * @sockb: second socket 418462306a36Sopenharmony_ci * 418562306a36Sopenharmony_ci * Check permissions before creating a fresh pair of sockets. 418662306a36Sopenharmony_ci * 418762306a36Sopenharmony_ci * Return: Returns 0 if permission is granted and the connection was 418862306a36Sopenharmony_ci * established. 418962306a36Sopenharmony_ci */ 419062306a36Sopenharmony_ciint security_socket_socketpair(struct socket *socka, struct socket *sockb) 419162306a36Sopenharmony_ci{ 419262306a36Sopenharmony_ci return call_int_hook(socket_socketpair, 0, socka, sockb); 419362306a36Sopenharmony_ci} 419462306a36Sopenharmony_ciEXPORT_SYMBOL(security_socket_socketpair); 419562306a36Sopenharmony_ci 419662306a36Sopenharmony_ci/** 419762306a36Sopenharmony_ci * security_socket_bind() - Check if a socket bind operation is allowed 419862306a36Sopenharmony_ci * @sock: socket 419962306a36Sopenharmony_ci * @address: requested bind address 420062306a36Sopenharmony_ci * @addrlen: length of address 420162306a36Sopenharmony_ci * 420262306a36Sopenharmony_ci * Check permission before socket protocol layer bind operation is performed 420362306a36Sopenharmony_ci * and the socket @sock is bound to the address specified in the @address 420462306a36Sopenharmony_ci * parameter. 420562306a36Sopenharmony_ci * 420662306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 420762306a36Sopenharmony_ci */ 420862306a36Sopenharmony_ciint security_socket_bind(struct socket *sock, 420962306a36Sopenharmony_ci struct sockaddr *address, int addrlen) 421062306a36Sopenharmony_ci{ 421162306a36Sopenharmony_ci return call_int_hook(socket_bind, 0, sock, address, addrlen); 421262306a36Sopenharmony_ci} 421362306a36Sopenharmony_ci 421462306a36Sopenharmony_ci/** 421562306a36Sopenharmony_ci * security_socket_connect() - Check if a socket connect operation is allowed 421662306a36Sopenharmony_ci * @sock: socket 421762306a36Sopenharmony_ci * @address: address of remote connection point 421862306a36Sopenharmony_ci * @addrlen: length of address 421962306a36Sopenharmony_ci * 422062306a36Sopenharmony_ci * Check permission before socket protocol layer connect operation attempts to 422162306a36Sopenharmony_ci * connect socket @sock to a remote address, @address. 422262306a36Sopenharmony_ci * 422362306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 422462306a36Sopenharmony_ci */ 422562306a36Sopenharmony_ciint security_socket_connect(struct socket *sock, 422662306a36Sopenharmony_ci struct sockaddr *address, int addrlen) 422762306a36Sopenharmony_ci{ 422862306a36Sopenharmony_ci return call_int_hook(socket_connect, 0, sock, address, addrlen); 422962306a36Sopenharmony_ci} 423062306a36Sopenharmony_ci 423162306a36Sopenharmony_ci/** 423262306a36Sopenharmony_ci * security_socket_listen() - Check if a socket is allowed to listen 423362306a36Sopenharmony_ci * @sock: socket 423462306a36Sopenharmony_ci * @backlog: connection queue size 423562306a36Sopenharmony_ci * 423662306a36Sopenharmony_ci * Check permission before socket protocol layer listen operation. 423762306a36Sopenharmony_ci * 423862306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 423962306a36Sopenharmony_ci */ 424062306a36Sopenharmony_ciint security_socket_listen(struct socket *sock, int backlog) 424162306a36Sopenharmony_ci{ 424262306a36Sopenharmony_ci return call_int_hook(socket_listen, 0, sock, backlog); 424362306a36Sopenharmony_ci} 424462306a36Sopenharmony_ci 424562306a36Sopenharmony_ci/** 424662306a36Sopenharmony_ci * security_socket_accept() - Check if a socket is allowed to accept connections 424762306a36Sopenharmony_ci * @sock: listening socket 424862306a36Sopenharmony_ci * @newsock: newly creation connection socket 424962306a36Sopenharmony_ci * 425062306a36Sopenharmony_ci * Check permission before accepting a new connection. Note that the new 425162306a36Sopenharmony_ci * socket, @newsock, has been created and some information copied to it, but 425262306a36Sopenharmony_ci * the accept operation has not actually been performed. 425362306a36Sopenharmony_ci * 425462306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 425562306a36Sopenharmony_ci */ 425662306a36Sopenharmony_ciint security_socket_accept(struct socket *sock, struct socket *newsock) 425762306a36Sopenharmony_ci{ 425862306a36Sopenharmony_ci return call_int_hook(socket_accept, 0, sock, newsock); 425962306a36Sopenharmony_ci} 426062306a36Sopenharmony_ci 426162306a36Sopenharmony_ci/** 426262306a36Sopenharmony_ci * security_socket_sendmsg() - Check is sending a message is allowed 426362306a36Sopenharmony_ci * @sock: sending socket 426462306a36Sopenharmony_ci * @msg: message to send 426562306a36Sopenharmony_ci * @size: size of message 426662306a36Sopenharmony_ci * 426762306a36Sopenharmony_ci * Check permission before transmitting a message to another socket. 426862306a36Sopenharmony_ci * 426962306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 427062306a36Sopenharmony_ci */ 427162306a36Sopenharmony_ciint security_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size) 427262306a36Sopenharmony_ci{ 427362306a36Sopenharmony_ci return call_int_hook(socket_sendmsg, 0, sock, msg, size); 427462306a36Sopenharmony_ci} 427562306a36Sopenharmony_ci 427662306a36Sopenharmony_ci/** 427762306a36Sopenharmony_ci * security_socket_recvmsg() - Check if receiving a message is allowed 427862306a36Sopenharmony_ci * @sock: receiving socket 427962306a36Sopenharmony_ci * @msg: message to receive 428062306a36Sopenharmony_ci * @size: size of message 428162306a36Sopenharmony_ci * @flags: operational flags 428262306a36Sopenharmony_ci * 428362306a36Sopenharmony_ci * Check permission before receiving a message from a socket. 428462306a36Sopenharmony_ci * 428562306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 428662306a36Sopenharmony_ci */ 428762306a36Sopenharmony_ciint security_socket_recvmsg(struct socket *sock, struct msghdr *msg, 428862306a36Sopenharmony_ci int size, int flags) 428962306a36Sopenharmony_ci{ 429062306a36Sopenharmony_ci return call_int_hook(socket_recvmsg, 0, sock, msg, size, flags); 429162306a36Sopenharmony_ci} 429262306a36Sopenharmony_ci 429362306a36Sopenharmony_ci/** 429462306a36Sopenharmony_ci * security_socket_getsockname() - Check if reading the socket addr is allowed 429562306a36Sopenharmony_ci * @sock: socket 429662306a36Sopenharmony_ci * 429762306a36Sopenharmony_ci * Check permission before reading the local address (name) of the socket 429862306a36Sopenharmony_ci * object. 429962306a36Sopenharmony_ci * 430062306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 430162306a36Sopenharmony_ci */ 430262306a36Sopenharmony_ciint security_socket_getsockname(struct socket *sock) 430362306a36Sopenharmony_ci{ 430462306a36Sopenharmony_ci return call_int_hook(socket_getsockname, 0, sock); 430562306a36Sopenharmony_ci} 430662306a36Sopenharmony_ci 430762306a36Sopenharmony_ci/** 430862306a36Sopenharmony_ci * security_socket_getpeername() - Check if reading the peer's addr is allowed 430962306a36Sopenharmony_ci * @sock: socket 431062306a36Sopenharmony_ci * 431162306a36Sopenharmony_ci * Check permission before the remote address (name) of a socket object. 431262306a36Sopenharmony_ci * 431362306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 431462306a36Sopenharmony_ci */ 431562306a36Sopenharmony_ciint security_socket_getpeername(struct socket *sock) 431662306a36Sopenharmony_ci{ 431762306a36Sopenharmony_ci return call_int_hook(socket_getpeername, 0, sock); 431862306a36Sopenharmony_ci} 431962306a36Sopenharmony_ci 432062306a36Sopenharmony_ci/** 432162306a36Sopenharmony_ci * security_socket_getsockopt() - Check if reading a socket option is allowed 432262306a36Sopenharmony_ci * @sock: socket 432362306a36Sopenharmony_ci * @level: option's protocol level 432462306a36Sopenharmony_ci * @optname: option name 432562306a36Sopenharmony_ci * 432662306a36Sopenharmony_ci * Check permissions before retrieving the options associated with socket 432762306a36Sopenharmony_ci * @sock. 432862306a36Sopenharmony_ci * 432962306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 433062306a36Sopenharmony_ci */ 433162306a36Sopenharmony_ciint security_socket_getsockopt(struct socket *sock, int level, int optname) 433262306a36Sopenharmony_ci{ 433362306a36Sopenharmony_ci return call_int_hook(socket_getsockopt, 0, sock, level, optname); 433462306a36Sopenharmony_ci} 433562306a36Sopenharmony_ci 433662306a36Sopenharmony_ci/** 433762306a36Sopenharmony_ci * security_socket_setsockopt() - Check if setting a socket option is allowed 433862306a36Sopenharmony_ci * @sock: socket 433962306a36Sopenharmony_ci * @level: option's protocol level 434062306a36Sopenharmony_ci * @optname: option name 434162306a36Sopenharmony_ci * 434262306a36Sopenharmony_ci * Check permissions before setting the options associated with socket @sock. 434362306a36Sopenharmony_ci * 434462306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 434562306a36Sopenharmony_ci */ 434662306a36Sopenharmony_ciint security_socket_setsockopt(struct socket *sock, int level, int optname) 434762306a36Sopenharmony_ci{ 434862306a36Sopenharmony_ci return call_int_hook(socket_setsockopt, 0, sock, level, optname); 434962306a36Sopenharmony_ci} 435062306a36Sopenharmony_ci 435162306a36Sopenharmony_ci/** 435262306a36Sopenharmony_ci * security_socket_shutdown() - Checks if shutting down the socket is allowed 435362306a36Sopenharmony_ci * @sock: socket 435462306a36Sopenharmony_ci * @how: flag indicating how sends and receives are handled 435562306a36Sopenharmony_ci * 435662306a36Sopenharmony_ci * Checks permission before all or part of a connection on the socket @sock is 435762306a36Sopenharmony_ci * shut down. 435862306a36Sopenharmony_ci * 435962306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 436062306a36Sopenharmony_ci */ 436162306a36Sopenharmony_ciint security_socket_shutdown(struct socket *sock, int how) 436262306a36Sopenharmony_ci{ 436362306a36Sopenharmony_ci return call_int_hook(socket_shutdown, 0, sock, how); 436462306a36Sopenharmony_ci} 436562306a36Sopenharmony_ci 436662306a36Sopenharmony_ci/** 436762306a36Sopenharmony_ci * security_sock_rcv_skb() - Check if an incoming network packet is allowed 436862306a36Sopenharmony_ci * @sk: destination sock 436962306a36Sopenharmony_ci * @skb: incoming packet 437062306a36Sopenharmony_ci * 437162306a36Sopenharmony_ci * Check permissions on incoming network packets. This hook is distinct from 437262306a36Sopenharmony_ci * Netfilter's IP input hooks since it is the first time that the incoming 437362306a36Sopenharmony_ci * sk_buff @skb has been associated with a particular socket, @sk. Must not 437462306a36Sopenharmony_ci * sleep inside this hook because some callers hold spinlocks. 437562306a36Sopenharmony_ci * 437662306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 437762306a36Sopenharmony_ci */ 437862306a36Sopenharmony_ciint security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) 437962306a36Sopenharmony_ci{ 438062306a36Sopenharmony_ci return call_int_hook(socket_sock_rcv_skb, 0, sk, skb); 438162306a36Sopenharmony_ci} 438262306a36Sopenharmony_ciEXPORT_SYMBOL(security_sock_rcv_skb); 438362306a36Sopenharmony_ci 438462306a36Sopenharmony_ci/** 438562306a36Sopenharmony_ci * security_socket_getpeersec_stream() - Get the remote peer label 438662306a36Sopenharmony_ci * @sock: socket 438762306a36Sopenharmony_ci * @optval: destination buffer 438862306a36Sopenharmony_ci * @optlen: size of peer label copied into the buffer 438962306a36Sopenharmony_ci * @len: maximum size of the destination buffer 439062306a36Sopenharmony_ci * 439162306a36Sopenharmony_ci * This hook allows the security module to provide peer socket security state 439262306a36Sopenharmony_ci * for unix or connected tcp sockets to userspace via getsockopt SO_GETPEERSEC. 439362306a36Sopenharmony_ci * For tcp sockets this can be meaningful if the socket is associated with an 439462306a36Sopenharmony_ci * ipsec SA. 439562306a36Sopenharmony_ci * 439662306a36Sopenharmony_ci * Return: Returns 0 if all is well, otherwise, typical getsockopt return 439762306a36Sopenharmony_ci * values. 439862306a36Sopenharmony_ci */ 439962306a36Sopenharmony_ciint security_socket_getpeersec_stream(struct socket *sock, sockptr_t optval, 440062306a36Sopenharmony_ci sockptr_t optlen, unsigned int len) 440162306a36Sopenharmony_ci{ 440262306a36Sopenharmony_ci struct security_hook_list *hp; 440362306a36Sopenharmony_ci int rc; 440462306a36Sopenharmony_ci 440562306a36Sopenharmony_ci /* 440662306a36Sopenharmony_ci * Only one module will provide a security context. 440762306a36Sopenharmony_ci */ 440862306a36Sopenharmony_ci hlist_for_each_entry(hp, &security_hook_heads.socket_getpeersec_stream, 440962306a36Sopenharmony_ci list) { 441062306a36Sopenharmony_ci rc = hp->hook.socket_getpeersec_stream(sock, optval, optlen, 441162306a36Sopenharmony_ci len); 441262306a36Sopenharmony_ci if (rc != LSM_RET_DEFAULT(socket_getpeersec_stream)) 441362306a36Sopenharmony_ci return rc; 441462306a36Sopenharmony_ci } 441562306a36Sopenharmony_ci return LSM_RET_DEFAULT(socket_getpeersec_stream); 441662306a36Sopenharmony_ci} 441762306a36Sopenharmony_ci 441862306a36Sopenharmony_ci/** 441962306a36Sopenharmony_ci * security_socket_getpeersec_dgram() - Get the remote peer label 442062306a36Sopenharmony_ci * @sock: socket 442162306a36Sopenharmony_ci * @skb: datagram packet 442262306a36Sopenharmony_ci * @secid: remote peer label secid 442362306a36Sopenharmony_ci * 442462306a36Sopenharmony_ci * This hook allows the security module to provide peer socket security state 442562306a36Sopenharmony_ci * for udp sockets on a per-packet basis to userspace via getsockopt 442662306a36Sopenharmony_ci * SO_GETPEERSEC. The application must first have indicated the IP_PASSSEC 442762306a36Sopenharmony_ci * option via getsockopt. It can then retrieve the security state returned by 442862306a36Sopenharmony_ci * this hook for a packet via the SCM_SECURITY ancillary message type. 442962306a36Sopenharmony_ci * 443062306a36Sopenharmony_ci * Return: Returns 0 on success, error on failure. 443162306a36Sopenharmony_ci */ 443262306a36Sopenharmony_ciint security_socket_getpeersec_dgram(struct socket *sock, 443362306a36Sopenharmony_ci struct sk_buff *skb, u32 *secid) 443462306a36Sopenharmony_ci{ 443562306a36Sopenharmony_ci struct security_hook_list *hp; 443662306a36Sopenharmony_ci int rc; 443762306a36Sopenharmony_ci 443862306a36Sopenharmony_ci /* 443962306a36Sopenharmony_ci * Only one module will provide a security context. 444062306a36Sopenharmony_ci */ 444162306a36Sopenharmony_ci hlist_for_each_entry(hp, &security_hook_heads.socket_getpeersec_dgram, 444262306a36Sopenharmony_ci list) { 444362306a36Sopenharmony_ci rc = hp->hook.socket_getpeersec_dgram(sock, skb, secid); 444462306a36Sopenharmony_ci if (rc != LSM_RET_DEFAULT(socket_getpeersec_dgram)) 444562306a36Sopenharmony_ci return rc; 444662306a36Sopenharmony_ci } 444762306a36Sopenharmony_ci return LSM_RET_DEFAULT(socket_getpeersec_dgram); 444862306a36Sopenharmony_ci} 444962306a36Sopenharmony_ciEXPORT_SYMBOL(security_socket_getpeersec_dgram); 445062306a36Sopenharmony_ci 445162306a36Sopenharmony_ci/** 445262306a36Sopenharmony_ci * security_sk_alloc() - Allocate and initialize a sock's LSM blob 445362306a36Sopenharmony_ci * @sk: sock 445462306a36Sopenharmony_ci * @family: protocol family 445562306a36Sopenharmony_ci * @priority: gfp flags 445662306a36Sopenharmony_ci * 445762306a36Sopenharmony_ci * Allocate and attach a security structure to the sk->sk_security field, which 445862306a36Sopenharmony_ci * is used to copy security attributes between local stream sockets. 445962306a36Sopenharmony_ci * 446062306a36Sopenharmony_ci * Return: Returns 0 on success, error on failure. 446162306a36Sopenharmony_ci */ 446262306a36Sopenharmony_ciint security_sk_alloc(struct sock *sk, int family, gfp_t priority) 446362306a36Sopenharmony_ci{ 446462306a36Sopenharmony_ci return call_int_hook(sk_alloc_security, 0, sk, family, priority); 446562306a36Sopenharmony_ci} 446662306a36Sopenharmony_ci 446762306a36Sopenharmony_ci/** 446862306a36Sopenharmony_ci * security_sk_free() - Free the sock's LSM blob 446962306a36Sopenharmony_ci * @sk: sock 447062306a36Sopenharmony_ci * 447162306a36Sopenharmony_ci * Deallocate security structure. 447262306a36Sopenharmony_ci */ 447362306a36Sopenharmony_civoid security_sk_free(struct sock *sk) 447462306a36Sopenharmony_ci{ 447562306a36Sopenharmony_ci call_void_hook(sk_free_security, sk); 447662306a36Sopenharmony_ci} 447762306a36Sopenharmony_ci 447862306a36Sopenharmony_ci/** 447962306a36Sopenharmony_ci * security_sk_clone() - Clone a sock's LSM state 448062306a36Sopenharmony_ci * @sk: original sock 448162306a36Sopenharmony_ci * @newsk: target sock 448262306a36Sopenharmony_ci * 448362306a36Sopenharmony_ci * Clone/copy security structure. 448462306a36Sopenharmony_ci */ 448562306a36Sopenharmony_civoid security_sk_clone(const struct sock *sk, struct sock *newsk) 448662306a36Sopenharmony_ci{ 448762306a36Sopenharmony_ci call_void_hook(sk_clone_security, sk, newsk); 448862306a36Sopenharmony_ci} 448962306a36Sopenharmony_ciEXPORT_SYMBOL(security_sk_clone); 449062306a36Sopenharmony_ci 449162306a36Sopenharmony_ci/** 449262306a36Sopenharmony_ci * security_sk_classify_flow() - Set a flow's secid based on socket 449362306a36Sopenharmony_ci * @sk: original socket 449462306a36Sopenharmony_ci * @flic: target flow 449562306a36Sopenharmony_ci * 449662306a36Sopenharmony_ci * Set the target flow's secid to socket's secid. 449762306a36Sopenharmony_ci */ 449862306a36Sopenharmony_civoid security_sk_classify_flow(const struct sock *sk, struct flowi_common *flic) 449962306a36Sopenharmony_ci{ 450062306a36Sopenharmony_ci call_void_hook(sk_getsecid, sk, &flic->flowic_secid); 450162306a36Sopenharmony_ci} 450262306a36Sopenharmony_ciEXPORT_SYMBOL(security_sk_classify_flow); 450362306a36Sopenharmony_ci 450462306a36Sopenharmony_ci/** 450562306a36Sopenharmony_ci * security_req_classify_flow() - Set a flow's secid based on request_sock 450662306a36Sopenharmony_ci * @req: request_sock 450762306a36Sopenharmony_ci * @flic: target flow 450862306a36Sopenharmony_ci * 450962306a36Sopenharmony_ci * Sets @flic's secid to @req's secid. 451062306a36Sopenharmony_ci */ 451162306a36Sopenharmony_civoid security_req_classify_flow(const struct request_sock *req, 451262306a36Sopenharmony_ci struct flowi_common *flic) 451362306a36Sopenharmony_ci{ 451462306a36Sopenharmony_ci call_void_hook(req_classify_flow, req, flic); 451562306a36Sopenharmony_ci} 451662306a36Sopenharmony_ciEXPORT_SYMBOL(security_req_classify_flow); 451762306a36Sopenharmony_ci 451862306a36Sopenharmony_ci/** 451962306a36Sopenharmony_ci * security_sock_graft() - Reconcile LSM state when grafting a sock on a socket 452062306a36Sopenharmony_ci * @sk: sock being grafted 452162306a36Sopenharmony_ci * @parent: target parent socket 452262306a36Sopenharmony_ci * 452362306a36Sopenharmony_ci * Sets @parent's inode secid to @sk's secid and update @sk with any necessary 452462306a36Sopenharmony_ci * LSM state from @parent. 452562306a36Sopenharmony_ci */ 452662306a36Sopenharmony_civoid security_sock_graft(struct sock *sk, struct socket *parent) 452762306a36Sopenharmony_ci{ 452862306a36Sopenharmony_ci call_void_hook(sock_graft, sk, parent); 452962306a36Sopenharmony_ci} 453062306a36Sopenharmony_ciEXPORT_SYMBOL(security_sock_graft); 453162306a36Sopenharmony_ci 453262306a36Sopenharmony_ci/** 453362306a36Sopenharmony_ci * security_inet_conn_request() - Set request_sock state using incoming connect 453462306a36Sopenharmony_ci * @sk: parent listening sock 453562306a36Sopenharmony_ci * @skb: incoming connection 453662306a36Sopenharmony_ci * @req: new request_sock 453762306a36Sopenharmony_ci * 453862306a36Sopenharmony_ci * Initialize the @req LSM state based on @sk and the incoming connect in @skb. 453962306a36Sopenharmony_ci * 454062306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 454162306a36Sopenharmony_ci */ 454262306a36Sopenharmony_ciint security_inet_conn_request(const struct sock *sk, 454362306a36Sopenharmony_ci struct sk_buff *skb, struct request_sock *req) 454462306a36Sopenharmony_ci{ 454562306a36Sopenharmony_ci return call_int_hook(inet_conn_request, 0, sk, skb, req); 454662306a36Sopenharmony_ci} 454762306a36Sopenharmony_ciEXPORT_SYMBOL(security_inet_conn_request); 454862306a36Sopenharmony_ci 454962306a36Sopenharmony_ci/** 455062306a36Sopenharmony_ci * security_inet_csk_clone() - Set new sock LSM state based on request_sock 455162306a36Sopenharmony_ci * @newsk: new sock 455262306a36Sopenharmony_ci * @req: connection request_sock 455362306a36Sopenharmony_ci * 455462306a36Sopenharmony_ci * Set that LSM state of @sock using the LSM state from @req. 455562306a36Sopenharmony_ci */ 455662306a36Sopenharmony_civoid security_inet_csk_clone(struct sock *newsk, 455762306a36Sopenharmony_ci const struct request_sock *req) 455862306a36Sopenharmony_ci{ 455962306a36Sopenharmony_ci call_void_hook(inet_csk_clone, newsk, req); 456062306a36Sopenharmony_ci} 456162306a36Sopenharmony_ci 456262306a36Sopenharmony_ci/** 456362306a36Sopenharmony_ci * security_inet_conn_established() - Update sock's LSM state with connection 456462306a36Sopenharmony_ci * @sk: sock 456562306a36Sopenharmony_ci * @skb: connection packet 456662306a36Sopenharmony_ci * 456762306a36Sopenharmony_ci * Update @sock's LSM state to represent a new connection from @skb. 456862306a36Sopenharmony_ci */ 456962306a36Sopenharmony_civoid security_inet_conn_established(struct sock *sk, 457062306a36Sopenharmony_ci struct sk_buff *skb) 457162306a36Sopenharmony_ci{ 457262306a36Sopenharmony_ci call_void_hook(inet_conn_established, sk, skb); 457362306a36Sopenharmony_ci} 457462306a36Sopenharmony_ciEXPORT_SYMBOL(security_inet_conn_established); 457562306a36Sopenharmony_ci 457662306a36Sopenharmony_ci/** 457762306a36Sopenharmony_ci * security_secmark_relabel_packet() - Check if setting a secmark is allowed 457862306a36Sopenharmony_ci * @secid: new secmark value 457962306a36Sopenharmony_ci * 458062306a36Sopenharmony_ci * Check if the process should be allowed to relabel packets to @secid. 458162306a36Sopenharmony_ci * 458262306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 458362306a36Sopenharmony_ci */ 458462306a36Sopenharmony_ciint security_secmark_relabel_packet(u32 secid) 458562306a36Sopenharmony_ci{ 458662306a36Sopenharmony_ci return call_int_hook(secmark_relabel_packet, 0, secid); 458762306a36Sopenharmony_ci} 458862306a36Sopenharmony_ciEXPORT_SYMBOL(security_secmark_relabel_packet); 458962306a36Sopenharmony_ci 459062306a36Sopenharmony_ci/** 459162306a36Sopenharmony_ci * security_secmark_refcount_inc() - Increment the secmark labeling rule count 459262306a36Sopenharmony_ci * 459362306a36Sopenharmony_ci * Tells the LSM to increment the number of secmark labeling rules loaded. 459462306a36Sopenharmony_ci */ 459562306a36Sopenharmony_civoid security_secmark_refcount_inc(void) 459662306a36Sopenharmony_ci{ 459762306a36Sopenharmony_ci call_void_hook(secmark_refcount_inc); 459862306a36Sopenharmony_ci} 459962306a36Sopenharmony_ciEXPORT_SYMBOL(security_secmark_refcount_inc); 460062306a36Sopenharmony_ci 460162306a36Sopenharmony_ci/** 460262306a36Sopenharmony_ci * security_secmark_refcount_dec() - Decrement the secmark labeling rule count 460362306a36Sopenharmony_ci * 460462306a36Sopenharmony_ci * Tells the LSM to decrement the number of secmark labeling rules loaded. 460562306a36Sopenharmony_ci */ 460662306a36Sopenharmony_civoid security_secmark_refcount_dec(void) 460762306a36Sopenharmony_ci{ 460862306a36Sopenharmony_ci call_void_hook(secmark_refcount_dec); 460962306a36Sopenharmony_ci} 461062306a36Sopenharmony_ciEXPORT_SYMBOL(security_secmark_refcount_dec); 461162306a36Sopenharmony_ci 461262306a36Sopenharmony_ci/** 461362306a36Sopenharmony_ci * security_tun_dev_alloc_security() - Allocate a LSM blob for a TUN device 461462306a36Sopenharmony_ci * @security: pointer to the LSM blob 461562306a36Sopenharmony_ci * 461662306a36Sopenharmony_ci * This hook allows a module to allocate a security structure for a TUN device, 461762306a36Sopenharmony_ci * returning the pointer in @security. 461862306a36Sopenharmony_ci * 461962306a36Sopenharmony_ci * Return: Returns a zero on success, negative values on failure. 462062306a36Sopenharmony_ci */ 462162306a36Sopenharmony_ciint security_tun_dev_alloc_security(void **security) 462262306a36Sopenharmony_ci{ 462362306a36Sopenharmony_ci return call_int_hook(tun_dev_alloc_security, 0, security); 462462306a36Sopenharmony_ci} 462562306a36Sopenharmony_ciEXPORT_SYMBOL(security_tun_dev_alloc_security); 462662306a36Sopenharmony_ci 462762306a36Sopenharmony_ci/** 462862306a36Sopenharmony_ci * security_tun_dev_free_security() - Free a TUN device LSM blob 462962306a36Sopenharmony_ci * @security: LSM blob 463062306a36Sopenharmony_ci * 463162306a36Sopenharmony_ci * This hook allows a module to free the security structure for a TUN device. 463262306a36Sopenharmony_ci */ 463362306a36Sopenharmony_civoid security_tun_dev_free_security(void *security) 463462306a36Sopenharmony_ci{ 463562306a36Sopenharmony_ci call_void_hook(tun_dev_free_security, security); 463662306a36Sopenharmony_ci} 463762306a36Sopenharmony_ciEXPORT_SYMBOL(security_tun_dev_free_security); 463862306a36Sopenharmony_ci 463962306a36Sopenharmony_ci/** 464062306a36Sopenharmony_ci * security_tun_dev_create() - Check if creating a TUN device is allowed 464162306a36Sopenharmony_ci * 464262306a36Sopenharmony_ci * Check permissions prior to creating a new TUN device. 464362306a36Sopenharmony_ci * 464462306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 464562306a36Sopenharmony_ci */ 464662306a36Sopenharmony_ciint security_tun_dev_create(void) 464762306a36Sopenharmony_ci{ 464862306a36Sopenharmony_ci return call_int_hook(tun_dev_create, 0); 464962306a36Sopenharmony_ci} 465062306a36Sopenharmony_ciEXPORT_SYMBOL(security_tun_dev_create); 465162306a36Sopenharmony_ci 465262306a36Sopenharmony_ci/** 465362306a36Sopenharmony_ci * security_tun_dev_attach_queue() - Check if attaching a TUN queue is allowed 465462306a36Sopenharmony_ci * @security: TUN device LSM blob 465562306a36Sopenharmony_ci * 465662306a36Sopenharmony_ci * Check permissions prior to attaching to a TUN device queue. 465762306a36Sopenharmony_ci * 465862306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 465962306a36Sopenharmony_ci */ 466062306a36Sopenharmony_ciint security_tun_dev_attach_queue(void *security) 466162306a36Sopenharmony_ci{ 466262306a36Sopenharmony_ci return call_int_hook(tun_dev_attach_queue, 0, security); 466362306a36Sopenharmony_ci} 466462306a36Sopenharmony_ciEXPORT_SYMBOL(security_tun_dev_attach_queue); 466562306a36Sopenharmony_ci 466662306a36Sopenharmony_ci/** 466762306a36Sopenharmony_ci * security_tun_dev_attach() - Update TUN device LSM state on attach 466862306a36Sopenharmony_ci * @sk: associated sock 466962306a36Sopenharmony_ci * @security: TUN device LSM blob 467062306a36Sopenharmony_ci * 467162306a36Sopenharmony_ci * This hook can be used by the module to update any security state associated 467262306a36Sopenharmony_ci * with the TUN device's sock structure. 467362306a36Sopenharmony_ci * 467462306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 467562306a36Sopenharmony_ci */ 467662306a36Sopenharmony_ciint security_tun_dev_attach(struct sock *sk, void *security) 467762306a36Sopenharmony_ci{ 467862306a36Sopenharmony_ci return call_int_hook(tun_dev_attach, 0, sk, security); 467962306a36Sopenharmony_ci} 468062306a36Sopenharmony_ciEXPORT_SYMBOL(security_tun_dev_attach); 468162306a36Sopenharmony_ci 468262306a36Sopenharmony_ci/** 468362306a36Sopenharmony_ci * security_tun_dev_open() - Update TUN device LSM state on open 468462306a36Sopenharmony_ci * @security: TUN device LSM blob 468562306a36Sopenharmony_ci * 468662306a36Sopenharmony_ci * This hook can be used by the module to update any security state associated 468762306a36Sopenharmony_ci * with the TUN device's security structure. 468862306a36Sopenharmony_ci * 468962306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 469062306a36Sopenharmony_ci */ 469162306a36Sopenharmony_ciint security_tun_dev_open(void *security) 469262306a36Sopenharmony_ci{ 469362306a36Sopenharmony_ci return call_int_hook(tun_dev_open, 0, security); 469462306a36Sopenharmony_ci} 469562306a36Sopenharmony_ciEXPORT_SYMBOL(security_tun_dev_open); 469662306a36Sopenharmony_ci 469762306a36Sopenharmony_ci/** 469862306a36Sopenharmony_ci * security_sctp_assoc_request() - Update the LSM on a SCTP association req 469962306a36Sopenharmony_ci * @asoc: SCTP association 470062306a36Sopenharmony_ci * @skb: packet requesting the association 470162306a36Sopenharmony_ci * 470262306a36Sopenharmony_ci * Passes the @asoc and @chunk->skb of the association INIT packet to the LSM. 470362306a36Sopenharmony_ci * 470462306a36Sopenharmony_ci * Return: Returns 0 on success, error on failure. 470562306a36Sopenharmony_ci */ 470662306a36Sopenharmony_ciint security_sctp_assoc_request(struct sctp_association *asoc, 470762306a36Sopenharmony_ci struct sk_buff *skb) 470862306a36Sopenharmony_ci{ 470962306a36Sopenharmony_ci return call_int_hook(sctp_assoc_request, 0, asoc, skb); 471062306a36Sopenharmony_ci} 471162306a36Sopenharmony_ciEXPORT_SYMBOL(security_sctp_assoc_request); 471262306a36Sopenharmony_ci 471362306a36Sopenharmony_ci/** 471462306a36Sopenharmony_ci * security_sctp_bind_connect() - Validate a list of addrs for a SCTP option 471562306a36Sopenharmony_ci * @sk: socket 471662306a36Sopenharmony_ci * @optname: SCTP option to validate 471762306a36Sopenharmony_ci * @address: list of IP addresses to validate 471862306a36Sopenharmony_ci * @addrlen: length of the address list 471962306a36Sopenharmony_ci * 472062306a36Sopenharmony_ci * Validiate permissions required for each address associated with sock @sk. 472162306a36Sopenharmony_ci * Depending on @optname, the addresses will be treated as either a connect or 472262306a36Sopenharmony_ci * bind service. The @addrlen is calculated on each IPv4 and IPv6 address using 472362306a36Sopenharmony_ci * sizeof(struct sockaddr_in) or sizeof(struct sockaddr_in6). 472462306a36Sopenharmony_ci * 472562306a36Sopenharmony_ci * Return: Returns 0 on success, error on failure. 472662306a36Sopenharmony_ci */ 472762306a36Sopenharmony_ciint security_sctp_bind_connect(struct sock *sk, int optname, 472862306a36Sopenharmony_ci struct sockaddr *address, int addrlen) 472962306a36Sopenharmony_ci{ 473062306a36Sopenharmony_ci return call_int_hook(sctp_bind_connect, 0, sk, optname, 473162306a36Sopenharmony_ci address, addrlen); 473262306a36Sopenharmony_ci} 473362306a36Sopenharmony_ciEXPORT_SYMBOL(security_sctp_bind_connect); 473462306a36Sopenharmony_ci 473562306a36Sopenharmony_ci/** 473662306a36Sopenharmony_ci * security_sctp_sk_clone() - Clone a SCTP sock's LSM state 473762306a36Sopenharmony_ci * @asoc: SCTP association 473862306a36Sopenharmony_ci * @sk: original sock 473962306a36Sopenharmony_ci * @newsk: target sock 474062306a36Sopenharmony_ci * 474162306a36Sopenharmony_ci * Called whenever a new socket is created by accept(2) (i.e. a TCP style 474262306a36Sopenharmony_ci * socket) or when a socket is 'peeled off' e.g userspace calls 474362306a36Sopenharmony_ci * sctp_peeloff(3). 474462306a36Sopenharmony_ci */ 474562306a36Sopenharmony_civoid security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk, 474662306a36Sopenharmony_ci struct sock *newsk) 474762306a36Sopenharmony_ci{ 474862306a36Sopenharmony_ci call_void_hook(sctp_sk_clone, asoc, sk, newsk); 474962306a36Sopenharmony_ci} 475062306a36Sopenharmony_ciEXPORT_SYMBOL(security_sctp_sk_clone); 475162306a36Sopenharmony_ci 475262306a36Sopenharmony_ci/** 475362306a36Sopenharmony_ci * security_sctp_assoc_established() - Update LSM state when assoc established 475462306a36Sopenharmony_ci * @asoc: SCTP association 475562306a36Sopenharmony_ci * @skb: packet establishing the association 475662306a36Sopenharmony_ci * 475762306a36Sopenharmony_ci * Passes the @asoc and @chunk->skb of the association COOKIE_ACK packet to the 475862306a36Sopenharmony_ci * security module. 475962306a36Sopenharmony_ci * 476062306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 476162306a36Sopenharmony_ci */ 476262306a36Sopenharmony_ciint security_sctp_assoc_established(struct sctp_association *asoc, 476362306a36Sopenharmony_ci struct sk_buff *skb) 476462306a36Sopenharmony_ci{ 476562306a36Sopenharmony_ci return call_int_hook(sctp_assoc_established, 0, asoc, skb); 476662306a36Sopenharmony_ci} 476762306a36Sopenharmony_ciEXPORT_SYMBOL(security_sctp_assoc_established); 476862306a36Sopenharmony_ci 476962306a36Sopenharmony_ci/** 477062306a36Sopenharmony_ci * security_mptcp_add_subflow() - Inherit the LSM label from the MPTCP socket 477162306a36Sopenharmony_ci * @sk: the owning MPTCP socket 477262306a36Sopenharmony_ci * @ssk: the new subflow 477362306a36Sopenharmony_ci * 477462306a36Sopenharmony_ci * Update the labeling for the given MPTCP subflow, to match the one of the 477562306a36Sopenharmony_ci * owning MPTCP socket. This hook has to be called after the socket creation and 477662306a36Sopenharmony_ci * initialization via the security_socket_create() and 477762306a36Sopenharmony_ci * security_socket_post_create() LSM hooks. 477862306a36Sopenharmony_ci * 477962306a36Sopenharmony_ci * Return: Returns 0 on success or a negative error code on failure. 478062306a36Sopenharmony_ci */ 478162306a36Sopenharmony_ciint security_mptcp_add_subflow(struct sock *sk, struct sock *ssk) 478262306a36Sopenharmony_ci{ 478362306a36Sopenharmony_ci return call_int_hook(mptcp_add_subflow, 0, sk, ssk); 478462306a36Sopenharmony_ci} 478562306a36Sopenharmony_ci 478662306a36Sopenharmony_ci#endif /* CONFIG_SECURITY_NETWORK */ 478762306a36Sopenharmony_ci 478862306a36Sopenharmony_ci#ifdef CONFIG_SECURITY_INFINIBAND 478962306a36Sopenharmony_ci/** 479062306a36Sopenharmony_ci * security_ib_pkey_access() - Check if access to an IB pkey is allowed 479162306a36Sopenharmony_ci * @sec: LSM blob 479262306a36Sopenharmony_ci * @subnet_prefix: subnet prefix of the port 479362306a36Sopenharmony_ci * @pkey: IB pkey 479462306a36Sopenharmony_ci * 479562306a36Sopenharmony_ci * Check permission to access a pkey when modifying a QP. 479662306a36Sopenharmony_ci * 479762306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 479862306a36Sopenharmony_ci */ 479962306a36Sopenharmony_ciint security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey) 480062306a36Sopenharmony_ci{ 480162306a36Sopenharmony_ci return call_int_hook(ib_pkey_access, 0, sec, subnet_prefix, pkey); 480262306a36Sopenharmony_ci} 480362306a36Sopenharmony_ciEXPORT_SYMBOL(security_ib_pkey_access); 480462306a36Sopenharmony_ci 480562306a36Sopenharmony_ci/** 480662306a36Sopenharmony_ci * security_ib_endport_manage_subnet() - Check if SMPs traffic is allowed 480762306a36Sopenharmony_ci * @sec: LSM blob 480862306a36Sopenharmony_ci * @dev_name: IB device name 480962306a36Sopenharmony_ci * @port_num: port number 481062306a36Sopenharmony_ci * 481162306a36Sopenharmony_ci * Check permissions to send and receive SMPs on a end port. 481262306a36Sopenharmony_ci * 481362306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 481462306a36Sopenharmony_ci */ 481562306a36Sopenharmony_ciint security_ib_endport_manage_subnet(void *sec, 481662306a36Sopenharmony_ci const char *dev_name, u8 port_num) 481762306a36Sopenharmony_ci{ 481862306a36Sopenharmony_ci return call_int_hook(ib_endport_manage_subnet, 0, sec, 481962306a36Sopenharmony_ci dev_name, port_num); 482062306a36Sopenharmony_ci} 482162306a36Sopenharmony_ciEXPORT_SYMBOL(security_ib_endport_manage_subnet); 482262306a36Sopenharmony_ci 482362306a36Sopenharmony_ci/** 482462306a36Sopenharmony_ci * security_ib_alloc_security() - Allocate an Infiniband LSM blob 482562306a36Sopenharmony_ci * @sec: LSM blob 482662306a36Sopenharmony_ci * 482762306a36Sopenharmony_ci * Allocate a security structure for Infiniband objects. 482862306a36Sopenharmony_ci * 482962306a36Sopenharmony_ci * Return: Returns 0 on success, non-zero on failure. 483062306a36Sopenharmony_ci */ 483162306a36Sopenharmony_ciint security_ib_alloc_security(void **sec) 483262306a36Sopenharmony_ci{ 483362306a36Sopenharmony_ci return call_int_hook(ib_alloc_security, 0, sec); 483462306a36Sopenharmony_ci} 483562306a36Sopenharmony_ciEXPORT_SYMBOL(security_ib_alloc_security); 483662306a36Sopenharmony_ci 483762306a36Sopenharmony_ci/** 483862306a36Sopenharmony_ci * security_ib_free_security() - Free an Infiniband LSM blob 483962306a36Sopenharmony_ci * @sec: LSM blob 484062306a36Sopenharmony_ci * 484162306a36Sopenharmony_ci * Deallocate an Infiniband security structure. 484262306a36Sopenharmony_ci */ 484362306a36Sopenharmony_civoid security_ib_free_security(void *sec) 484462306a36Sopenharmony_ci{ 484562306a36Sopenharmony_ci call_void_hook(ib_free_security, sec); 484662306a36Sopenharmony_ci} 484762306a36Sopenharmony_ciEXPORT_SYMBOL(security_ib_free_security); 484862306a36Sopenharmony_ci#endif /* CONFIG_SECURITY_INFINIBAND */ 484962306a36Sopenharmony_ci 485062306a36Sopenharmony_ci#ifdef CONFIG_SECURITY_NETWORK_XFRM 485162306a36Sopenharmony_ci/** 485262306a36Sopenharmony_ci * security_xfrm_policy_alloc() - Allocate a xfrm policy LSM blob 485362306a36Sopenharmony_ci * @ctxp: xfrm security context being added to the SPD 485462306a36Sopenharmony_ci * @sec_ctx: security label provided by userspace 485562306a36Sopenharmony_ci * @gfp: gfp flags 485662306a36Sopenharmony_ci * 485762306a36Sopenharmony_ci * Allocate a security structure to the xp->security field; the security field 485862306a36Sopenharmony_ci * is initialized to NULL when the xfrm_policy is allocated. 485962306a36Sopenharmony_ci * 486062306a36Sopenharmony_ci * Return: Return 0 if operation was successful. 486162306a36Sopenharmony_ci */ 486262306a36Sopenharmony_ciint security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, 486362306a36Sopenharmony_ci struct xfrm_user_sec_ctx *sec_ctx, 486462306a36Sopenharmony_ci gfp_t gfp) 486562306a36Sopenharmony_ci{ 486662306a36Sopenharmony_ci return call_int_hook(xfrm_policy_alloc_security, 0, ctxp, sec_ctx, gfp); 486762306a36Sopenharmony_ci} 486862306a36Sopenharmony_ciEXPORT_SYMBOL(security_xfrm_policy_alloc); 486962306a36Sopenharmony_ci 487062306a36Sopenharmony_ci/** 487162306a36Sopenharmony_ci * security_xfrm_policy_clone() - Clone xfrm policy LSM state 487262306a36Sopenharmony_ci * @old_ctx: xfrm security context 487362306a36Sopenharmony_ci * @new_ctxp: target xfrm security context 487462306a36Sopenharmony_ci * 487562306a36Sopenharmony_ci * Allocate a security structure in new_ctxp that contains the information from 487662306a36Sopenharmony_ci * the old_ctx structure. 487762306a36Sopenharmony_ci * 487862306a36Sopenharmony_ci * Return: Return 0 if operation was successful. 487962306a36Sopenharmony_ci */ 488062306a36Sopenharmony_ciint security_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, 488162306a36Sopenharmony_ci struct xfrm_sec_ctx **new_ctxp) 488262306a36Sopenharmony_ci{ 488362306a36Sopenharmony_ci return call_int_hook(xfrm_policy_clone_security, 0, old_ctx, new_ctxp); 488462306a36Sopenharmony_ci} 488562306a36Sopenharmony_ci 488662306a36Sopenharmony_ci/** 488762306a36Sopenharmony_ci * security_xfrm_policy_free() - Free a xfrm security context 488862306a36Sopenharmony_ci * @ctx: xfrm security context 488962306a36Sopenharmony_ci * 489062306a36Sopenharmony_ci * Free LSM resources associated with @ctx. 489162306a36Sopenharmony_ci */ 489262306a36Sopenharmony_civoid security_xfrm_policy_free(struct xfrm_sec_ctx *ctx) 489362306a36Sopenharmony_ci{ 489462306a36Sopenharmony_ci call_void_hook(xfrm_policy_free_security, ctx); 489562306a36Sopenharmony_ci} 489662306a36Sopenharmony_ciEXPORT_SYMBOL(security_xfrm_policy_free); 489762306a36Sopenharmony_ci 489862306a36Sopenharmony_ci/** 489962306a36Sopenharmony_ci * security_xfrm_policy_delete() - Check if deleting a xfrm policy is allowed 490062306a36Sopenharmony_ci * @ctx: xfrm security context 490162306a36Sopenharmony_ci * 490262306a36Sopenharmony_ci * Authorize deletion of a SPD entry. 490362306a36Sopenharmony_ci * 490462306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 490562306a36Sopenharmony_ci */ 490662306a36Sopenharmony_ciint security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) 490762306a36Sopenharmony_ci{ 490862306a36Sopenharmony_ci return call_int_hook(xfrm_policy_delete_security, 0, ctx); 490962306a36Sopenharmony_ci} 491062306a36Sopenharmony_ci 491162306a36Sopenharmony_ci/** 491262306a36Sopenharmony_ci * security_xfrm_state_alloc() - Allocate a xfrm state LSM blob 491362306a36Sopenharmony_ci * @x: xfrm state being added to the SAD 491462306a36Sopenharmony_ci * @sec_ctx: security label provided by userspace 491562306a36Sopenharmony_ci * 491662306a36Sopenharmony_ci * Allocate a security structure to the @x->security field; the security field 491762306a36Sopenharmony_ci * is initialized to NULL when the xfrm_state is allocated. Set the context to 491862306a36Sopenharmony_ci * correspond to @sec_ctx. 491962306a36Sopenharmony_ci * 492062306a36Sopenharmony_ci * Return: Return 0 if operation was successful. 492162306a36Sopenharmony_ci */ 492262306a36Sopenharmony_ciint security_xfrm_state_alloc(struct xfrm_state *x, 492362306a36Sopenharmony_ci struct xfrm_user_sec_ctx *sec_ctx) 492462306a36Sopenharmony_ci{ 492562306a36Sopenharmony_ci return call_int_hook(xfrm_state_alloc, 0, x, sec_ctx); 492662306a36Sopenharmony_ci} 492762306a36Sopenharmony_ciEXPORT_SYMBOL(security_xfrm_state_alloc); 492862306a36Sopenharmony_ci 492962306a36Sopenharmony_ci/** 493062306a36Sopenharmony_ci * security_xfrm_state_alloc_acquire() - Allocate a xfrm state LSM blob 493162306a36Sopenharmony_ci * @x: xfrm state being added to the SAD 493262306a36Sopenharmony_ci * @polsec: associated policy's security context 493362306a36Sopenharmony_ci * @secid: secid from the flow 493462306a36Sopenharmony_ci * 493562306a36Sopenharmony_ci * Allocate a security structure to the x->security field; the security field 493662306a36Sopenharmony_ci * is initialized to NULL when the xfrm_state is allocated. Set the context to 493762306a36Sopenharmony_ci * correspond to secid. 493862306a36Sopenharmony_ci * 493962306a36Sopenharmony_ci * Return: Returns 0 if operation was successful. 494062306a36Sopenharmony_ci */ 494162306a36Sopenharmony_ciint security_xfrm_state_alloc_acquire(struct xfrm_state *x, 494262306a36Sopenharmony_ci struct xfrm_sec_ctx *polsec, u32 secid) 494362306a36Sopenharmony_ci{ 494462306a36Sopenharmony_ci return call_int_hook(xfrm_state_alloc_acquire, 0, x, polsec, secid); 494562306a36Sopenharmony_ci} 494662306a36Sopenharmony_ci 494762306a36Sopenharmony_ci/** 494862306a36Sopenharmony_ci * security_xfrm_state_delete() - Check if deleting a xfrm state is allowed 494962306a36Sopenharmony_ci * @x: xfrm state 495062306a36Sopenharmony_ci * 495162306a36Sopenharmony_ci * Authorize deletion of x->security. 495262306a36Sopenharmony_ci * 495362306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 495462306a36Sopenharmony_ci */ 495562306a36Sopenharmony_ciint security_xfrm_state_delete(struct xfrm_state *x) 495662306a36Sopenharmony_ci{ 495762306a36Sopenharmony_ci return call_int_hook(xfrm_state_delete_security, 0, x); 495862306a36Sopenharmony_ci} 495962306a36Sopenharmony_ciEXPORT_SYMBOL(security_xfrm_state_delete); 496062306a36Sopenharmony_ci 496162306a36Sopenharmony_ci/** 496262306a36Sopenharmony_ci * security_xfrm_state_free() - Free a xfrm state 496362306a36Sopenharmony_ci * @x: xfrm state 496462306a36Sopenharmony_ci * 496562306a36Sopenharmony_ci * Deallocate x->security. 496662306a36Sopenharmony_ci */ 496762306a36Sopenharmony_civoid security_xfrm_state_free(struct xfrm_state *x) 496862306a36Sopenharmony_ci{ 496962306a36Sopenharmony_ci call_void_hook(xfrm_state_free_security, x); 497062306a36Sopenharmony_ci} 497162306a36Sopenharmony_ci 497262306a36Sopenharmony_ci/** 497362306a36Sopenharmony_ci * security_xfrm_policy_lookup() - Check if using a xfrm policy is allowed 497462306a36Sopenharmony_ci * @ctx: target xfrm security context 497562306a36Sopenharmony_ci * @fl_secid: flow secid used to authorize access 497662306a36Sopenharmony_ci * 497762306a36Sopenharmony_ci * Check permission when a flow selects a xfrm_policy for processing XFRMs on a 497862306a36Sopenharmony_ci * packet. The hook is called when selecting either a per-socket policy or a 497962306a36Sopenharmony_ci * generic xfrm policy. 498062306a36Sopenharmony_ci * 498162306a36Sopenharmony_ci * Return: Return 0 if permission is granted, -ESRCH otherwise, or -errno on 498262306a36Sopenharmony_ci * other errors. 498362306a36Sopenharmony_ci */ 498462306a36Sopenharmony_ciint security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid) 498562306a36Sopenharmony_ci{ 498662306a36Sopenharmony_ci return call_int_hook(xfrm_policy_lookup, 0, ctx, fl_secid); 498762306a36Sopenharmony_ci} 498862306a36Sopenharmony_ci 498962306a36Sopenharmony_ci/** 499062306a36Sopenharmony_ci * security_xfrm_state_pol_flow_match() - Check for a xfrm match 499162306a36Sopenharmony_ci * @x: xfrm state to match 499262306a36Sopenharmony_ci * @xp: xfrm policy to check for a match 499362306a36Sopenharmony_ci * @flic: flow to check for a match. 499462306a36Sopenharmony_ci * 499562306a36Sopenharmony_ci * Check @xp and @flic for a match with @x. 499662306a36Sopenharmony_ci * 499762306a36Sopenharmony_ci * Return: Returns 1 if there is a match. 499862306a36Sopenharmony_ci */ 499962306a36Sopenharmony_ciint security_xfrm_state_pol_flow_match(struct xfrm_state *x, 500062306a36Sopenharmony_ci struct xfrm_policy *xp, 500162306a36Sopenharmony_ci const struct flowi_common *flic) 500262306a36Sopenharmony_ci{ 500362306a36Sopenharmony_ci struct security_hook_list *hp; 500462306a36Sopenharmony_ci int rc = LSM_RET_DEFAULT(xfrm_state_pol_flow_match); 500562306a36Sopenharmony_ci 500662306a36Sopenharmony_ci /* 500762306a36Sopenharmony_ci * Since this function is expected to return 0 or 1, the judgment 500862306a36Sopenharmony_ci * becomes difficult if multiple LSMs supply this call. Fortunately, 500962306a36Sopenharmony_ci * we can use the first LSM's judgment because currently only SELinux 501062306a36Sopenharmony_ci * supplies this call. 501162306a36Sopenharmony_ci * 501262306a36Sopenharmony_ci * For speed optimization, we explicitly break the loop rather than 501362306a36Sopenharmony_ci * using the macro 501462306a36Sopenharmony_ci */ 501562306a36Sopenharmony_ci hlist_for_each_entry(hp, &security_hook_heads.xfrm_state_pol_flow_match, 501662306a36Sopenharmony_ci list) { 501762306a36Sopenharmony_ci rc = hp->hook.xfrm_state_pol_flow_match(x, xp, flic); 501862306a36Sopenharmony_ci break; 501962306a36Sopenharmony_ci } 502062306a36Sopenharmony_ci return rc; 502162306a36Sopenharmony_ci} 502262306a36Sopenharmony_ci 502362306a36Sopenharmony_ci/** 502462306a36Sopenharmony_ci * security_xfrm_decode_session() - Determine the xfrm secid for a packet 502562306a36Sopenharmony_ci * @skb: xfrm packet 502662306a36Sopenharmony_ci * @secid: secid 502762306a36Sopenharmony_ci * 502862306a36Sopenharmony_ci * Decode the packet in @skb and return the security label in @secid. 502962306a36Sopenharmony_ci * 503062306a36Sopenharmony_ci * Return: Return 0 if all xfrms used have the same secid. 503162306a36Sopenharmony_ci */ 503262306a36Sopenharmony_ciint security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) 503362306a36Sopenharmony_ci{ 503462306a36Sopenharmony_ci return call_int_hook(xfrm_decode_session, 0, skb, secid, 1); 503562306a36Sopenharmony_ci} 503662306a36Sopenharmony_ci 503762306a36Sopenharmony_civoid security_skb_classify_flow(struct sk_buff *skb, struct flowi_common *flic) 503862306a36Sopenharmony_ci{ 503962306a36Sopenharmony_ci int rc = call_int_hook(xfrm_decode_session, 0, skb, &flic->flowic_secid, 504062306a36Sopenharmony_ci 0); 504162306a36Sopenharmony_ci 504262306a36Sopenharmony_ci BUG_ON(rc); 504362306a36Sopenharmony_ci} 504462306a36Sopenharmony_ciEXPORT_SYMBOL(security_skb_classify_flow); 504562306a36Sopenharmony_ci#endif /* CONFIG_SECURITY_NETWORK_XFRM */ 504662306a36Sopenharmony_ci 504762306a36Sopenharmony_ci#ifdef CONFIG_KEYS 504862306a36Sopenharmony_ci/** 504962306a36Sopenharmony_ci * security_key_alloc() - Allocate and initialize a kernel key LSM blob 505062306a36Sopenharmony_ci * @key: key 505162306a36Sopenharmony_ci * @cred: credentials 505262306a36Sopenharmony_ci * @flags: allocation flags 505362306a36Sopenharmony_ci * 505462306a36Sopenharmony_ci * Permit allocation of a key and assign security data. Note that key does not 505562306a36Sopenharmony_ci * have a serial number assigned at this point. 505662306a36Sopenharmony_ci * 505762306a36Sopenharmony_ci * Return: Return 0 if permission is granted, -ve error otherwise. 505862306a36Sopenharmony_ci */ 505962306a36Sopenharmony_ciint security_key_alloc(struct key *key, const struct cred *cred, 506062306a36Sopenharmony_ci unsigned long flags) 506162306a36Sopenharmony_ci{ 506262306a36Sopenharmony_ci return call_int_hook(key_alloc, 0, key, cred, flags); 506362306a36Sopenharmony_ci} 506462306a36Sopenharmony_ci 506562306a36Sopenharmony_ci/** 506662306a36Sopenharmony_ci * security_key_free() - Free a kernel key LSM blob 506762306a36Sopenharmony_ci * @key: key 506862306a36Sopenharmony_ci * 506962306a36Sopenharmony_ci * Notification of destruction; free security data. 507062306a36Sopenharmony_ci */ 507162306a36Sopenharmony_civoid security_key_free(struct key *key) 507262306a36Sopenharmony_ci{ 507362306a36Sopenharmony_ci call_void_hook(key_free, key); 507462306a36Sopenharmony_ci} 507562306a36Sopenharmony_ci 507662306a36Sopenharmony_ci/** 507762306a36Sopenharmony_ci * security_key_permission() - Check if a kernel key operation is allowed 507862306a36Sopenharmony_ci * @key_ref: key reference 507962306a36Sopenharmony_ci * @cred: credentials of actor requesting access 508062306a36Sopenharmony_ci * @need_perm: requested permissions 508162306a36Sopenharmony_ci * 508262306a36Sopenharmony_ci * See whether a specific operational right is granted to a process on a key. 508362306a36Sopenharmony_ci * 508462306a36Sopenharmony_ci * Return: Return 0 if permission is granted, -ve error otherwise. 508562306a36Sopenharmony_ci */ 508662306a36Sopenharmony_ciint security_key_permission(key_ref_t key_ref, const struct cred *cred, 508762306a36Sopenharmony_ci enum key_need_perm need_perm) 508862306a36Sopenharmony_ci{ 508962306a36Sopenharmony_ci return call_int_hook(key_permission, 0, key_ref, cred, need_perm); 509062306a36Sopenharmony_ci} 509162306a36Sopenharmony_ci 509262306a36Sopenharmony_ci/** 509362306a36Sopenharmony_ci * security_key_getsecurity() - Get the key's security label 509462306a36Sopenharmony_ci * @key: key 509562306a36Sopenharmony_ci * @buffer: security label buffer 509662306a36Sopenharmony_ci * 509762306a36Sopenharmony_ci * Get a textual representation of the security context attached to a key for 509862306a36Sopenharmony_ci * the purposes of honouring KEYCTL_GETSECURITY. This function allocates the 509962306a36Sopenharmony_ci * storage for the NUL-terminated string and the caller should free it. 510062306a36Sopenharmony_ci * 510162306a36Sopenharmony_ci * Return: Returns the length of @buffer (including terminating NUL) or -ve if 510262306a36Sopenharmony_ci * an error occurs. May also return 0 (and a NULL buffer pointer) if 510362306a36Sopenharmony_ci * there is no security label assigned to the key. 510462306a36Sopenharmony_ci */ 510562306a36Sopenharmony_ciint security_key_getsecurity(struct key *key, char **buffer) 510662306a36Sopenharmony_ci{ 510762306a36Sopenharmony_ci *buffer = NULL; 510862306a36Sopenharmony_ci return call_int_hook(key_getsecurity, 0, key, buffer); 510962306a36Sopenharmony_ci} 511062306a36Sopenharmony_ci#endif /* CONFIG_KEYS */ 511162306a36Sopenharmony_ci 511262306a36Sopenharmony_ci#ifdef CONFIG_AUDIT 511362306a36Sopenharmony_ci/** 511462306a36Sopenharmony_ci * security_audit_rule_init() - Allocate and init an LSM audit rule struct 511562306a36Sopenharmony_ci * @field: audit action 511662306a36Sopenharmony_ci * @op: rule operator 511762306a36Sopenharmony_ci * @rulestr: rule context 511862306a36Sopenharmony_ci * @lsmrule: receive buffer for audit rule struct 511962306a36Sopenharmony_ci * 512062306a36Sopenharmony_ci * Allocate and initialize an LSM audit rule structure. 512162306a36Sopenharmony_ci * 512262306a36Sopenharmony_ci * Return: Return 0 if @lsmrule has been successfully set, -EINVAL in case of 512362306a36Sopenharmony_ci * an invalid rule. 512462306a36Sopenharmony_ci */ 512562306a36Sopenharmony_ciint security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) 512662306a36Sopenharmony_ci{ 512762306a36Sopenharmony_ci return call_int_hook(audit_rule_init, 0, field, op, rulestr, lsmrule); 512862306a36Sopenharmony_ci} 512962306a36Sopenharmony_ci 513062306a36Sopenharmony_ci/** 513162306a36Sopenharmony_ci * security_audit_rule_known() - Check if an audit rule contains LSM fields 513262306a36Sopenharmony_ci * @krule: audit rule 513362306a36Sopenharmony_ci * 513462306a36Sopenharmony_ci * Specifies whether given @krule contains any fields related to the current 513562306a36Sopenharmony_ci * LSM. 513662306a36Sopenharmony_ci * 513762306a36Sopenharmony_ci * Return: Returns 1 in case of relation found, 0 otherwise. 513862306a36Sopenharmony_ci */ 513962306a36Sopenharmony_ciint security_audit_rule_known(struct audit_krule *krule) 514062306a36Sopenharmony_ci{ 514162306a36Sopenharmony_ci return call_int_hook(audit_rule_known, 0, krule); 514262306a36Sopenharmony_ci} 514362306a36Sopenharmony_ci 514462306a36Sopenharmony_ci/** 514562306a36Sopenharmony_ci * security_audit_rule_free() - Free an LSM audit rule struct 514662306a36Sopenharmony_ci * @lsmrule: audit rule struct 514762306a36Sopenharmony_ci * 514862306a36Sopenharmony_ci * Deallocate the LSM audit rule structure previously allocated by 514962306a36Sopenharmony_ci * audit_rule_init(). 515062306a36Sopenharmony_ci */ 515162306a36Sopenharmony_civoid security_audit_rule_free(void *lsmrule) 515262306a36Sopenharmony_ci{ 515362306a36Sopenharmony_ci call_void_hook(audit_rule_free, lsmrule); 515462306a36Sopenharmony_ci} 515562306a36Sopenharmony_ci 515662306a36Sopenharmony_ci/** 515762306a36Sopenharmony_ci * security_audit_rule_match() - Check if a label matches an audit rule 515862306a36Sopenharmony_ci * @secid: security label 515962306a36Sopenharmony_ci * @field: LSM audit field 516062306a36Sopenharmony_ci * @op: matching operator 516162306a36Sopenharmony_ci * @lsmrule: audit rule 516262306a36Sopenharmony_ci * 516362306a36Sopenharmony_ci * Determine if given @secid matches a rule previously approved by 516462306a36Sopenharmony_ci * security_audit_rule_known(). 516562306a36Sopenharmony_ci * 516662306a36Sopenharmony_ci * Return: Returns 1 if secid matches the rule, 0 if it does not, -ERRNO on 516762306a36Sopenharmony_ci * failure. 516862306a36Sopenharmony_ci */ 516962306a36Sopenharmony_ciint security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule) 517062306a36Sopenharmony_ci{ 517162306a36Sopenharmony_ci return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule); 517262306a36Sopenharmony_ci} 517362306a36Sopenharmony_ci#endif /* CONFIG_AUDIT */ 517462306a36Sopenharmony_ci 517562306a36Sopenharmony_ci#ifdef CONFIG_BPF_SYSCALL 517662306a36Sopenharmony_ci/** 517762306a36Sopenharmony_ci * security_bpf() - Check if the bpf syscall operation is allowed 517862306a36Sopenharmony_ci * @cmd: command 517962306a36Sopenharmony_ci * @attr: bpf attribute 518062306a36Sopenharmony_ci * @size: size 518162306a36Sopenharmony_ci * 518262306a36Sopenharmony_ci * Do a initial check for all bpf syscalls after the attribute is copied into 518362306a36Sopenharmony_ci * the kernel. The actual security module can implement their own rules to 518462306a36Sopenharmony_ci * check the specific cmd they need. 518562306a36Sopenharmony_ci * 518662306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 518762306a36Sopenharmony_ci */ 518862306a36Sopenharmony_ciint security_bpf(int cmd, union bpf_attr *attr, unsigned int size) 518962306a36Sopenharmony_ci{ 519062306a36Sopenharmony_ci return call_int_hook(bpf, 0, cmd, attr, size); 519162306a36Sopenharmony_ci} 519262306a36Sopenharmony_ci 519362306a36Sopenharmony_ci/** 519462306a36Sopenharmony_ci * security_bpf_map() - Check if access to a bpf map is allowed 519562306a36Sopenharmony_ci * @map: bpf map 519662306a36Sopenharmony_ci * @fmode: mode 519762306a36Sopenharmony_ci * 519862306a36Sopenharmony_ci * Do a check when the kernel generates and returns a file descriptor for eBPF 519962306a36Sopenharmony_ci * maps. 520062306a36Sopenharmony_ci * 520162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 520262306a36Sopenharmony_ci */ 520362306a36Sopenharmony_ciint security_bpf_map(struct bpf_map *map, fmode_t fmode) 520462306a36Sopenharmony_ci{ 520562306a36Sopenharmony_ci return call_int_hook(bpf_map, 0, map, fmode); 520662306a36Sopenharmony_ci} 520762306a36Sopenharmony_ci 520862306a36Sopenharmony_ci/** 520962306a36Sopenharmony_ci * security_bpf_prog() - Check if access to a bpf program is allowed 521062306a36Sopenharmony_ci * @prog: bpf program 521162306a36Sopenharmony_ci * 521262306a36Sopenharmony_ci * Do a check when the kernel generates and returns a file descriptor for eBPF 521362306a36Sopenharmony_ci * programs. 521462306a36Sopenharmony_ci * 521562306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 521662306a36Sopenharmony_ci */ 521762306a36Sopenharmony_ciint security_bpf_prog(struct bpf_prog *prog) 521862306a36Sopenharmony_ci{ 521962306a36Sopenharmony_ci return call_int_hook(bpf_prog, 0, prog); 522062306a36Sopenharmony_ci} 522162306a36Sopenharmony_ci 522262306a36Sopenharmony_ci/** 522362306a36Sopenharmony_ci * security_bpf_map_alloc() - Allocate a bpf map LSM blob 522462306a36Sopenharmony_ci * @map: bpf map 522562306a36Sopenharmony_ci * 522662306a36Sopenharmony_ci * Initialize the security field inside bpf map. 522762306a36Sopenharmony_ci * 522862306a36Sopenharmony_ci * Return: Returns 0 on success, error on failure. 522962306a36Sopenharmony_ci */ 523062306a36Sopenharmony_ciint security_bpf_map_alloc(struct bpf_map *map) 523162306a36Sopenharmony_ci{ 523262306a36Sopenharmony_ci return call_int_hook(bpf_map_alloc_security, 0, map); 523362306a36Sopenharmony_ci} 523462306a36Sopenharmony_ci 523562306a36Sopenharmony_ci/** 523662306a36Sopenharmony_ci * security_bpf_prog_alloc() - Allocate a bpf program LSM blob 523762306a36Sopenharmony_ci * @aux: bpf program aux info struct 523862306a36Sopenharmony_ci * 523962306a36Sopenharmony_ci * Initialize the security field inside bpf program. 524062306a36Sopenharmony_ci * 524162306a36Sopenharmony_ci * Return: Returns 0 on success, error on failure. 524262306a36Sopenharmony_ci */ 524362306a36Sopenharmony_ciint security_bpf_prog_alloc(struct bpf_prog_aux *aux) 524462306a36Sopenharmony_ci{ 524562306a36Sopenharmony_ci return call_int_hook(bpf_prog_alloc_security, 0, aux); 524662306a36Sopenharmony_ci} 524762306a36Sopenharmony_ci 524862306a36Sopenharmony_ci/** 524962306a36Sopenharmony_ci * security_bpf_map_free() - Free a bpf map's LSM blob 525062306a36Sopenharmony_ci * @map: bpf map 525162306a36Sopenharmony_ci * 525262306a36Sopenharmony_ci * Clean up the security information stored inside bpf map. 525362306a36Sopenharmony_ci */ 525462306a36Sopenharmony_civoid security_bpf_map_free(struct bpf_map *map) 525562306a36Sopenharmony_ci{ 525662306a36Sopenharmony_ci call_void_hook(bpf_map_free_security, map); 525762306a36Sopenharmony_ci} 525862306a36Sopenharmony_ci 525962306a36Sopenharmony_ci/** 526062306a36Sopenharmony_ci * security_bpf_prog_free() - Free a bpf program's LSM blob 526162306a36Sopenharmony_ci * @aux: bpf program aux info struct 526262306a36Sopenharmony_ci * 526362306a36Sopenharmony_ci * Clean up the security information stored inside bpf prog. 526462306a36Sopenharmony_ci */ 526562306a36Sopenharmony_civoid security_bpf_prog_free(struct bpf_prog_aux *aux) 526662306a36Sopenharmony_ci{ 526762306a36Sopenharmony_ci call_void_hook(bpf_prog_free_security, aux); 526862306a36Sopenharmony_ci} 526962306a36Sopenharmony_ci#endif /* CONFIG_BPF_SYSCALL */ 527062306a36Sopenharmony_ci 527162306a36Sopenharmony_ci/** 527262306a36Sopenharmony_ci * security_locked_down() - Check if a kernel feature is allowed 527362306a36Sopenharmony_ci * @what: requested kernel feature 527462306a36Sopenharmony_ci * 527562306a36Sopenharmony_ci * Determine whether a kernel feature that potentially enables arbitrary code 527662306a36Sopenharmony_ci * execution in kernel space should be permitted. 527762306a36Sopenharmony_ci * 527862306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 527962306a36Sopenharmony_ci */ 528062306a36Sopenharmony_ciint security_locked_down(enum lockdown_reason what) 528162306a36Sopenharmony_ci{ 528262306a36Sopenharmony_ci return call_int_hook(locked_down, 0, what); 528362306a36Sopenharmony_ci} 528462306a36Sopenharmony_ciEXPORT_SYMBOL(security_locked_down); 528562306a36Sopenharmony_ci 528662306a36Sopenharmony_ci#ifdef CONFIG_PERF_EVENTS 528762306a36Sopenharmony_ci/** 528862306a36Sopenharmony_ci * security_perf_event_open() - Check if a perf event open is allowed 528962306a36Sopenharmony_ci * @attr: perf event attribute 529062306a36Sopenharmony_ci * @type: type of event 529162306a36Sopenharmony_ci * 529262306a36Sopenharmony_ci * Check whether the @type of perf_event_open syscall is allowed. 529362306a36Sopenharmony_ci * 529462306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 529562306a36Sopenharmony_ci */ 529662306a36Sopenharmony_ciint security_perf_event_open(struct perf_event_attr *attr, int type) 529762306a36Sopenharmony_ci{ 529862306a36Sopenharmony_ci return call_int_hook(perf_event_open, 0, attr, type); 529962306a36Sopenharmony_ci} 530062306a36Sopenharmony_ci 530162306a36Sopenharmony_ci/** 530262306a36Sopenharmony_ci * security_perf_event_alloc() - Allocate a perf event LSM blob 530362306a36Sopenharmony_ci * @event: perf event 530462306a36Sopenharmony_ci * 530562306a36Sopenharmony_ci * Allocate and save perf_event security info. 530662306a36Sopenharmony_ci * 530762306a36Sopenharmony_ci * Return: Returns 0 on success, error on failure. 530862306a36Sopenharmony_ci */ 530962306a36Sopenharmony_ciint security_perf_event_alloc(struct perf_event *event) 531062306a36Sopenharmony_ci{ 531162306a36Sopenharmony_ci return call_int_hook(perf_event_alloc, 0, event); 531262306a36Sopenharmony_ci} 531362306a36Sopenharmony_ci 531462306a36Sopenharmony_ci/** 531562306a36Sopenharmony_ci * security_perf_event_free() - Free a perf event LSM blob 531662306a36Sopenharmony_ci * @event: perf event 531762306a36Sopenharmony_ci * 531862306a36Sopenharmony_ci * Release (free) perf_event security info. 531962306a36Sopenharmony_ci */ 532062306a36Sopenharmony_civoid security_perf_event_free(struct perf_event *event) 532162306a36Sopenharmony_ci{ 532262306a36Sopenharmony_ci call_void_hook(perf_event_free, event); 532362306a36Sopenharmony_ci} 532462306a36Sopenharmony_ci 532562306a36Sopenharmony_ci/** 532662306a36Sopenharmony_ci * security_perf_event_read() - Check if reading a perf event label is allowed 532762306a36Sopenharmony_ci * @event: perf event 532862306a36Sopenharmony_ci * 532962306a36Sopenharmony_ci * Read perf_event security info if allowed. 533062306a36Sopenharmony_ci * 533162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 533262306a36Sopenharmony_ci */ 533362306a36Sopenharmony_ciint security_perf_event_read(struct perf_event *event) 533462306a36Sopenharmony_ci{ 533562306a36Sopenharmony_ci return call_int_hook(perf_event_read, 0, event); 533662306a36Sopenharmony_ci} 533762306a36Sopenharmony_ci 533862306a36Sopenharmony_ci/** 533962306a36Sopenharmony_ci * security_perf_event_write() - Check if writing a perf event label is allowed 534062306a36Sopenharmony_ci * @event: perf event 534162306a36Sopenharmony_ci * 534262306a36Sopenharmony_ci * Write perf_event security info if allowed. 534362306a36Sopenharmony_ci * 534462306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 534562306a36Sopenharmony_ci */ 534662306a36Sopenharmony_ciint security_perf_event_write(struct perf_event *event) 534762306a36Sopenharmony_ci{ 534862306a36Sopenharmony_ci return call_int_hook(perf_event_write, 0, event); 534962306a36Sopenharmony_ci} 535062306a36Sopenharmony_ci#endif /* CONFIG_PERF_EVENTS */ 535162306a36Sopenharmony_ci 535262306a36Sopenharmony_ci/** 535362306a36Sopenharmony_ci * security_mmap_region() - Check if mmap region is allowed 535462306a36Sopenharmony_ci * @vma: vm area 535562306a36Sopenharmony_ci * 535662306a36Sopenharmony_ci * Mmap region if allowed. 535762306a36Sopenharmony_ci * 535862306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 535962306a36Sopenharmony_ci */ 536062306a36Sopenharmony_ci#ifdef CONFIG_SECURITY_XPM 536162306a36Sopenharmony_ciint security_mmap_region(struct vm_area_struct *vma) 536262306a36Sopenharmony_ci{ 536362306a36Sopenharmony_ci return call_int_hook(mmap_region, 0, vma); 536462306a36Sopenharmony_ci} 536562306a36Sopenharmony_ci#endif 536662306a36Sopenharmony_ci 536762306a36Sopenharmony_ci#ifdef CONFIG_IO_URING 536862306a36Sopenharmony_ci/** 536962306a36Sopenharmony_ci * security_uring_override_creds() - Check if overriding creds is allowed 537062306a36Sopenharmony_ci * @new: new credentials 537162306a36Sopenharmony_ci * 537262306a36Sopenharmony_ci * Check if the current task, executing an io_uring operation, is allowed to 537362306a36Sopenharmony_ci * override it's credentials with @new. 537462306a36Sopenharmony_ci * 537562306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 537662306a36Sopenharmony_ci */ 537762306a36Sopenharmony_ciint security_uring_override_creds(const struct cred *new) 537862306a36Sopenharmony_ci{ 537962306a36Sopenharmony_ci return call_int_hook(uring_override_creds, 0, new); 538062306a36Sopenharmony_ci} 538162306a36Sopenharmony_ci 538262306a36Sopenharmony_ci/** 538362306a36Sopenharmony_ci * security_uring_sqpoll() - Check if IORING_SETUP_SQPOLL is allowed 538462306a36Sopenharmony_ci * 538562306a36Sopenharmony_ci * Check whether the current task is allowed to spawn a io_uring polling thread 538662306a36Sopenharmony_ci * (IORING_SETUP_SQPOLL). 538762306a36Sopenharmony_ci * 538862306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 538962306a36Sopenharmony_ci */ 539062306a36Sopenharmony_ciint security_uring_sqpoll(void) 539162306a36Sopenharmony_ci{ 539262306a36Sopenharmony_ci return call_int_hook(uring_sqpoll, 0); 539362306a36Sopenharmony_ci} 539462306a36Sopenharmony_ci 539562306a36Sopenharmony_ci/** 539662306a36Sopenharmony_ci * security_uring_cmd() - Check if a io_uring passthrough command is allowed 539762306a36Sopenharmony_ci * @ioucmd: command 539862306a36Sopenharmony_ci * 539962306a36Sopenharmony_ci * Check whether the file_operations uring_cmd is allowed to run. 540062306a36Sopenharmony_ci * 540162306a36Sopenharmony_ci * Return: Returns 0 if permission is granted. 540262306a36Sopenharmony_ci */ 540362306a36Sopenharmony_ciint security_uring_cmd(struct io_uring_cmd *ioucmd) 540462306a36Sopenharmony_ci{ 540562306a36Sopenharmony_ci return call_int_hook(uring_cmd, 0, ioucmd); 540662306a36Sopenharmony_ci} 540762306a36Sopenharmony_ci#endif /* CONFIG_IO_URING */ 5408