xref: /linux-6.15/security/security.c (revision 082f1db0)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * Security plug functions
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  * Copyright (C) 2001 WireX Communications, Inc <[email protected]>
61da177e4SLinus Torvalds  * Copyright (C) 2001-2002 Greg Kroah-Hartman <[email protected]>
71da177e4SLinus Torvalds  * Copyright (C) 2001 Networks Associates Technology, Inc <[email protected]>
8d291f1a6SDaniel Jurgens  * Copyright (C) 2016 Mellanox Technologies
91661372cSPaul Moore  * Copyright (C) 2023 Microsoft Corporation <[email protected]>
101da177e4SLinus Torvalds  */
111da177e4SLinus Torvalds 
129b8c7c14SKees Cook #define pr_fmt(fmt) "LSM: " fmt
139b8c7c14SKees Cook 
14afdb09c7SChenbo Feng #include <linux/bpf.h>
15c59ede7bSRandy.Dunlap #include <linux/capability.h>
16d47be3dfSDavid Quigley #include <linux/dcache.h>
17876979c9SPaul Gortmaker #include <linux/export.h>
181da177e4SLinus Torvalds #include <linux/init.h>
191da177e4SLinus Torvalds #include <linux/kernel.h>
20b89999d0SScott Branden #include <linux/kernel_read_file.h>
213c4ed7bdSCasey Schaufler #include <linux/lsm_hooks.h>
228b3ec681SAl Viro #include <linux/mman.h>
238b3ec681SAl Viro #include <linux/mount.h>
248b3ec681SAl Viro #include <linux/personality.h>
2575331a59SPaul Mundt #include <linux/backing-dev.h>
263bb857e4SMickaël Salaün #include <linux/string.h>
2792383111SRoberto Sassu #include <linux/xattr.h>
28ecd5f82eSCasey Schaufler #include <linux/msg.h>
29d8bdd795SJann Horn #include <linux/overflow.h>
3061a1dcdcSCasey Schaufler #include <linux/perf_event.h>
31b55d26bdSDeven Bowers #include <linux/fs.h>
3240401530SAl Viro #include <net/flow.h>
332aff9d20SCasey Schaufler #include <net/sock.h>
341da177e4SLinus Torvalds 
35417c5643SKP Singh #define SECURITY_HOOK_ACTIVE_KEY(HOOK, IDX) security_hook_active_##HOOK##_##IDX
36417c5643SKP Singh 
37417c5643SKP Singh /*
38417c5643SKP Singh  * Identifier for the LSM static calls.
39417c5643SKP Singh  * HOOK is an LSM hook as defined in linux/lsm_hookdefs.h
40417c5643SKP Singh  * IDX is the index of the static call. 0 <= NUM < MAX_LSM_COUNT
41417c5643SKP Singh  */
42417c5643SKP Singh #define LSM_STATIC_CALL(HOOK, IDX) lsm_static_call_##HOOK##_##IDX
43417c5643SKP Singh 
44417c5643SKP Singh /*
45417c5643SKP Singh  * Call the macro M for each LSM hook MAX_LSM_COUNT times.
46417c5643SKP Singh  */
47417c5643SKP Singh #define LSM_LOOP_UNROLL(M, ...) 		\
48417c5643SKP Singh do {						\
49417c5643SKP Singh 	UNROLL(MAX_LSM_COUNT, M, __VA_ARGS__)	\
50417c5643SKP Singh } while (0)
51417c5643SKP Singh 
52417c5643SKP Singh #define LSM_DEFINE_UNROLL(M, ...) UNROLL(MAX_LSM_COUNT, M, __VA_ARGS__)
53417c5643SKP Singh 
549285c5adSCasey Schaufler /*
5559438b46SStephen Smalley  * These are descriptions of the reasons that can be passed to the
5659438b46SStephen Smalley  * security_locked_down() LSM hook. Placing this array here allows
5759438b46SStephen Smalley  * all security modules to use the same descriptions for auditing
5859438b46SStephen Smalley  * purposes.
5959438b46SStephen Smalley  */
6059438b46SStephen Smalley const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX + 1] = {
6159438b46SStephen Smalley 	[LOCKDOWN_NONE] = "none",
6259438b46SStephen Smalley 	[LOCKDOWN_MODULE_SIGNATURE] = "unsigned module loading",
6359438b46SStephen Smalley 	[LOCKDOWN_DEV_MEM] = "/dev/mem,kmem,port",
6459438b46SStephen Smalley 	[LOCKDOWN_EFI_TEST] = "/dev/efi_test access",
6559438b46SStephen Smalley 	[LOCKDOWN_KEXEC] = "kexec of unsigned images",
6659438b46SStephen Smalley 	[LOCKDOWN_HIBERNATION] = "hibernation",
6759438b46SStephen Smalley 	[LOCKDOWN_PCI_ACCESS] = "direct PCI access",
6859438b46SStephen Smalley 	[LOCKDOWN_IOPORT] = "raw io port access",
6959438b46SStephen Smalley 	[LOCKDOWN_MSR] = "raw MSR access",
7059438b46SStephen Smalley 	[LOCKDOWN_ACPI_TABLES] = "modifying ACPI tables",
7199df7a28SNathan Lynch 	[LOCKDOWN_DEVICE_TREE] = "modifying device tree contents",
7259438b46SStephen Smalley 	[LOCKDOWN_PCMCIA_CIS] = "direct PCMCIA CIS storage",
7359438b46SStephen Smalley 	[LOCKDOWN_TIOCSSERIAL] = "reconfiguration of serial port IO",
7459438b46SStephen Smalley 	[LOCKDOWN_MODULE_PARAMETERS] = "unsafe module parameters",
7559438b46SStephen Smalley 	[LOCKDOWN_MMIOTRACE] = "unsafe mmio",
7659438b46SStephen Smalley 	[LOCKDOWN_DEBUGFS] = "debugfs access",
7759438b46SStephen Smalley 	[LOCKDOWN_XMON_WR] = "xmon write access",
7851e1bb9eSDaniel Borkmann 	[LOCKDOWN_BPF_WRITE_USER] = "use of bpf to write user RAM",
79eadb2f47SDaniel Thompson 	[LOCKDOWN_DBG_WRITE_KERNEL] = "use of kgdb/kdb to write kernel RAM",
80b8f3e488SNathan Lynch 	[LOCKDOWN_RTAS_ERROR_INJECTION] = "RTAS error injection",
8159438b46SStephen Smalley 	[LOCKDOWN_INTEGRITY_MAX] = "integrity",
8259438b46SStephen Smalley 	[LOCKDOWN_KCORE] = "/proc/kcore access",
8359438b46SStephen Smalley 	[LOCKDOWN_KPROBES] = "use of kprobes",
8471330842SDaniel Borkmann 	[LOCKDOWN_BPF_READ_KERNEL] = "use of bpf to read kernel RAM",
85eadb2f47SDaniel Thompson 	[LOCKDOWN_DBG_READ_KERNEL] = "use of kgdb/kdb to read kernel RAM",
8659438b46SStephen Smalley 	[LOCKDOWN_PERF] = "unsafe use of perf",
8759438b46SStephen Smalley 	[LOCKDOWN_TRACEFS] = "use of tracefs",
8859438b46SStephen Smalley 	[LOCKDOWN_XMON_RW] = "xmon read and write access",
89c7a5899eSAntony Antony 	[LOCKDOWN_XFRM_SECRET] = "xfrm SA secret",
9059438b46SStephen Smalley 	[LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality",
9159438b46SStephen Smalley };
9259438b46SStephen Smalley 
9342df744cSJanne Karhunen static BLOCKING_NOTIFIER_HEAD(blocking_lsm_notifier_chain);
948f408ab6SDaniel Jurgens 
9533bf60caSCasey Schaufler static struct kmem_cache *lsm_file_cache;
96afb1cbe3SCasey Schaufler static struct kmem_cache *lsm_inode_cache;
9733bf60caSCasey Schaufler 
98d69dece5SCasey Schaufler char *lsm_names;
99f22f9aafSPaul Moore static struct lsm_blob_sizes blob_sizes __ro_after_init;
100bbd3662aSCasey Schaufler 
101076c54c5SAhmed S. Darwish /* Boot-time LSM user choice */
10279f7865dSKees Cook static __initdata const char *chosen_lsm_order;
1035ef4e419SKees Cook static __initdata const char *chosen_major_lsm;
1041da177e4SLinus Torvalds 
10513e735c0SKees Cook static __initconst const char *const builtin_lsm_order = CONFIG_LSM;
10613e735c0SKees Cook 
1072d4d5119SKees Cook /* Ordered list of LSMs to initialize. */
108d6bd12e8STetsuo Handa static __initdata struct lsm_info *ordered_lsms[MAX_LSM_COUNT + 1];
10914bd99c8SKees Cook static __initdata struct lsm_info *exclusive;
1102d4d5119SKees Cook 
111417c5643SKP Singh #ifdef CONFIG_HAVE_STATIC_CALL
112417c5643SKP Singh #define LSM_HOOK_TRAMP(NAME, NUM) \
113417c5643SKP Singh 	&STATIC_CALL_TRAMP(LSM_STATIC_CALL(NAME, NUM))
114417c5643SKP Singh #else
115417c5643SKP Singh #define LSM_HOOK_TRAMP(NAME, NUM) NULL
116417c5643SKP Singh #endif
117417c5643SKP Singh 
118417c5643SKP Singh /*
119417c5643SKP Singh  * Define static calls and static keys for each LSM hook.
120417c5643SKP Singh  */
121417c5643SKP Singh #define DEFINE_LSM_STATIC_CALL(NUM, NAME, RET, ...)			\
122417c5643SKP Singh 	DEFINE_STATIC_CALL_NULL(LSM_STATIC_CALL(NAME, NUM),		\
123417c5643SKP Singh 				*((RET(*)(__VA_ARGS__))NULL));		\
124417c5643SKP Singh 	DEFINE_STATIC_KEY_FALSE(SECURITY_HOOK_ACTIVE_KEY(NAME, NUM));
125417c5643SKP Singh 
126417c5643SKP Singh #define LSM_HOOK(RET, DEFAULT, NAME, ...)				\
127417c5643SKP Singh 	LSM_DEFINE_UNROLL(DEFINE_LSM_STATIC_CALL, NAME, RET, __VA_ARGS__)
128417c5643SKP Singh #include <linux/lsm_hook_defs.h>
129417c5643SKP Singh #undef LSM_HOOK
130417c5643SKP Singh #undef DEFINE_LSM_STATIC_CALL
131417c5643SKP Singh 
132417c5643SKP Singh /*
133417c5643SKP Singh  * Initialise a table of static calls for each LSM hook.
134417c5643SKP Singh  * DEFINE_STATIC_CALL_NULL invocation above generates a key (STATIC_CALL_KEY)
135417c5643SKP Singh  * and a trampoline (STATIC_CALL_TRAMP) which are used to call
136417c5643SKP Singh  * __static_call_update when updating the static call.
137417c5643SKP Singh  *
138417c5643SKP Singh  * The static calls table is used by early LSMs, some architectures can fault on
139417c5643SKP Singh  * unaligned accesses and the fault handling code may not be ready by then.
140417c5643SKP Singh  * Thus, the static calls table should be aligned to avoid any unhandled faults
141417c5643SKP Singh  * in early init.
142417c5643SKP Singh  */
143417c5643SKP Singh struct lsm_static_calls_table
144417c5643SKP Singh 	static_calls_table __ro_after_init __aligned(sizeof(u64)) = {
145417c5643SKP Singh #define INIT_LSM_STATIC_CALL(NUM, NAME)					\
146417c5643SKP Singh 	(struct lsm_static_call) {					\
147417c5643SKP Singh 		.key = &STATIC_CALL_KEY(LSM_STATIC_CALL(NAME, NUM)),	\
148417c5643SKP Singh 		.trampoline = LSM_HOOK_TRAMP(NAME, NUM),		\
149417c5643SKP Singh 		.active = &SECURITY_HOOK_ACTIVE_KEY(NAME, NUM),		\
150417c5643SKP Singh 	},
151417c5643SKP Singh #define LSM_HOOK(RET, DEFAULT, NAME, ...)				\
152417c5643SKP Singh 	.NAME = {							\
153417c5643SKP Singh 		LSM_DEFINE_UNROLL(INIT_LSM_STATIC_CALL, NAME)		\
154417c5643SKP Singh 	},
155417c5643SKP Singh #include <linux/lsm_hook_defs.h>
156417c5643SKP Singh #undef LSM_HOOK
157417c5643SKP Singh #undef INIT_LSM_STATIC_CALL
158417c5643SKP Singh 	};
159417c5643SKP Singh 
1609b8c7c14SKees Cook static __initdata bool debug;
1619b8c7c14SKees Cook #define init_debug(...)						\
1629b8c7c14SKees Cook 	do {							\
1639b8c7c14SKees Cook 		if (debug)					\
1649b8c7c14SKees Cook 			pr_info(__VA_ARGS__);			\
1659b8c7c14SKees Cook 	} while (0)
1661b1eeca7SArd Biesheuvel 
is_enabled(struct lsm_info * lsm)167f4941d75SKees Cook static bool __init is_enabled(struct lsm_info *lsm)
168f4941d75SKees Cook {
169a8027fb0SKees Cook 	if (!lsm->enabled)
170f4941d75SKees Cook 		return false;
171a8027fb0SKees Cook 
172a8027fb0SKees Cook 	return *lsm->enabled;
173f4941d75SKees Cook }
174f4941d75SKees Cook 
175f4941d75SKees Cook /* Mark an LSM's enabled flag. */
176f4941d75SKees Cook static int lsm_enabled_true __initdata = 1;
177f4941d75SKees Cook static int lsm_enabled_false __initdata = 0;
set_enabled(struct lsm_info * lsm,bool enabled)178f4941d75SKees Cook static void __init set_enabled(struct lsm_info *lsm, bool enabled)
179f4941d75SKees Cook {
180f4941d75SKees Cook 	/*
181f4941d75SKees Cook 	 * When an LSM hasn't configured an enable variable, we can use
182f4941d75SKees Cook 	 * a hard-coded location for storing the default enabled state.
183f4941d75SKees Cook 	 */
184f4941d75SKees Cook 	if (!lsm->enabled) {
185f4941d75SKees Cook 		if (enabled)
186f4941d75SKees Cook 			lsm->enabled = &lsm_enabled_true;
187f4941d75SKees Cook 		else
188f4941d75SKees Cook 			lsm->enabled = &lsm_enabled_false;
189f4941d75SKees Cook 	} else if (lsm->enabled == &lsm_enabled_true) {
190f4941d75SKees Cook 		if (!enabled)
191f4941d75SKees Cook 			lsm->enabled = &lsm_enabled_false;
192f4941d75SKees Cook 	} else if (lsm->enabled == &lsm_enabled_false) {
193f4941d75SKees Cook 		if (enabled)
194f4941d75SKees Cook 			lsm->enabled = &lsm_enabled_true;
195f4941d75SKees Cook 	} else {
196f4941d75SKees Cook 		*lsm->enabled = enabled;
197f4941d75SKees Cook 	}
198f4941d75SKees Cook }
199f4941d75SKees Cook 
2002d4d5119SKees Cook /* Is an LSM already listed in the ordered LSMs list? */
exists_ordered_lsm(struct lsm_info * lsm)2012d4d5119SKees Cook static bool __init exists_ordered_lsm(struct lsm_info *lsm)
2022d4d5119SKees Cook {
2032d4d5119SKees Cook 	struct lsm_info **check;
2042d4d5119SKees Cook 
2052d4d5119SKees Cook 	for (check = ordered_lsms; *check; check++)
2062d4d5119SKees Cook 		if (*check == lsm)
2072d4d5119SKees Cook 			return true;
2082d4d5119SKees Cook 
2092d4d5119SKees Cook 	return false;
2102d4d5119SKees Cook }
2112d4d5119SKees Cook 
2122d4d5119SKees Cook /* Append an LSM to the list of ordered LSMs to initialize. */
2132d4d5119SKees Cook static int last_lsm __initdata;
append_ordered_lsm(struct lsm_info * lsm,const char * from)2142d4d5119SKees Cook static void __init append_ordered_lsm(struct lsm_info *lsm, const char *from)
2152d4d5119SKees Cook {
2162d4d5119SKees Cook 	/* Ignore duplicate selections. */
2172d4d5119SKees Cook 	if (exists_ordered_lsm(lsm))
2182d4d5119SKees Cook 		return;
2192d4d5119SKees Cook 
220d6bd12e8STetsuo Handa 	if (WARN(last_lsm == MAX_LSM_COUNT, "%s: out of LSM static calls!?\n", from))
2212d4d5119SKees Cook 		return;
2222d4d5119SKees Cook 
223a8027fb0SKees Cook 	/* Enable this LSM, if it is not already set. */
224a8027fb0SKees Cook 	if (!lsm->enabled)
225a8027fb0SKees Cook 		lsm->enabled = &lsm_enabled_true;
2262d4d5119SKees Cook 	ordered_lsms[last_lsm++] = lsm;
227a8027fb0SKees Cook 
22886ef3c73SKees Cook 	init_debug("%s ordered: %s (%s)\n", from, lsm->name,
22986ef3c73SKees Cook 		   is_enabled(lsm) ? "enabled" : "disabled");
2302d4d5119SKees Cook }
2312d4d5119SKees Cook 
232f4941d75SKees Cook /* Is an LSM allowed to be initialized? */
lsm_allowed(struct lsm_info * lsm)233f4941d75SKees Cook static bool __init lsm_allowed(struct lsm_info *lsm)
234f4941d75SKees Cook {
235f4941d75SKees Cook 	/* Skip if the LSM is disabled. */
236f4941d75SKees Cook 	if (!is_enabled(lsm))
237f4941d75SKees Cook 		return false;
238f4941d75SKees Cook 
23914bd99c8SKees Cook 	/* Not allowed if another exclusive LSM already initialized. */
24014bd99c8SKees Cook 	if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && exclusive) {
24114bd99c8SKees Cook 		init_debug("exclusive disabled: %s\n", lsm->name);
24214bd99c8SKees Cook 		return false;
24314bd99c8SKees Cook 	}
24414bd99c8SKees Cook 
245f4941d75SKees Cook 	return true;
246f4941d75SKees Cook }
247f4941d75SKees Cook 
lsm_set_blob_size(int * need,int * lbs)248bbd3662aSCasey Schaufler static void __init lsm_set_blob_size(int *need, int *lbs)
249bbd3662aSCasey Schaufler {
250bbd3662aSCasey Schaufler 	int offset;
251bbd3662aSCasey Schaufler 
252b9f5ce27SGünther Noack 	if (*need <= 0)
253b9f5ce27SGünther Noack 		return;
254b9f5ce27SGünther Noack 
255b9f5ce27SGünther Noack 	offset = ALIGN(*lbs, sizeof(void *));
256b9f5ce27SGünther Noack 	*lbs = offset + *need;
257bbd3662aSCasey Schaufler 	*need = offset;
258bbd3662aSCasey Schaufler }
259bbd3662aSCasey Schaufler 
lsm_set_blob_sizes(struct lsm_blob_sizes * needed)260bbd3662aSCasey Schaufler static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
261bbd3662aSCasey Schaufler {
262bbd3662aSCasey Schaufler 	if (!needed)
263bbd3662aSCasey Schaufler 		return;
264bbd3662aSCasey Schaufler 
265bbd3662aSCasey Schaufler 	lsm_set_blob_size(&needed->lbs_cred, &blob_sizes.lbs_cred);
26633bf60caSCasey Schaufler 	lsm_set_blob_size(&needed->lbs_file, &blob_sizes.lbs_file);
26766de33a0SCasey Schaufler 	lsm_set_blob_size(&needed->lbs_ib, &blob_sizes.lbs_ib);
268afb1cbe3SCasey Schaufler 	/*
269afb1cbe3SCasey Schaufler 	 * The inode blob gets an rcu_head in addition to
270afb1cbe3SCasey Schaufler 	 * what the modules might need.
271afb1cbe3SCasey Schaufler 	 */
272afb1cbe3SCasey Schaufler 	if (needed->lbs_inode && blob_sizes.lbs_inode == 0)
273afb1cbe3SCasey Schaufler 		blob_sizes.lbs_inode = sizeof(struct rcu_head);
274afb1cbe3SCasey Schaufler 	lsm_set_blob_size(&needed->lbs_inode, &blob_sizes.lbs_inode);
275ecd5f82eSCasey Schaufler 	lsm_set_blob_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc);
2765f8d28f6SCasey Schaufler 	lsm_set_blob_size(&needed->lbs_key, &blob_sizes.lbs_key);
277ecd5f82eSCasey Schaufler 	lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg);
27861a1dcdcSCasey Schaufler 	lsm_set_blob_size(&needed->lbs_perf_event, &blob_sizes.lbs_perf_event);
2792aff9d20SCasey Schaufler 	lsm_set_blob_size(&needed->lbs_sock, &blob_sizes.lbs_sock);
2801aea7808SCasey Schaufler 	lsm_set_blob_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock);
281f4ad8f2cSCasey Schaufler 	lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task);
282a39c0f77SCasey Schaufler 	lsm_set_blob_size(&needed->lbs_tun_dev, &blob_sizes.lbs_tun_dev);
2836bcdfd2cSRoberto Sassu 	lsm_set_blob_size(&needed->lbs_xattr_count,
2846bcdfd2cSRoberto Sassu 			  &blob_sizes.lbs_xattr_count);
285b55d26bdSDeven Bowers 	lsm_set_blob_size(&needed->lbs_bdev, &blob_sizes.lbs_bdev);
286bbd3662aSCasey Schaufler }
287bbd3662aSCasey Schaufler 
288d8e9bbd4SKees Cook /* Prepare LSM for initialization. */
prepare_lsm(struct lsm_info * lsm)289d8e9bbd4SKees Cook static void __init prepare_lsm(struct lsm_info *lsm)
290f4941d75SKees Cook {
291f4941d75SKees Cook 	int enabled = lsm_allowed(lsm);
292f4941d75SKees Cook 
293f4941d75SKees Cook 	/* Record enablement (to handle any following exclusive LSMs). */
294f4941d75SKees Cook 	set_enabled(lsm, enabled);
295f4941d75SKees Cook 
296d8e9bbd4SKees Cook 	/* If enabled, do pre-initialization work. */
297f4941d75SKees Cook 	if (enabled) {
29814bd99c8SKees Cook 		if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !exclusive) {
29914bd99c8SKees Cook 			exclusive = lsm;
30014bd99c8SKees Cook 			init_debug("exclusive chosen:   %s\n", lsm->name);
30114bd99c8SKees Cook 		}
302bbd3662aSCasey Schaufler 
303bbd3662aSCasey Schaufler 		lsm_set_blob_sizes(lsm->blobs);
304d8e9bbd4SKees Cook 	}
305d8e9bbd4SKees Cook }
306d8e9bbd4SKees Cook 
307d8e9bbd4SKees Cook /* Initialize a given LSM, if it is enabled. */
initialize_lsm(struct lsm_info * lsm)308d8e9bbd4SKees Cook static void __init initialize_lsm(struct lsm_info *lsm)
309d8e9bbd4SKees Cook {
310d8e9bbd4SKees Cook 	if (is_enabled(lsm)) {
311d8e9bbd4SKees Cook 		int ret;
31214bd99c8SKees Cook 
313f4941d75SKees Cook 		init_debug("initializing %s\n", lsm->name);
314f4941d75SKees Cook 		ret = lsm->init();
315f4941d75SKees Cook 		WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret);
316f4941d75SKees Cook 	}
317f4941d75SKees Cook }
318f4941d75SKees Cook 
3199285c5adSCasey Schaufler /*
3209285c5adSCasey Schaufler  * Current index to use while initializing the lsm id list.
3219285c5adSCasey Schaufler  */
3229285c5adSCasey Schaufler u32 lsm_active_cnt __ro_after_init;
323d6bd12e8STetsuo Handa const struct lsm_id *lsm_idlist[MAX_LSM_COUNT];
3249285c5adSCasey Schaufler 
32513e735c0SKees Cook /* Populate ordered LSMs list from comma-separated LSM name list. */
ordered_lsm_parse(const char * order,const char * origin)3262d4d5119SKees Cook static void __init ordered_lsm_parse(const char *order, const char *origin)
327657d910bSKees Cook {
328657d910bSKees Cook 	struct lsm_info *lsm;
32913e735c0SKees Cook 	char *sep, *name, *next;
33013e735c0SKees Cook 
331e2bc445bSKees Cook 	/* LSM_ORDER_FIRST is always first. */
332e2bc445bSKees Cook 	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
333e2bc445bSKees Cook 		if (lsm->order == LSM_ORDER_FIRST)
334e2bc445bSKees Cook 			append_ordered_lsm(lsm, "  first");
335e2bc445bSKees Cook 	}
336e2bc445bSKees Cook 
3377e611486SKees Cook 	/* Process "security=", if given. */
3387e611486SKees Cook 	if (chosen_major_lsm) {
3397e611486SKees Cook 		struct lsm_info *major;
3407e611486SKees Cook 
3417e611486SKees Cook 		/*
3427e611486SKees Cook 		 * To match the original "security=" behavior, this
3437e611486SKees Cook 		 * explicitly does NOT fallback to another Legacy Major
3447e611486SKees Cook 		 * if the selected one was separately disabled: disable
3457e611486SKees Cook 		 * all non-matching Legacy Major LSMs.
3467e611486SKees Cook 		 */
3477e611486SKees Cook 		for (major = __start_lsm_info; major < __end_lsm_info;
3487e611486SKees Cook 		     major++) {
3497e611486SKees Cook 			if ((major->flags & LSM_FLAG_LEGACY_MAJOR) &&
3507e611486SKees Cook 			    strcmp(major->name, chosen_major_lsm) != 0) {
3517e611486SKees Cook 				set_enabled(major, false);
35286ef3c73SKees Cook 				init_debug("security=%s disabled: %s (only one legacy major LSM)\n",
3537e611486SKees Cook 					   chosen_major_lsm, major->name);
3547e611486SKees Cook 			}
3557e611486SKees Cook 		}
3567e611486SKees Cook 	}
3575ef4e419SKees Cook 
35813e735c0SKees Cook 	sep = kstrdup(order, GFP_KERNEL);
35913e735c0SKees Cook 	next = sep;
36013e735c0SKees Cook 	/* Walk the list, looking for matching LSMs. */
36113e735c0SKees Cook 	while ((name = strsep(&next, ",")) != NULL) {
36213e735c0SKees Cook 		bool found = false;
363657d910bSKees Cook 
364657d910bSKees Cook 		for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
36542994ee3SRoberto Sassu 			if (strcmp(lsm->name, name) == 0) {
36642994ee3SRoberto Sassu 				if (lsm->order == LSM_ORDER_MUTABLE)
3672d4d5119SKees Cook 					append_ordered_lsm(lsm, origin);
36813e735c0SKees Cook 				found = true;
369657d910bSKees Cook 			}
370657d910bSKees Cook 		}
371657d910bSKees Cook 
37213e735c0SKees Cook 		if (!found)
37386ef3c73SKees Cook 			init_debug("%s ignored: %s (not built into kernel)\n",
37486ef3c73SKees Cook 				   origin, name);
37513e735c0SKees Cook 	}
376c91d8106SCasey Schaufler 
377c91d8106SCasey Schaufler 	/* Process "security=", if given. */
378c91d8106SCasey Schaufler 	if (chosen_major_lsm) {
379c91d8106SCasey Schaufler 		for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
380c91d8106SCasey Schaufler 			if (exists_ordered_lsm(lsm))
381c91d8106SCasey Schaufler 				continue;
382c91d8106SCasey Schaufler 			if (strcmp(lsm->name, chosen_major_lsm) == 0)
383c91d8106SCasey Schaufler 				append_ordered_lsm(lsm, "security=");
384c91d8106SCasey Schaufler 		}
385c91d8106SCasey Schaufler 	}
386c91d8106SCasey Schaufler 
38742994ee3SRoberto Sassu 	/* LSM_ORDER_LAST is always last. */
38842994ee3SRoberto Sassu 	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
38942994ee3SRoberto Sassu 		if (lsm->order == LSM_ORDER_LAST)
39042994ee3SRoberto Sassu 			append_ordered_lsm(lsm, "   last");
39142994ee3SRoberto Sassu 	}
39242994ee3SRoberto Sassu 
393c91d8106SCasey Schaufler 	/* Disable all LSMs not in the ordered list. */
394c91d8106SCasey Schaufler 	for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
395c91d8106SCasey Schaufler 		if (exists_ordered_lsm(lsm))
396c91d8106SCasey Schaufler 			continue;
397c91d8106SCasey Schaufler 		set_enabled(lsm, false);
39886ef3c73SKees Cook 		init_debug("%s skipped: %s (not in requested order)\n",
39986ef3c73SKees Cook 			   origin, lsm->name);
400c91d8106SCasey Schaufler 	}
401c91d8106SCasey Schaufler 
40213e735c0SKees Cook 	kfree(sep);
40313e735c0SKees Cook }
40413e735c0SKees Cook 
lsm_static_call_init(struct security_hook_list * hl)405417c5643SKP Singh static void __init lsm_static_call_init(struct security_hook_list *hl)
406417c5643SKP Singh {
407417c5643SKP Singh 	struct lsm_static_call *scall = hl->scalls;
408417c5643SKP Singh 	int i;
409417c5643SKP Singh 
410417c5643SKP Singh 	for (i = 0; i < MAX_LSM_COUNT; i++) {
411417c5643SKP Singh 		/* Update the first static call that is not used yet */
412417c5643SKP Singh 		if (!scall->hl) {
413417c5643SKP Singh 			__static_call_update(scall->key, scall->trampoline,
414417c5643SKP Singh 					     hl->hook.lsm_func_addr);
415417c5643SKP Singh 			scall->hl = hl;
416417c5643SKP Singh 			static_branch_enable(scall->active);
417417c5643SKP Singh 			return;
418417c5643SKP Singh 		}
419417c5643SKP Singh 		scall++;
420417c5643SKP Singh 	}
421417c5643SKP Singh 	panic("%s - Ran out of static slots.\n", __func__);
422417c5643SKP Singh }
423417c5643SKP Singh 
4241cfb2a51STetsuo Handa static void __init lsm_early_cred(struct cred *cred);
4251cfb2a51STetsuo Handa static void __init lsm_early_task(struct task_struct *task);
4261cfb2a51STetsuo Handa 
427e6b1db98SMatthew Garrett static int lsm_append(const char *new, char **result);
428e6b1db98SMatthew Garrett 
report_lsm_order(void)42986ef3c73SKees Cook static void __init report_lsm_order(void)
43086ef3c73SKees Cook {
43186ef3c73SKees Cook 	struct lsm_info **lsm, *early;
43286ef3c73SKees Cook 	int first = 0;
43386ef3c73SKees Cook 
43486ef3c73SKees Cook 	pr_info("initializing lsm=");
43586ef3c73SKees Cook 
43686ef3c73SKees Cook 	/* Report each enabled LSM name, comma separated. */
43763c1845bSPaul Moore 	for (early = __start_early_lsm_info;
43863c1845bSPaul Moore 	     early < __end_early_lsm_info; early++)
43986ef3c73SKees Cook 		if (is_enabled(early))
44086ef3c73SKees Cook 			pr_cont("%s%s", first++ == 0 ? "" : ",", early->name);
44186ef3c73SKees Cook 	for (lsm = ordered_lsms; *lsm; lsm++)
44286ef3c73SKees Cook 		if (is_enabled(*lsm))
44386ef3c73SKees Cook 			pr_cont("%s%s", first++ == 0 ? "" : ",", (*lsm)->name);
44486ef3c73SKees Cook 
44586ef3c73SKees Cook 	pr_cont("\n");
44686ef3c73SKees Cook }
44786ef3c73SKees Cook 
ordered_lsm_init(void)4482d4d5119SKees Cook static void __init ordered_lsm_init(void)
4492d4d5119SKees Cook {
4502d4d5119SKees Cook 	struct lsm_info **lsm;
4512d4d5119SKees Cook 
45289a9684eSKees Cook 	if (chosen_lsm_order) {
45389a9684eSKees Cook 		if (chosen_major_lsm) {
45486ef3c73SKees Cook 			pr_warn("security=%s is ignored because it is superseded by lsm=%s\n",
45586ef3c73SKees Cook 				chosen_major_lsm, chosen_lsm_order);
45689a9684eSKees Cook 			chosen_major_lsm = NULL;
45789a9684eSKees Cook 		}
45879f7865dSKees Cook 		ordered_lsm_parse(chosen_lsm_order, "cmdline");
45989a9684eSKees Cook 	} else
46013e735c0SKees Cook 		ordered_lsm_parse(builtin_lsm_order, "builtin");
4612d4d5119SKees Cook 
4622d4d5119SKees Cook 	for (lsm = ordered_lsms; *lsm; lsm++)
463d8e9bbd4SKees Cook 		prepare_lsm(*lsm);
464d8e9bbd4SKees Cook 
46586ef3c73SKees Cook 	report_lsm_order();
46686ef3c73SKees Cook 
467bbd3662aSCasey Schaufler 	init_debug("cred blob size       = %d\n", blob_sizes.lbs_cred);
46833bf60caSCasey Schaufler 	init_debug("file blob size       = %d\n", blob_sizes.lbs_file);
46966de33a0SCasey Schaufler 	init_debug("ib blob size         = %d\n", blob_sizes.lbs_ib);
470afb1cbe3SCasey Schaufler 	init_debug("inode blob size      = %d\n", blob_sizes.lbs_inode);
471ecd5f82eSCasey Schaufler 	init_debug("ipc blob size        = %d\n", blob_sizes.lbs_ipc);
4725f8d28f6SCasey Schaufler #ifdef CONFIG_KEYS
4735f8d28f6SCasey Schaufler 	init_debug("key blob size        = %d\n", blob_sizes.lbs_key);
4745f8d28f6SCasey Schaufler #endif /* CONFIG_KEYS */
475ecd5f82eSCasey Schaufler 	init_debug("msg_msg blob size    = %d\n", blob_sizes.lbs_msg_msg);
4762aff9d20SCasey Schaufler 	init_debug("sock blob size       = %d\n", blob_sizes.lbs_sock);
4771aea7808SCasey Schaufler 	init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
47861a1dcdcSCasey Schaufler 	init_debug("perf event blob size = %d\n", blob_sizes.lbs_perf_event);
479f4ad8f2cSCasey Schaufler 	init_debug("task blob size       = %d\n", blob_sizes.lbs_task);
480a39c0f77SCasey Schaufler 	init_debug("tun device blob size = %d\n", blob_sizes.lbs_tun_dev);
4816bcdfd2cSRoberto Sassu 	init_debug("xattr slots          = %d\n", blob_sizes.lbs_xattr_count);
482b55d26bdSDeven Bowers 	init_debug("bdev blob size       = %d\n", blob_sizes.lbs_bdev);
48333bf60caSCasey Schaufler 
48433bf60caSCasey Schaufler 	/*
48533bf60caSCasey Schaufler 	 * Create any kmem_caches needed for blobs
48633bf60caSCasey Schaufler 	 */
48733bf60caSCasey Schaufler 	if (blob_sizes.lbs_file)
48833bf60caSCasey Schaufler 		lsm_file_cache = kmem_cache_create("lsm_file_cache",
48933bf60caSCasey Schaufler 						   blob_sizes.lbs_file, 0,
49033bf60caSCasey Schaufler 						   SLAB_PANIC, NULL);
491afb1cbe3SCasey Schaufler 	if (blob_sizes.lbs_inode)
492afb1cbe3SCasey Schaufler 		lsm_inode_cache = kmem_cache_create("lsm_inode_cache",
493afb1cbe3SCasey Schaufler 						    blob_sizes.lbs_inode, 0,
494afb1cbe3SCasey Schaufler 						    SLAB_PANIC, NULL);
495bbd3662aSCasey Schaufler 
4961cfb2a51STetsuo Handa 	lsm_early_cred((struct cred *) current->cred);
4971cfb2a51STetsuo Handa 	lsm_early_task(current);
498d8e9bbd4SKees Cook 	for (lsm = ordered_lsms; *lsm; lsm++)
499d8e9bbd4SKees Cook 		initialize_lsm(*lsm);
5002d4d5119SKees Cook }
5012d4d5119SKees Cook 
early_security_init(void)502e6b1db98SMatthew Garrett int __init early_security_init(void)
503e6b1db98SMatthew Garrett {
504e6b1db98SMatthew Garrett 	struct lsm_info *lsm;
505e6b1db98SMatthew Garrett 
506e6b1db98SMatthew Garrett 	for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) {
507e6b1db98SMatthew Garrett 		if (!lsm->enabled)
508e6b1db98SMatthew Garrett 			lsm->enabled = &lsm_enabled_true;
509e6b1db98SMatthew Garrett 		prepare_lsm(lsm);
510e6b1db98SMatthew Garrett 		initialize_lsm(lsm);
511e6b1db98SMatthew Garrett 	}
512e6b1db98SMatthew Garrett 
513e6b1db98SMatthew Garrett 	return 0;
514e6b1db98SMatthew Garrett }
515e6b1db98SMatthew Garrett 
5161da177e4SLinus Torvalds /**
5171da177e4SLinus Torvalds  * security_init - initializes the security framework
5181da177e4SLinus Torvalds  *
5191da177e4SLinus Torvalds  * This should be called early in the kernel initialization sequence.
5201da177e4SLinus Torvalds  */
security_init(void)5211da177e4SLinus Torvalds int __init security_init(void)
5221da177e4SLinus Torvalds {
523e6b1db98SMatthew Garrett 	struct lsm_info *lsm;
5243dfc9b02STetsuo Handa 
52586ef3c73SKees Cook 	init_debug("legacy security=%s\n", chosen_major_lsm ? : " *unspecified*");
52686ef3c73SKees Cook 	init_debug("  CONFIG_LSM=%s\n", builtin_lsm_order);
52786ef3c73SKees Cook 	init_debug("boot arg lsm=%s\n", chosen_lsm_order ? : " *unspecified*");
52898d29170SKees Cook 
529e6b1db98SMatthew Garrett 	/*
530e6b1db98SMatthew Garrett 	 * Append the names of the early LSM modules now that kmalloc() is
531e6b1db98SMatthew Garrett 	 * available
532e6b1db98SMatthew Garrett 	 */
533e6b1db98SMatthew Garrett 	for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) {
53486ef3c73SKees Cook 		init_debug("  early started: %s (%s)\n", lsm->name,
53586ef3c73SKees Cook 			   is_enabled(lsm) ? "enabled" : "disabled");
536e6b1db98SMatthew Garrett 		if (lsm->enabled)
537e6b1db98SMatthew Garrett 			lsm_append(lsm->name, &lsm_names);
538e6b1db98SMatthew Garrett 	}
5391da177e4SLinus Torvalds 
540657d910bSKees Cook 	/* Load LSMs in specified order. */
541657d910bSKees Cook 	ordered_lsm_init();
542657d910bSKees Cook 
5431da177e4SLinus Torvalds 	return 0;
5441da177e4SLinus Torvalds }
5451da177e4SLinus Torvalds 
546076c54c5SAhmed S. Darwish /* Save user chosen LSM */
choose_major_lsm(char * str)5475ef4e419SKees Cook static int __init choose_major_lsm(char *str)
548076c54c5SAhmed S. Darwish {
5495ef4e419SKees Cook 	chosen_major_lsm = str;
550076c54c5SAhmed S. Darwish 	return 1;
551076c54c5SAhmed S. Darwish }
5525ef4e419SKees Cook __setup("security=", choose_major_lsm);
553076c54c5SAhmed S. Darwish 
55479f7865dSKees Cook /* Explicitly choose LSM initialization order. */
choose_lsm_order(char * str)55579f7865dSKees Cook static int __init choose_lsm_order(char *str)
55679f7865dSKees Cook {
55779f7865dSKees Cook 	chosen_lsm_order = str;
55879f7865dSKees Cook 	return 1;
55979f7865dSKees Cook }
56079f7865dSKees Cook __setup("lsm=", choose_lsm_order);
56179f7865dSKees Cook 
5629b8c7c14SKees Cook /* Enable LSM order debugging. */
enable_debug(char * str)5639b8c7c14SKees Cook static int __init enable_debug(char *str)
5649b8c7c14SKees Cook {
5659b8c7c14SKees Cook 	debug = true;
5669b8c7c14SKees Cook 	return 1;
5679b8c7c14SKees Cook }
5689b8c7c14SKees Cook __setup("lsm.debug", enable_debug);
5699b8c7c14SKees Cook 
match_last_lsm(const char * list,const char * lsm)5703bb857e4SMickaël Salaün static bool match_last_lsm(const char *list, const char *lsm)
5713bb857e4SMickaël Salaün {
5723bb857e4SMickaël Salaün 	const char *last;
5733bb857e4SMickaël Salaün 
5743bb857e4SMickaël Salaün 	if (WARN_ON(!list || !lsm))
5753bb857e4SMickaël Salaün 		return false;
5763bb857e4SMickaël Salaün 	last = strrchr(list, ',');
5773bb857e4SMickaël Salaün 	if (last)
5783bb857e4SMickaël Salaün 		/* Pass the comma, strcmp() will check for '\0' */
5793bb857e4SMickaël Salaün 		last++;
5803bb857e4SMickaël Salaün 	else
5813bb857e4SMickaël Salaün 		last = list;
5823bb857e4SMickaël Salaün 	return !strcmp(last, lsm);
5833bb857e4SMickaël Salaün }
5843bb857e4SMickaël Salaün 
lsm_append(const char * new,char ** result)585e6b1db98SMatthew Garrett static int lsm_append(const char *new, char **result)
586d69dece5SCasey Schaufler {
587d69dece5SCasey Schaufler 	char *cp;
588d69dece5SCasey Schaufler 
589d69dece5SCasey Schaufler 	if (*result == NULL) {
590d69dece5SCasey Schaufler 		*result = kstrdup(new, GFP_KERNEL);
59187ea5843SEric Biggers 		if (*result == NULL)
59287ea5843SEric Biggers 			return -ENOMEM;
593d69dece5SCasey Schaufler 	} else {
5943bb857e4SMickaël Salaün 		/* Check if it is the last registered name */
5953bb857e4SMickaël Salaün 		if (match_last_lsm(*result, new))
5963bb857e4SMickaël Salaün 			return 0;
597d69dece5SCasey Schaufler 		cp = kasprintf(GFP_KERNEL, "%s,%s", *result, new);
598d69dece5SCasey Schaufler 		if (cp == NULL)
599d69dece5SCasey Schaufler 			return -ENOMEM;
600d69dece5SCasey Schaufler 		kfree(*result);
601d69dece5SCasey Schaufler 		*result = cp;
602d69dece5SCasey Schaufler 	}
603d69dece5SCasey Schaufler 	return 0;
604d69dece5SCasey Schaufler }
605d69dece5SCasey Schaufler 
606076c54c5SAhmed S. Darwish /**
607d69dece5SCasey Schaufler  * security_add_hooks - Add a modules hooks to the hook lists.
608d69dece5SCasey Schaufler  * @hooks: the hooks to add
609d69dece5SCasey Schaufler  * @count: the number of hooks to add
610f3b8788cSCasey Schaufler  * @lsmid: the identification information for the security module
611d69dece5SCasey Schaufler  *
612d69dece5SCasey Schaufler  * Each LSM has to register its hooks with the infrastructure.
613d69dece5SCasey Schaufler  */
security_add_hooks(struct security_hook_list * hooks,int count,const struct lsm_id * lsmid)614d69dece5SCasey Schaufler void __init security_add_hooks(struct security_hook_list *hooks, int count,
615f3b8788cSCasey Schaufler 			       const struct lsm_id *lsmid)
616d69dece5SCasey Schaufler {
617d69dece5SCasey Schaufler 	int i;
618d69dece5SCasey Schaufler 
6199285c5adSCasey Schaufler 	/*
6209285c5adSCasey Schaufler 	 * A security module may call security_add_hooks() more
6219285c5adSCasey Schaufler 	 * than once during initialization, and LSM initialization
6229285c5adSCasey Schaufler 	 * is serialized. Landlock is one such case.
6239285c5adSCasey Schaufler 	 * Look at the previous entry, if there is one, for duplication.
6249285c5adSCasey Schaufler 	 */
6259285c5adSCasey Schaufler 	if (lsm_active_cnt == 0 || lsm_idlist[lsm_active_cnt - 1] != lsmid) {
626d6bd12e8STetsuo Handa 		if (lsm_active_cnt >= MAX_LSM_COUNT)
6279285c5adSCasey Schaufler 			panic("%s Too many LSMs registered.\n", __func__);
6289285c5adSCasey Schaufler 		lsm_idlist[lsm_active_cnt++] = lsmid;
6299285c5adSCasey Schaufler 	}
6309285c5adSCasey Schaufler 
631d69dece5SCasey Schaufler 	for (i = 0; i < count; i++) {
632f3b8788cSCasey Schaufler 		hooks[i].lsmid = lsmid;
633417c5643SKP Singh 		lsm_static_call_init(&hooks[i]);
634d69dece5SCasey Schaufler 	}
635e6b1db98SMatthew Garrett 
636e6b1db98SMatthew Garrett 	/*
637e6b1db98SMatthew Garrett 	 * Don't try to append during early_security_init(), we'll come back
638e6b1db98SMatthew Garrett 	 * and fix this up afterwards.
639e6b1db98SMatthew Garrett 	 */
640e6b1db98SMatthew Garrett 	if (slab_is_available()) {
641f3b8788cSCasey Schaufler 		if (lsm_append(lsmid->name, &lsm_names) < 0)
642d69dece5SCasey Schaufler 			panic("%s - Cannot get early memory.\n", __func__);
643d69dece5SCasey Schaufler 	}
644e6b1db98SMatthew Garrett }
645d69dece5SCasey Schaufler 
call_blocking_lsm_notifier(enum lsm_event event,void * data)64642df744cSJanne Karhunen int call_blocking_lsm_notifier(enum lsm_event event, void *data)
6478f408ab6SDaniel Jurgens {
64842df744cSJanne Karhunen 	return blocking_notifier_call_chain(&blocking_lsm_notifier_chain,
64942df744cSJanne Karhunen 					    event, data);
6508f408ab6SDaniel Jurgens }
65142df744cSJanne Karhunen EXPORT_SYMBOL(call_blocking_lsm_notifier);
6528f408ab6SDaniel Jurgens 
register_blocking_lsm_notifier(struct notifier_block * nb)65342df744cSJanne Karhunen int register_blocking_lsm_notifier(struct notifier_block *nb)
6548f408ab6SDaniel Jurgens {
65542df744cSJanne Karhunen 	return blocking_notifier_chain_register(&blocking_lsm_notifier_chain,
65642df744cSJanne Karhunen 						nb);
6578f408ab6SDaniel Jurgens }
65842df744cSJanne Karhunen EXPORT_SYMBOL(register_blocking_lsm_notifier);
6598f408ab6SDaniel Jurgens 
unregister_blocking_lsm_notifier(struct notifier_block * nb)66042df744cSJanne Karhunen int unregister_blocking_lsm_notifier(struct notifier_block *nb)
6618f408ab6SDaniel Jurgens {
66242df744cSJanne Karhunen 	return blocking_notifier_chain_unregister(&blocking_lsm_notifier_chain,
66342df744cSJanne Karhunen 						  nb);
6648f408ab6SDaniel Jurgens }
66542df744cSJanne Karhunen EXPORT_SYMBOL(unregister_blocking_lsm_notifier);
6668f408ab6SDaniel Jurgens 
667bbd3662aSCasey Schaufler /**
66809001284SCasey Schaufler  * lsm_blob_alloc - allocate a composite blob
66909001284SCasey Schaufler  * @dest: the destination for the blob
67009001284SCasey Schaufler  * @size: the size of the blob
67109001284SCasey Schaufler  * @gfp: allocation type
67209001284SCasey Schaufler  *
67309001284SCasey Schaufler  * Allocate a blob for all the modules
67409001284SCasey Schaufler  *
67509001284SCasey Schaufler  * Returns 0, or -ENOMEM if memory can't be allocated.
67609001284SCasey Schaufler  */
lsm_blob_alloc(void ** dest,size_t size,gfp_t gfp)67709001284SCasey Schaufler static int lsm_blob_alloc(void **dest, size_t size, gfp_t gfp)
67809001284SCasey Schaufler {
67909001284SCasey Schaufler 	if (size == 0) {
68009001284SCasey Schaufler 		*dest = NULL;
68109001284SCasey Schaufler 		return 0;
68209001284SCasey Schaufler 	}
68309001284SCasey Schaufler 
68409001284SCasey Schaufler 	*dest = kzalloc(size, gfp);
68509001284SCasey Schaufler 	if (*dest == NULL)
68609001284SCasey Schaufler 		return -ENOMEM;
68709001284SCasey Schaufler 	return 0;
68809001284SCasey Schaufler }
68909001284SCasey Schaufler 
69009001284SCasey Schaufler /**
691bbd3662aSCasey Schaufler  * lsm_cred_alloc - allocate a composite cred blob
692bbd3662aSCasey Schaufler  * @cred: the cred that needs a blob
693bbd3662aSCasey Schaufler  * @gfp: allocation type
694bbd3662aSCasey Schaufler  *
695bbd3662aSCasey Schaufler  * Allocate the cred blob for all the modules
696bbd3662aSCasey Schaufler  *
697bbd3662aSCasey Schaufler  * Returns 0, or -ENOMEM if memory can't be allocated.
698bbd3662aSCasey Schaufler  */
lsm_cred_alloc(struct cred * cred,gfp_t gfp)699bbd3662aSCasey Schaufler static int lsm_cred_alloc(struct cred *cred, gfp_t gfp)
700bbd3662aSCasey Schaufler {
70109001284SCasey Schaufler 	return lsm_blob_alloc(&cred->security, blob_sizes.lbs_cred, gfp);
702bbd3662aSCasey Schaufler }
703bbd3662aSCasey Schaufler 
704bbd3662aSCasey Schaufler /**
705bbd3662aSCasey Schaufler  * lsm_early_cred - during initialization allocate a composite cred blob
706bbd3662aSCasey Schaufler  * @cred: the cred that needs a blob
707bbd3662aSCasey Schaufler  *
7081cfb2a51STetsuo Handa  * Allocate the cred blob for all the modules
709bbd3662aSCasey Schaufler  */
lsm_early_cred(struct cred * cred)7101cfb2a51STetsuo Handa static void __init lsm_early_cred(struct cred *cred)
711bbd3662aSCasey Schaufler {
7121cfb2a51STetsuo Handa 	int rc = lsm_cred_alloc(cred, GFP_KERNEL);
713bbd3662aSCasey Schaufler 
714bbd3662aSCasey Schaufler 	if (rc)
715bbd3662aSCasey Schaufler 		panic("%s: Early cred alloc failed.\n", __func__);
716bbd3662aSCasey Schaufler }
717bbd3662aSCasey Schaufler 
71833bf60caSCasey Schaufler /**
71933bf60caSCasey Schaufler  * lsm_file_alloc - allocate a composite file blob
72033bf60caSCasey Schaufler  * @file: the file that needs a blob
72133bf60caSCasey Schaufler  *
72233bf60caSCasey Schaufler  * Allocate the file blob for all the modules
72333bf60caSCasey Schaufler  *
72433bf60caSCasey Schaufler  * Returns 0, or -ENOMEM if memory can't be allocated.
72533bf60caSCasey Schaufler  */
lsm_file_alloc(struct file * file)72633bf60caSCasey Schaufler static int lsm_file_alloc(struct file *file)
72733bf60caSCasey Schaufler {
72833bf60caSCasey Schaufler 	if (!lsm_file_cache) {
72933bf60caSCasey Schaufler 		file->f_security = NULL;
73033bf60caSCasey Schaufler 		return 0;
73133bf60caSCasey Schaufler 	}
73233bf60caSCasey Schaufler 
73333bf60caSCasey Schaufler 	file->f_security = kmem_cache_zalloc(lsm_file_cache, GFP_KERNEL);
73433bf60caSCasey Schaufler 	if (file->f_security == NULL)
73533bf60caSCasey Schaufler 		return -ENOMEM;
73633bf60caSCasey Schaufler 	return 0;
73733bf60caSCasey Schaufler }
73833bf60caSCasey Schaufler 
739afb1cbe3SCasey Schaufler /**
740afb1cbe3SCasey Schaufler  * lsm_inode_alloc - allocate a composite inode blob
741afb1cbe3SCasey Schaufler  * @inode: the inode that needs a blob
7429897713fSMichal Hocko  * @gfp: allocation flags
743afb1cbe3SCasey Schaufler  *
744afb1cbe3SCasey Schaufler  * Allocate the inode blob for all the modules
745afb1cbe3SCasey Schaufler  *
746afb1cbe3SCasey Schaufler  * Returns 0, or -ENOMEM if memory can't be allocated.
747afb1cbe3SCasey Schaufler  */
lsm_inode_alloc(struct inode * inode,gfp_t gfp)7489897713fSMichal Hocko static int lsm_inode_alloc(struct inode *inode, gfp_t gfp)
749afb1cbe3SCasey Schaufler {
750afb1cbe3SCasey Schaufler 	if (!lsm_inode_cache) {
751afb1cbe3SCasey Schaufler 		inode->i_security = NULL;
752afb1cbe3SCasey Schaufler 		return 0;
753afb1cbe3SCasey Schaufler 	}
754afb1cbe3SCasey Schaufler 
7559897713fSMichal Hocko 	inode->i_security = kmem_cache_zalloc(lsm_inode_cache, gfp);
756afb1cbe3SCasey Schaufler 	if (inode->i_security == NULL)
757afb1cbe3SCasey Schaufler 		return -ENOMEM;
758afb1cbe3SCasey Schaufler 	return 0;
759afb1cbe3SCasey Schaufler }
760afb1cbe3SCasey Schaufler 
761f4ad8f2cSCasey Schaufler /**
762f4ad8f2cSCasey Schaufler  * lsm_task_alloc - allocate a composite task blob
763f4ad8f2cSCasey Schaufler  * @task: the task that needs a blob
764f4ad8f2cSCasey Schaufler  *
765f4ad8f2cSCasey Schaufler  * Allocate the task blob for all the modules
766f4ad8f2cSCasey Schaufler  *
767f4ad8f2cSCasey Schaufler  * Returns 0, or -ENOMEM if memory can't be allocated.
768f4ad8f2cSCasey Schaufler  */
lsm_task_alloc(struct task_struct * task)7693e8c7367SWei Yongjun static int lsm_task_alloc(struct task_struct *task)
770f4ad8f2cSCasey Schaufler {
77109001284SCasey Schaufler 	return lsm_blob_alloc(&task->security, blob_sizes.lbs_task, GFP_KERNEL);
772f4ad8f2cSCasey Schaufler }
773f4ad8f2cSCasey Schaufler 
774f4ad8f2cSCasey Schaufler /**
775ecd5f82eSCasey Schaufler  * lsm_ipc_alloc - allocate a composite ipc blob
776ecd5f82eSCasey Schaufler  * @kip: the ipc that needs a blob
777ecd5f82eSCasey Schaufler  *
778ecd5f82eSCasey Schaufler  * Allocate the ipc blob for all the modules
779ecd5f82eSCasey Schaufler  *
780ecd5f82eSCasey Schaufler  * Returns 0, or -ENOMEM if memory can't be allocated.
781ecd5f82eSCasey Schaufler  */
lsm_ipc_alloc(struct kern_ipc_perm * kip)7823e8c7367SWei Yongjun static int lsm_ipc_alloc(struct kern_ipc_perm *kip)
783ecd5f82eSCasey Schaufler {
78409001284SCasey Schaufler 	return lsm_blob_alloc(&kip->security, blob_sizes.lbs_ipc, GFP_KERNEL);
785ecd5f82eSCasey Schaufler }
786ecd5f82eSCasey Schaufler 
7875f8d28f6SCasey Schaufler #ifdef CONFIG_KEYS
7885f8d28f6SCasey Schaufler /**
7895f8d28f6SCasey Schaufler  * lsm_key_alloc - allocate a composite key blob
7905f8d28f6SCasey Schaufler  * @key: the key that needs a blob
7915f8d28f6SCasey Schaufler  *
7925f8d28f6SCasey Schaufler  * Allocate the key blob for all the modules
7935f8d28f6SCasey Schaufler  *
7945f8d28f6SCasey Schaufler  * Returns 0, or -ENOMEM if memory can't be allocated.
7955f8d28f6SCasey Schaufler  */
lsm_key_alloc(struct key * key)7965f8d28f6SCasey Schaufler static int lsm_key_alloc(struct key *key)
7975f8d28f6SCasey Schaufler {
79809001284SCasey Schaufler 	return lsm_blob_alloc(&key->security, blob_sizes.lbs_key, GFP_KERNEL);
7995f8d28f6SCasey Schaufler }
8005f8d28f6SCasey Schaufler #endif /* CONFIG_KEYS */
8015f8d28f6SCasey Schaufler 
802ecd5f82eSCasey Schaufler /**
803ecd5f82eSCasey Schaufler  * lsm_msg_msg_alloc - allocate a composite msg_msg blob
804ecd5f82eSCasey Schaufler  * @mp: the msg_msg that needs a blob
805ecd5f82eSCasey Schaufler  *
806ecd5f82eSCasey Schaufler  * Allocate the ipc blob for all the modules
807ecd5f82eSCasey Schaufler  *
808ecd5f82eSCasey Schaufler  * Returns 0, or -ENOMEM if memory can't be allocated.
809ecd5f82eSCasey Schaufler  */
lsm_msg_msg_alloc(struct msg_msg * mp)8103e8c7367SWei Yongjun static int lsm_msg_msg_alloc(struct msg_msg *mp)
811ecd5f82eSCasey Schaufler {
81209001284SCasey Schaufler 	return lsm_blob_alloc(&mp->security, blob_sizes.lbs_msg_msg,
81309001284SCasey Schaufler 			      GFP_KERNEL);
814ecd5f82eSCasey Schaufler }
815ecd5f82eSCasey Schaufler 
816ecd5f82eSCasey Schaufler /**
817b55d26bdSDeven Bowers  * lsm_bdev_alloc - allocate a composite block_device blob
818b55d26bdSDeven Bowers  * @bdev: the block_device that needs a blob
819b55d26bdSDeven Bowers  *
820b55d26bdSDeven Bowers  * Allocate the block_device blob for all the modules
821b55d26bdSDeven Bowers  *
822b55d26bdSDeven Bowers  * Returns 0, or -ENOMEM if memory can't be allocated.
823b55d26bdSDeven Bowers  */
lsm_bdev_alloc(struct block_device * bdev)824b55d26bdSDeven Bowers static int lsm_bdev_alloc(struct block_device *bdev)
825b55d26bdSDeven Bowers {
826b55d26bdSDeven Bowers 	if (blob_sizes.lbs_bdev == 0) {
827b55d26bdSDeven Bowers 		bdev->bd_security = NULL;
828b55d26bdSDeven Bowers 		return 0;
829b55d26bdSDeven Bowers 	}
830b55d26bdSDeven Bowers 
831b55d26bdSDeven Bowers 	bdev->bd_security = kzalloc(blob_sizes.lbs_bdev, GFP_KERNEL);
832b55d26bdSDeven Bowers 	if (!bdev->bd_security)
833b55d26bdSDeven Bowers 		return -ENOMEM;
834b55d26bdSDeven Bowers 
835b55d26bdSDeven Bowers 	return 0;
836b55d26bdSDeven Bowers }
837b55d26bdSDeven Bowers 
838b55d26bdSDeven Bowers /**
839f4ad8f2cSCasey Schaufler  * lsm_early_task - during initialization allocate a composite task blob
840f4ad8f2cSCasey Schaufler  * @task: the task that needs a blob
841f4ad8f2cSCasey Schaufler  *
8421cfb2a51STetsuo Handa  * Allocate the task blob for all the modules
843f4ad8f2cSCasey Schaufler  */
lsm_early_task(struct task_struct * task)8441cfb2a51STetsuo Handa static void __init lsm_early_task(struct task_struct *task)
845f4ad8f2cSCasey Schaufler {
8461cfb2a51STetsuo Handa 	int rc = lsm_task_alloc(task);
847f4ad8f2cSCasey Schaufler 
848f4ad8f2cSCasey Schaufler 	if (rc)
849f4ad8f2cSCasey Schaufler 		panic("%s: Early task alloc failed.\n", __func__);
850f4ad8f2cSCasey Schaufler }
851f4ad8f2cSCasey Schaufler 
8521aea7808SCasey Schaufler /**
8531aea7808SCasey Schaufler  * lsm_superblock_alloc - allocate a composite superblock blob
8541aea7808SCasey Schaufler  * @sb: the superblock that needs a blob
8551aea7808SCasey Schaufler  *
8561aea7808SCasey Schaufler  * Allocate the superblock blob for all the modules
8571aea7808SCasey Schaufler  *
8581aea7808SCasey Schaufler  * Returns 0, or -ENOMEM if memory can't be allocated.
8591aea7808SCasey Schaufler  */
lsm_superblock_alloc(struct super_block * sb)8601aea7808SCasey Schaufler static int lsm_superblock_alloc(struct super_block *sb)
8611aea7808SCasey Schaufler {
86209001284SCasey Schaufler 	return lsm_blob_alloc(&sb->s_security, blob_sizes.lbs_superblock,
86309001284SCasey Schaufler 			      GFP_KERNEL);
8641aea7808SCasey Schaufler }
8651aea7808SCasey Schaufler 
866e1ca7129SCasey Schaufler /**
867e1ca7129SCasey Schaufler  * lsm_fill_user_ctx - Fill a user space lsm_ctx structure
868d7cf3412SPaul Moore  * @uctx: a userspace LSM context to be filled
869d7cf3412SPaul Moore  * @uctx_len: available uctx size (input), used uctx size (output)
870d7cf3412SPaul Moore  * @val: the new LSM context value
871d7cf3412SPaul Moore  * @val_len: the size of the new LSM context value
872e1ca7129SCasey Schaufler  * @id: LSM id
873e1ca7129SCasey Schaufler  * @flags: LSM defined flags
874e1ca7129SCasey Schaufler  *
875eaf0e7a3SPaul Moore  * Fill all of the fields in a userspace lsm_ctx structure.  If @uctx is NULL
876eaf0e7a3SPaul Moore  * simply calculate the required size to output via @utc_len and return
877eaf0e7a3SPaul Moore  * success.
878e1ca7129SCasey Schaufler  *
879d7cf3412SPaul Moore  * Returns 0 on success, -E2BIG if userspace buffer is not large enough,
880d7cf3412SPaul Moore  * -EFAULT on a copyout error, -ENOMEM if memory can't be allocated.
881e1ca7129SCasey Schaufler  */
lsm_fill_user_ctx(struct lsm_ctx __user * uctx,u32 * uctx_len,void * val,size_t val_len,u64 id,u64 flags)882a5a858f6SCasey Schaufler int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len,
883d7cf3412SPaul Moore 		      void *val, size_t val_len,
884d7cf3412SPaul Moore 		      u64 id, u64 flags)
885e1ca7129SCasey Schaufler {
886d7cf3412SPaul Moore 	struct lsm_ctx *nctx = NULL;
887d7cf3412SPaul Moore 	size_t nctx_len;
888e1ca7129SCasey Schaufler 	int rc = 0;
889e1ca7129SCasey Schaufler 
89041793202SPaul Moore 	nctx_len = ALIGN(struct_size(nctx, ctx, val_len), sizeof(void *));
891d7cf3412SPaul Moore 	if (nctx_len > *uctx_len) {
892d7cf3412SPaul Moore 		rc = -E2BIG;
893d7cf3412SPaul Moore 		goto out;
894d7cf3412SPaul Moore 	}
895e1ca7129SCasey Schaufler 
896eaf0e7a3SPaul Moore 	/* no buffer - return success/0 and set @uctx_len to the req size */
897eaf0e7a3SPaul Moore 	if (!uctx)
898eaf0e7a3SPaul Moore 		goto out;
899eaf0e7a3SPaul Moore 
900d7cf3412SPaul Moore 	nctx = kzalloc(nctx_len, GFP_KERNEL);
901d7cf3412SPaul Moore 	if (nctx == NULL) {
902d7cf3412SPaul Moore 		rc = -ENOMEM;
903d7cf3412SPaul Moore 		goto out;
904d7cf3412SPaul Moore 	}
905d7cf3412SPaul Moore 	nctx->id = id;
906d7cf3412SPaul Moore 	nctx->flags = flags;
907d7cf3412SPaul Moore 	nctx->len = nctx_len;
908d7cf3412SPaul Moore 	nctx->ctx_len = val_len;
909d7cf3412SPaul Moore 	memcpy(nctx->ctx, val, val_len);
910e1ca7129SCasey Schaufler 
911d7cf3412SPaul Moore 	if (copy_to_user(uctx, nctx, nctx_len))
912e1ca7129SCasey Schaufler 		rc = -EFAULT;
913e1ca7129SCasey Schaufler 
914d7cf3412SPaul Moore out:
915d7cf3412SPaul Moore 	kfree(nctx);
916d7cf3412SPaul Moore 	*uctx_len = nctx_len;
917e1ca7129SCasey Schaufler 	return rc;
918e1ca7129SCasey Schaufler }
919e1ca7129SCasey Schaufler 
920f25fce3eSCasey Schaufler /*
92198e828a0SKP Singh  * The default value of the LSM hook is defined in linux/lsm_hook_defs.h and
92298e828a0SKP Singh  * can be accessed with:
92398e828a0SKP Singh  *
92498e828a0SKP Singh  *	LSM_RET_DEFAULT(<hook_name>)
92598e828a0SKP Singh  *
92698e828a0SKP Singh  * The macros below define static constants for the default value of each
92798e828a0SKP Singh  * LSM hook.
92898e828a0SKP Singh  */
92998e828a0SKP Singh #define LSM_RET_DEFAULT(NAME) (NAME##_default)
93098e828a0SKP Singh #define DECLARE_LSM_RET_DEFAULT_void(DEFAULT, NAME)
93198e828a0SKP Singh #define DECLARE_LSM_RET_DEFAULT_int(DEFAULT, NAME) \
93286dd9fd5SKees Cook 	static const int __maybe_unused LSM_RET_DEFAULT(NAME) = (DEFAULT);
93398e828a0SKP Singh #define LSM_HOOK(RET, DEFAULT, NAME, ...) \
93498e828a0SKP Singh 	DECLARE_LSM_RET_DEFAULT_##RET(DEFAULT, NAME)
93598e828a0SKP Singh 
93698e828a0SKP Singh #include <linux/lsm_hook_defs.h>
93798e828a0SKP Singh #undef LSM_HOOK
93898e828a0SKP Singh 
93998e828a0SKP Singh /*
940b1d9e6b0SCasey Schaufler  * Hook list operation macros.
9411da177e4SLinus Torvalds  *
942f25fce3eSCasey Schaufler  * call_void_hook:
943f25fce3eSCasey Schaufler  *	This is a hook that does not return a value.
9441da177e4SLinus Torvalds  *
945f25fce3eSCasey Schaufler  * call_int_hook:
946f25fce3eSCasey Schaufler  *	This is a hook that returns a value.
9471da177e4SLinus Torvalds  */
948417c5643SKP Singh #define __CALL_STATIC_VOID(NUM, HOOK, ...)				     \
949b1d9e6b0SCasey Schaufler do {									     \
950417c5643SKP Singh 	if (static_branch_unlikely(&SECURITY_HOOK_ACTIVE_KEY(HOOK, NUM))) {    \
951417c5643SKP Singh 		static_call(LSM_STATIC_CALL(HOOK, NUM))(__VA_ARGS__);	     \
952417c5643SKP Singh 	}								     \
953417c5643SKP Singh } while (0);
954417c5643SKP Singh 
955417c5643SKP Singh #define call_void_hook(HOOK, ...)                                 \
956417c5643SKP Singh 	do {                                                      \
957417c5643SKP Singh 		LSM_LOOP_UNROLL(__CALL_STATIC_VOID, HOOK, __VA_ARGS__); \
958b1d9e6b0SCasey Schaufler 	} while (0)
9591da177e4SLinus Torvalds 
960417c5643SKP Singh 
961417c5643SKP Singh #define __CALL_STATIC_INT(NUM, R, HOOK, LABEL, ...)			     \
962b1d9e6b0SCasey Schaufler do {									     \
963417c5643SKP Singh 	if (static_branch_unlikely(&SECURITY_HOOK_ACTIVE_KEY(HOOK, NUM))) {  \
964417c5643SKP Singh 		R = static_call(LSM_STATIC_CALL(HOOK, NUM))(__VA_ARGS__);    \
965417c5643SKP Singh 		if (R != LSM_RET_DEFAULT(HOOK))				     \
966417c5643SKP Singh 			goto LABEL;					     \
967b1d9e6b0SCasey Schaufler 	}								     \
968417c5643SKP Singh } while (0);
969417c5643SKP Singh 
970417c5643SKP Singh #define call_int_hook(HOOK, ...)					\
971417c5643SKP Singh ({									\
972417c5643SKP Singh 	__label__ OUT;							\
973417c5643SKP Singh 	int RC = LSM_RET_DEFAULT(HOOK);					\
974417c5643SKP Singh 									\
975417c5643SKP Singh 	LSM_LOOP_UNROLL(__CALL_STATIC_INT, RC, HOOK, OUT, __VA_ARGS__);	\
976417c5643SKP Singh OUT:									\
977b1d9e6b0SCasey Schaufler 	RC;								\
978b1d9e6b0SCasey Schaufler })
9791da177e4SLinus Torvalds 
980417c5643SKP Singh #define lsm_for_each_hook(scall, NAME)					\
981417c5643SKP Singh 	for (scall = static_calls_table.NAME;				\
982417c5643SKP Singh 	     scall - static_calls_table.NAME < MAX_LSM_COUNT; scall++)  \
983417c5643SKP Singh 		if (static_key_enabled(&scall->active->key))
984417c5643SKP Singh 
98520510f2fSJames Morris /* Security operations */
98620510f2fSJames Morris 
9871427ddbeSPaul Moore /**
9881427ddbeSPaul Moore  * security_binder_set_context_mgr() - Check if becoming binder ctx mgr is ok
9891427ddbeSPaul Moore  * @mgr: task credentials of current binder process
9901427ddbeSPaul Moore  *
9911427ddbeSPaul Moore  * Check whether @mgr is allowed to be the binder context manager.
9921427ddbeSPaul Moore  *
9931427ddbeSPaul Moore  * Return: Return 0 if permission is granted.
9941427ddbeSPaul Moore  */
security_binder_set_context_mgr(const struct cred * mgr)99552f88693STodd Kjos int security_binder_set_context_mgr(const struct cred *mgr)
99679af7307SStephen Smalley {
997260017f3SOndrej Mosnacek 	return call_int_hook(binder_set_context_mgr, mgr);
99879af7307SStephen Smalley }
99979af7307SStephen Smalley 
10001427ddbeSPaul Moore /**
10011427ddbeSPaul Moore  * security_binder_transaction() - Check if a binder transaction is allowed
10021427ddbeSPaul Moore  * @from: sending process
10031427ddbeSPaul Moore  * @to: receiving process
10041427ddbeSPaul Moore  *
10051427ddbeSPaul Moore  * Check whether @from is allowed to invoke a binder transaction call to @to.
10061427ddbeSPaul Moore  *
10071427ddbeSPaul Moore  * Return: Returns 0 if permission is granted.
10081427ddbeSPaul Moore  */
security_binder_transaction(const struct cred * from,const struct cred * to)100952f88693STodd Kjos int security_binder_transaction(const struct cred *from,
101052f88693STodd Kjos 				const struct cred *to)
101179af7307SStephen Smalley {
1012260017f3SOndrej Mosnacek 	return call_int_hook(binder_transaction, from, to);
101379af7307SStephen Smalley }
101479af7307SStephen Smalley 
10151427ddbeSPaul Moore /**
10161427ddbeSPaul Moore  * security_binder_transfer_binder() - Check if a binder transfer is allowed
10171427ddbeSPaul Moore  * @from: sending process
10181427ddbeSPaul Moore  * @to: receiving process
10191427ddbeSPaul Moore  *
10201427ddbeSPaul Moore  * Check whether @from is allowed to transfer a binder reference to @to.
10211427ddbeSPaul Moore  *
10221427ddbeSPaul Moore  * Return: Returns 0 if permission is granted.
10231427ddbeSPaul Moore  */
security_binder_transfer_binder(const struct cred * from,const struct cred * to)102452f88693STodd Kjos int security_binder_transfer_binder(const struct cred *from,
102552f88693STodd Kjos 				    const struct cred *to)
102679af7307SStephen Smalley {
1027260017f3SOndrej Mosnacek 	return call_int_hook(binder_transfer_binder, from, to);
102879af7307SStephen Smalley }
102979af7307SStephen Smalley 
10301427ddbeSPaul Moore /**
10311427ddbeSPaul Moore  * security_binder_transfer_file() - Check if a binder file xfer is allowed
10321427ddbeSPaul Moore  * @from: sending process
10331427ddbeSPaul Moore  * @to: receiving process
10341427ddbeSPaul Moore  * @file: file being transferred
10351427ddbeSPaul Moore  *
10361427ddbeSPaul Moore  * Check whether @from is allowed to transfer @file to @to.
10371427ddbeSPaul Moore  *
10381427ddbeSPaul Moore  * Return: Returns 0 if permission is granted.
10391427ddbeSPaul Moore  */
security_binder_transfer_file(const struct cred * from,const struct cred * to,const struct file * file)104052f88693STodd Kjos int security_binder_transfer_file(const struct cred *from,
10418e4672d6SKhadija Kamran 				  const struct cred *to, const struct file *file)
104279af7307SStephen Smalley {
1043260017f3SOndrej Mosnacek 	return call_int_hook(binder_transfer_file, from, to, file);
104479af7307SStephen Smalley }
104579af7307SStephen Smalley 
1046e261301cSPaul Moore /**
1047e261301cSPaul Moore  * security_ptrace_access_check() - Check if tracing is allowed
1048e261301cSPaul Moore  * @child: target process
1049e261301cSPaul Moore  * @mode: PTRACE_MODE flags
1050e261301cSPaul Moore  *
1051e261301cSPaul Moore  * Check permission before allowing the current process to trace the @child
1052e261301cSPaul Moore  * process.  Security modules may also want to perform a process tracing check
1053e261301cSPaul Moore  * during an execve in the set_security or apply_creds hooks of tracing check
1054e261301cSPaul Moore  * during an execve in the bprm_set_creds hook of binprm_security_ops if the
1055e261301cSPaul Moore  * process is being traced and its security attributes would be changed by the
1056e261301cSPaul Moore  * execve.
1057e261301cSPaul Moore  *
1058e261301cSPaul Moore  * Return: Returns 0 if permission is granted.
1059e261301cSPaul Moore  */
security_ptrace_access_check(struct task_struct * child,unsigned int mode)10609e48858fSIngo Molnar int security_ptrace_access_check(struct task_struct *child, unsigned int mode)
106120510f2fSJames Morris {
1062260017f3SOndrej Mosnacek 	return call_int_hook(ptrace_access_check, child, mode);
10635cd9c58fSDavid Howells }
10645cd9c58fSDavid Howells 
1065e261301cSPaul Moore /**
1066e261301cSPaul Moore  * security_ptrace_traceme() - Check if tracing is allowed
1067e261301cSPaul Moore  * @parent: tracing process
1068e261301cSPaul Moore  *
1069e261301cSPaul Moore  * Check that the @parent process has sufficient permission to trace the
1070e261301cSPaul Moore  * current process before allowing the current process to present itself to the
1071e261301cSPaul Moore  * @parent process for tracing.
1072e261301cSPaul Moore  *
1073e261301cSPaul Moore  * Return: Returns 0 if permission is granted.
1074e261301cSPaul Moore  */
security_ptrace_traceme(struct task_struct * parent)10755cd9c58fSDavid Howells int security_ptrace_traceme(struct task_struct *parent)
10765cd9c58fSDavid Howells {
1077260017f3SOndrej Mosnacek 	return call_int_hook(ptrace_traceme, parent);
107820510f2fSJames Morris }
107920510f2fSJames Morris 
1080e261301cSPaul Moore /**
1081e261301cSPaul Moore  * security_capget() - Get the capability sets for a process
1082e261301cSPaul Moore  * @target: target process
1083e261301cSPaul Moore  * @effective: effective capability set
1084e261301cSPaul Moore  * @inheritable: inheritable capability set
1085e261301cSPaul Moore  * @permitted: permitted capability set
1086e261301cSPaul Moore  *
1087e261301cSPaul Moore  * Get the @effective, @inheritable, and @permitted capability sets for the
1088e261301cSPaul Moore  * @target process.  The hook may also perform permission checking to determine
1089e261301cSPaul Moore  * if the current process is allowed to see the capability sets of the @target
1090e261301cSPaul Moore  * process.
1091e261301cSPaul Moore  *
1092e261301cSPaul Moore  * Return: Returns 0 if the capability sets were successfully obtained.
1093e261301cSPaul Moore  */
security_capget(const struct task_struct * target,kernel_cap_t * effective,kernel_cap_t * inheritable,kernel_cap_t * permitted)10946672efbbSKhadija Kamran int security_capget(const struct task_struct *target,
109520510f2fSJames Morris 		    kernel_cap_t *effective,
109620510f2fSJames Morris 		    kernel_cap_t *inheritable,
109720510f2fSJames Morris 		    kernel_cap_t *permitted)
109820510f2fSJames Morris {
1099260017f3SOndrej Mosnacek 	return call_int_hook(capget, target, effective, inheritable, permitted);
110020510f2fSJames Morris }
110120510f2fSJames Morris 
1102e261301cSPaul Moore /**
1103e261301cSPaul Moore  * security_capset() - Set the capability sets for a process
1104e261301cSPaul Moore  * @new: new credentials for the target process
1105e261301cSPaul Moore  * @old: current credentials of the target process
1106e261301cSPaul Moore  * @effective: effective capability set
1107e261301cSPaul Moore  * @inheritable: inheritable capability set
1108e261301cSPaul Moore  * @permitted: permitted capability set
1109e261301cSPaul Moore  *
1110e261301cSPaul Moore  * Set the @effective, @inheritable, and @permitted capability sets for the
1111e261301cSPaul Moore  * current process.
1112e261301cSPaul Moore  *
1113e261301cSPaul Moore  * Return: Returns 0 and update @new if permission is granted.
1114e261301cSPaul Moore  */
security_capset(struct cred * new,const struct cred * old,const kernel_cap_t * effective,const kernel_cap_t * inheritable,const kernel_cap_t * permitted)1115d84f4f99SDavid Howells int security_capset(struct cred *new, const struct cred *old,
1116d84f4f99SDavid Howells 		    const kernel_cap_t *effective,
111715a2460eSDavid Howells 		    const kernel_cap_t *inheritable,
111815a2460eSDavid Howells 		    const kernel_cap_t *permitted)
111920510f2fSJames Morris {
1120260017f3SOndrej Mosnacek 	return call_int_hook(capset, new, old, effective, inheritable,
1121260017f3SOndrej Mosnacek 			     permitted);
112220510f2fSJames Morris }
112320510f2fSJames Morris 
1124e261301cSPaul Moore /**
1125e261301cSPaul Moore  * security_capable() - Check if a process has the necessary capability
1126e261301cSPaul Moore  * @cred: credentials to examine
1127e261301cSPaul Moore  * @ns: user namespace
1128e261301cSPaul Moore  * @cap: capability requested
1129e261301cSPaul Moore  * @opts: capability check options
1130e261301cSPaul Moore  *
1131e261301cSPaul Moore  * Check whether the @tsk process has the @cap capability in the indicated
1132e261301cSPaul Moore  * credentials.  @cap contains the capability <include/linux/capability.h>.
1133e261301cSPaul Moore  * @opts contains options for the capable check <include/linux/security.h>.
1134e261301cSPaul Moore  *
1135e261301cSPaul Moore  * Return: Returns 0 if the capability is granted.
1136e261301cSPaul Moore  */
security_capable(const struct cred * cred,struct user_namespace * ns,int cap,unsigned int opts)1137c1a85a00SMicah Morton int security_capable(const struct cred *cred,
1138c1a85a00SMicah Morton 		     struct user_namespace *ns,
1139c1a85a00SMicah Morton 		     int cap,
1140c1a85a00SMicah Morton 		     unsigned int opts)
114120510f2fSJames Morris {
1142260017f3SOndrej Mosnacek 	return call_int_hook(capable, cred, ns, cap, opts);
114320510f2fSJames Morris }
114420510f2fSJames Morris 
1145e261301cSPaul Moore /**
1146e261301cSPaul Moore  * security_quotactl() - Check if a quotactl() syscall is allowed for this fs
1147e261301cSPaul Moore  * @cmds: commands
1148e261301cSPaul Moore  * @type: type
1149e261301cSPaul Moore  * @id: id
1150e261301cSPaul Moore  * @sb: filesystem
1151e261301cSPaul Moore  *
1152e261301cSPaul Moore  * Check whether the quotactl syscall is allowed for this @sb.
1153e261301cSPaul Moore  *
1154e261301cSPaul Moore  * Return: Returns 0 if permission is granted.
1155e261301cSPaul Moore  */
security_quotactl(int cmds,int type,int id,const struct super_block * sb)115625cc71d1SKhadija Kamran int security_quotactl(int cmds, int type, int id, const struct super_block *sb)
115720510f2fSJames Morris {
1158260017f3SOndrej Mosnacek 	return call_int_hook(quotactl, cmds, type, id, sb);
115920510f2fSJames Morris }
116020510f2fSJames Morris 
1161e261301cSPaul Moore /**
1162e261301cSPaul Moore  * security_quota_on() - Check if QUOTAON is allowed for a dentry
1163e261301cSPaul Moore  * @dentry: dentry
1164e261301cSPaul Moore  *
1165e261301cSPaul Moore  * Check whether QUOTAON is allowed for @dentry.
1166e261301cSPaul Moore  *
1167e261301cSPaul Moore  * Return: Returns 0 if permission is granted.
1168e261301cSPaul Moore  */
security_quota_on(struct dentry * dentry)116920510f2fSJames Morris int security_quota_on(struct dentry *dentry)
117020510f2fSJames Morris {
1171260017f3SOndrej Mosnacek 	return call_int_hook(quota_on, dentry);
117220510f2fSJames Morris }
117320510f2fSJames Morris 
1174e261301cSPaul Moore /**
1175e261301cSPaul Moore  * security_syslog() - Check if accessing the kernel message ring is allowed
1176e261301cSPaul Moore  * @type: SYSLOG_ACTION_* type
1177e261301cSPaul Moore  *
1178e261301cSPaul Moore  * Check permission before accessing the kernel message ring or changing
1179e261301cSPaul Moore  * logging to the console.  See the syslog(2) manual page for an explanation of
1180e261301cSPaul Moore  * the @type values.
1181e261301cSPaul Moore  *
1182e261301cSPaul Moore  * Return: Return 0 if permission is granted.
1183e261301cSPaul Moore  */
security_syslog(int type)118412b3052cSEric Paris int security_syslog(int type)
118520510f2fSJames Morris {
1186260017f3SOndrej Mosnacek 	return call_int_hook(syslog, type);
118720510f2fSJames Morris }
118820510f2fSJames Morris 
1189e261301cSPaul Moore /**
1190e261301cSPaul Moore  * security_settime64() - Check if changing the system time is allowed
1191e261301cSPaul Moore  * @ts: new time
1192e261301cSPaul Moore  * @tz: timezone
1193e261301cSPaul Moore  *
1194e261301cSPaul Moore  * Check permission to change the system time, struct timespec64 is defined in
1195e261301cSPaul Moore  * <include/linux/time64.h> and timezone is defined in <include/linux/time.h>.
1196e261301cSPaul Moore  *
1197e261301cSPaul Moore  * Return: Returns 0 if permission is granted.
1198e261301cSPaul Moore  */
security_settime64(const struct timespec64 * ts,const struct timezone * tz)1199457db29bSBaolin Wang int security_settime64(const struct timespec64 *ts, const struct timezone *tz)
120020510f2fSJames Morris {
1201260017f3SOndrej Mosnacek 	return call_int_hook(settime, ts, tz);
120220510f2fSJames Morris }
120320510f2fSJames Morris 
1204e261301cSPaul Moore /**
1205e261301cSPaul Moore  * security_vm_enough_memory_mm() - Check if allocating a new mem map is allowed
1206e261301cSPaul Moore  * @mm: mm struct
1207e261301cSPaul Moore  * @pages: number of pages
1208e261301cSPaul Moore  *
1209e261301cSPaul Moore  * Check permissions for allocating a new virtual mapping.  If all LSMs return
1210e261301cSPaul Moore  * a positive value, __vm_enough_memory() will be called with cap_sys_admin
1211e261301cSPaul Moore  * set. If at least one LSM returns 0 or negative, __vm_enough_memory() will be
1212e261301cSPaul Moore  * called with cap_sys_admin cleared.
1213e261301cSPaul Moore  *
1214e261301cSPaul Moore  * Return: Returns 0 if permission is granted by the LSM infrastructure to the
1215e261301cSPaul Moore  *         caller.
1216e261301cSPaul Moore  */
security_vm_enough_memory_mm(struct mm_struct * mm,long pages)121720510f2fSJames Morris int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
121820510f2fSJames Morris {
1219417c5643SKP Singh 	struct lsm_static_call *scall;
1220b1d9e6b0SCasey Schaufler 	int cap_sys_admin = 1;
1221b1d9e6b0SCasey Schaufler 	int rc;
1222b1d9e6b0SCasey Schaufler 
1223b1d9e6b0SCasey Schaufler 	/*
1224be72a575SXu Kuohai 	 * The module will respond with 0 if it thinks the __vm_enough_memory()
1225be72a575SXu Kuohai 	 * call should be made with the cap_sys_admin set. If all of the modules
1226be72a575SXu Kuohai 	 * agree that it should be set it will. If any module thinks it should
1227be72a575SXu Kuohai 	 * not be set it won't.
1228b1d9e6b0SCasey Schaufler 	 */
1229417c5643SKP Singh 	lsm_for_each_hook(scall, vm_enough_memory) {
1230417c5643SKP Singh 		rc = scall->hl->hook.vm_enough_memory(mm, pages);
1231be72a575SXu Kuohai 		if (rc < 0) {
1232b1d9e6b0SCasey Schaufler 			cap_sys_admin = 0;
1233b1d9e6b0SCasey Schaufler 			break;
1234b1d9e6b0SCasey Schaufler 		}
1235b1d9e6b0SCasey Schaufler 	}
1236b1d9e6b0SCasey Schaufler 	return __vm_enough_memory(mm, pages, cap_sys_admin);
123720510f2fSJames Morris }
123820510f2fSJames Morris 
12391661372cSPaul Moore /**
12401661372cSPaul Moore  * security_bprm_creds_for_exec() - Prepare the credentials for exec()
12411661372cSPaul Moore  * @bprm: binary program information
12421661372cSPaul Moore  *
12431661372cSPaul Moore  * If the setup in prepare_exec_creds did not setup @bprm->cred->security
12441661372cSPaul Moore  * properly for executing @bprm->file, update the LSM's portion of
12451661372cSPaul Moore  * @bprm->cred->security to be what commit_creds needs to install for the new
12461661372cSPaul Moore  * program.  This hook may also optionally check permissions (e.g. for
12471661372cSPaul Moore  * transitions between security domains).  The hook must set @bprm->secureexec
12481661372cSPaul Moore  * to 1 if AT_SECURE should be set to request libc enable secure mode.  @bprm
12491661372cSPaul Moore  * contains the linux_binprm structure.
12501661372cSPaul Moore  *
1251a5874fdeSMickaël Salaün  * If execveat(2) is called with the AT_EXECVE_CHECK flag, bprm->is_check is
1252a5874fdeSMickaël Salaün  * set.  The result must be the same as without this flag even if the execution
1253a5874fdeSMickaël Salaün  * will never really happen and @bprm will always be dropped.
1254a5874fdeSMickaël Salaün  *
1255a5874fdeSMickaël Salaün  * This hook must not change current->cred, only @bprm->cred.
1256a5874fdeSMickaël Salaün  *
12571661372cSPaul Moore  * Return: Returns 0 if the hook is successful and permission is granted.
12581661372cSPaul Moore  */
security_bprm_creds_for_exec(struct linux_binprm * bprm)1259b8bff599SEric W. Biederman int security_bprm_creds_for_exec(struct linux_binprm *bprm)
126020510f2fSJames Morris {
1261260017f3SOndrej Mosnacek 	return call_int_hook(bprm_creds_for_exec, bprm);
1262b8bff599SEric W. Biederman }
1263b8bff599SEric W. Biederman 
12641661372cSPaul Moore /**
12651661372cSPaul Moore  * security_bprm_creds_from_file() - Update linux_binprm creds based on file
12661661372cSPaul Moore  * @bprm: binary program information
12671661372cSPaul Moore  * @file: associated file
12681661372cSPaul Moore  *
12691661372cSPaul Moore  * If @file is setpcap, suid, sgid or otherwise marked to change privilege upon
12701661372cSPaul Moore  * exec, update @bprm->cred to reflect that change. This is called after
12711661372cSPaul Moore  * finding the binary that will be executed without an interpreter.  This
12721661372cSPaul Moore  * ensures that the credentials will not be derived from a script that the
12731661372cSPaul Moore  * binary will need to reopen, which when reopend may end up being a completely
12741661372cSPaul Moore  * different file.  This hook may also optionally check permissions (e.g. for
12751661372cSPaul Moore  * transitions between security domains).  The hook must set @bprm->secureexec
12761661372cSPaul Moore  * to 1 if AT_SECURE should be set to request libc enable secure mode.  The
12771661372cSPaul Moore  * hook must add to @bprm->per_clear any personality flags that should be
12781661372cSPaul Moore  * cleared from current->personality.  @bprm contains the linux_binprm
12791661372cSPaul Moore  * structure.
12801661372cSPaul Moore  *
12811661372cSPaul Moore  * Return: Returns 0 if the hook is successful and permission is granted.
12821661372cSPaul Moore  */
security_bprm_creds_from_file(struct linux_binprm * bprm,const struct file * file)12834a00c673SKhadija Kamran int security_bprm_creds_from_file(struct linux_binprm *bprm, const struct file *file)
128420510f2fSJames Morris {
1285260017f3SOndrej Mosnacek 	return call_int_hook(bprm_creds_from_file, bprm, file);
128620510f2fSJames Morris }
128720510f2fSJames Morris 
12881661372cSPaul Moore /**
12891661372cSPaul Moore  * security_bprm_check() - Mediate binary handler search
12901661372cSPaul Moore  * @bprm: binary program information
12911661372cSPaul Moore  *
12921661372cSPaul Moore  * This hook mediates the point when a search for a binary handler will begin.
12931661372cSPaul Moore  * It allows a check against the @bprm->cred->security value which was set in
12941661372cSPaul Moore  * the preceding creds_for_exec call.  The argv list and envp list are reliably
12951661372cSPaul Moore  * available in @bprm.  This hook may be called multiple times during a single
12961661372cSPaul Moore  * execve.  @bprm contains the linux_binprm structure.
12971661372cSPaul Moore  *
12981661372cSPaul Moore  * Return: Returns 0 if the hook is successful and permission is granted.
12991661372cSPaul Moore  */
security_bprm_check(struct linux_binprm * bprm)130020510f2fSJames Morris int security_bprm_check(struct linux_binprm *bprm)
130120510f2fSJames Morris {
1302260017f3SOndrej Mosnacek 	return call_int_hook(bprm_check_security, bprm);
130320510f2fSJames Morris }
130420510f2fSJames Morris 
13051661372cSPaul Moore /**
13061661372cSPaul Moore  * security_bprm_committing_creds() - Install creds for a process during exec()
13071661372cSPaul Moore  * @bprm: binary program information
13081661372cSPaul Moore  *
13091661372cSPaul Moore  * Prepare to install the new security attributes of a process being
13101661372cSPaul Moore  * transformed by an execve operation, based on the old credentials pointed to
13111661372cSPaul Moore  * by @current->cred and the information set in @bprm->cred by the
13121661372cSPaul Moore  * bprm_creds_for_exec hook.  @bprm points to the linux_binprm structure.  This
13131661372cSPaul Moore  * hook is a good place to perform state changes on the process such as closing
13141661372cSPaul Moore  * open file descriptors to which access will no longer be granted when the
13151661372cSPaul Moore  * attributes are changed.  This is called immediately before commit_creds().
13161661372cSPaul Moore  */
security_bprm_committing_creds(const struct linux_binprm * bprm)131764fc9526SKhadija Kamran void security_bprm_committing_creds(const struct linux_binprm *bprm)
1318a6f76f23SDavid Howells {
1319f25fce3eSCasey Schaufler 	call_void_hook(bprm_committing_creds, bprm);
1320a6f76f23SDavid Howells }
1321a6f76f23SDavid Howells 
13221661372cSPaul Moore /**
13231661372cSPaul Moore  * security_bprm_committed_creds() - Tidy up after cred install during exec()
13241661372cSPaul Moore  * @bprm: binary program information
13251661372cSPaul Moore  *
13261661372cSPaul Moore  * Tidy up after the installation of the new security attributes of a process
13271661372cSPaul Moore  * being transformed by an execve operation.  The new credentials have, by this
13281661372cSPaul Moore  * point, been set to @current->cred.  @bprm points to the linux_binprm
13291661372cSPaul Moore  * structure.  This hook is a good place to perform state changes on the
13301661372cSPaul Moore  * process such as clearing out non-inheritable signal state.  This is called
13311661372cSPaul Moore  * immediately after commit_creds().
13321661372cSPaul Moore  */
security_bprm_committed_creds(const struct linux_binprm * bprm)1333a721f7b8SKhadija Kamran void security_bprm_committed_creds(const struct linux_binprm *bprm)
1334a6f76f23SDavid Howells {
1335f25fce3eSCasey Schaufler 	call_void_hook(bprm_committed_creds, bprm);
1336a6f76f23SDavid Howells }
1337a6f76f23SDavid Howells 
133836819f18SPaul Moore /**
1339d80a8f1bSDavid Howells  * security_fs_context_submount() - Initialise fc->security
1340d80a8f1bSDavid Howells  * @fc: new filesystem context
1341d80a8f1bSDavid Howells  * @reference: dentry reference for submount/remount
1342d80a8f1bSDavid Howells  *
1343d80a8f1bSDavid Howells  * Fill out the ->security field for a new fs_context.
1344d80a8f1bSDavid Howells  *
1345d80a8f1bSDavid Howells  * Return: Returns 0 on success or negative error code on failure.
1346d80a8f1bSDavid Howells  */
security_fs_context_submount(struct fs_context * fc,struct super_block * reference)1347d80a8f1bSDavid Howells int security_fs_context_submount(struct fs_context *fc, struct super_block *reference)
1348d80a8f1bSDavid Howells {
1349260017f3SOndrej Mosnacek 	return call_int_hook(fs_context_submount, fc, reference);
1350d80a8f1bSDavid Howells }
1351d80a8f1bSDavid Howells 
1352d80a8f1bSDavid Howells /**
135336819f18SPaul Moore  * security_fs_context_dup() - Duplicate a fs_context LSM blob
135436819f18SPaul Moore  * @fc: destination filesystem context
135536819f18SPaul Moore  * @src_fc: source filesystem context
135636819f18SPaul Moore  *
135736819f18SPaul Moore  * Allocate and attach a security structure to sc->security.  This pointer is
135836819f18SPaul Moore  * initialised to NULL by the caller.  @fc indicates the new filesystem context.
135936819f18SPaul Moore  * @src_fc indicates the original filesystem context.
136036819f18SPaul Moore  *
136136819f18SPaul Moore  * Return: Returns 0 on success or a negative error code on failure.
136236819f18SPaul Moore  */
security_fs_context_dup(struct fs_context * fc,struct fs_context * src_fc)13630b52075eSAl Viro int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc)
13640b52075eSAl Viro {
1365260017f3SOndrej Mosnacek 	return call_int_hook(fs_context_dup, fc, src_fc);
13660b52075eSAl Viro }
13670b52075eSAl Viro 
136836819f18SPaul Moore /**
136936819f18SPaul Moore  * security_fs_context_parse_param() - Configure a filesystem context
137036819f18SPaul Moore  * @fc: filesystem context
137136819f18SPaul Moore  * @param: filesystem parameter
137236819f18SPaul Moore  *
137336819f18SPaul Moore  * Userspace provided a parameter to configure a superblock.  The LSM can
137436819f18SPaul Moore  * consume the parameter or return it to the caller for use elsewhere.
137536819f18SPaul Moore  *
137636819f18SPaul Moore  * Return: If the parameter is used by the LSM it should return 0, if it is
137736819f18SPaul Moore  *         returned to the caller -ENOPARAM is returned, otherwise a negative
137836819f18SPaul Moore  *         error code is returned.
137936819f18SPaul Moore  */
security_fs_context_parse_param(struct fs_context * fc,struct fs_parameter * param)1380ecff3057SCasey Schaufler int security_fs_context_parse_param(struct fs_context *fc,
1381ecff3057SCasey Schaufler 				    struct fs_parameter *param)
1382da2441fdSDavid Howells {
1383417c5643SKP Singh 	struct lsm_static_call *scall;
1384ecff3057SCasey Schaufler 	int trc;
1385ecff3057SCasey Schaufler 	int rc = -ENOPARAM;
1386ecff3057SCasey Schaufler 
1387417c5643SKP Singh 	lsm_for_each_hook(scall, fs_context_parse_param) {
1388417c5643SKP Singh 		trc = scall->hl->hook.fs_context_parse_param(fc, param);
1389ecff3057SCasey Schaufler 		if (trc == 0)
1390ecff3057SCasey Schaufler 			rc = 0;
1391ecff3057SCasey Schaufler 		else if (trc != -ENOPARAM)
1392ecff3057SCasey Schaufler 			return trc;
1393ecff3057SCasey Schaufler 	}
1394ecff3057SCasey Schaufler 	return rc;
1395da2441fdSDavid Howells }
1396da2441fdSDavid Howells 
139708526a90SPaul Moore /**
139808526a90SPaul Moore  * security_sb_alloc() - Allocate a super_block LSM blob
139908526a90SPaul Moore  * @sb: filesystem superblock
140008526a90SPaul Moore  *
140108526a90SPaul Moore  * Allocate and attach a security structure to the sb->s_security field.  The
140208526a90SPaul Moore  * s_security field is initialized to NULL when the structure is allocated.
140308526a90SPaul Moore  * @sb contains the super_block structure to be modified.
140408526a90SPaul Moore  *
140508526a90SPaul Moore  * Return: Returns 0 if operation was successful.
140608526a90SPaul Moore  */
security_sb_alloc(struct super_block * sb)140720510f2fSJames Morris int security_sb_alloc(struct super_block *sb)
140820510f2fSJames Morris {
14091aea7808SCasey Schaufler 	int rc = lsm_superblock_alloc(sb);
14101aea7808SCasey Schaufler 
14111aea7808SCasey Schaufler 	if (unlikely(rc))
14121aea7808SCasey Schaufler 		return rc;
1413260017f3SOndrej Mosnacek 	rc = call_int_hook(sb_alloc_security, sb);
14141aea7808SCasey Schaufler 	if (unlikely(rc))
14151aea7808SCasey Schaufler 		security_sb_free(sb);
14161aea7808SCasey Schaufler 	return rc;
141720510f2fSJames Morris }
141820510f2fSJames Morris 
141908526a90SPaul Moore /**
142008526a90SPaul Moore  * security_sb_delete() - Release super_block LSM associated objects
142108526a90SPaul Moore  * @sb: filesystem superblock
142208526a90SPaul Moore  *
142308526a90SPaul Moore  * Release objects tied to a superblock (e.g. inodes).  @sb contains the
142408526a90SPaul Moore  * super_block structure being released.
142508526a90SPaul Moore  */
security_sb_delete(struct super_block * sb)142683e804f0SMickaël Salaün void security_sb_delete(struct super_block *sb)
142783e804f0SMickaël Salaün {
142883e804f0SMickaël Salaün 	call_void_hook(sb_delete, sb);
142920510f2fSJames Morris }
143020510f2fSJames Morris 
143108526a90SPaul Moore /**
143208526a90SPaul Moore  * security_sb_free() - Free a super_block LSM blob
143308526a90SPaul Moore  * @sb: filesystem superblock
143408526a90SPaul Moore  *
143508526a90SPaul Moore  * Deallocate and clear the sb->s_security field.  @sb contains the super_block
143608526a90SPaul Moore  * structure to be modified.
143708526a90SPaul Moore  */
security_sb_free(struct super_block * sb)143820510f2fSJames Morris void security_sb_free(struct super_block *sb)
143920510f2fSJames Morris {
1440f25fce3eSCasey Schaufler 	call_void_hook(sb_free_security, sb);
14411aea7808SCasey Schaufler 	kfree(sb->s_security);
14421aea7808SCasey Schaufler 	sb->s_security = NULL;
144320510f2fSJames Morris }
144420510f2fSJames Morris 
144508526a90SPaul Moore /**
144608526a90SPaul Moore  * security_free_mnt_opts() - Free memory associated with mount options
14471e2523d7SPaul Moore  * @mnt_opts: LSM processed mount options
144808526a90SPaul Moore  *
144908526a90SPaul Moore  * Free memory associated with @mnt_ops.
145008526a90SPaul Moore  */
security_free_mnt_opts(void ** mnt_opts)1451204cc0ccSAl Viro void security_free_mnt_opts(void **mnt_opts)
145220510f2fSJames Morris {
1453204cc0ccSAl Viro 	if (!*mnt_opts)
1454204cc0ccSAl Viro 		return;
1455204cc0ccSAl Viro 	call_void_hook(sb_free_mnt_opts, *mnt_opts);
1456204cc0ccSAl Viro 	*mnt_opts = NULL;
145720510f2fSJames Morris }
1458204cc0ccSAl Viro EXPORT_SYMBOL(security_free_mnt_opts);
145920510f2fSJames Morris 
146008526a90SPaul Moore /**
146108526a90SPaul Moore  * security_sb_eat_lsm_opts() - Consume LSM mount options
146208526a90SPaul Moore  * @options: mount options
14631e2523d7SPaul Moore  * @mnt_opts: LSM processed mount options
146408526a90SPaul Moore  *
146508526a90SPaul Moore  * Eat (scan @options) and save them in @mnt_opts.
146608526a90SPaul Moore  *
146708526a90SPaul Moore  * Return: Returns 0 on success, negative values on failure.
146808526a90SPaul Moore  */
security_sb_eat_lsm_opts(char * options,void ** mnt_opts)1469204cc0ccSAl Viro int security_sb_eat_lsm_opts(char *options, void **mnt_opts)
1470ff36fe2cSEric Paris {
1471260017f3SOndrej Mosnacek 	return call_int_hook(sb_eat_lsm_opts, options, mnt_opts);
1472ff36fe2cSEric Paris }
1473f5c0c26dSAl Viro EXPORT_SYMBOL(security_sb_eat_lsm_opts);
1474ff36fe2cSEric Paris 
147508526a90SPaul Moore /**
147608526a90SPaul Moore  * security_sb_mnt_opts_compat() - Check if new mount options are allowed
147708526a90SPaul Moore  * @sb: filesystem superblock
147808526a90SPaul Moore  * @mnt_opts: new mount options
147908526a90SPaul Moore  *
148008526a90SPaul Moore  * Determine if the new mount options in @mnt_opts are allowed given the
148108526a90SPaul Moore  * existing mounted filesystem at @sb.  @sb superblock being compared.
148208526a90SPaul Moore  *
148308526a90SPaul Moore  * Return: Returns 0 if options are compatible.
148408526a90SPaul Moore  */
security_sb_mnt_opts_compat(struct super_block * sb,void * mnt_opts)148569c4a42dSOlga Kornievskaia int security_sb_mnt_opts_compat(struct super_block *sb,
148669c4a42dSOlga Kornievskaia 				void *mnt_opts)
148769c4a42dSOlga Kornievskaia {
1488260017f3SOndrej Mosnacek 	return call_int_hook(sb_mnt_opts_compat, sb, mnt_opts);
148969c4a42dSOlga Kornievskaia }
149069c4a42dSOlga Kornievskaia EXPORT_SYMBOL(security_sb_mnt_opts_compat);
149169c4a42dSOlga Kornievskaia 
149208526a90SPaul Moore /**
149308526a90SPaul Moore  * security_sb_remount() - Verify no incompatible mount changes during remount
149408526a90SPaul Moore  * @sb: filesystem superblock
149508526a90SPaul Moore  * @mnt_opts: (re)mount options
149608526a90SPaul Moore  *
149708526a90SPaul Moore  * Extracts security system specific mount options and verifies no changes are
149808526a90SPaul Moore  * being made to those options.
149908526a90SPaul Moore  *
150008526a90SPaul Moore  * Return: Returns 0 if permission is granted.
150108526a90SPaul Moore  */
security_sb_remount(struct super_block * sb,void * mnt_opts)1502c039bc3cSAl Viro int security_sb_remount(struct super_block *sb,
1503204cc0ccSAl Viro 			void *mnt_opts)
150420510f2fSJames Morris {
1505260017f3SOndrej Mosnacek 	return call_int_hook(sb_remount, sb, mnt_opts);
150620510f2fSJames Morris }
1507a65001e8SAl Viro EXPORT_SYMBOL(security_sb_remount);
150820510f2fSJames Morris 
150908526a90SPaul Moore /**
151008526a90SPaul Moore  * security_sb_kern_mount() - Check if a kernel mount is allowed
151108526a90SPaul Moore  * @sb: filesystem superblock
151208526a90SPaul Moore  *
151308526a90SPaul Moore  * Mount this @sb if allowed by permissions.
151408526a90SPaul Moore  *
151508526a90SPaul Moore  * Return: Returns 0 if permission is granted.
151608526a90SPaul Moore  */
security_sb_kern_mount(const struct super_block * sb)151720a2aa47SKhadija Kamran int security_sb_kern_mount(const struct super_block *sb)
151820510f2fSJames Morris {
1519260017f3SOndrej Mosnacek 	return call_int_hook(sb_kern_mount, sb);
152020510f2fSJames Morris }
152120510f2fSJames Morris 
152208526a90SPaul Moore /**
152308526a90SPaul Moore  * security_sb_show_options() - Output the mount options for a superblock
152408526a90SPaul Moore  * @m: output file
152508526a90SPaul Moore  * @sb: filesystem superblock
152608526a90SPaul Moore  *
152708526a90SPaul Moore  * Show (print on @m) mount options for this @sb.
152808526a90SPaul Moore  *
152908526a90SPaul Moore  * Return: Returns 0 on success, negative values on failure.
153008526a90SPaul Moore  */
security_sb_show_options(struct seq_file * m,struct super_block * sb)15312069f457SEric Paris int security_sb_show_options(struct seq_file *m, struct super_block *sb)
15322069f457SEric Paris {
1533260017f3SOndrej Mosnacek 	return call_int_hook(sb_show_options, m, sb);
15342069f457SEric Paris }
15352069f457SEric Paris 
153608526a90SPaul Moore /**
153708526a90SPaul Moore  * security_sb_statfs() - Check if accessing fs stats is allowed
153808526a90SPaul Moore  * @dentry: superblock handle
153908526a90SPaul Moore  *
154008526a90SPaul Moore  * Check permission before obtaining filesystem statistics for the @mnt
154108526a90SPaul Moore  * mountpoint.  @dentry is a handle on the superblock for the filesystem.
154208526a90SPaul Moore  *
154308526a90SPaul Moore  * Return: Returns 0 if permission is granted.
154408526a90SPaul Moore  */
security_sb_statfs(struct dentry * dentry)154520510f2fSJames Morris int security_sb_statfs(struct dentry *dentry)
154620510f2fSJames Morris {
1547260017f3SOndrej Mosnacek 	return call_int_hook(sb_statfs, dentry);
154820510f2fSJames Morris }
154920510f2fSJames Morris 
155008526a90SPaul Moore /**
155108526a90SPaul Moore  * security_sb_mount() - Check permission for mounting a filesystem
155208526a90SPaul Moore  * @dev_name: filesystem backing device
155308526a90SPaul Moore  * @path: mount point
155408526a90SPaul Moore  * @type: filesystem type
155508526a90SPaul Moore  * @flags: mount flags
155608526a90SPaul Moore  * @data: filesystem specific data
155708526a90SPaul Moore  *
155808526a90SPaul Moore  * Check permission before an object specified by @dev_name is mounted on the
155908526a90SPaul Moore  * mount point named by @nd.  For an ordinary mount, @dev_name identifies a
156008526a90SPaul Moore  * device if the file system type requires a device.  For a remount
156108526a90SPaul Moore  * (@flags & MS_REMOUNT), @dev_name is irrelevant.  For a loopback/bind mount
156208526a90SPaul Moore  * (@flags & MS_BIND), @dev_name identifies the	pathname of the object being
156308526a90SPaul Moore  * mounted.
156408526a90SPaul Moore  *
156508526a90SPaul Moore  * Return: Returns 0 if permission is granted.
156608526a90SPaul Moore  */
security_sb_mount(const char * dev_name,const struct path * path,const char * type,unsigned long flags,void * data)15678a04c43bSAl Viro int security_sb_mount(const char *dev_name, const struct path *path,
1568808d4e3cSAl Viro 		      const char *type, unsigned long flags, void *data)
156920510f2fSJames Morris {
1570260017f3SOndrej Mosnacek 	return call_int_hook(sb_mount, dev_name, path, type, flags, data);
157120510f2fSJames Morris }
157220510f2fSJames Morris 
157308526a90SPaul Moore /**
157408526a90SPaul Moore  * security_sb_umount() - Check permission for unmounting a filesystem
157508526a90SPaul Moore  * @mnt: mounted filesystem
157608526a90SPaul Moore  * @flags: unmount flags
157708526a90SPaul Moore  *
157808526a90SPaul Moore  * Check permission before the @mnt file system is unmounted.
157908526a90SPaul Moore  *
158008526a90SPaul Moore  * Return: Returns 0 if permission is granted.
158108526a90SPaul Moore  */
security_sb_umount(struct vfsmount * mnt,int flags)158220510f2fSJames Morris int security_sb_umount(struct vfsmount *mnt, int flags)
158320510f2fSJames Morris {
1584260017f3SOndrej Mosnacek 	return call_int_hook(sb_umount, mnt, flags);
158520510f2fSJames Morris }
158620510f2fSJames Morris 
158708526a90SPaul Moore /**
158808526a90SPaul Moore  * security_sb_pivotroot() - Check permissions for pivoting the rootfs
158908526a90SPaul Moore  * @old_path: new location for current rootfs
159008526a90SPaul Moore  * @new_path: location of the new rootfs
159108526a90SPaul Moore  *
159208526a90SPaul Moore  * Check permission before pivoting the root filesystem.
159308526a90SPaul Moore  *
159408526a90SPaul Moore  * Return: Returns 0 if permission is granted.
159508526a90SPaul Moore  */
security_sb_pivotroot(const struct path * old_path,const struct path * new_path)159663c1845bSPaul Moore int security_sb_pivotroot(const struct path *old_path,
159763c1845bSPaul Moore 			  const struct path *new_path)
159820510f2fSJames Morris {
1599260017f3SOndrej Mosnacek 	return call_int_hook(sb_pivotroot, old_path, new_path);
160020510f2fSJames Morris }
160120510f2fSJames Morris 
160208526a90SPaul Moore /**
160308526a90SPaul Moore  * security_sb_set_mnt_opts() - Set the mount options for a filesystem
160408526a90SPaul Moore  * @sb: filesystem superblock
160508526a90SPaul Moore  * @mnt_opts: binary mount options
160608526a90SPaul Moore  * @kern_flags: kernel flags (in)
160708526a90SPaul Moore  * @set_kern_flags: kernel flags (out)
160808526a90SPaul Moore  *
160908526a90SPaul Moore  * Set the security relevant mount options used for a superblock.
161008526a90SPaul Moore  *
161108526a90SPaul Moore  * Return: Returns 0 on success, error on failure.
161208526a90SPaul Moore  */
security_sb_set_mnt_opts(struct super_block * sb,void * mnt_opts,unsigned long kern_flags,unsigned long * set_kern_flags)1613c9180a57SEric Paris int security_sb_set_mnt_opts(struct super_block *sb,
1614204cc0ccSAl Viro 			     void *mnt_opts,
1615649f6e77SDavid Quigley 			     unsigned long kern_flags,
1616649f6e77SDavid Quigley 			     unsigned long *set_kern_flags)
1617c9180a57SEric Paris {
1618417c5643SKP Singh 	struct lsm_static_call *scall;
1619260017f3SOndrej Mosnacek 	int rc = mnt_opts ? -EOPNOTSUPP : LSM_RET_DEFAULT(sb_set_mnt_opts);
1620260017f3SOndrej Mosnacek 
1621417c5643SKP Singh 	lsm_for_each_hook(scall, sb_set_mnt_opts) {
1622417c5643SKP Singh 		rc = scall->hl->hook.sb_set_mnt_opts(sb, mnt_opts, kern_flags,
1623260017f3SOndrej Mosnacek 					      set_kern_flags);
1624260017f3SOndrej Mosnacek 		if (rc != LSM_RET_DEFAULT(sb_set_mnt_opts))
1625260017f3SOndrej Mosnacek 			break;
1626260017f3SOndrej Mosnacek 	}
1627260017f3SOndrej Mosnacek 	return rc;
1628c9180a57SEric Paris }
1629e0007529SEric Paris EXPORT_SYMBOL(security_sb_set_mnt_opts);
1630c9180a57SEric Paris 
163108526a90SPaul Moore /**
163208526a90SPaul Moore  * security_sb_clone_mnt_opts() - Duplicate superblock mount options
16331e2523d7SPaul Moore  * @oldsb: source superblock
16341e2523d7SPaul Moore  * @newsb: destination superblock
163508526a90SPaul Moore  * @kern_flags: kernel flags (in)
163608526a90SPaul Moore  * @set_kern_flags: kernel flags (out)
163708526a90SPaul Moore  *
163808526a90SPaul Moore  * Copy all security options from a given superblock to another.
163908526a90SPaul Moore  *
164008526a90SPaul Moore  * Return: Returns 0 on success, error on failure.
164108526a90SPaul Moore  */
security_sb_clone_mnt_opts(const struct super_block * oldsb,struct super_block * newsb,unsigned long kern_flags,unsigned long * set_kern_flags)1642094f7b69SJeff Layton int security_sb_clone_mnt_opts(const struct super_block *oldsb,
16430b4d3452SScott Mayhew 			       struct super_block *newsb,
16440b4d3452SScott Mayhew 			       unsigned long kern_flags,
16450b4d3452SScott Mayhew 			       unsigned long *set_kern_flags)
1646c9180a57SEric Paris {
1647260017f3SOndrej Mosnacek 	return call_int_hook(sb_clone_mnt_opts, oldsb, newsb,
16480b4d3452SScott Mayhew 			     kern_flags, set_kern_flags);
1649c9180a57SEric Paris }
1650e0007529SEric Paris EXPORT_SYMBOL(security_sb_clone_mnt_opts);
1651e0007529SEric Paris 
165208526a90SPaul Moore /**
165308526a90SPaul Moore  * security_move_mount() - Check permissions for moving a mount
165408526a90SPaul Moore  * @from_path: source mount point
165508526a90SPaul Moore  * @to_path: destination mount point
165608526a90SPaul Moore  *
165708526a90SPaul Moore  * Check permission before a mount is moved.
165808526a90SPaul Moore  *
165908526a90SPaul Moore  * Return: Returns 0 if permission is granted.
166008526a90SPaul Moore  */
security_move_mount(const struct path * from_path,const struct path * to_path)166163c1845bSPaul Moore int security_move_mount(const struct path *from_path,
166263c1845bSPaul Moore 			const struct path *to_path)
16632db154b3SDavid Howells {
1664260017f3SOndrej Mosnacek 	return call_int_hook(move_mount, from_path, to_path);
16652db154b3SDavid Howells }
16662db154b3SDavid Howells 
1667916e3258SPaul Moore /**
1668916e3258SPaul Moore  * security_path_notify() - Check if setting a watch is allowed
1669916e3258SPaul Moore  * @path: file path
1670916e3258SPaul Moore  * @mask: event mask
1671916e3258SPaul Moore  * @obj_type: file path type
1672916e3258SPaul Moore  *
1673916e3258SPaul Moore  * Check permissions before setting a watch on events as defined by @mask, on
1674916e3258SPaul Moore  * an object at @path, whose type is defined by @obj_type.
1675916e3258SPaul Moore  *
1676916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
1677916e3258SPaul Moore  */
security_path_notify(const struct path * path,u64 mask,unsigned int obj_type)1678ac5656d8SAaron Goidel int security_path_notify(const struct path *path, u64 mask,
1679ac5656d8SAaron Goidel 			 unsigned int obj_type)
1680ac5656d8SAaron Goidel {
1681260017f3SOndrej Mosnacek 	return call_int_hook(path_notify, path, mask, obj_type);
1682ac5656d8SAaron Goidel }
1683ac5656d8SAaron Goidel 
1684916e3258SPaul Moore /**
1685916e3258SPaul Moore  * security_inode_alloc() - Allocate an inode LSM blob
1686916e3258SPaul Moore  * @inode: the inode
16879897713fSMichal Hocko  * @gfp: allocation flags
1688916e3258SPaul Moore  *
1689916e3258SPaul Moore  * Allocate and attach a security structure to @inode->i_security.  The
1690916e3258SPaul Moore  * i_security field is initialized to NULL when the inode structure is
1691916e3258SPaul Moore  * allocated.
1692916e3258SPaul Moore  *
1693916e3258SPaul Moore  * Return: Return 0 if operation was successful.
1694916e3258SPaul Moore  */
security_inode_alloc(struct inode * inode,gfp_t gfp)16959897713fSMichal Hocko int security_inode_alloc(struct inode *inode, gfp_t gfp)
169620510f2fSJames Morris {
16979897713fSMichal Hocko 	int rc = lsm_inode_alloc(inode, gfp);
1698afb1cbe3SCasey Schaufler 
1699afb1cbe3SCasey Schaufler 	if (unlikely(rc))
1700afb1cbe3SCasey Schaufler 		return rc;
1701260017f3SOndrej Mosnacek 	rc = call_int_hook(inode_alloc_security, inode);
1702afb1cbe3SCasey Schaufler 	if (unlikely(rc))
1703afb1cbe3SCasey Schaufler 		security_inode_free(inode);
1704afb1cbe3SCasey Schaufler 	return rc;
1705afb1cbe3SCasey Schaufler }
1706afb1cbe3SCasey Schaufler 
inode_free_by_rcu(struct rcu_head * head)1707afb1cbe3SCasey Schaufler static void inode_free_by_rcu(struct rcu_head *head)
1708afb1cbe3SCasey Schaufler {
170963dff3e4SPaul Moore 	/* The rcu head is at the start of the inode blob */
171063dff3e4SPaul Moore 	call_void_hook(inode_free_security_rcu, head);
1711afb1cbe3SCasey Schaufler 	kmem_cache_free(lsm_inode_cache, head);
171220510f2fSJames Morris }
171320510f2fSJames Morris 
1714916e3258SPaul Moore /**
1715916e3258SPaul Moore  * security_inode_free() - Free an inode's LSM blob
1716916e3258SPaul Moore  * @inode: the inode
1717916e3258SPaul Moore  *
171863dff3e4SPaul Moore  * Release any LSM resources associated with @inode, although due to the
171963dff3e4SPaul Moore  * inode's RCU protections it is possible that the resources will not be
172063dff3e4SPaul Moore  * fully released until after the current RCU grace period has elapsed.
172163dff3e4SPaul Moore  *
172263dff3e4SPaul Moore  * It is important for LSMs to note that despite being present in a call to
172363dff3e4SPaul Moore  * security_inode_free(), @inode may still be referenced in a VFS path walk
172463dff3e4SPaul Moore  * and calls to security_inode_permission() may be made during, or after,
172563dff3e4SPaul Moore  * a call to security_inode_free().  For this reason the inode->i_security
172663dff3e4SPaul Moore  * field is released via a call_rcu() callback and any LSMs which need to
172763dff3e4SPaul Moore  * retain inode state for use in security_inode_permission() should only
172863dff3e4SPaul Moore  * release that state in the inode_free_security_rcu() LSM hook callback.
1729916e3258SPaul Moore  */
security_inode_free(struct inode * inode)173020510f2fSJames Morris void security_inode_free(struct inode *inode)
173120510f2fSJames Morris {
1732f25fce3eSCasey Schaufler 	call_void_hook(inode_free_security, inode);
173363dff3e4SPaul Moore 	if (!inode->i_security)
173463dff3e4SPaul Moore 		return;
173563dff3e4SPaul Moore 	call_rcu((struct rcu_head *)inode->i_security, inode_free_by_rcu);
173620510f2fSJames Morris }
173720510f2fSJames Morris 
173808526a90SPaul Moore /**
173908526a90SPaul Moore  * security_dentry_init_security() - Perform dentry initialization
174008526a90SPaul Moore  * @dentry: the dentry to initialize
174108526a90SPaul Moore  * @mode: mode used to determine resource type
174208526a90SPaul Moore  * @name: name of the last path component
174308526a90SPaul Moore  * @xattr_name: name of the security/LSM xattr
1744b530104fSCasey Schaufler  * @lsmctx: pointer to the resulting LSM context
174508526a90SPaul Moore  *
174608526a90SPaul Moore  * Compute a context for a dentry as the inode is not yet available since NFSv4
174708526a90SPaul Moore  * has no label backed by an EA anyway.  It is important to note that
174808526a90SPaul Moore  * @xattr_name does not need to be free'd by the caller, it is a static string.
174908526a90SPaul Moore  *
175008526a90SPaul Moore  * Return: Returns 0 on success, negative values on failure.
175108526a90SPaul Moore  */
security_dentry_init_security(struct dentry * dentry,int mode,const struct qstr * name,const char ** xattr_name,struct lsm_context * lsmctx)1752d47be3dfSDavid Quigley int security_dentry_init_security(struct dentry *dentry, int mode,
175315bf3239SVivek Goyal 				  const struct qstr *name,
1754b530104fSCasey Schaufler 				  const char **xattr_name,
1755b530104fSCasey Schaufler 				  struct lsm_context *lsmctx)
1756d47be3dfSDavid Quigley {
1757260017f3SOndrej Mosnacek 	return call_int_hook(dentry_init_security, dentry, mode, name,
1758b530104fSCasey Schaufler 			     xattr_name, lsmctx);
1759d47be3dfSDavid Quigley }
1760d47be3dfSDavid Quigley EXPORT_SYMBOL(security_dentry_init_security);
1761d47be3dfSDavid Quigley 
176208526a90SPaul Moore /**
176308526a90SPaul Moore  * security_dentry_create_files_as() - Perform dentry initialization
176408526a90SPaul Moore  * @dentry: the dentry to initialize
176508526a90SPaul Moore  * @mode: mode used to determine resource type
176608526a90SPaul Moore  * @name: name of the last path component
176708526a90SPaul Moore  * @old: creds to use for LSM context calculations
176808526a90SPaul Moore  * @new: creds to modify
176908526a90SPaul Moore  *
177008526a90SPaul Moore  * Compute a context for a dentry as the inode is not yet available and set
177108526a90SPaul Moore  * that context in passed in creds so that new files are created using that
177208526a90SPaul Moore  * context. Context is calculated using the passed in creds and not the creds
177308526a90SPaul Moore  * of the caller.
177408526a90SPaul Moore  *
177508526a90SPaul Moore  * Return: Returns 0 on success, error on failure.
177608526a90SPaul Moore  */
security_dentry_create_files_as(struct dentry * dentry,int mode,struct qstr * name,const struct cred * old,struct cred * new)17772602625bSVivek Goyal int security_dentry_create_files_as(struct dentry *dentry, int mode,
17782602625bSVivek Goyal 				    struct qstr *name,
17792602625bSVivek Goyal 				    const struct cred *old, struct cred *new)
17802602625bSVivek Goyal {
1781260017f3SOndrej Mosnacek 	return call_int_hook(dentry_create_files_as, dentry, mode,
17822602625bSVivek Goyal 			     name, old, new);
17832602625bSVivek Goyal }
17842602625bSVivek Goyal EXPORT_SYMBOL(security_dentry_create_files_as);
17852602625bSVivek Goyal 
1786916e3258SPaul Moore /**
1787916e3258SPaul Moore  * security_inode_init_security() - Initialize an inode's LSM context
1788916e3258SPaul Moore  * @inode: the inode
1789916e3258SPaul Moore  * @dir: parent directory
1790916e3258SPaul Moore  * @qstr: last component of the pathname
1791916e3258SPaul Moore  * @initxattrs: callback function to write xattrs
1792916e3258SPaul Moore  * @fs_data: filesystem specific data
1793916e3258SPaul Moore  *
1794916e3258SPaul Moore  * Obtain the security attribute name suffix and value to set on a newly
1795916e3258SPaul Moore  * created inode and set up the incore security field for the new inode.  This
1796916e3258SPaul Moore  * hook is called by the fs code as part of the inode creation transaction and
1797916e3258SPaul Moore  * provides for atomic labeling of the inode, unlike the post_create/mkdir/...
17986bcdfd2cSRoberto Sassu  * hooks called by the VFS.
1799916e3258SPaul Moore  *
18006bcdfd2cSRoberto Sassu  * The hook function is expected to populate the xattrs array, by calling
18016bcdfd2cSRoberto Sassu  * lsm_get_xattr_slot() to retrieve the slots reserved by the security module
18026bcdfd2cSRoberto Sassu  * with the lbs_xattr_count field of the lsm_blob_sizes structure.  For each
18036bcdfd2cSRoberto Sassu  * slot, the hook function should set ->name to the attribute name suffix
18046bcdfd2cSRoberto Sassu  * (e.g. selinux), to allocate ->value (will be freed by the caller) and set it
18056bcdfd2cSRoberto Sassu  * to the attribute value, to set ->value_len to the length of the value.  If
18066bcdfd2cSRoberto Sassu  * the security module does not use security attributes or does not wish to put
18076bcdfd2cSRoberto Sassu  * a security attribute on this particular inode, then it should return
18086bcdfd2cSRoberto Sassu  * -EOPNOTSUPP to skip this processing.
1809916e3258SPaul Moore  *
1810faf302f5SRoberto Sassu  * Return: Returns 0 if the LSM successfully initialized all of the inode
1811faf302f5SRoberto Sassu  *         security attributes that are required, negative values otherwise.
1812916e3258SPaul Moore  */
security_inode_init_security(struct inode * inode,struct inode * dir,const struct qstr * qstr,const initxattrs initxattrs,void * fs_data)181320510f2fSJames Morris int security_inode_init_security(struct inode *inode, struct inode *dir,
18149d8f13baSMimi Zohar 				 const struct qstr *qstr,
18159d8f13baSMimi Zohar 				 const initxattrs initxattrs, void *fs_data)
18169d8f13baSMimi Zohar {
1817417c5643SKP Singh 	struct lsm_static_call *scall;
18186bcdfd2cSRoberto Sassu 	struct xattr *new_xattrs = NULL;
18196bcdfd2cSRoberto Sassu 	int ret = -EOPNOTSUPP, xattr_count = 0;
18209d8f13baSMimi Zohar 
18219d8f13baSMimi Zohar 	if (unlikely(IS_PRIVATE(inode)))
1822fb88c2b6SMimi Zohar 		return 0;
18239d8f13baSMimi Zohar 
18246bcdfd2cSRoberto Sassu 	if (!blob_sizes.lbs_xattr_count)
18256bcdfd2cSRoberto Sassu 		return 0;
18266bcdfd2cSRoberto Sassu 
18276bcdfd2cSRoberto Sassu 	if (initxattrs) {
182875a323e6SRoberto Sassu 		/* Allocate +1 as terminator. */
182975a323e6SRoberto Sassu 		new_xattrs = kcalloc(blob_sizes.lbs_xattr_count + 1,
18306bcdfd2cSRoberto Sassu 				     sizeof(*new_xattrs), GFP_NOFS);
18316bcdfd2cSRoberto Sassu 		if (!new_xattrs)
18326bcdfd2cSRoberto Sassu 			return -ENOMEM;
18336bcdfd2cSRoberto Sassu 	}
18346bcdfd2cSRoberto Sassu 
1835417c5643SKP Singh 	lsm_for_each_hook(scall, inode_init_security) {
1836417c5643SKP Singh 		ret = scall->hl->hook.inode_init_security(inode, dir, qstr, new_xattrs,
18376bcdfd2cSRoberto Sassu 						  &xattr_count);
18386bcdfd2cSRoberto Sassu 		if (ret && ret != -EOPNOTSUPP)
18396bcdfd2cSRoberto Sassu 			goto out;
18406bcdfd2cSRoberto Sassu 		/*
18416bcdfd2cSRoberto Sassu 		 * As documented in lsm_hooks.h, -EOPNOTSUPP in this context
18426bcdfd2cSRoberto Sassu 		 * means that the LSM is not willing to provide an xattr, not
18436bcdfd2cSRoberto Sassu 		 * that it wants to signal an error. Thus, continue to invoke
18446bcdfd2cSRoberto Sassu 		 * the remaining LSMs.
18456bcdfd2cSRoberto Sassu 		 */
18466bcdfd2cSRoberto Sassu 	}
18476bcdfd2cSRoberto Sassu 
18486bcdfd2cSRoberto Sassu 	/* If initxattrs() is NULL, xattr_count is zero, skip the call. */
18496bcdfd2cSRoberto Sassu 	if (!xattr_count)
18509d8f13baSMimi Zohar 		goto out;
1851823eb1ccSMimi Zohar 
18529d8f13baSMimi Zohar 	ret = initxattrs(inode, new_xattrs, fs_data);
18539d8f13baSMimi Zohar out:
18546bcdfd2cSRoberto Sassu 	for (; xattr_count > 0; xattr_count--)
18556bcdfd2cSRoberto Sassu 		kfree(new_xattrs[xattr_count - 1].value);
18566bcdfd2cSRoberto Sassu 	kfree(new_xattrs);
18579d8f13baSMimi Zohar 	return (ret == -EOPNOTSUPP) ? 0 : ret;
18589d8f13baSMimi Zohar }
18599d8f13baSMimi Zohar EXPORT_SYMBOL(security_inode_init_security);
18609d8f13baSMimi Zohar 
1861916e3258SPaul Moore /**
1862916e3258SPaul Moore  * security_inode_init_security_anon() - Initialize an anonymous inode
1863916e3258SPaul Moore  * @inode: the inode
1864916e3258SPaul Moore  * @name: the anonymous inode class
1865916e3258SPaul Moore  * @context_inode: an optional related inode
1866916e3258SPaul Moore  *
1867916e3258SPaul Moore  * Set up the incore security field for the new anonymous inode and return
1868916e3258SPaul Moore  * whether the inode creation is permitted by the security module or not.
1869916e3258SPaul Moore  *
1870916e3258SPaul Moore  * Return: Returns 0 on success, -EACCES if the security module denies the
1871916e3258SPaul Moore  * creation of this inode, or another -errno upon other errors.
1872916e3258SPaul Moore  */
security_inode_init_security_anon(struct inode * inode,const struct qstr * name,const struct inode * context_inode)1873215b674bSLokesh Gidra int security_inode_init_security_anon(struct inode *inode,
1874215b674bSLokesh Gidra 				      const struct qstr *name,
1875215b674bSLokesh Gidra 				      const struct inode *context_inode)
1876215b674bSLokesh Gidra {
1877260017f3SOndrej Mosnacek 	return call_int_hook(inode_init_security_anon, inode, name,
1878215b674bSLokesh Gidra 			     context_inode);
1879215b674bSLokesh Gidra }
1880215b674bSLokesh Gidra 
1881be6d3e56SKentaro Takeda #ifdef CONFIG_SECURITY_PATH
1882916e3258SPaul Moore /**
1883916e3258SPaul Moore  * security_path_mknod() - Check if creating a special file is allowed
1884916e3258SPaul Moore  * @dir: parent directory
1885916e3258SPaul Moore  * @dentry: new file
1886916e3258SPaul Moore  * @mode: new file mode
1887916e3258SPaul Moore  * @dev: device number
1888916e3258SPaul Moore  *
1889916e3258SPaul Moore  * Check permissions when creating a file. Note that this hook is called even
1890916e3258SPaul Moore  * if mknod operation is being done for a regular file.
1891916e3258SPaul Moore  *
1892916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
1893916e3258SPaul Moore  */
security_path_mknod(const struct path * dir,struct dentry * dentry,umode_t mode,unsigned int dev)189463c1845bSPaul Moore int security_path_mknod(const struct path *dir, struct dentry *dentry,
189563c1845bSPaul Moore 			umode_t mode, unsigned int dev)
1896be6d3e56SKentaro Takeda {
1897c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry))))
1898be6d3e56SKentaro Takeda 		return 0;
1899260017f3SOndrej Mosnacek 	return call_int_hook(path_mknod, dir, dentry, mode, dev);
1900be6d3e56SKentaro Takeda }
1901be6d3e56SKentaro Takeda EXPORT_SYMBOL(security_path_mknod);
1902be6d3e56SKentaro Takeda 
1903916e3258SPaul Moore /**
1904701b3899SRoberto Sassu  * security_path_post_mknod() - Update inode security after reg file creation
190508abce60SRoberto Sassu  * @idmap: idmap of the mount
190608abce60SRoberto Sassu  * @dentry: new file
190708abce60SRoberto Sassu  *
1908701b3899SRoberto Sassu  * Update inode security field after a regular file has been created.
190908abce60SRoberto Sassu  */
security_path_post_mknod(struct mnt_idmap * idmap,struct dentry * dentry)191008abce60SRoberto Sassu void security_path_post_mknod(struct mnt_idmap *idmap, struct dentry *dentry)
191108abce60SRoberto Sassu {
191208abce60SRoberto Sassu 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
191308abce60SRoberto Sassu 		return;
191408abce60SRoberto Sassu 	call_void_hook(path_post_mknod, idmap, dentry);
191508abce60SRoberto Sassu }
191608abce60SRoberto Sassu 
191708abce60SRoberto Sassu /**
1918916e3258SPaul Moore  * security_path_mkdir() - Check if creating a new directory is allowed
1919916e3258SPaul Moore  * @dir: parent directory
1920916e3258SPaul Moore  * @dentry: new directory
1921916e3258SPaul Moore  * @mode: new directory mode
1922916e3258SPaul Moore  *
1923916e3258SPaul Moore  * Check permissions to create a new directory in the existing directory.
1924916e3258SPaul Moore  *
1925916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
1926916e3258SPaul Moore  */
security_path_mkdir(const struct path * dir,struct dentry * dentry,umode_t mode)192763c1845bSPaul Moore int security_path_mkdir(const struct path *dir, struct dentry *dentry,
192863c1845bSPaul Moore 			umode_t mode)
1929be6d3e56SKentaro Takeda {
1930c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry))))
1931be6d3e56SKentaro Takeda 		return 0;
1932260017f3SOndrej Mosnacek 	return call_int_hook(path_mkdir, dir, dentry, mode);
1933be6d3e56SKentaro Takeda }
193482140443SDavid Howells EXPORT_SYMBOL(security_path_mkdir);
1935be6d3e56SKentaro Takeda 
1936916e3258SPaul Moore /**
1937916e3258SPaul Moore  * security_path_rmdir() - Check if removing a directory is allowed
1938916e3258SPaul Moore  * @dir: parent directory
1939916e3258SPaul Moore  * @dentry: directory to remove
1940916e3258SPaul Moore  *
1941916e3258SPaul Moore  * Check the permission to remove a directory.
1942916e3258SPaul Moore  *
1943916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
1944916e3258SPaul Moore  */
security_path_rmdir(const struct path * dir,struct dentry * dentry)1945989f74e0SAl Viro int security_path_rmdir(const struct path *dir, struct dentry *dentry)
1946be6d3e56SKentaro Takeda {
1947c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry))))
1948be6d3e56SKentaro Takeda 		return 0;
1949260017f3SOndrej Mosnacek 	return call_int_hook(path_rmdir, dir, dentry);
1950be6d3e56SKentaro Takeda }
1951be6d3e56SKentaro Takeda 
1952916e3258SPaul Moore /**
1953916e3258SPaul Moore  * security_path_unlink() - Check if removing a hard link is allowed
1954916e3258SPaul Moore  * @dir: parent directory
1955916e3258SPaul Moore  * @dentry: file
1956916e3258SPaul Moore  *
1957916e3258SPaul Moore  * Check the permission to remove a hard link to a file.
1958916e3258SPaul Moore  *
1959916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
1960916e3258SPaul Moore  */
security_path_unlink(const struct path * dir,struct dentry * dentry)1961989f74e0SAl Viro int security_path_unlink(const struct path *dir, struct dentry *dentry)
1962be6d3e56SKentaro Takeda {
1963c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry))))
1964be6d3e56SKentaro Takeda 		return 0;
1965260017f3SOndrej Mosnacek 	return call_int_hook(path_unlink, dir, dentry);
1966be6d3e56SKentaro Takeda }
196782140443SDavid Howells EXPORT_SYMBOL(security_path_unlink);
1968be6d3e56SKentaro Takeda 
1969916e3258SPaul Moore /**
1970916e3258SPaul Moore  * security_path_symlink() - Check if creating a symbolic link is allowed
1971916e3258SPaul Moore  * @dir: parent directory
1972916e3258SPaul Moore  * @dentry: symbolic link
1973916e3258SPaul Moore  * @old_name: file pathname
1974916e3258SPaul Moore  *
1975916e3258SPaul Moore  * Check the permission to create a symbolic link to a file.
1976916e3258SPaul Moore  *
1977916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
1978916e3258SPaul Moore  */
security_path_symlink(const struct path * dir,struct dentry * dentry,const char * old_name)1979d3607752SAl Viro int security_path_symlink(const struct path *dir, struct dentry *dentry,
1980be6d3e56SKentaro Takeda 			  const char *old_name)
1981be6d3e56SKentaro Takeda {
1982c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry))))
1983be6d3e56SKentaro Takeda 		return 0;
1984260017f3SOndrej Mosnacek 	return call_int_hook(path_symlink, dir, dentry, old_name);
1985be6d3e56SKentaro Takeda }
1986be6d3e56SKentaro Takeda 
1987916e3258SPaul Moore /**
1988916e3258SPaul Moore  * security_path_link - Check if creating a hard link is allowed
1989916e3258SPaul Moore  * @old_dentry: existing file
1990916e3258SPaul Moore  * @new_dir: new parent directory
1991916e3258SPaul Moore  * @new_dentry: new link
1992916e3258SPaul Moore  *
1993916e3258SPaul Moore  * Check permission before creating a new hard link to a file.
1994916e3258SPaul Moore  *
1995916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
1996916e3258SPaul Moore  */
security_path_link(struct dentry * old_dentry,const struct path * new_dir,struct dentry * new_dentry)19973ccee46aSAl Viro int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
1998be6d3e56SKentaro Takeda 		       struct dentry *new_dentry)
1999be6d3e56SKentaro Takeda {
2000c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry))))
2001be6d3e56SKentaro Takeda 		return 0;
2002260017f3SOndrej Mosnacek 	return call_int_hook(path_link, old_dentry, new_dir, new_dentry);
2003be6d3e56SKentaro Takeda }
2004be6d3e56SKentaro Takeda 
2005916e3258SPaul Moore /**
2006916e3258SPaul Moore  * security_path_rename() - Check if renaming a file is allowed
2007916e3258SPaul Moore  * @old_dir: parent directory of the old file
2008916e3258SPaul Moore  * @old_dentry: the old file
2009916e3258SPaul Moore  * @new_dir: parent directory of the new file
2010916e3258SPaul Moore  * @new_dentry: the new file
2011916e3258SPaul Moore  * @flags: flags
2012916e3258SPaul Moore  *
2013916e3258SPaul Moore  * Check for permission to rename a file or directory.
2014916e3258SPaul Moore  *
2015916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2016916e3258SPaul Moore  */
security_path_rename(const struct path * old_dir,struct dentry * old_dentry,const struct path * new_dir,struct dentry * new_dentry,unsigned int flags)20173ccee46aSAl Viro int security_path_rename(const struct path *old_dir, struct dentry *old_dentry,
20183ccee46aSAl Viro 			 const struct path *new_dir, struct dentry *new_dentry,
20190b3974ebSMiklos Szeredi 			 unsigned int flags)
2020be6d3e56SKentaro Takeda {
2021c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)) ||
202263c1845bSPaul Moore 		     (d_is_positive(new_dentry) &&
202363c1845bSPaul Moore 		      IS_PRIVATE(d_backing_inode(new_dentry)))))
2024be6d3e56SKentaro Takeda 		return 0;
2025da1ce067SMiklos Szeredi 
2026260017f3SOndrej Mosnacek 	return call_int_hook(path_rename, old_dir, old_dentry, new_dir,
2027100f59d9SMickaël Salaün 			     new_dentry, flags);
2028be6d3e56SKentaro Takeda }
202982140443SDavid Howells EXPORT_SYMBOL(security_path_rename);
2030be6d3e56SKentaro Takeda 
2031916e3258SPaul Moore /**
2032916e3258SPaul Moore  * security_path_truncate() - Check if truncating a file is allowed
2033916e3258SPaul Moore  * @path: file
2034916e3258SPaul Moore  *
2035916e3258SPaul Moore  * Check permission before truncating the file indicated by path.  Note that
2036916e3258SPaul Moore  * truncation permissions may also be checked based on already opened files,
2037916e3258SPaul Moore  * using the security_file_truncate() hook.
2038916e3258SPaul Moore  *
2039916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2040916e3258SPaul Moore  */
security_path_truncate(const struct path * path)204181f4c506SAl Viro int security_path_truncate(const struct path *path)
2042be6d3e56SKentaro Takeda {
2043c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry))))
2044be6d3e56SKentaro Takeda 		return 0;
2045260017f3SOndrej Mosnacek 	return call_int_hook(path_truncate, path);
2046be6d3e56SKentaro Takeda }
204789eda068STetsuo Handa 
2048916e3258SPaul Moore /**
2049916e3258SPaul Moore  * security_path_chmod() - Check if changing the file's mode is allowed
2050916e3258SPaul Moore  * @path: file
2051916e3258SPaul Moore  * @mode: new mode
2052916e3258SPaul Moore  *
2053916e3258SPaul Moore  * Check for permission to change a mode of the file @path. The new mode is
2054916e3258SPaul Moore  * specified in @mode which is a bitmask of constants from
2055916e3258SPaul Moore  * <include/uapi/linux/stat.h>.
2056916e3258SPaul Moore  *
2057916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2058916e3258SPaul Moore  */
security_path_chmod(const struct path * path,umode_t mode)2059be01f9f2SAl Viro int security_path_chmod(const struct path *path, umode_t mode)
206089eda068STetsuo Handa {
2061c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry))))
206289eda068STetsuo Handa 		return 0;
2063260017f3SOndrej Mosnacek 	return call_int_hook(path_chmod, path, mode);
206489eda068STetsuo Handa }
206589eda068STetsuo Handa 
2066916e3258SPaul Moore /**
2067916e3258SPaul Moore  * security_path_chown() - Check if changing the file's owner/group is allowed
2068916e3258SPaul Moore  * @path: file
2069916e3258SPaul Moore  * @uid: file owner
2070916e3258SPaul Moore  * @gid: file group
2071916e3258SPaul Moore  *
2072916e3258SPaul Moore  * Check for permission to change owner/group of a file or directory.
2073916e3258SPaul Moore  *
2074916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2075916e3258SPaul Moore  */
security_path_chown(const struct path * path,kuid_t uid,kgid_t gid)20767fd25dacSAl Viro int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
207789eda068STetsuo Handa {
2078c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry))))
207989eda068STetsuo Handa 		return 0;
2080260017f3SOndrej Mosnacek 	return call_int_hook(path_chown, path, uid, gid);
208189eda068STetsuo Handa }
20828b8efb44STetsuo Handa 
2083916e3258SPaul Moore /**
2084916e3258SPaul Moore  * security_path_chroot() - Check if changing the root directory is allowed
2085916e3258SPaul Moore  * @path: directory
2086916e3258SPaul Moore  *
2087916e3258SPaul Moore  * Check for permission to change root directory.
2088916e3258SPaul Moore  *
2089916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2090916e3258SPaul Moore  */
security_path_chroot(const struct path * path)209177b286c0SAl Viro int security_path_chroot(const struct path *path)
20928b8efb44STetsuo Handa {
2093260017f3SOndrej Mosnacek 	return call_int_hook(path_chroot, path);
20948b8efb44STetsuo Handa }
209563c1845bSPaul Moore #endif /* CONFIG_SECURITY_PATH */
2096be6d3e56SKentaro Takeda 
2097916e3258SPaul Moore /**
2098916e3258SPaul Moore  * security_inode_create() - Check if creating a file is allowed
2099916e3258SPaul Moore  * @dir: the parent directory
2100916e3258SPaul Moore  * @dentry: the file being created
2101916e3258SPaul Moore  * @mode: requested file mode
2102916e3258SPaul Moore  *
2103916e3258SPaul Moore  * Check permission to create a regular file.
2104916e3258SPaul Moore  *
2105916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2106916e3258SPaul Moore  */
security_inode_create(struct inode * dir,struct dentry * dentry,umode_t mode)210763c1845bSPaul Moore int security_inode_create(struct inode *dir, struct dentry *dentry,
210863c1845bSPaul Moore 			  umode_t mode)
210920510f2fSJames Morris {
211020510f2fSJames Morris 	if (unlikely(IS_PRIVATE(dir)))
211120510f2fSJames Morris 		return 0;
2112260017f3SOndrej Mosnacek 	return call_int_hook(inode_create, dir, dentry, mode);
211320510f2fSJames Morris }
2114800a9647SDavid Howells EXPORT_SYMBOL_GPL(security_inode_create);
211520510f2fSJames Morris 
2116916e3258SPaul Moore /**
2117a7811e34SRoberto Sassu  * security_inode_post_create_tmpfile() - Update inode security of new tmpfile
2118a7811e34SRoberto Sassu  * @idmap: idmap of the mount
2119a7811e34SRoberto Sassu  * @inode: inode of the new tmpfile
2120a7811e34SRoberto Sassu  *
2121a7811e34SRoberto Sassu  * Update inode security data after a tmpfile has been created.
2122a7811e34SRoberto Sassu  */
security_inode_post_create_tmpfile(struct mnt_idmap * idmap,struct inode * inode)2123a7811e34SRoberto Sassu void security_inode_post_create_tmpfile(struct mnt_idmap *idmap,
2124a7811e34SRoberto Sassu 					struct inode *inode)
2125a7811e34SRoberto Sassu {
2126a7811e34SRoberto Sassu 	if (unlikely(IS_PRIVATE(inode)))
2127a7811e34SRoberto Sassu 		return;
2128a7811e34SRoberto Sassu 	call_void_hook(inode_post_create_tmpfile, idmap, inode);
2129a7811e34SRoberto Sassu }
2130a7811e34SRoberto Sassu 
2131a7811e34SRoberto Sassu /**
2132916e3258SPaul Moore  * security_inode_link() - Check if creating a hard link is allowed
2133916e3258SPaul Moore  * @old_dentry: existing file
2134916e3258SPaul Moore  * @dir: new parent directory
2135916e3258SPaul Moore  * @new_dentry: new link
2136916e3258SPaul Moore  *
2137916e3258SPaul Moore  * Check permission before creating a new hard link to a file.
2138916e3258SPaul Moore  *
2139916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2140916e3258SPaul Moore  */
security_inode_link(struct dentry * old_dentry,struct inode * dir,struct dentry * new_dentry)214120510f2fSJames Morris int security_inode_link(struct dentry *old_dentry, struct inode *dir,
214220510f2fSJames Morris 			struct dentry *new_dentry)
214320510f2fSJames Morris {
2144c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry))))
214520510f2fSJames Morris 		return 0;
2146260017f3SOndrej Mosnacek 	return call_int_hook(inode_link, old_dentry, dir, new_dentry);
214720510f2fSJames Morris }
214820510f2fSJames Morris 
2149916e3258SPaul Moore /**
2150916e3258SPaul Moore  * security_inode_unlink() - Check if removing a hard link is allowed
2151916e3258SPaul Moore  * @dir: parent directory
2152916e3258SPaul Moore  * @dentry: file
2153916e3258SPaul Moore  *
2154916e3258SPaul Moore  * Check the permission to remove a hard link to a file.
2155916e3258SPaul Moore  *
2156916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2157916e3258SPaul Moore  */
security_inode_unlink(struct inode * dir,struct dentry * dentry)215820510f2fSJames Morris int security_inode_unlink(struct inode *dir, struct dentry *dentry)
215920510f2fSJames Morris {
2160c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
216120510f2fSJames Morris 		return 0;
2162260017f3SOndrej Mosnacek 	return call_int_hook(inode_unlink, dir, dentry);
216320510f2fSJames Morris }
216420510f2fSJames Morris 
2165916e3258SPaul Moore /**
21661e2523d7SPaul Moore  * security_inode_symlink() - Check if creating a symbolic link is allowed
2167916e3258SPaul Moore  * @dir: parent directory
2168916e3258SPaul Moore  * @dentry: symbolic link
2169916e3258SPaul Moore  * @old_name: existing filename
2170916e3258SPaul Moore  *
2171916e3258SPaul Moore  * Check the permission to create a symbolic link to a file.
2172916e3258SPaul Moore  *
2173916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2174916e3258SPaul Moore  */
security_inode_symlink(struct inode * dir,struct dentry * dentry,const char * old_name)217520510f2fSJames Morris int security_inode_symlink(struct inode *dir, struct dentry *dentry,
217620510f2fSJames Morris 			   const char *old_name)
217720510f2fSJames Morris {
217820510f2fSJames Morris 	if (unlikely(IS_PRIVATE(dir)))
217920510f2fSJames Morris 		return 0;
2180260017f3SOndrej Mosnacek 	return call_int_hook(inode_symlink, dir, dentry, old_name);
218120510f2fSJames Morris }
218220510f2fSJames Morris 
2183916e3258SPaul Moore /**
2184916e3258SPaul Moore  * security_inode_mkdir() - Check if creation a new director is allowed
2185916e3258SPaul Moore  * @dir: parent directory
2186916e3258SPaul Moore  * @dentry: new directory
2187916e3258SPaul Moore  * @mode: new directory mode
2188916e3258SPaul Moore  *
2189916e3258SPaul Moore  * Check permissions to create a new directory in the existing directory
2190916e3258SPaul Moore  * associated with inode structure @dir.
2191916e3258SPaul Moore  *
2192916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2193916e3258SPaul Moore  */
security_inode_mkdir(struct inode * dir,struct dentry * dentry,umode_t mode)219418bb1db3SAl Viro int security_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
219520510f2fSJames Morris {
219620510f2fSJames Morris 	if (unlikely(IS_PRIVATE(dir)))
219720510f2fSJames Morris 		return 0;
2198260017f3SOndrej Mosnacek 	return call_int_hook(inode_mkdir, dir, dentry, mode);
219920510f2fSJames Morris }
2200800a9647SDavid Howells EXPORT_SYMBOL_GPL(security_inode_mkdir);
220120510f2fSJames Morris 
2202916e3258SPaul Moore /**
2203916e3258SPaul Moore  * security_inode_rmdir() - Check if removing a directory is allowed
2204916e3258SPaul Moore  * @dir: parent directory
2205916e3258SPaul Moore  * @dentry: directory to be removed
2206916e3258SPaul Moore  *
2207916e3258SPaul Moore  * Check the permission to remove a directory.
2208916e3258SPaul Moore  *
2209916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2210916e3258SPaul Moore  */
security_inode_rmdir(struct inode * dir,struct dentry * dentry)221120510f2fSJames Morris int security_inode_rmdir(struct inode *dir, struct dentry *dentry)
221220510f2fSJames Morris {
2213c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
221420510f2fSJames Morris 		return 0;
2215260017f3SOndrej Mosnacek 	return call_int_hook(inode_rmdir, dir, dentry);
221620510f2fSJames Morris }
221720510f2fSJames Morris 
2218916e3258SPaul Moore /**
2219916e3258SPaul Moore  * security_inode_mknod() - Check if creating a special file is allowed
2220916e3258SPaul Moore  * @dir: parent directory
2221916e3258SPaul Moore  * @dentry: new file
2222916e3258SPaul Moore  * @mode: new file mode
2223916e3258SPaul Moore  * @dev: device number
2224916e3258SPaul Moore  *
2225916e3258SPaul Moore  * Check permissions when creating a special file (or a socket or a fifo file
2226916e3258SPaul Moore  * created via the mknod system call).  Note that if mknod operation is being
2227916e3258SPaul Moore  * done for a regular file, then the create hook will be called and not this
2228916e3258SPaul Moore  * hook.
2229916e3258SPaul Moore  *
2230916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2231916e3258SPaul Moore  */
security_inode_mknod(struct inode * dir,struct dentry * dentry,umode_t mode,dev_t dev)223263c1845bSPaul Moore int security_inode_mknod(struct inode *dir, struct dentry *dentry,
223363c1845bSPaul Moore 			 umode_t mode, dev_t dev)
223420510f2fSJames Morris {
223520510f2fSJames Morris 	if (unlikely(IS_PRIVATE(dir)))
223620510f2fSJames Morris 		return 0;
2237260017f3SOndrej Mosnacek 	return call_int_hook(inode_mknod, dir, dentry, mode, dev);
223820510f2fSJames Morris }
223920510f2fSJames Morris 
2240916e3258SPaul Moore /**
2241916e3258SPaul Moore  * security_inode_rename() - Check if renaming a file is allowed
2242916e3258SPaul Moore  * @old_dir: parent directory of the old file
2243916e3258SPaul Moore  * @old_dentry: the old file
2244916e3258SPaul Moore  * @new_dir: parent directory of the new file
2245916e3258SPaul Moore  * @new_dentry: the new file
2246916e3258SPaul Moore  * @flags: flags
2247916e3258SPaul Moore  *
2248916e3258SPaul Moore  * Check for permission to rename a file or directory.
2249916e3258SPaul Moore  *
2250916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2251916e3258SPaul Moore  */
security_inode_rename(struct inode * old_dir,struct dentry * old_dentry,struct inode * new_dir,struct dentry * new_dentry,unsigned int flags)225220510f2fSJames Morris int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
22530b3974ebSMiklos Szeredi 			  struct inode *new_dir, struct dentry *new_dentry,
22540b3974ebSMiklos Szeredi 			  unsigned int flags)
225520510f2fSJames Morris {
2256c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)) ||
225763c1845bSPaul Moore 		     (d_is_positive(new_dentry) &&
225863c1845bSPaul Moore 		      IS_PRIVATE(d_backing_inode(new_dentry)))))
225920510f2fSJames Morris 		return 0;
2260da1ce067SMiklos Szeredi 
2261da1ce067SMiklos Szeredi 	if (flags & RENAME_EXCHANGE) {
2262260017f3SOndrej Mosnacek 		int err = call_int_hook(inode_rename, new_dir, new_dentry,
2263da1ce067SMiklos Szeredi 					old_dir, old_dentry);
2264da1ce067SMiklos Szeredi 		if (err)
2265da1ce067SMiklos Szeredi 			return err;
2266da1ce067SMiklos Szeredi 	}
2267da1ce067SMiklos Szeredi 
2268260017f3SOndrej Mosnacek 	return call_int_hook(inode_rename, old_dir, old_dentry,
226920510f2fSJames Morris 			     new_dir, new_dentry);
227020510f2fSJames Morris }
227120510f2fSJames Morris 
2272916e3258SPaul Moore /**
2273916e3258SPaul Moore  * security_inode_readlink() - Check if reading a symbolic link is allowed
2274916e3258SPaul Moore  * @dentry: link
2275916e3258SPaul Moore  *
2276916e3258SPaul Moore  * Check the permission to read the symbolic link.
2277916e3258SPaul Moore  *
2278916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2279916e3258SPaul Moore  */
security_inode_readlink(struct dentry * dentry)228020510f2fSJames Morris int security_inode_readlink(struct dentry *dentry)
228120510f2fSJames Morris {
2282c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
228320510f2fSJames Morris 		return 0;
2284260017f3SOndrej Mosnacek 	return call_int_hook(inode_readlink, dentry);
228520510f2fSJames Morris }
228620510f2fSJames Morris 
2287916e3258SPaul Moore /**
2288916e3258SPaul Moore  * security_inode_follow_link() - Check if following a symbolic link is allowed
2289916e3258SPaul Moore  * @dentry: link dentry
2290916e3258SPaul Moore  * @inode: link inode
2291916e3258SPaul Moore  * @rcu: true if in RCU-walk mode
2292916e3258SPaul Moore  *
2293916e3258SPaul Moore  * Check permission to follow a symbolic link when looking up a pathname.  If
2294916e3258SPaul Moore  * @rcu is true, @inode is not stable.
2295916e3258SPaul Moore  *
2296916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2297916e3258SPaul Moore  */
security_inode_follow_link(struct dentry * dentry,struct inode * inode,bool rcu)2298bda0be7aSNeilBrown int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
2299bda0be7aSNeilBrown 			       bool rcu)
230020510f2fSJames Morris {
2301bda0be7aSNeilBrown 	if (unlikely(IS_PRIVATE(inode)))
230220510f2fSJames Morris 		return 0;
2303260017f3SOndrej Mosnacek 	return call_int_hook(inode_follow_link, dentry, inode, rcu);
230420510f2fSJames Morris }
230520510f2fSJames Morris 
2306916e3258SPaul Moore /**
2307916e3258SPaul Moore  * security_inode_permission() - Check if accessing an inode is allowed
2308916e3258SPaul Moore  * @inode: inode
2309916e3258SPaul Moore  * @mask: access mask
2310916e3258SPaul Moore  *
2311916e3258SPaul Moore  * Check permission before accessing an inode.  This hook is called by the
2312916e3258SPaul Moore  * existing Linux permission function, so a security module can use it to
2313916e3258SPaul Moore  * provide additional checking for existing Linux permission checks.  Notice
2314916e3258SPaul Moore  * that this hook is called when a file is opened (as well as many other
2315916e3258SPaul Moore  * operations), whereas the file_security_ops permission hook is called when
2316916e3258SPaul Moore  * the actual read/write operations are performed.
2317916e3258SPaul Moore  *
2318916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2319916e3258SPaul Moore  */
security_inode_permission(struct inode * inode,int mask)2320b77b0646SAl Viro int security_inode_permission(struct inode *inode, int mask)
232120510f2fSJames Morris {
232220510f2fSJames Morris 	if (unlikely(IS_PRIVATE(inode)))
232320510f2fSJames Morris 		return 0;
2324260017f3SOndrej Mosnacek 	return call_int_hook(inode_permission, inode, mask);
232520510f2fSJames Morris }
232620510f2fSJames Morris 
2327916e3258SPaul Moore /**
2328916e3258SPaul Moore  * security_inode_setattr() - Check if setting file attributes is allowed
2329916e3258SPaul Moore  * @idmap: idmap of the mount
2330916e3258SPaul Moore  * @dentry: file
2331916e3258SPaul Moore  * @attr: new attributes
2332916e3258SPaul Moore  *
2333916e3258SPaul Moore  * Check permission before setting file attributes.  Note that the kernel call
2334916e3258SPaul Moore  * to notify_change is performed from several locations, whenever file
2335916e3258SPaul Moore  * attributes change (such as when a file is truncated, chown/chmod operations,
2336916e3258SPaul Moore  * transferring disk quotas, etc).
2337916e3258SPaul Moore  *
2338916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2339916e3258SPaul Moore  */
security_inode_setattr(struct mnt_idmap * idmap,struct dentry * dentry,struct iattr * attr)2340c1632a0fSChristian Brauner int security_inode_setattr(struct mnt_idmap *idmap,
23410e363cf3SChristian Brauner 			   struct dentry *dentry, struct iattr *attr)
234220510f2fSJames Morris {
2343c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
234420510f2fSJames Morris 		return 0;
2345260017f3SOndrej Mosnacek 	return call_int_hook(inode_setattr, idmap, dentry, attr);
234620510f2fSJames Morris }
2347b1da47e2SMiklos Szeredi EXPORT_SYMBOL_GPL(security_inode_setattr);
234820510f2fSJames Morris 
2349916e3258SPaul Moore /**
235077fa6f31SRoberto Sassu  * security_inode_post_setattr() - Update the inode after a setattr operation
235177fa6f31SRoberto Sassu  * @idmap: idmap of the mount
235277fa6f31SRoberto Sassu  * @dentry: file
235377fa6f31SRoberto Sassu  * @ia_valid: file attributes set
235477fa6f31SRoberto Sassu  *
235577fa6f31SRoberto Sassu  * Update inode security field after successful setting file attributes.
235677fa6f31SRoberto Sassu  */
security_inode_post_setattr(struct mnt_idmap * idmap,struct dentry * dentry,int ia_valid)235777fa6f31SRoberto Sassu void security_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
235877fa6f31SRoberto Sassu 				 int ia_valid)
235977fa6f31SRoberto Sassu {
236077fa6f31SRoberto Sassu 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
236177fa6f31SRoberto Sassu 		return;
236277fa6f31SRoberto Sassu 	call_void_hook(inode_post_setattr, idmap, dentry, ia_valid);
236377fa6f31SRoberto Sassu }
236477fa6f31SRoberto Sassu 
236577fa6f31SRoberto Sassu /**
2366916e3258SPaul Moore  * security_inode_getattr() - Check if getting file attributes is allowed
2367916e3258SPaul Moore  * @path: file
2368916e3258SPaul Moore  *
2369916e3258SPaul Moore  * Check permission before obtaining file attributes.
2370916e3258SPaul Moore  *
2371916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2372916e3258SPaul Moore  */
security_inode_getattr(const struct path * path)23733f7036a0SAl Viro int security_inode_getattr(const struct path *path)
237420510f2fSJames Morris {
2375c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry))))
237620510f2fSJames Morris 		return 0;
2377260017f3SOndrej Mosnacek 	return call_int_hook(inode_getattr, path);
237820510f2fSJames Morris }
237920510f2fSJames Morris 
2380916e3258SPaul Moore /**
2381916e3258SPaul Moore  * security_inode_setxattr() - Check if setting file xattrs is allowed
2382916e3258SPaul Moore  * @idmap: idmap of the mount
2383916e3258SPaul Moore  * @dentry: file
2384916e3258SPaul Moore  * @name: xattr name
2385916e3258SPaul Moore  * @value: xattr value
23861e2523d7SPaul Moore  * @size: size of xattr value
2387916e3258SPaul Moore  * @flags: flags
2388916e3258SPaul Moore  *
238961df7b82SPaul Moore  * This hook performs the desired permission checks before setting the extended
239061df7b82SPaul Moore  * attributes (xattrs) on @dentry.  It is important to note that we have some
239161df7b82SPaul Moore  * additional logic before the main LSM implementation calls to detect if we
239261df7b82SPaul Moore  * need to perform an additional capability check at the LSM layer.
239361df7b82SPaul Moore  *
239461df7b82SPaul Moore  * Normally we enforce a capability check prior to executing the various LSM
239561df7b82SPaul Moore  * hook implementations, but if a LSM wants to avoid this capability check,
239661df7b82SPaul Moore  * it can register a 'inode_xattr_skipcap' hook and return a value of 1 for
239761df7b82SPaul Moore  * xattrs that it wants to avoid the capability check, leaving the LSM fully
239861df7b82SPaul Moore  * responsible for enforcing the access control for the specific xattr.  If all
239961df7b82SPaul Moore  * of the enabled LSMs refrain from registering a 'inode_xattr_skipcap' hook,
240061df7b82SPaul Moore  * or return a 0 (the default return value), the capability check is still
240161df7b82SPaul Moore  * performed.  If no 'inode_xattr_skipcap' hooks are registered the capability
240261df7b82SPaul Moore  * check is performed.
2403916e3258SPaul Moore  *
2404916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2405916e3258SPaul Moore  */
security_inode_setxattr(struct mnt_idmap * idmap,struct dentry * dentry,const char * name,const void * value,size_t size,int flags)240639f60c1cSChristian Brauner int security_inode_setxattr(struct mnt_idmap *idmap,
240771bc356fSChristian Brauner 			    struct dentry *dentry, const char *name,
24088f0cfa52SDavid Howells 			    const void *value, size_t size, int flags)
240920510f2fSJames Morris {
241061df7b82SPaul Moore 	int rc;
24113e1be52dSMimi Zohar 
2412c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
241320510f2fSJames Morris 		return 0;
2414b1d9e6b0SCasey Schaufler 
241561df7b82SPaul Moore 	/* enforce the capability checks at the lsm layer, if needed */
241661df7b82SPaul Moore 	if (!call_int_hook(inode_xattr_skipcap, name)) {
241761df7b82SPaul Moore 		rc = cap_inode_setxattr(dentry, name, value, size, flags);
241861df7b82SPaul Moore 		if (rc)
241961df7b82SPaul Moore 			return rc;
242061df7b82SPaul Moore 	}
242161df7b82SPaul Moore 
242261df7b82SPaul Moore 	return call_int_hook(inode_setxattr, idmap, dentry, name, value, size,
242361df7b82SPaul Moore 			     flags);
242420510f2fSJames Morris }
242520510f2fSJames Morris 
2426916e3258SPaul Moore /**
2427916e3258SPaul Moore  * security_inode_set_acl() - Check if setting posix acls is allowed
2428916e3258SPaul Moore  * @idmap: idmap of the mount
2429916e3258SPaul Moore  * @dentry: file
2430916e3258SPaul Moore  * @acl_name: acl name
2431916e3258SPaul Moore  * @kacl: acl struct
2432916e3258SPaul Moore  *
2433916e3258SPaul Moore  * Check permission before setting posix acls, the posix acls in @kacl are
2434916e3258SPaul Moore  * identified by @acl_name.
2435916e3258SPaul Moore  *
2436916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2437916e3258SPaul Moore  */
security_inode_set_acl(struct mnt_idmap * idmap,struct dentry * dentry,const char * acl_name,struct posix_acl * kacl)2438700b7940SChristian Brauner int security_inode_set_acl(struct mnt_idmap *idmap,
243972b3897eSChristian Brauner 			   struct dentry *dentry, const char *acl_name,
244072b3897eSChristian Brauner 			   struct posix_acl *kacl)
244172b3897eSChristian Brauner {
244272b3897eSChristian Brauner 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
244372b3897eSChristian Brauner 		return 0;
2444260017f3SOndrej Mosnacek 	return call_int_hook(inode_set_acl, idmap, dentry, acl_name, kacl);
244572b3897eSChristian Brauner }
244672b3897eSChristian Brauner 
2447916e3258SPaul Moore /**
24488b9d0b82SRoberto Sassu  * security_inode_post_set_acl() - Update inode security from posix acls set
24498b9d0b82SRoberto Sassu  * @dentry: file
24508b9d0b82SRoberto Sassu  * @acl_name: acl name
24518b9d0b82SRoberto Sassu  * @kacl: acl struct
24528b9d0b82SRoberto Sassu  *
24538b9d0b82SRoberto Sassu  * Update inode security data after successfully setting posix acls on @dentry.
24548b9d0b82SRoberto Sassu  * The posix acls in @kacl are identified by @acl_name.
24558b9d0b82SRoberto Sassu  */
security_inode_post_set_acl(struct dentry * dentry,const char * acl_name,struct posix_acl * kacl)24568b9d0b82SRoberto Sassu void security_inode_post_set_acl(struct dentry *dentry, const char *acl_name,
24578b9d0b82SRoberto Sassu 				 struct posix_acl *kacl)
24588b9d0b82SRoberto Sassu {
24598b9d0b82SRoberto Sassu 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
24608b9d0b82SRoberto Sassu 		return;
24618b9d0b82SRoberto Sassu 	call_void_hook(inode_post_set_acl, dentry, acl_name, kacl);
246272b3897eSChristian Brauner }
246372b3897eSChristian Brauner 
2464916e3258SPaul Moore /**
2465916e3258SPaul Moore  * security_inode_get_acl() - Check if reading posix acls is allowed
2466916e3258SPaul Moore  * @idmap: idmap of the mount
2467916e3258SPaul Moore  * @dentry: file
2468916e3258SPaul Moore  * @acl_name: acl name
2469916e3258SPaul Moore  *
2470916e3258SPaul Moore  * Check permission before getting osix acls, the posix acls are identified by
2471916e3258SPaul Moore  * @acl_name.
2472916e3258SPaul Moore  *
2473916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2474916e3258SPaul Moore  */
security_inode_get_acl(struct mnt_idmap * idmap,struct dentry * dentry,const char * acl_name)2475700b7940SChristian Brauner int security_inode_get_acl(struct mnt_idmap *idmap,
247672b3897eSChristian Brauner 			   struct dentry *dentry, const char *acl_name)
247772b3897eSChristian Brauner {
247872b3897eSChristian Brauner 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
247972b3897eSChristian Brauner 		return 0;
2480260017f3SOndrej Mosnacek 	return call_int_hook(inode_get_acl, idmap, dentry, acl_name);
248172b3897eSChristian Brauner }
248272b3897eSChristian Brauner 
2483916e3258SPaul Moore /**
2484916e3258SPaul Moore  * security_inode_remove_acl() - Check if removing a posix acl is allowed
2485916e3258SPaul Moore  * @idmap: idmap of the mount
2486916e3258SPaul Moore  * @dentry: file
2487916e3258SPaul Moore  * @acl_name: acl name
2488916e3258SPaul Moore  *
2489916e3258SPaul Moore  * Check permission before removing posix acls, the posix acls are identified
2490916e3258SPaul Moore  * by @acl_name.
2491916e3258SPaul Moore  *
2492916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2493916e3258SPaul Moore  */
security_inode_remove_acl(struct mnt_idmap * idmap,struct dentry * dentry,const char * acl_name)2494700b7940SChristian Brauner int security_inode_remove_acl(struct mnt_idmap *idmap,
249572b3897eSChristian Brauner 			      struct dentry *dentry, const char *acl_name)
249672b3897eSChristian Brauner {
249772b3897eSChristian Brauner 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
249872b3897eSChristian Brauner 		return 0;
2499260017f3SOndrej Mosnacek 	return call_int_hook(inode_remove_acl, idmap, dentry, acl_name);
250072b3897eSChristian Brauner }
250172b3897eSChristian Brauner 
2502916e3258SPaul Moore /**
25032d705d80SRoberto Sassu  * security_inode_post_remove_acl() - Update inode security after rm posix acls
25042d705d80SRoberto Sassu  * @idmap: idmap of the mount
25052d705d80SRoberto Sassu  * @dentry: file
25062d705d80SRoberto Sassu  * @acl_name: acl name
25072d705d80SRoberto Sassu  *
25082d705d80SRoberto Sassu  * Update inode security data after successfully removing posix acls on
25092d705d80SRoberto Sassu  * @dentry in @idmap. The posix acls are identified by @acl_name.
25102d705d80SRoberto Sassu  */
security_inode_post_remove_acl(struct mnt_idmap * idmap,struct dentry * dentry,const char * acl_name)25112d705d80SRoberto Sassu void security_inode_post_remove_acl(struct mnt_idmap *idmap,
25122d705d80SRoberto Sassu 				    struct dentry *dentry, const char *acl_name)
25132d705d80SRoberto Sassu {
25142d705d80SRoberto Sassu 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
25152d705d80SRoberto Sassu 		return;
25162d705d80SRoberto Sassu 	call_void_hook(inode_post_remove_acl, idmap, dentry, acl_name);
251771bc356fSChristian Brauner }
251871bc356fSChristian Brauner 
2519916e3258SPaul Moore /**
2520916e3258SPaul Moore  * security_inode_post_setxattr() - Update the inode after a setxattr operation
2521916e3258SPaul Moore  * @dentry: file
2522916e3258SPaul Moore  * @name: xattr name
2523916e3258SPaul Moore  * @value: xattr value
2524916e3258SPaul Moore  * @size: xattr value size
2525916e3258SPaul Moore  * @flags: flags
2526916e3258SPaul Moore  *
2527916e3258SPaul Moore  * Update inode security field after successful setxattr operation.
2528916e3258SPaul Moore  */
security_inode_post_setxattr(struct dentry * dentry,const char * name,const void * value,size_t size,int flags)252920510f2fSJames Morris void security_inode_post_setxattr(struct dentry *dentry, const char *name,
25308f0cfa52SDavid Howells 				  const void *value, size_t size, int flags)
25318f0cfa52SDavid Howells {
253220510f2fSJames Morris 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
2533c6f493d6SDavid Howells 		return;
253420510f2fSJames Morris 	call_void_hook(inode_post_setxattr, dentry, name, value, size, flags);
25353e1be52dSMimi Zohar }
253620510f2fSJames Morris 
2537916e3258SPaul Moore /**
2538916e3258SPaul Moore  * security_inode_getxattr() - Check if xattr access is allowed
2539916e3258SPaul Moore  * @dentry: file
2540916e3258SPaul Moore  * @name: xattr name
2541916e3258SPaul Moore  *
2542916e3258SPaul Moore  * Check permission before obtaining the extended attributes identified by
2543916e3258SPaul Moore  * @name for @dentry.
2544916e3258SPaul Moore  *
2545916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2546916e3258SPaul Moore  */
security_inode_getxattr(struct dentry * dentry,const char * name)254720510f2fSJames Morris int security_inode_getxattr(struct dentry *dentry, const char *name)
25488f0cfa52SDavid Howells {
254920510f2fSJames Morris 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
2550c6f493d6SDavid Howells 		return 0;
2551260017f3SOndrej Mosnacek 	return call_int_hook(inode_getxattr, dentry, name);
2552f25fce3eSCasey Schaufler }
255320510f2fSJames Morris 
2554916e3258SPaul Moore /**
2555916e3258SPaul Moore  * security_inode_listxattr() - Check if listing xattrs is allowed
2556916e3258SPaul Moore  * @dentry: file
2557916e3258SPaul Moore  *
2558916e3258SPaul Moore  * Check permission before obtaining the list of extended attribute names for
2559916e3258SPaul Moore  * @dentry.
2560916e3258SPaul Moore  *
2561916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2562916e3258SPaul Moore  */
security_inode_listxattr(struct dentry * dentry)256320510f2fSJames Morris int security_inode_listxattr(struct dentry *dentry)
256420510f2fSJames Morris {
256520510f2fSJames Morris 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
2566c6f493d6SDavid Howells 		return 0;
2567260017f3SOndrej Mosnacek 	return call_int_hook(inode_listxattr, dentry);
2568f25fce3eSCasey Schaufler }
256920510f2fSJames Morris 
2570916e3258SPaul Moore /**
2571916e3258SPaul Moore  * security_inode_removexattr() - Check if removing an xattr is allowed
2572916e3258SPaul Moore  * @idmap: idmap of the mount
2573916e3258SPaul Moore  * @dentry: file
2574916e3258SPaul Moore  * @name: xattr name
2575916e3258SPaul Moore  *
257661df7b82SPaul Moore  * This hook performs the desired permission checks before setting the extended
257761df7b82SPaul Moore  * attributes (xattrs) on @dentry.  It is important to note that we have some
257861df7b82SPaul Moore  * additional logic before the main LSM implementation calls to detect if we
257961df7b82SPaul Moore  * need to perform an additional capability check at the LSM layer.
258061df7b82SPaul Moore  *
258161df7b82SPaul Moore  * Normally we enforce a capability check prior to executing the various LSM
258261df7b82SPaul Moore  * hook implementations, but if a LSM wants to avoid this capability check,
258361df7b82SPaul Moore  * it can register a 'inode_xattr_skipcap' hook and return a value of 1 for
258461df7b82SPaul Moore  * xattrs that it wants to avoid the capability check, leaving the LSM fully
258561df7b82SPaul Moore  * responsible for enforcing the access control for the specific xattr.  If all
258661df7b82SPaul Moore  * of the enabled LSMs refrain from registering a 'inode_xattr_skipcap' hook,
258761df7b82SPaul Moore  * or return a 0 (the default return value), the capability check is still
258861df7b82SPaul Moore  * performed.  If no 'inode_xattr_skipcap' hooks are registered the capability
258961df7b82SPaul Moore  * check is performed.
2590916e3258SPaul Moore  *
2591916e3258SPaul Moore  * Return: Returns 0 if permission is granted.
2592916e3258SPaul Moore  */
security_inode_removexattr(struct mnt_idmap * idmap,struct dentry * dentry,const char * name)259339f60c1cSChristian Brauner int security_inode_removexattr(struct mnt_idmap *idmap,
25948f0cfa52SDavid Howells 			       struct dentry *dentry, const char *name)
259520510f2fSJames Morris {
259661df7b82SPaul Moore 	int rc;
25973e1be52dSMimi Zohar 
2598c6f493d6SDavid Howells 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
259920510f2fSJames Morris 		return 0;
260061df7b82SPaul Moore 
260161df7b82SPaul Moore 	/* enforce the capability checks at the lsm layer, if needed */
260261df7b82SPaul Moore 	if (!call_int_hook(inode_xattr_skipcap, name)) {
260361df7b82SPaul Moore 		rc = cap_inode_removexattr(idmap, dentry, name);
260461df7b82SPaul Moore 		if (rc)
260561df7b82SPaul Moore 			return rc;
260661df7b82SPaul Moore 	}
260761df7b82SPaul Moore 
260861df7b82SPaul Moore 	return call_int_hook(inode_removexattr, idmap, dentry, name);
260920510f2fSJames Morris }
261020510f2fSJames Morris 
2611916e3258SPaul Moore /**
2612dae52cbfSRoberto Sassu  * security_inode_post_removexattr() - Update the inode after a removexattr op
2613dae52cbfSRoberto Sassu  * @dentry: file
2614dae52cbfSRoberto Sassu  * @name: xattr name
2615dae52cbfSRoberto Sassu  *
2616dae52cbfSRoberto Sassu  * Update the inode after a successful removexattr operation.
2617dae52cbfSRoberto Sassu  */
security_inode_post_removexattr(struct dentry * dentry,const char * name)2618dae52cbfSRoberto Sassu void security_inode_post_removexattr(struct dentry *dentry, const char *name)
2619dae52cbfSRoberto Sassu {
2620dae52cbfSRoberto Sassu 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
2621dae52cbfSRoberto Sassu 		return;
2622dae52cbfSRoberto Sassu 	call_void_hook(inode_post_removexattr, dentry, name);
262320510f2fSJames Morris }
262420510f2fSJames Morris 
2625916e3258SPaul Moore /**
2626916e3258SPaul Moore  * security_inode_need_killpriv() - Check if security_inode_killpriv() required
2627916e3258SPaul Moore  * @dentry: associated dentry
2628916e3258SPaul Moore  *
2629916e3258SPaul Moore  * Called when an inode has been changed to determine if
2630916e3258SPaul Moore  * security_inode_killpriv() should be called.
2631916e3258SPaul Moore  *
2632916e3258SPaul Moore  * Return: Return <0 on error to abort the inode change operation, return 0 if
2633916e3258SPaul Moore  *         security_inode_killpriv() does not need to be called, return >0 if
2634916e3258SPaul Moore  *         security_inode_killpriv() does need to be called.
2635916e3258SPaul Moore  */
security_inode_need_killpriv(struct dentry * dentry)2636b5376771SSerge E. Hallyn int security_inode_need_killpriv(struct dentry *dentry)
2637b5376771SSerge E. Hallyn {
2638260017f3SOndrej Mosnacek 	return call_int_hook(inode_need_killpriv, dentry);
2639b5376771SSerge E. Hallyn }
2640b5376771SSerge E. Hallyn 
2641916e3258SPaul Moore /**
2642916e3258SPaul Moore  * security_inode_killpriv() - The setuid bit is removed, update LSM state
2643916e3258SPaul Moore  * @idmap: idmap of the mount
2644916e3258SPaul Moore  * @dentry: associated dentry
2645916e3258SPaul Moore  *
2646916e3258SPaul Moore  * The @dentry's setuid bit is being removed.  Remove similar security labels.
2647916e3258SPaul Moore  * Called with the dentry->d_inode->i_mutex held.
2648916e3258SPaul Moore  *
2649916e3258SPaul Moore  * Return: Return 0 on success.  If error is returned, then the operation
2650916e3258SPaul Moore  *         causing setuid bit removal is failed.
2651916e3258SPaul Moore  */
security_inode_killpriv(struct mnt_idmap * idmap,struct dentry * dentry)265239f60c1cSChristian Brauner int security_inode_killpriv(struct mnt_idmap *idmap,
265371bc356fSChristian Brauner 			    struct dentry *dentry)
2654b5376771SSerge E. Hallyn {
2655260017f3SOndrej Mosnacek 	return call_int_hook(inode_killpriv, idmap, dentry);
2656b5376771SSerge E. Hallyn }
2657b5376771SSerge E. Hallyn 
2658916e3258SPaul Moore /**
2659916e3258SPaul Moore  * security_inode_getsecurity() - Get the xattr security label of an inode
2660916e3258SPaul Moore  * @idmap: idmap of the mount
2661916e3258SPaul Moore  * @inode: inode
2662916e3258SPaul Moore  * @name: xattr name
2663916e3258SPaul Moore  * @buffer: security label buffer
2664916e3258SPaul Moore  * @alloc: allocation flag
2665916e3258SPaul Moore  *
2666916e3258SPaul Moore  * Retrieve a copy of the extended attribute representation of the security
2667916e3258SPaul Moore  * label associated with @name for @inode via @buffer.  Note that @name is the
2668916e3258SPaul Moore  * remainder of the attribute name after the security prefix has been removed.
2669916e3258SPaul Moore  * @alloc is used to specify if the call should return a value via the buffer
2670916e3258SPaul Moore  * or just the value length.
2671916e3258SPaul Moore  *
2672916e3258SPaul Moore  * Return: Returns size of buffer on success.
2673916e3258SPaul Moore  */
security_inode_getsecurity(struct mnt_idmap * idmap,struct inode * inode,const char * name,void ** buffer,bool alloc)26744609e1f1SChristian Brauner int security_inode_getsecurity(struct mnt_idmap *idmap,
267571bc356fSChristian Brauner 			       struct inode *inode, const char *name,
267671bc356fSChristian Brauner 			       void **buffer, bool alloc)
267720510f2fSJames Morris {
267820510f2fSJames Morris 	if (unlikely(IS_PRIVATE(inode)))
267998e828a0SKP Singh 		return LSM_RET_DEFAULT(inode_getsecurity);
2680260017f3SOndrej Mosnacek 
2681260017f3SOndrej Mosnacek 	return call_int_hook(inode_getsecurity, idmap, inode, name, buffer,
268263c1845bSPaul Moore 			     alloc);
268320510f2fSJames Morris }
268420510f2fSJames Morris 
2685916e3258SPaul Moore /**
2686916e3258SPaul Moore  * security_inode_setsecurity() - Set the xattr security label of an inode
2687916e3258SPaul Moore  * @inode: inode
2688916e3258SPaul Moore  * @name: xattr name
2689916e3258SPaul Moore  * @value: security label
2690916e3258SPaul Moore  * @size: length of security label
2691916e3258SPaul Moore  * @flags: flags
2692916e3258SPaul Moore  *
2693916e3258SPaul Moore  * Set the security label associated with @name for @inode from the extended
2694916e3258SPaul Moore  * attribute value @value.  @size indicates the size of the @value in bytes.
2695916e3258SPaul Moore  * @flags may be XATTR_CREATE, XATTR_REPLACE, or 0. Note that @name is the
2696916e3258SPaul Moore  * remainder of the attribute name after the security. prefix has been removed.
2697916e3258SPaul Moore  *
2698916e3258SPaul Moore  * Return: Returns 0 on success.
2699916e3258SPaul Moore  */
security_inode_setsecurity(struct inode * inode,const char * name,const void * value,size_t size,int flags)270063c1845bSPaul Moore int security_inode_setsecurity(struct inode *inode, const char *name,
270163c1845bSPaul Moore 			       const void *value, size_t size, int flags)
270220510f2fSJames Morris {
270320510f2fSJames Morris 	if (unlikely(IS_PRIVATE(inode)))
270498e828a0SKP Singh 		return LSM_RET_DEFAULT(inode_setsecurity);
2705260017f3SOndrej Mosnacek 
2706260017f3SOndrej Mosnacek 	return call_int_hook(inode_setsecurity, inode, name, value, size,
27072885c1e3SCasey Schaufler 			     flags);
270820510f2fSJames Morris }
270920510f2fSJames Morris 
2710916e3258SPaul Moore /**
2711916e3258SPaul Moore  * security_inode_listsecurity() - List the xattr security label names
2712916e3258SPaul Moore  * @inode: inode
2713916e3258SPaul Moore  * @buffer: buffer
2714916e3258SPaul Moore  * @buffer_size: size of buffer
2715916e3258SPaul Moore  *
2716916e3258SPaul Moore  * Copy the extended attribute names for the security labels associated with
2717916e3258SPaul Moore  * @inode into @buffer.  The maximum size of @buffer is specified by
2718916e3258SPaul Moore  * @buffer_size.  @buffer may be NULL to request the size of the buffer
2719916e3258SPaul Moore  * required.
2720916e3258SPaul Moore  *
2721916e3258SPaul Moore  * Return: Returns number of bytes used/required on success.
2722916e3258SPaul Moore  */
security_inode_listsecurity(struct inode * inode,char * buffer,size_t buffer_size)272363c1845bSPaul Moore int security_inode_listsecurity(struct inode *inode,
272463c1845bSPaul Moore 				char *buffer, size_t buffer_size)
272520510f2fSJames Morris {
272620510f2fSJames Morris 	if (unlikely(IS_PRIVATE(inode)))
272720510f2fSJames Morris 		return 0;
2728260017f3SOndrej Mosnacek 	return call_int_hook(inode_listsecurity, inode, buffer, buffer_size);
272920510f2fSJames Morris }
2730c9bccef6SDavid Quigley EXPORT_SYMBOL(security_inode_listsecurity);
273120510f2fSJames Morris 
2732916e3258SPaul Moore /**
273307f9d2c1SCasey Schaufler  * security_inode_getlsmprop() - Get an inode's LSM data
2734916e3258SPaul Moore  * @inode: inode
273507f9d2c1SCasey Schaufler  * @prop: lsm specific information to return
2736916e3258SPaul Moore  *
273707f9d2c1SCasey Schaufler  * Get the lsm specific information associated with the node.
2738916e3258SPaul Moore  */
security_inode_getlsmprop(struct inode * inode,struct lsm_prop * prop)273907f9d2c1SCasey Schaufler void security_inode_getlsmprop(struct inode *inode, struct lsm_prop *prop)
27408a076191SAhmed S. Darwish {
274107f9d2c1SCasey Schaufler 	call_void_hook(inode_getlsmprop, inode, prop);
27428a076191SAhmed S. Darwish }
27438a076191SAhmed S. Darwish 
2744916e3258SPaul Moore /**
2745916e3258SPaul Moore  * security_inode_copy_up() - Create new creds for an overlayfs copy-up op
2746916e3258SPaul Moore  * @src: union dentry of copy-up file
2747916e3258SPaul Moore  * @new: newly created creds
2748916e3258SPaul Moore  *
2749916e3258SPaul Moore  * A file is about to be copied up from lower layer to upper layer of overlay
2750916e3258SPaul Moore  * filesystem. Security module can prepare a set of new creds and modify as
2751916e3258SPaul Moore  * need be and return new creds. Caller will switch to new creds temporarily to
2752916e3258SPaul Moore  * create new file and release newly allocated creds.
2753916e3258SPaul Moore  *
2754916e3258SPaul Moore  * Return: Returns 0 on success or a negative error code on error.
2755916e3258SPaul Moore  */
security_inode_copy_up(struct dentry * src,struct cred ** new)2756d8ad8b49SVivek Goyal int security_inode_copy_up(struct dentry *src, struct cred **new)
2757d8ad8b49SVivek Goyal {
2758260017f3SOndrej Mosnacek 	return call_int_hook(inode_copy_up, src, new);
2759d8ad8b49SVivek Goyal }
2760d8ad8b49SVivek Goyal EXPORT_SYMBOL(security_inode_copy_up);
2761d8ad8b49SVivek Goyal 
2762916e3258SPaul Moore /**
2763916e3258SPaul Moore  * security_inode_copy_up_xattr() - Filter xattrs in an overlayfs copy-up op
276432538047SStefan Berger  * @src: union dentry of copy-up file
2765916e3258SPaul Moore  * @name: xattr name
2766916e3258SPaul Moore  *
2767916e3258SPaul Moore  * Filter the xattrs being copied up when a unioned file is copied up from a
2768916e3258SPaul Moore  * lower layer to the union/overlay layer.   The caller is responsible for
2769916e3258SPaul Moore  * reading and writing the xattrs, this hook is merely a filter.
2770916e3258SPaul Moore  *
2771924e19c3SXu Kuohai  * Return: Returns 0 to accept the xattr, -ECANCELED to discard the xattr,
2772924e19c3SXu Kuohai  *         -EOPNOTSUPP if the security module does not know about attribute,
2773924e19c3SXu Kuohai  *         or a negative error code to abort the copy up.
2774916e3258SPaul Moore  */
security_inode_copy_up_xattr(struct dentry * src,const char * name)277532538047SStefan Berger int security_inode_copy_up_xattr(struct dentry *src, const char *name)
2776121ab822SVivek Goyal {
277723e390cdSKP Singh 	int rc;
277823e390cdSKP Singh 
277932538047SStefan Berger 	rc = call_int_hook(inode_copy_up_xattr, src, name);
278023e390cdSKP Singh 	if (rc != LSM_RET_DEFAULT(inode_copy_up_xattr))
278123e390cdSKP Singh 		return rc;
278223e390cdSKP Singh 
278392383111SRoberto Sassu 	return LSM_RET_DEFAULT(inode_copy_up_xattr);
2784121ab822SVivek Goyal }
2785121ab822SVivek Goyal EXPORT_SYMBOL(security_inode_copy_up_xattr);
2786121ab822SVivek Goyal 
27879348944bSPaul Moore /**
2788fb55e177SFan Wu  * security_inode_setintegrity() - Set the inode's integrity data
2789fb55e177SFan Wu  * @inode: inode
2790fb55e177SFan Wu  * @type: type of integrity, e.g. hash digest, signature, etc
2791fb55e177SFan Wu  * @value: the integrity value
2792fb55e177SFan Wu  * @size: size of the integrity value
2793fb55e177SFan Wu  *
2794fb55e177SFan Wu  * Register a verified integrity measurement of a inode with LSMs.
2795fb55e177SFan Wu  * LSMs should free the previously saved data if @value is NULL.
2796fb55e177SFan Wu  *
2797fb55e177SFan Wu  * Return: Returns 0 on success, negative values on failure.
2798fb55e177SFan Wu  */
security_inode_setintegrity(const struct inode * inode,enum lsm_integrity_type type,const void * value,size_t size)2799fb55e177SFan Wu int security_inode_setintegrity(const struct inode *inode,
2800fb55e177SFan Wu 				enum lsm_integrity_type type, const void *value,
2801fb55e177SFan Wu 				size_t size)
2802fb55e177SFan Wu {
2803fb55e177SFan Wu 	return call_int_hook(inode_setintegrity, inode, type, value, size);
2804fb55e177SFan Wu }
2805fb55e177SFan Wu EXPORT_SYMBOL(security_inode_setintegrity);
2806fb55e177SFan Wu 
2807fb55e177SFan Wu /**
28089348944bSPaul Moore  * security_kernfs_init_security() - Init LSM context for a kernfs node
28099348944bSPaul Moore  * @kn_dir: parent kernfs node
28109348944bSPaul Moore  * @kn: the kernfs node to initialize
28119348944bSPaul Moore  *
28129348944bSPaul Moore  * Initialize the security context of a newly created kernfs node based on its
28139348944bSPaul Moore  * own and its parent's attributes.
28149348944bSPaul Moore  *
28159348944bSPaul Moore  * Return: Returns 0 if permission is granted.
28169348944bSPaul Moore  */
security_kernfs_init_security(struct kernfs_node * kn_dir,struct kernfs_node * kn)2817b230d5abSOndrej Mosnacek int security_kernfs_init_security(struct kernfs_node *kn_dir,
2818b230d5abSOndrej Mosnacek 				  struct kernfs_node *kn)
2819b230d5abSOndrej Mosnacek {
2820260017f3SOndrej Mosnacek 	return call_int_hook(kernfs_init_security, kn_dir, kn);
2821b230d5abSOndrej Mosnacek }
2822b230d5abSOndrej Mosnacek 
2823a0fd6480SPaul Moore /**
2824a0fd6480SPaul Moore  * security_file_permission() - Check file permissions
2825a0fd6480SPaul Moore  * @file: file
2826a0fd6480SPaul Moore  * @mask: requested permissions
2827a0fd6480SPaul Moore  *
2828a0fd6480SPaul Moore  * Check file permissions before accessing an open file.  This hook is called
2829a0fd6480SPaul Moore  * by various operations that read or write files.  A security module can use
2830a0fd6480SPaul Moore  * this hook to perform additional checking on these operations, e.g. to
2831a0fd6480SPaul Moore  * revalidate permissions on use to support privilege bracketing or policy
2832a0fd6480SPaul Moore  * changes.  Notice that this hook is used when the actual read/write
2833a0fd6480SPaul Moore  * operations are performed, whereas the inode_security_ops hook is called when
2834a0fd6480SPaul Moore  * a file is opened (as well as many other operations).  Although this hook can
2835a0fd6480SPaul Moore  * be used to revalidate permissions for various system call operations that
2836a0fd6480SPaul Moore  * read or write files, it does not address the revalidation of permissions for
2837a0fd6480SPaul Moore  * memory-mapped files.  Security modules must handle this separately if they
2838a0fd6480SPaul Moore  * need such revalidation.
2839a0fd6480SPaul Moore  *
2840a0fd6480SPaul Moore  * Return: Returns 0 if permission is granted.
2841a0fd6480SPaul Moore  */
security_file_permission(struct file * file,int mask)284220510f2fSJames Morris int security_file_permission(struct file *file, int mask)
284320510f2fSJames Morris {
2844260017f3SOndrej Mosnacek 	return call_int_hook(file_permission, file, mask);
284520510f2fSJames Morris }
284620510f2fSJames Morris 
2847a0fd6480SPaul Moore /**
2848a0fd6480SPaul Moore  * security_file_alloc() - Allocate and init a file's LSM blob
2849a0fd6480SPaul Moore  * @file: the file
2850a0fd6480SPaul Moore  *
2851a0fd6480SPaul Moore  * Allocate and attach a security structure to the file->f_security field.  The
2852a0fd6480SPaul Moore  * security field is initialized to NULL when the structure is first created.
2853a0fd6480SPaul Moore  *
2854a0fd6480SPaul Moore  * Return: Return 0 if the hook is successful and permission is granted.
2855a0fd6480SPaul Moore  */
security_file_alloc(struct file * file)285620510f2fSJames Morris int security_file_alloc(struct file *file)
285720510f2fSJames Morris {
285833bf60caSCasey Schaufler 	int rc = lsm_file_alloc(file);
285933bf60caSCasey Schaufler 
286033bf60caSCasey Schaufler 	if (rc)
286133bf60caSCasey Schaufler 		return rc;
2862260017f3SOndrej Mosnacek 	rc = call_int_hook(file_alloc_security, file);
286333bf60caSCasey Schaufler 	if (unlikely(rc))
286433bf60caSCasey Schaufler 		security_file_free(file);
286533bf60caSCasey Schaufler 	return rc;
286620510f2fSJames Morris }
286720510f2fSJames Morris 
2868a0fd6480SPaul Moore /**
2869f09068b5SRoberto Sassu  * security_file_release() - Perform actions before releasing the file ref
2870f09068b5SRoberto Sassu  * @file: the file
2871f09068b5SRoberto Sassu  *
2872f09068b5SRoberto Sassu  * Perform actions before releasing the last reference to a file.
2873f09068b5SRoberto Sassu  */
security_file_release(struct file * file)2874f09068b5SRoberto Sassu void security_file_release(struct file *file)
2875f09068b5SRoberto Sassu {
2876f09068b5SRoberto Sassu 	call_void_hook(file_release, file);
2877f09068b5SRoberto Sassu }
2878f09068b5SRoberto Sassu 
2879f09068b5SRoberto Sassu /**
2880a0fd6480SPaul Moore  * security_file_free() - Free a file's LSM blob
2881a0fd6480SPaul Moore  * @file: the file
2882a0fd6480SPaul Moore  *
2883a0fd6480SPaul Moore  * Deallocate and free any security structures stored in file->f_security.
2884a0fd6480SPaul Moore  */
security_file_free(struct file * file)288520510f2fSJames Morris void security_file_free(struct file *file)
288620510f2fSJames Morris {
288733bf60caSCasey Schaufler 	void *blob;
288833bf60caSCasey Schaufler 
2889f25fce3eSCasey Schaufler 	call_void_hook(file_free_security, file);
289033bf60caSCasey Schaufler 
289133bf60caSCasey Schaufler 	blob = file->f_security;
289233bf60caSCasey Schaufler 	if (blob) {
289333bf60caSCasey Schaufler 		file->f_security = NULL;
289433bf60caSCasey Schaufler 		kmem_cache_free(lsm_file_cache, blob);
289533bf60caSCasey Schaufler 	}
289620510f2fSJames Morris }
289720510f2fSJames Morris 
2898a0fd6480SPaul Moore /**
2899a0fd6480SPaul Moore  * security_file_ioctl() - Check if an ioctl is allowed
2900a0fd6480SPaul Moore  * @file: associated file
2901a0fd6480SPaul Moore  * @cmd: ioctl cmd
2902a0fd6480SPaul Moore  * @arg: ioctl arguments
2903a0fd6480SPaul Moore  *
2904a0fd6480SPaul Moore  * Check permission for an ioctl operation on @file.  Note that @arg sometimes
2905a0fd6480SPaul Moore  * represents a user space pointer; in other cases, it may be a simple integer
2906a0fd6480SPaul Moore  * value.  When @arg represents a user space pointer, it should never be used
2907a0fd6480SPaul Moore  * by the security module.
2908a0fd6480SPaul Moore  *
2909a0fd6480SPaul Moore  * Return: Returns 0 if permission is granted.
2910a0fd6480SPaul Moore  */
security_file_ioctl(struct file * file,unsigned int cmd,unsigned long arg)291120510f2fSJames Morris int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
291220510f2fSJames Morris {
2913260017f3SOndrej Mosnacek 	return call_int_hook(file_ioctl, file, cmd, arg);
291420510f2fSJames Morris }
2915292f902aSMiklos Szeredi EXPORT_SYMBOL_GPL(security_file_ioctl);
291620510f2fSJames Morris 
2917f1bb47a3SAlfred Piccioni /**
2918f1bb47a3SAlfred Piccioni  * security_file_ioctl_compat() - Check if an ioctl is allowed in compat mode
2919f1bb47a3SAlfred Piccioni  * @file: associated file
2920f1bb47a3SAlfred Piccioni  * @cmd: ioctl cmd
2921f1bb47a3SAlfred Piccioni  * @arg: ioctl arguments
2922f1bb47a3SAlfred Piccioni  *
2923f1bb47a3SAlfred Piccioni  * Compat version of security_file_ioctl() that correctly handles 32-bit
2924f1bb47a3SAlfred Piccioni  * processes running on 64-bit kernels.
2925f1bb47a3SAlfred Piccioni  *
2926f1bb47a3SAlfred Piccioni  * Return: Returns 0 if permission is granted.
2927f1bb47a3SAlfred Piccioni  */
security_file_ioctl_compat(struct file * file,unsigned int cmd,unsigned long arg)2928f1bb47a3SAlfred Piccioni int security_file_ioctl_compat(struct file *file, unsigned int cmd,
2929f1bb47a3SAlfred Piccioni 			       unsigned long arg)
2930f1bb47a3SAlfred Piccioni {
2931260017f3SOndrej Mosnacek 	return call_int_hook(file_ioctl_compat, file, cmd, arg);
2932f1bb47a3SAlfred Piccioni }
2933f1bb47a3SAlfred Piccioni EXPORT_SYMBOL_GPL(security_file_ioctl_compat);
2934f1bb47a3SAlfred Piccioni 
mmap_prot(struct file * file,unsigned long prot)293598de59bfSAl Viro static inline unsigned long mmap_prot(struct file *file, unsigned long prot)
293620510f2fSJames Morris {
29378b3ec681SAl Viro 	/*
293898de59bfSAl Viro 	 * Does we have PROT_READ and does the application expect
293998de59bfSAl Viro 	 * it to imply PROT_EXEC?  If not, nothing to talk about...
29408b3ec681SAl Viro 	 */
294198de59bfSAl Viro 	if ((prot & (PROT_READ | PROT_EXEC)) != PROT_READ)
294298de59bfSAl Viro 		return prot;
29438b3ec681SAl Viro 	if (!(current->personality & READ_IMPLIES_EXEC))
294498de59bfSAl Viro 		return prot;
294598de59bfSAl Viro 	/*
294698de59bfSAl Viro 	 * if that's an anonymous mapping, let it.
294798de59bfSAl Viro 	 */
294898de59bfSAl Viro 	if (!file)
294998de59bfSAl Viro 		return prot | PROT_EXEC;
295098de59bfSAl Viro 	/*
295198de59bfSAl Viro 	 * ditto if it's not on noexec mount, except that on !MMU we need
2952b4caecd4SChristoph Hellwig 	 * NOMMU_MAP_EXEC (== VM_MAYEXEC) in this case
295398de59bfSAl Viro 	 */
295490f8572bSEric W. Biederman 	if (!path_noexec(&file->f_path)) {
29558b3ec681SAl Viro #ifndef CONFIG_MMU
2956b4caecd4SChristoph Hellwig 		if (file->f_op->mmap_capabilities) {
2957b4caecd4SChristoph Hellwig 			unsigned caps = file->f_op->mmap_capabilities(file);
2958b4caecd4SChristoph Hellwig 			if (!(caps & NOMMU_MAP_EXEC))
295998de59bfSAl Viro 				return prot;
2960b4caecd4SChristoph Hellwig 		}
29618b3ec681SAl Viro #endif
296298de59bfSAl Viro 		return prot | PROT_EXEC;
29638b3ec681SAl Viro 	}
296498de59bfSAl Viro 	/* anything on noexec mount won't get PROT_EXEC */
296598de59bfSAl Viro 	return prot;
296698de59bfSAl Viro }
296798de59bfSAl Viro 
2968a0fd6480SPaul Moore /**
2969a0fd6480SPaul Moore  * security_mmap_file() - Check if mmap'ing a file is allowed
2970a0fd6480SPaul Moore  * @file: file
2971a0fd6480SPaul Moore  * @prot: protection applied by the kernel
2972a0fd6480SPaul Moore  * @flags: flags
2973a0fd6480SPaul Moore  *
2974a0fd6480SPaul Moore  * Check permissions for a mmap operation.  The @file may be NULL, e.g. if
2975a0fd6480SPaul Moore  * mapping anonymous memory.
2976a0fd6480SPaul Moore  *
2977a0fd6480SPaul Moore  * Return: Returns 0 if permission is granted.
2978a0fd6480SPaul Moore  */
security_mmap_file(struct file * file,unsigned long prot,unsigned long flags)297998de59bfSAl Viro int security_mmap_file(struct file *file, unsigned long prot,
298098de59bfSAl Viro 		       unsigned long flags)
298198de59bfSAl Viro {
2982260017f3SOndrej Mosnacek 	return call_int_hook(mmap_file, file, prot, mmap_prot(file, prot),
2983cd3cec0aSRoberto Sassu 			     flags);
298420510f2fSJames Morris }
298520510f2fSJames Morris 
2986a0fd6480SPaul Moore /**
2987a0fd6480SPaul Moore  * security_mmap_addr() - Check if mmap'ing an address is allowed
2988a0fd6480SPaul Moore  * @addr: address
2989a0fd6480SPaul Moore  *
2990a0fd6480SPaul Moore  * Check permissions for a mmap operation at @addr.
2991a0fd6480SPaul Moore  *
2992a0fd6480SPaul Moore  * Return: Returns 0 if permission is granted.
2993a0fd6480SPaul Moore  */
security_mmap_addr(unsigned long addr)2994e5467859SAl Viro int security_mmap_addr(unsigned long addr)
2995e5467859SAl Viro {
2996260017f3SOndrej Mosnacek 	return call_int_hook(mmap_addr, addr);
2997e5467859SAl Viro }
2998e5467859SAl Viro 
2999a0fd6480SPaul Moore /**
3000a0fd6480SPaul Moore  * security_file_mprotect() - Check if changing memory protections is allowed
3001a0fd6480SPaul Moore  * @vma: memory region
3002a0fd6480SPaul Moore  * @reqprot: application requested protection
30031e2523d7SPaul Moore  * @prot: protection applied by the kernel
3004a0fd6480SPaul Moore  *
3005a0fd6480SPaul Moore  * Check permissions before changing memory access permissions.
3006a0fd6480SPaul Moore  *
3007a0fd6480SPaul Moore  * Return: Returns 0 if permission is granted.
3008a0fd6480SPaul Moore  */
security_file_mprotect(struct vm_area_struct * vma,unsigned long reqprot,unsigned long prot)300920510f2fSJames Morris int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
301020510f2fSJames Morris 			   unsigned long prot)
301120510f2fSJames Morris {
3012260017f3SOndrej Mosnacek 	return call_int_hook(file_mprotect, vma, reqprot, prot);
301320510f2fSJames Morris }
301420510f2fSJames Morris 
3015a0fd6480SPaul Moore /**
3016a0fd6480SPaul Moore  * security_file_lock() - Check if a file lock is allowed
3017a0fd6480SPaul Moore  * @file: file
3018a0fd6480SPaul Moore  * @cmd: lock operation (e.g. F_RDLCK, F_WRLCK)
3019a0fd6480SPaul Moore  *
3020a0fd6480SPaul Moore  * Check permission before performing file locking operations.  Note the hook
3021a0fd6480SPaul Moore  * mediates both flock and fcntl style locks.
3022a0fd6480SPaul Moore  *
3023a0fd6480SPaul Moore  * Return: Returns 0 if permission is granted.
3024a0fd6480SPaul Moore  */
security_file_lock(struct file * file,unsigned int cmd)302520510f2fSJames Morris int security_file_lock(struct file *file, unsigned int cmd)
302620510f2fSJames Morris {
3027260017f3SOndrej Mosnacek 	return call_int_hook(file_lock, file, cmd);
302820510f2fSJames Morris }
302920510f2fSJames Morris 
3030a0fd6480SPaul Moore /**
3031a0fd6480SPaul Moore  * security_file_fcntl() - Check if fcntl() op is allowed
3032a0fd6480SPaul Moore  * @file: file
3033ff72942cSPairman Guo  * @cmd: fcntl command
3034a0fd6480SPaul Moore  * @arg: command argument
3035a0fd6480SPaul Moore  *
3036a0fd6480SPaul Moore  * Check permission before allowing the file operation specified by @cmd from
3037a0fd6480SPaul Moore  * being performed on the file @file.  Note that @arg sometimes represents a
3038a0fd6480SPaul Moore  * user space pointer; in other cases, it may be a simple integer value.  When
3039a0fd6480SPaul Moore  * @arg represents a user space pointer, it should never be used by the
3040a0fd6480SPaul Moore  * security module.
3041a0fd6480SPaul Moore  *
3042a0fd6480SPaul Moore  * Return: Returns 0 if permission is granted.
3043a0fd6480SPaul Moore  */
security_file_fcntl(struct file * file,unsigned int cmd,unsigned long arg)304420510f2fSJames Morris int security_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
304520510f2fSJames Morris {
3046260017f3SOndrej Mosnacek 	return call_int_hook(file_fcntl, file, cmd, arg);
304720510f2fSJames Morris }
304820510f2fSJames Morris 
3049a0fd6480SPaul Moore /**
3050a0fd6480SPaul Moore  * security_file_set_fowner() - Set the file owner info in the LSM blob
3051a0fd6480SPaul Moore  * @file: the file
3052a0fd6480SPaul Moore  *
3053a0fd6480SPaul Moore  * Save owner security information (typically from current->security) in
3054a0fd6480SPaul Moore  * file->f_security for later use by the send_sigiotask hook.
3055a0fd6480SPaul Moore  *
305619c9d55dSMickaël Salaün  * This hook is called with file->f_owner.lock held.
305719c9d55dSMickaël Salaün  *
3058a0fd6480SPaul Moore  * Return: Returns 0 on success.
3059a0fd6480SPaul Moore  */
security_file_set_fowner(struct file * file)3060e0b93eddSJeff Layton void security_file_set_fowner(struct file *file)
306120510f2fSJames Morris {
3062f25fce3eSCasey Schaufler 	call_void_hook(file_set_fowner, file);
306320510f2fSJames Morris }
306420510f2fSJames Morris 
3065a0fd6480SPaul Moore /**
3066a0fd6480SPaul Moore  * security_file_send_sigiotask() - Check if sending SIGIO/SIGURG is allowed
3067a0fd6480SPaul Moore  * @tsk: target task
3068a0fd6480SPaul Moore  * @fown: signal sender
3069a0fd6480SPaul Moore  * @sig: signal to be sent, SIGIO is sent if 0
3070a0fd6480SPaul Moore  *
3071a0fd6480SPaul Moore  * Check permission for the file owner @fown to send SIGIO or SIGURG to the
3072a0fd6480SPaul Moore  * process @tsk.  Note that this hook is sometimes called from interrupt.  Note
3073a0fd6480SPaul Moore  * that the fown_struct, @fown, is never outside the context of a struct file,
3074a0fd6480SPaul Moore  * so the file structure (and associated security information) can always be
3075a0fd6480SPaul Moore  * obtained: container_of(fown, struct file, f_owner).
3076a0fd6480SPaul Moore  *
3077a0fd6480SPaul Moore  * Return: Returns 0 if permission is granted.
3078a0fd6480SPaul Moore  */
security_file_send_sigiotask(struct task_struct * tsk,struct fown_struct * fown,int sig)307920510f2fSJames Morris int security_file_send_sigiotask(struct task_struct *tsk,
308020510f2fSJames Morris 				 struct fown_struct *fown, int sig)
308120510f2fSJames Morris {
3082260017f3SOndrej Mosnacek 	return call_int_hook(file_send_sigiotask, tsk, fown, sig);
308320510f2fSJames Morris }
308420510f2fSJames Morris 
3085a0fd6480SPaul Moore /**
3086936615f6SPairman Guo  * security_file_receive() - Check if receiving a file via IPC is allowed
3087a0fd6480SPaul Moore  * @file: file being received
3088a0fd6480SPaul Moore  *
3089a0fd6480SPaul Moore  * This hook allows security modules to control the ability of a process to
3090a0fd6480SPaul Moore  * receive an open file descriptor via socket IPC.
3091a0fd6480SPaul Moore  *
3092a0fd6480SPaul Moore  * Return: Returns 0 if permission is granted.
3093a0fd6480SPaul Moore  */
security_file_receive(struct file * file)309420510f2fSJames Morris int security_file_receive(struct file *file)
309520510f2fSJames Morris {
3096260017f3SOndrej Mosnacek 	return call_int_hook(file_receive, file);
309720510f2fSJames Morris }
309820510f2fSJames Morris 
3099a0fd6480SPaul Moore /**
3100a0fd6480SPaul Moore  * security_file_open() - Save open() time state for late use by the LSM
3101a0fd6480SPaul Moore  * @file:
3102a0fd6480SPaul Moore  *
3103a0fd6480SPaul Moore  * Save open-time permission checking state for later use upon file_permission,
3104a0fd6480SPaul Moore  * and recheck access if anything has changed since inode_permission.
3105a0fd6480SPaul Moore  *
3106a5874fdeSMickaël Salaün  * We can check if a file is opened for execution (e.g. execve(2) call), either
3107a5874fdeSMickaël Salaün  * directly or indirectly (e.g. ELF's ld.so) by checking file->f_flags &
3108a5874fdeSMickaël Salaün  * __FMODE_EXEC .
3109a5874fdeSMickaël Salaün  *
3110a0fd6480SPaul Moore  * Return: Returns 0 if permission is granted.
3111a0fd6480SPaul Moore  */
security_file_open(struct file * file)3112e3f20ae2SAl Viro int security_file_open(struct file *file)
311320510f2fSJames Morris {
31141cda52f1SSong Liu 	return call_int_hook(file_open, file);
311520510f2fSJames Morris }
311620510f2fSJames Morris 
3117a0fd6480SPaul Moore /**
31188f46ff57SRoberto Sassu  * security_file_post_open() - Evaluate a file after it has been opened
31198f46ff57SRoberto Sassu  * @file: the file
31208f46ff57SRoberto Sassu  * @mask: access mask
31218f46ff57SRoberto Sassu  *
31228f46ff57SRoberto Sassu  * Evaluate an opened file and the access mask requested with open(). The hook
31238f46ff57SRoberto Sassu  * is useful for LSMs that require the file content to be available in order to
31248f46ff57SRoberto Sassu  * make decisions.
31258f46ff57SRoberto Sassu  *
31268f46ff57SRoberto Sassu  * Return: Returns 0 if permission is granted.
31278f46ff57SRoberto Sassu  */
security_file_post_open(struct file * file,int mask)31288f46ff57SRoberto Sassu int security_file_post_open(struct file *file, int mask)
31298f46ff57SRoberto Sassu {
3130260017f3SOndrej Mosnacek 	return call_int_hook(file_post_open, file, mask);
31318f46ff57SRoberto Sassu }
31328f46ff57SRoberto Sassu EXPORT_SYMBOL_GPL(security_file_post_open);
31338f46ff57SRoberto Sassu 
31348f46ff57SRoberto Sassu /**
3135a0fd6480SPaul Moore  * security_file_truncate() - Check if truncating a file is allowed
3136a0fd6480SPaul Moore  * @file: file
3137a0fd6480SPaul Moore  *
3138a0fd6480SPaul Moore  * Check permission before truncating a file, i.e. using ftruncate.  Note that
3139a0fd6480SPaul Moore  * truncation permission may also be checked based on the path, using the
3140a0fd6480SPaul Moore  * @path_truncate hook.
3141a0fd6480SPaul Moore  *
3142a0fd6480SPaul Moore  * Return: Returns 0 if permission is granted.
3143a0fd6480SPaul Moore  */
security_file_truncate(struct file * file)31443350607dSGünther Noack int security_file_truncate(struct file *file)
31453350607dSGünther Noack {
3146260017f3SOndrej Mosnacek 	return call_int_hook(file_truncate, file);
31473350607dSGünther Noack }
31483350607dSGünther Noack 
3149130c53bfSPaul Moore /**
3150130c53bfSPaul Moore  * security_task_alloc() - Allocate a task's LSM blob
3151130c53bfSPaul Moore  * @task: the task
3152130c53bfSPaul Moore  * @clone_flags: flags indicating what is being shared
3153130c53bfSPaul Moore  *
3154130c53bfSPaul Moore  * Handle allocation of task-related resources.
3155130c53bfSPaul Moore  *
3156130c53bfSPaul Moore  * Return: Returns a zero on success, negative values on failure.
3157130c53bfSPaul Moore  */
security_task_alloc(struct task_struct * task,unsigned long clone_flags)3158e4e55b47STetsuo Handa int security_task_alloc(struct task_struct *task, unsigned long clone_flags)
3159e4e55b47STetsuo Handa {
3160f4ad8f2cSCasey Schaufler 	int rc = lsm_task_alloc(task);
3161f4ad8f2cSCasey Schaufler 
3162f4ad8f2cSCasey Schaufler 	if (rc)
3163f4ad8f2cSCasey Schaufler 		return rc;
3164260017f3SOndrej Mosnacek 	rc = call_int_hook(task_alloc, task, clone_flags);
3165f4ad8f2cSCasey Schaufler 	if (unlikely(rc))
3166f4ad8f2cSCasey Schaufler 		security_task_free(task);
3167f4ad8f2cSCasey Schaufler 	return rc;
3168e4e55b47STetsuo Handa }
3169e4e55b47STetsuo Handa 
3170130c53bfSPaul Moore /**
3171130c53bfSPaul Moore  * security_task_free() - Free a task's LSM blob and related resources
3172130c53bfSPaul Moore  * @task: task
3173130c53bfSPaul Moore  *
3174130c53bfSPaul Moore  * Handle release of task-related resources.  Note that this can be called from
3175130c53bfSPaul Moore  * interrupt context.
3176130c53bfSPaul Moore  */
security_task_free(struct task_struct * task)31771a2a4d06SKees Cook void security_task_free(struct task_struct *task)
31781a2a4d06SKees Cook {
3179f25fce3eSCasey Schaufler 	call_void_hook(task_free, task);
3180f4ad8f2cSCasey Schaufler 
3181f4ad8f2cSCasey Schaufler 	kfree(task->security);
3182f4ad8f2cSCasey Schaufler 	task->security = NULL;
31831a2a4d06SKees Cook }
31841a2a4d06SKees Cook 
3185130c53bfSPaul Moore /**
3186130c53bfSPaul Moore  * security_cred_alloc_blank() - Allocate the min memory to allow cred_transfer
3187130c53bfSPaul Moore  * @cred: credentials
3188130c53bfSPaul Moore  * @gfp: gfp flags
3189130c53bfSPaul Moore  *
3190130c53bfSPaul Moore  * Only allocate sufficient memory and attach to @cred such that
3191130c53bfSPaul Moore  * cred_transfer() will not get ENOMEM.
3192130c53bfSPaul Moore  *
3193130c53bfSPaul Moore  * Return: Returns 0 on success, negative values on failure.
3194130c53bfSPaul Moore  */
security_cred_alloc_blank(struct cred * cred,gfp_t gfp)3195ee18d64cSDavid Howells int security_cred_alloc_blank(struct cred *cred, gfp_t gfp)
3196ee18d64cSDavid Howells {
3197bbd3662aSCasey Schaufler 	int rc = lsm_cred_alloc(cred, gfp);
3198bbd3662aSCasey Schaufler 
3199bbd3662aSCasey Schaufler 	if (rc)
3200bbd3662aSCasey Schaufler 		return rc;
3201bbd3662aSCasey Schaufler 
3202260017f3SOndrej Mosnacek 	rc = call_int_hook(cred_alloc_blank, cred, gfp);
320333bf60caSCasey Schaufler 	if (unlikely(rc))
3204bbd3662aSCasey Schaufler 		security_cred_free(cred);
3205bbd3662aSCasey Schaufler 	return rc;
3206ee18d64cSDavid Howells }
3207ee18d64cSDavid Howells 
3208130c53bfSPaul Moore /**
3209130c53bfSPaul Moore  * security_cred_free() - Free the cred's LSM blob and associated resources
3210130c53bfSPaul Moore  * @cred: credentials
3211130c53bfSPaul Moore  *
3212130c53bfSPaul Moore  * Deallocate and clear the cred->security field in a set of credentials.
3213130c53bfSPaul Moore  */
security_cred_free(struct cred * cred)3214f1752eecSDavid Howells void security_cred_free(struct cred *cred)
321520510f2fSJames Morris {
3216a5795fd3SJames Morris 	/*
3217a5795fd3SJames Morris 	 * There is a failure case in prepare_creds() that
3218a5795fd3SJames Morris 	 * may result in a call here with ->security being NULL.
3219a5795fd3SJames Morris 	 */
3220a5795fd3SJames Morris 	if (unlikely(cred->security == NULL))
3221a5795fd3SJames Morris 		return;
3222a5795fd3SJames Morris 
3223f25fce3eSCasey Schaufler 	call_void_hook(cred_free, cred);
3224bbd3662aSCasey Schaufler 
3225bbd3662aSCasey Schaufler 	kfree(cred->security);
3226bbd3662aSCasey Schaufler 	cred->security = NULL;
322720510f2fSJames Morris }
322820510f2fSJames Morris 
3229130c53bfSPaul Moore /**
3230130c53bfSPaul Moore  * security_prepare_creds() - Prepare a new set of credentials
3231130c53bfSPaul Moore  * @new: new credentials
3232130c53bfSPaul Moore  * @old: original credentials
3233130c53bfSPaul Moore  * @gfp: gfp flags
3234130c53bfSPaul Moore  *
3235130c53bfSPaul Moore  * Prepare a new set of credentials by copying the data from the old set.
3236130c53bfSPaul Moore  *
3237130c53bfSPaul Moore  * Return: Returns 0 on success, negative values on failure.
3238130c53bfSPaul Moore  */
security_prepare_creds(struct cred * new,const struct cred * old,gfp_t gfp)3239d84f4f99SDavid Howells int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp)
3240d84f4f99SDavid Howells {
3241bbd3662aSCasey Schaufler 	int rc = lsm_cred_alloc(new, gfp);
3242bbd3662aSCasey Schaufler 
3243bbd3662aSCasey Schaufler 	if (rc)
3244bbd3662aSCasey Schaufler 		return rc;
3245bbd3662aSCasey Schaufler 
3246260017f3SOndrej Mosnacek 	rc = call_int_hook(cred_prepare, new, old, gfp);
324733bf60caSCasey Schaufler 	if (unlikely(rc))
3248bbd3662aSCasey Schaufler 		security_cred_free(new);
3249bbd3662aSCasey Schaufler 	return rc;
3250d84f4f99SDavid Howells }
3251d84f4f99SDavid Howells 
3252130c53bfSPaul Moore /**
3253130c53bfSPaul Moore  * security_transfer_creds() - Transfer creds
3254130c53bfSPaul Moore  * @new: target credentials
3255130c53bfSPaul Moore  * @old: original credentials
3256130c53bfSPaul Moore  *
3257130c53bfSPaul Moore  * Transfer data from original creds to new creds.
3258130c53bfSPaul Moore  */
security_transfer_creds(struct cred * new,const struct cred * old)3259ee18d64cSDavid Howells void security_transfer_creds(struct cred *new, const struct cred *old)
3260ee18d64cSDavid Howells {
3261f25fce3eSCasey Schaufler 	call_void_hook(cred_transfer, new, old);
3262ee18d64cSDavid Howells }
3263ee18d64cSDavid Howells 
3264130c53bfSPaul Moore /**
3265130c53bfSPaul Moore  * security_cred_getsecid() - Get the secid from a set of credentials
3266130c53bfSPaul Moore  * @c: credentials
3267130c53bfSPaul Moore  * @secid: secid value
3268130c53bfSPaul Moore  *
3269130c53bfSPaul Moore  * Retrieve the security identifier of the cred structure @c.  In case of
3270130c53bfSPaul Moore  * failure, @secid will be set to zero.
3271130c53bfSPaul Moore  */
security_cred_getsecid(const struct cred * c,u32 * secid)32723ec30113SMatthew Garrett void security_cred_getsecid(const struct cred *c, u32 *secid)
32733ec30113SMatthew Garrett {
32743ec30113SMatthew Garrett 	*secid = 0;
32753ec30113SMatthew Garrett 	call_void_hook(cred_getsecid, c, secid);
32763ec30113SMatthew Garrett }
32773ec30113SMatthew Garrett EXPORT_SYMBOL(security_cred_getsecid);
32783ec30113SMatthew Garrett 
3279130c53bfSPaul Moore /**
3280b0654ca4SCasey Schaufler  * security_cred_getlsmprop() - Get the LSM data from a set of credentials
3281b0654ca4SCasey Schaufler  * @c: credentials
3282b0654ca4SCasey Schaufler  * @prop: destination for the LSM data
3283b0654ca4SCasey Schaufler  *
3284b0654ca4SCasey Schaufler  * Retrieve the security data of the cred structure @c.  In case of
3285b0654ca4SCasey Schaufler  * failure, @prop will be cleared.
3286b0654ca4SCasey Schaufler  */
security_cred_getlsmprop(const struct cred * c,struct lsm_prop * prop)3287b0654ca4SCasey Schaufler void security_cred_getlsmprop(const struct cred *c, struct lsm_prop *prop)
3288b0654ca4SCasey Schaufler {
3289b0654ca4SCasey Schaufler 	lsmprop_init(prop);
3290b0654ca4SCasey Schaufler 	call_void_hook(cred_getlsmprop, c, prop);
3291b0654ca4SCasey Schaufler }
3292b0654ca4SCasey Schaufler EXPORT_SYMBOL(security_cred_getlsmprop);
3293b0654ca4SCasey Schaufler 
3294b0654ca4SCasey Schaufler /**
3295130c53bfSPaul Moore  * security_kernel_act_as() - Set the kernel credentials to act as secid
3296130c53bfSPaul Moore  * @new: credentials
3297130c53bfSPaul Moore  * @secid: secid
3298130c53bfSPaul Moore  *
3299130c53bfSPaul Moore  * Set the credentials for a kernel service to act as (subjective context).
3300130c53bfSPaul Moore  * The current task must be the one that nominated @secid.
3301130c53bfSPaul Moore  *
3302130c53bfSPaul Moore  * Return: Returns 0 if successful.
3303130c53bfSPaul Moore  */
security_kernel_act_as(struct cred * new,u32 secid)33043a3b7ce9SDavid Howells int security_kernel_act_as(struct cred *new, u32 secid)
33053a3b7ce9SDavid Howells {
3306260017f3SOndrej Mosnacek 	return call_int_hook(kernel_act_as, new, secid);
33073a3b7ce9SDavid Howells }
33083a3b7ce9SDavid Howells 
3309130c53bfSPaul Moore /**
3310130c53bfSPaul Moore  * security_kernel_create_files_as() - Set file creation context using an inode
3311130c53bfSPaul Moore  * @new: target credentials
3312130c53bfSPaul Moore  * @inode: reference inode
3313130c53bfSPaul Moore  *
3314130c53bfSPaul Moore  * Set the file creation context in a set of credentials to be the same as the
3315130c53bfSPaul Moore  * objective context of the specified inode.  The current task must be the one
3316130c53bfSPaul Moore  * that nominated @inode.
3317130c53bfSPaul Moore  *
3318130c53bfSPaul Moore  * Return: Returns 0 if successful.
3319130c53bfSPaul Moore  */
security_kernel_create_files_as(struct cred * new,struct inode * inode)33203a3b7ce9SDavid Howells int security_kernel_create_files_as(struct cred *new, struct inode *inode)
33213a3b7ce9SDavid Howells {
3322260017f3SOndrej Mosnacek 	return call_int_hook(kernel_create_files_as, new, inode);
33233a3b7ce9SDavid Howells }
33243a3b7ce9SDavid Howells 
3325130c53bfSPaul Moore /**
3326936615f6SPairman Guo  * security_kernel_module_request() - Check if loading a module is allowed
3327130c53bfSPaul Moore  * @kmod_name: module name
3328130c53bfSPaul Moore  *
3329130c53bfSPaul Moore  * Ability to trigger the kernel to automatically upcall to userspace for
3330130c53bfSPaul Moore  * userspace to load a kernel module with the given name.
3331130c53bfSPaul Moore  *
3332130c53bfSPaul Moore  * Return: Returns 0 if successful.
3333130c53bfSPaul Moore  */
security_kernel_module_request(char * kmod_name)3334dd8dbf2eSEric Paris int security_kernel_module_request(char *kmod_name)
33359188499cSEric Paris {
3336260017f3SOndrej Mosnacek 	return call_int_hook(kernel_module_request, kmod_name);
33379188499cSEric Paris }
33389188499cSEric Paris 
3339130c53bfSPaul Moore /**
3340130c53bfSPaul Moore  * security_kernel_read_file() - Read a file specified by userspace
3341130c53bfSPaul Moore  * @file: file
3342130c53bfSPaul Moore  * @id: file identifier
3343130c53bfSPaul Moore  * @contents: trust if security_kernel_post_read_file() will be called
3344130c53bfSPaul Moore  *
3345130c53bfSPaul Moore  * Read a file specified by userspace.
3346130c53bfSPaul Moore  *
3347130c53bfSPaul Moore  * Return: Returns 0 if permission is granted.
3348130c53bfSPaul Moore  */
security_kernel_read_file(struct file * file,enum kernel_read_file_id id,bool contents)33492039bda1SKees Cook int security_kernel_read_file(struct file *file, enum kernel_read_file_id id,
33502039bda1SKees Cook 			      bool contents)
335139eeb4fbSMimi Zohar {
3352260017f3SOndrej Mosnacek 	return call_int_hook(kernel_read_file, file, id, contents);
335339eeb4fbSMimi Zohar }
335439eeb4fbSMimi Zohar EXPORT_SYMBOL_GPL(security_kernel_read_file);
335539eeb4fbSMimi Zohar 
3356130c53bfSPaul Moore /**
3357130c53bfSPaul Moore  * security_kernel_post_read_file() - Read a file specified by userspace
3358130c53bfSPaul Moore  * @file: file
3359130c53bfSPaul Moore  * @buf: file contents
3360130c53bfSPaul Moore  * @size: size of file contents
3361130c53bfSPaul Moore  * @id: file identifier
3362130c53bfSPaul Moore  *
3363130c53bfSPaul Moore  * Read a file specified by userspace.  This must be paired with a prior call
3364130c53bfSPaul Moore  * to security_kernel_read_file() call that indicated this hook would also be
3365130c53bfSPaul Moore  * called, see security_kernel_read_file() for more information.
3366130c53bfSPaul Moore  *
3367130c53bfSPaul Moore  * Return: Returns 0 if permission is granted.
3368130c53bfSPaul Moore  */
security_kernel_post_read_file(struct file * file,char * buf,loff_t size,enum kernel_read_file_id id)3369bc8ca5b9SMimi Zohar int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
3370bc8ca5b9SMimi Zohar 				   enum kernel_read_file_id id)
3371b44a7dfcSMimi Zohar {
3372260017f3SOndrej Mosnacek 	return call_int_hook(kernel_post_read_file, file, buf, size, id);
3373b44a7dfcSMimi Zohar }
3374b44a7dfcSMimi Zohar EXPORT_SYMBOL_GPL(security_kernel_post_read_file);
3375b44a7dfcSMimi Zohar 
3376130c53bfSPaul Moore /**
3377130c53bfSPaul Moore  * security_kernel_load_data() - Load data provided by userspace
3378130c53bfSPaul Moore  * @id: data identifier
3379130c53bfSPaul Moore  * @contents: true if security_kernel_post_load_data() will be called
3380130c53bfSPaul Moore  *
3381130c53bfSPaul Moore  * Load data provided by userspace.
3382130c53bfSPaul Moore  *
3383130c53bfSPaul Moore  * Return: Returns 0 if permission is granted.
3384130c53bfSPaul Moore  */
security_kernel_load_data(enum kernel_load_data_id id,bool contents)3385b64fcae7SKees Cook int security_kernel_load_data(enum kernel_load_data_id id, bool contents)
3386377179cdSMimi Zohar {
3387260017f3SOndrej Mosnacek 	return call_int_hook(kernel_load_data, id, contents);
3388377179cdSMimi Zohar }
338983a68a06SArnd Bergmann EXPORT_SYMBOL_GPL(security_kernel_load_data);
3390377179cdSMimi Zohar 
3391130c53bfSPaul Moore /**
3392130c53bfSPaul Moore  * security_kernel_post_load_data() - Load userspace data from a non-file source
3393130c53bfSPaul Moore  * @buf: data
3394130c53bfSPaul Moore  * @size: size of data
3395130c53bfSPaul Moore  * @id: data identifier
3396130c53bfSPaul Moore  * @description: text description of data, specific to the id value
3397130c53bfSPaul Moore  *
3398130c53bfSPaul Moore  * Load data provided by a non-file source (usually userspace buffer).  This
3399130c53bfSPaul Moore  * must be paired with a prior security_kernel_load_data() call that indicated
3400130c53bfSPaul Moore  * this hook would also be called, see security_kernel_load_data() for more
3401130c53bfSPaul Moore  * information.
3402130c53bfSPaul Moore  *
3403130c53bfSPaul Moore  * Return: Returns 0 if permission is granted.
3404130c53bfSPaul Moore  */
security_kernel_post_load_data(char * buf,loff_t size,enum kernel_load_data_id id,char * description)3405b64fcae7SKees Cook int security_kernel_post_load_data(char *buf, loff_t size,
3406b64fcae7SKees Cook 				   enum kernel_load_data_id id,
3407b64fcae7SKees Cook 				   char *description)
3408b64fcae7SKees Cook {
3409260017f3SOndrej Mosnacek 	return call_int_hook(kernel_post_load_data, buf, size, id, description);
3410b64fcae7SKees Cook }
3411b64fcae7SKees Cook EXPORT_SYMBOL_GPL(security_kernel_post_load_data);
3412b64fcae7SKees Cook 
3413130c53bfSPaul Moore /**
3414130c53bfSPaul Moore  * security_task_fix_setuid() - Update LSM with new user id attributes
3415130c53bfSPaul Moore  * @new: updated credentials
3416130c53bfSPaul Moore  * @old: credentials being replaced
3417130c53bfSPaul Moore  * @flags: LSM_SETID_* flag values
3418130c53bfSPaul Moore  *
3419130c53bfSPaul Moore  * Update the module's state after setting one or more of the user identity
3420130c53bfSPaul Moore  * attributes of the current process.  The @flags parameter indicates which of
3421130c53bfSPaul Moore  * the set*uid system calls invoked this hook.  If @new is the set of
3422130c53bfSPaul Moore  * credentials that will be installed.  Modifications should be made to this
3423130c53bfSPaul Moore  * rather than to @current->cred.
3424130c53bfSPaul Moore  *
3425130c53bfSPaul Moore  * Return: Returns 0 on success.
3426130c53bfSPaul Moore  */
security_task_fix_setuid(struct cred * new,const struct cred * old,int flags)3427d84f4f99SDavid Howells int security_task_fix_setuid(struct cred *new, const struct cred *old,
3428d84f4f99SDavid Howells 			     int flags)
342920510f2fSJames Morris {
3430260017f3SOndrej Mosnacek 	return call_int_hook(task_fix_setuid, new, old, flags);
343120510f2fSJames Morris }
343220510f2fSJames Morris 
3433130c53bfSPaul Moore /**
3434130c53bfSPaul Moore  * security_task_fix_setgid() - Update LSM with new group id attributes
3435130c53bfSPaul Moore  * @new: updated credentials
3436130c53bfSPaul Moore  * @old: credentials being replaced
3437130c53bfSPaul Moore  * @flags: LSM_SETID_* flag value
3438130c53bfSPaul Moore  *
3439130c53bfSPaul Moore  * Update the module's state after setting one or more of the group identity
3440130c53bfSPaul Moore  * attributes of the current process.  The @flags parameter indicates which of
3441130c53bfSPaul Moore  * the set*gid system calls invoked this hook.  @new is the set of credentials
3442130c53bfSPaul Moore  * that will be installed.  Modifications should be made to this rather than to
3443130c53bfSPaul Moore  * @current->cred.
3444130c53bfSPaul Moore  *
3445130c53bfSPaul Moore  * Return: Returns 0 on success.
3446130c53bfSPaul Moore  */
security_task_fix_setgid(struct cred * new,const struct cred * old,int flags)344739030e13SThomas Cedeno int security_task_fix_setgid(struct cred *new, const struct cred *old,
344839030e13SThomas Cedeno 			     int flags)
344939030e13SThomas Cedeno {
3450260017f3SOndrej Mosnacek 	return call_int_hook(task_fix_setgid, new, old, flags);
345139030e13SThomas Cedeno }
345239030e13SThomas Cedeno 
3453130c53bfSPaul Moore /**
3454130c53bfSPaul Moore  * security_task_fix_setgroups() - Update LSM with new supplementary groups
3455130c53bfSPaul Moore  * @new: updated credentials
3456130c53bfSPaul Moore  * @old: credentials being replaced
3457130c53bfSPaul Moore  *
3458130c53bfSPaul Moore  * Update the module's state after setting the supplementary group identity
3459130c53bfSPaul Moore  * attributes of the current process.  @new is the set of credentials that will
3460130c53bfSPaul Moore  * be installed.  Modifications should be made to this rather than to
3461130c53bfSPaul Moore  * @current->cred.
3462130c53bfSPaul Moore  *
3463130c53bfSPaul Moore  * Return: Returns 0 on success.
3464130c53bfSPaul Moore  */
security_task_fix_setgroups(struct cred * new,const struct cred * old)3465fcfe0ac2SMicah Morton int security_task_fix_setgroups(struct cred *new, const struct cred *old)
3466fcfe0ac2SMicah Morton {
3467260017f3SOndrej Mosnacek 	return call_int_hook(task_fix_setgroups, new, old);
3468fcfe0ac2SMicah Morton }
3469fcfe0ac2SMicah Morton 
3470130c53bfSPaul Moore /**
3471130c53bfSPaul Moore  * security_task_setpgid() - Check if setting the pgid is allowed
3472130c53bfSPaul Moore  * @p: task being modified
3473130c53bfSPaul Moore  * @pgid: new pgid
3474130c53bfSPaul Moore  *
3475130c53bfSPaul Moore  * Check permission before setting the process group identifier of the process
3476130c53bfSPaul Moore  * @p to @pgid.
3477130c53bfSPaul Moore  *
3478130c53bfSPaul Moore  * Return: Returns 0 if permission is granted.
3479130c53bfSPaul Moore  */
security_task_setpgid(struct task_struct * p,pid_t pgid)348020510f2fSJames Morris int security_task_setpgid(struct task_struct *p, pid_t pgid)
348120510f2fSJames Morris {
3482260017f3SOndrej Mosnacek 	return call_int_hook(task_setpgid, p, pgid);
348320510f2fSJames Morris }
348420510f2fSJames Morris 
3485130c53bfSPaul Moore /**
3486130c53bfSPaul Moore  * security_task_getpgid() - Check if getting the pgid is allowed
3487130c53bfSPaul Moore  * @p: task
3488130c53bfSPaul Moore  *
3489130c53bfSPaul Moore  * Check permission before getting the process group identifier of the process
3490130c53bfSPaul Moore  * @p.
3491130c53bfSPaul Moore  *
3492130c53bfSPaul Moore  * Return: Returns 0 if permission is granted.
3493130c53bfSPaul Moore  */
security_task_getpgid(struct task_struct * p)349420510f2fSJames Morris int security_task_getpgid(struct task_struct *p)
349520510f2fSJames Morris {
3496260017f3SOndrej Mosnacek 	return call_int_hook(task_getpgid, p);
349720510f2fSJames Morris }
349820510f2fSJames Morris 
3499130c53bfSPaul Moore /**
3500130c53bfSPaul Moore  * security_task_getsid() - Check if getting the session id is allowed
3501130c53bfSPaul Moore  * @p: task
3502130c53bfSPaul Moore  *
3503130c53bfSPaul Moore  * Check permission before getting the session identifier of the process @p.
3504130c53bfSPaul Moore  *
3505130c53bfSPaul Moore  * Return: Returns 0 if permission is granted.
3506130c53bfSPaul Moore  */
security_task_getsid(struct task_struct * p)350720510f2fSJames Morris int security_task_getsid(struct task_struct *p)
350820510f2fSJames Morris {
3509260017f3SOndrej Mosnacek 	return call_int_hook(task_getsid, p);
351020510f2fSJames Morris }
351120510f2fSJames Morris 
3512130c53bfSPaul Moore /**
351337f670aaSCasey Schaufler  * security_current_getlsmprop_subj() - Current task's subjective LSM data
351437f670aaSCasey Schaufler  * @prop: lsm specific information
3515130c53bfSPaul Moore  *
3516130c53bfSPaul Moore  * Retrieve the subjective security identifier of the current task and return
351737f670aaSCasey Schaufler  * it in @prop.
3518130c53bfSPaul Moore  */
security_current_getlsmprop_subj(struct lsm_prop * prop)351937f670aaSCasey Schaufler void security_current_getlsmprop_subj(struct lsm_prop *prop)
352020510f2fSJames Morris {
352137f670aaSCasey Schaufler 	lsmprop_init(prop);
352237f670aaSCasey Schaufler 	call_void_hook(current_getlsmprop_subj, prop);
352320510f2fSJames Morris }
352437f670aaSCasey Schaufler EXPORT_SYMBOL(security_current_getlsmprop_subj);
35254ebd7651SPaul Moore 
3526130c53bfSPaul Moore /**
352737f670aaSCasey Schaufler  * security_task_getlsmprop_obj() - Get a task's objective LSM data
3528130c53bfSPaul Moore  * @p: target task
352937f670aaSCasey Schaufler  * @prop: lsm specific information
3530130c53bfSPaul Moore  *
3531130c53bfSPaul Moore  * Retrieve the objective security identifier of the task_struct in @p and
353237f670aaSCasey Schaufler  * return it in @prop.
3533130c53bfSPaul Moore  */
security_task_getlsmprop_obj(struct task_struct * p,struct lsm_prop * prop)353437f670aaSCasey Schaufler void security_task_getlsmprop_obj(struct task_struct *p, struct lsm_prop *prop)
35354ebd7651SPaul Moore {
353637f670aaSCasey Schaufler 	lsmprop_init(prop);
353737f670aaSCasey Schaufler 	call_void_hook(task_getlsmprop_obj, p, prop);
35384ebd7651SPaul Moore }
353937f670aaSCasey Schaufler EXPORT_SYMBOL(security_task_getlsmprop_obj);
354020510f2fSJames Morris 
3541130c53bfSPaul Moore /**
3542130c53bfSPaul Moore  * security_task_setnice() - Check if setting a task's nice value is allowed
3543130c53bfSPaul Moore  * @p: target task
3544130c53bfSPaul Moore  * @nice: nice value
3545130c53bfSPaul Moore  *
3546130c53bfSPaul Moore  * Check permission before setting the nice value of @p to @nice.
3547130c53bfSPaul Moore  *
3548130c53bfSPaul Moore  * Return: Returns 0 if permission is granted.
3549130c53bfSPaul Moore  */
security_task_setnice(struct task_struct * p,int nice)355020510f2fSJames Morris int security_task_setnice(struct task_struct *p, int nice)
355120510f2fSJames Morris {
3552260017f3SOndrej Mosnacek 	return call_int_hook(task_setnice, p, nice);
355320510f2fSJames Morris }
355420510f2fSJames Morris 
3555130c53bfSPaul Moore /**
3556130c53bfSPaul Moore  * security_task_setioprio() - Check if setting a task's ioprio is allowed
3557130c53bfSPaul Moore  * @p: target task
3558130c53bfSPaul Moore  * @ioprio: ioprio value
3559130c53bfSPaul Moore  *
3560130c53bfSPaul Moore  * Check permission before setting the ioprio value of @p to @ioprio.
3561130c53bfSPaul Moore  *
3562130c53bfSPaul Moore  * Return: Returns 0 if permission is granted.
3563130c53bfSPaul Moore  */
security_task_setioprio(struct task_struct * p,int ioprio)356420510f2fSJames Morris int security_task_setioprio(struct task_struct *p, int ioprio)
356520510f2fSJames Morris {
3566260017f3SOndrej Mosnacek 	return call_int_hook(task_setioprio, p, ioprio);
356720510f2fSJames Morris }
356820510f2fSJames Morris 
3569130c53bfSPaul Moore /**
3570130c53bfSPaul Moore  * security_task_getioprio() - Check if getting a task's ioprio is allowed
3571130c53bfSPaul Moore  * @p: task
3572130c53bfSPaul Moore  *
3573130c53bfSPaul Moore  * Check permission before getting the ioprio value of @p.
3574130c53bfSPaul Moore  *
3575130c53bfSPaul Moore  * Return: Returns 0 if permission is granted.
3576130c53bfSPaul Moore  */
security_task_getioprio(struct task_struct * p)357720510f2fSJames Morris int security_task_getioprio(struct task_struct *p)
357820510f2fSJames Morris {
3579260017f3SOndrej Mosnacek 	return call_int_hook(task_getioprio, p);
358020510f2fSJames Morris }
358120510f2fSJames Morris 
3582130c53bfSPaul Moore /**
3583130c53bfSPaul Moore  * security_task_prlimit() - Check if get/setting resources limits is allowed
3584130c53bfSPaul Moore  * @cred: current task credentials
3585130c53bfSPaul Moore  * @tcred: target task credentials
3586130c53bfSPaul Moore  * @flags: LSM_PRLIMIT_* flag bits indicating a get/set/both
3587130c53bfSPaul Moore  *
3588130c53bfSPaul Moore  * Check permission before getting and/or setting the resource limits of
3589130c53bfSPaul Moore  * another task.
3590130c53bfSPaul Moore  *
3591130c53bfSPaul Moore  * Return: Returns 0 if permission is granted.
3592130c53bfSPaul Moore  */
security_task_prlimit(const struct cred * cred,const struct cred * tcred,unsigned int flags)3593791ec491SStephen Smalley int security_task_prlimit(const struct cred *cred, const struct cred *tcred,
3594791ec491SStephen Smalley 			  unsigned int flags)
3595791ec491SStephen Smalley {
3596260017f3SOndrej Mosnacek 	return call_int_hook(task_prlimit, cred, tcred, flags);
3597791ec491SStephen Smalley }
3598791ec491SStephen Smalley 
3599130c53bfSPaul Moore /**
3600130c53bfSPaul Moore  * security_task_setrlimit() - Check if setting a new rlimit value is allowed
3601130c53bfSPaul Moore  * @p: target task's group leader
3602130c53bfSPaul Moore  * @resource: resource whose limit is being set
3603130c53bfSPaul Moore  * @new_rlim: new resource limit
3604130c53bfSPaul Moore  *
3605130c53bfSPaul Moore  * Check permission before setting the resource limits of process @p for
3606130c53bfSPaul Moore  * @resource to @new_rlim.  The old resource limit values can be examined by
3607130c53bfSPaul Moore  * dereferencing (p->signal->rlim + resource).
3608130c53bfSPaul Moore  *
3609130c53bfSPaul Moore  * Return: Returns 0 if permission is granted.
3610130c53bfSPaul Moore  */
security_task_setrlimit(struct task_struct * p,unsigned int resource,struct rlimit * new_rlim)36118fd00b4dSJiri Slaby int security_task_setrlimit(struct task_struct *p, unsigned int resource,
36128fd00b4dSJiri Slaby 			    struct rlimit *new_rlim)
361320510f2fSJames Morris {
3614260017f3SOndrej Mosnacek 	return call_int_hook(task_setrlimit, p, resource, new_rlim);
361520510f2fSJames Morris }
361620510f2fSJames Morris 
3617130c53bfSPaul Moore /**
3618130c53bfSPaul Moore  * security_task_setscheduler() - Check if setting sched policy/param is allowed
3619130c53bfSPaul Moore  * @p: target task
3620130c53bfSPaul Moore  *
3621130c53bfSPaul Moore  * Check permission before setting scheduling policy and/or parameters of
3622130c53bfSPaul Moore  * process @p.
3623130c53bfSPaul Moore  *
3624130c53bfSPaul Moore  * Return: Returns 0 if permission is granted.
3625130c53bfSPaul Moore  */
security_task_setscheduler(struct task_struct * p)3626b0ae1981SKOSAKI Motohiro int security_task_setscheduler(struct task_struct *p)
362720510f2fSJames Morris {
3628260017f3SOndrej Mosnacek 	return call_int_hook(task_setscheduler, p);
362920510f2fSJames Morris }
363020510f2fSJames Morris 
3631130c53bfSPaul Moore /**
3632130c53bfSPaul Moore  * security_task_getscheduler() - Check if getting scheduling info is allowed
3633130c53bfSPaul Moore  * @p: target task
3634130c53bfSPaul Moore  *
3635130c53bfSPaul Moore  * Check permission before obtaining scheduling information for process @p.
3636130c53bfSPaul Moore  *
3637130c53bfSPaul Moore  * Return: Returns 0 if permission is granted.
3638130c53bfSPaul Moore  */
security_task_getscheduler(struct task_struct * p)363920510f2fSJames Morris int security_task_getscheduler(struct task_struct *p)
364020510f2fSJames Morris {
3641260017f3SOndrej Mosnacek 	return call_int_hook(task_getscheduler, p);
364220510f2fSJames Morris }
364320510f2fSJames Morris 
3644130c53bfSPaul Moore /**
3645130c53bfSPaul Moore  * security_task_movememory() - Check if moving memory is allowed
3646130c53bfSPaul Moore  * @p: task
3647130c53bfSPaul Moore  *
3648130c53bfSPaul Moore  * Check permission before moving memory owned by process @p.
3649130c53bfSPaul Moore  *
3650130c53bfSPaul Moore  * Return: Returns 0 if permission is granted.
3651130c53bfSPaul Moore  */
security_task_movememory(struct task_struct * p)365220510f2fSJames Morris int security_task_movememory(struct task_struct *p)
365320510f2fSJames Morris {
3654260017f3SOndrej Mosnacek 	return call_int_hook(task_movememory, p);
365520510f2fSJames Morris }
365620510f2fSJames Morris 
3657130c53bfSPaul Moore /**
3658130c53bfSPaul Moore  * security_task_kill() - Check if sending a signal is allowed
3659130c53bfSPaul Moore  * @p: target process
3660130c53bfSPaul Moore  * @info: signal information
3661130c53bfSPaul Moore  * @sig: signal value
3662130c53bfSPaul Moore  * @cred: credentials of the signal sender, NULL if @current
3663130c53bfSPaul Moore  *
3664130c53bfSPaul Moore  * Check permission before sending signal @sig to @p.  @info can be NULL, the
3665130c53bfSPaul Moore  * constant 1, or a pointer to a kernel_siginfo structure.  If @info is 1 or
3666130c53bfSPaul Moore  * SI_FROMKERNEL(info) is true, then the signal should be viewed as coming from
3667130c53bfSPaul Moore  * the kernel and should typically be permitted.  SIGIO signals are handled
3668130c53bfSPaul Moore  * separately by the send_sigiotask hook in file_security_ops.
3669130c53bfSPaul Moore  *
3670130c53bfSPaul Moore  * Return: Returns 0 if permission is granted.
3671130c53bfSPaul Moore  */
security_task_kill(struct task_struct * p,struct kernel_siginfo * info,int sig,const struct cred * cred)3672ae7795bcSEric W. Biederman int security_task_kill(struct task_struct *p, struct kernel_siginfo *info,
36736b4f3d01SStephen Smalley 		       int sig, const struct cred *cred)
367420510f2fSJames Morris {
3675260017f3SOndrej Mosnacek 	return call_int_hook(task_kill, p, info, sig, cred);
367620510f2fSJames Morris }
367720510f2fSJames Morris 
3678130c53bfSPaul Moore /**
3679130c53bfSPaul Moore  * security_task_prctl() - Check if a prctl op is allowed
3680130c53bfSPaul Moore  * @option: operation
3681130c53bfSPaul Moore  * @arg2: argument
3682130c53bfSPaul Moore  * @arg3: argument
3683130c53bfSPaul Moore  * @arg4: argument
3684130c53bfSPaul Moore  * @arg5: argument
3685130c53bfSPaul Moore  *
3686130c53bfSPaul Moore  * Check permission before performing a process control operation on the
3687130c53bfSPaul Moore  * current process.
3688130c53bfSPaul Moore  *
3689130c53bfSPaul Moore  * Return: Return -ENOSYS if no-one wanted to handle this op, any other value
3690130c53bfSPaul Moore  *         to cause prctl() to return immediately with that value.
3691130c53bfSPaul Moore  */
security_task_prctl(int option,unsigned long arg2,unsigned long arg3,unsigned long arg4,unsigned long arg5)369220510f2fSJames Morris int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
3693d84f4f99SDavid Howells 			unsigned long arg4, unsigned long arg5)
369420510f2fSJames Morris {
3695b1d9e6b0SCasey Schaufler 	int thisrc;
369698e828a0SKP Singh 	int rc = LSM_RET_DEFAULT(task_prctl);
3697417c5643SKP Singh 	struct lsm_static_call *scall;
3698b1d9e6b0SCasey Schaufler 
3699417c5643SKP Singh 	lsm_for_each_hook(scall, task_prctl) {
3700417c5643SKP Singh 		thisrc = scall->hl->hook.task_prctl(option, arg2, arg3, arg4, arg5);
370198e828a0SKP Singh 		if (thisrc != LSM_RET_DEFAULT(task_prctl)) {
3702b1d9e6b0SCasey Schaufler 			rc = thisrc;
3703b1d9e6b0SCasey Schaufler 			if (thisrc != 0)
3704b1d9e6b0SCasey Schaufler 				break;
3705b1d9e6b0SCasey Schaufler 		}
3706b1d9e6b0SCasey Schaufler 	}
3707c6993e4aSKees Cook 	return rc;
370820510f2fSJames Morris }
370920510f2fSJames Morris 
3710130c53bfSPaul Moore /**
3711130c53bfSPaul Moore  * security_task_to_inode() - Set the security attributes of a task's inode
3712130c53bfSPaul Moore  * @p: task
3713130c53bfSPaul Moore  * @inode: inode
3714130c53bfSPaul Moore  *
3715130c53bfSPaul Moore  * Set the security attributes for an inode based on an associated task's
3716130c53bfSPaul Moore  * security attributes, e.g. for /proc/pid inodes.
3717130c53bfSPaul Moore  */
security_task_to_inode(struct task_struct * p,struct inode * inode)371820510f2fSJames Morris void security_task_to_inode(struct task_struct *p, struct inode *inode)
371920510f2fSJames Morris {
3720f25fce3eSCasey Schaufler 	call_void_hook(task_to_inode, p, inode);
372120510f2fSJames Morris }
372220510f2fSJames Morris 
3723130c53bfSPaul Moore /**
3724130c53bfSPaul Moore  * security_create_user_ns() - Check if creating a new userns is allowed
3725130c53bfSPaul Moore  * @cred: prepared creds
3726130c53bfSPaul Moore  *
3727130c53bfSPaul Moore  * Check permission prior to creating a new user namespace.
3728130c53bfSPaul Moore  *
3729130c53bfSPaul Moore  * Return: Returns 0 if successful, otherwise < 0 error code.
3730130c53bfSPaul Moore  */
security_create_user_ns(const struct cred * cred)37317cd4c5c2SFrederick Lawler int security_create_user_ns(const struct cred *cred)
37327cd4c5c2SFrederick Lawler {
3733260017f3SOndrej Mosnacek 	return call_int_hook(userns_create, cred);
37347cd4c5c2SFrederick Lawler }
37357cd4c5c2SFrederick Lawler 
373643fad282SPaul Moore /**
373743fad282SPaul Moore  * security_ipc_permission() - Check if sysv ipc access is allowed
373843fad282SPaul Moore  * @ipcp: ipc permission structure
37391e2523d7SPaul Moore  * @flag: requested permissions
374043fad282SPaul Moore  *
374143fad282SPaul Moore  * Check permissions for access to IPC.
374243fad282SPaul Moore  *
374343fad282SPaul Moore  * Return: Returns 0 if permission is granted.
374443fad282SPaul Moore  */
security_ipc_permission(struct kern_ipc_perm * ipcp,short flag)374520510f2fSJames Morris int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
374620510f2fSJames Morris {
3747260017f3SOndrej Mosnacek 	return call_int_hook(ipc_permission, ipcp, flag);
374820510f2fSJames Morris }
374920510f2fSJames Morris 
375043fad282SPaul Moore /**
3751f4602f16SCasey Schaufler  * security_ipc_getlsmprop() - Get the sysv ipc object LSM data
375243fad282SPaul Moore  * @ipcp: ipc permission structure
3753f4602f16SCasey Schaufler  * @prop: pointer to lsm information
375443fad282SPaul Moore  *
3755f4602f16SCasey Schaufler  * Get the lsm information associated with the ipc object.
375643fad282SPaul Moore  */
3757f4602f16SCasey Schaufler 
security_ipc_getlsmprop(struct kern_ipc_perm * ipcp,struct lsm_prop * prop)3758f4602f16SCasey Schaufler void security_ipc_getlsmprop(struct kern_ipc_perm *ipcp, struct lsm_prop *prop)
37598a076191SAhmed S. Darwish {
3760f4602f16SCasey Schaufler 	lsmprop_init(prop);
3761f4602f16SCasey Schaufler 	call_void_hook(ipc_getlsmprop, ipcp, prop);
37628a076191SAhmed S. Darwish }
37638a076191SAhmed S. Darwish 
376443fad282SPaul Moore /**
376543fad282SPaul Moore  * security_msg_msg_alloc() - Allocate a sysv ipc message LSM blob
376643fad282SPaul Moore  * @msg: message structure
376743fad282SPaul Moore  *
376843fad282SPaul Moore  * Allocate and attach a security structure to the msg->security field.  The
376943fad282SPaul Moore  * security field is initialized to NULL when the structure is first created.
377043fad282SPaul Moore  *
377143fad282SPaul Moore  * Return: Return 0 if operation was successful and permission is granted.
377243fad282SPaul Moore  */
security_msg_msg_alloc(struct msg_msg * msg)377320510f2fSJames Morris int security_msg_msg_alloc(struct msg_msg *msg)
377420510f2fSJames Morris {
3775ecd5f82eSCasey Schaufler 	int rc = lsm_msg_msg_alloc(msg);
3776ecd5f82eSCasey Schaufler 
3777ecd5f82eSCasey Schaufler 	if (unlikely(rc))
3778ecd5f82eSCasey Schaufler 		return rc;
3779260017f3SOndrej Mosnacek 	rc = call_int_hook(msg_msg_alloc_security, msg);
3780ecd5f82eSCasey Schaufler 	if (unlikely(rc))
3781ecd5f82eSCasey Schaufler 		security_msg_msg_free(msg);
3782ecd5f82eSCasey Schaufler 	return rc;
378320510f2fSJames Morris }
378420510f2fSJames Morris 
378543fad282SPaul Moore /**
378643fad282SPaul Moore  * security_msg_msg_free() - Free a sysv ipc message LSM blob
378743fad282SPaul Moore  * @msg: message structure
378843fad282SPaul Moore  *
378943fad282SPaul Moore  * Deallocate the security structure for this message.
379043fad282SPaul Moore  */
security_msg_msg_free(struct msg_msg * msg)379120510f2fSJames Morris void security_msg_msg_free(struct msg_msg *msg)
379220510f2fSJames Morris {
3793f25fce3eSCasey Schaufler 	call_void_hook(msg_msg_free_security, msg);
3794ecd5f82eSCasey Schaufler 	kfree(msg->security);
3795ecd5f82eSCasey Schaufler 	msg->security = NULL;
379620510f2fSJames Morris }
379720510f2fSJames Morris 
379843fad282SPaul Moore /**
379943fad282SPaul Moore  * security_msg_queue_alloc() - Allocate a sysv ipc msg queue LSM blob
380043fad282SPaul Moore  * @msq: sysv ipc permission structure
380143fad282SPaul Moore  *
380243fad282SPaul Moore  * Allocate and attach a security structure to @msg. The security field is
380343fad282SPaul Moore  * initialized to NULL when the structure is first created.
380443fad282SPaul Moore  *
380543fad282SPaul Moore  * Return: Returns 0 if operation was successful and permission is granted.
380643fad282SPaul Moore  */
security_msg_queue_alloc(struct kern_ipc_perm * msq)3807d8c6e854SEric W. Biederman int security_msg_queue_alloc(struct kern_ipc_perm *msq)
380820510f2fSJames Morris {
3809ecd5f82eSCasey Schaufler 	int rc = lsm_ipc_alloc(msq);
3810ecd5f82eSCasey Schaufler 
3811ecd5f82eSCasey Schaufler 	if (unlikely(rc))
3812ecd5f82eSCasey Schaufler 		return rc;
3813260017f3SOndrej Mosnacek 	rc = call_int_hook(msg_queue_alloc_security, msq);
3814ecd5f82eSCasey Schaufler 	if (unlikely(rc))
3815ecd5f82eSCasey Schaufler 		security_msg_queue_free(msq);
3816ecd5f82eSCasey Schaufler 	return rc;
381720510f2fSJames Morris }
381820510f2fSJames Morris 
381943fad282SPaul Moore /**
382043fad282SPaul Moore  * security_msg_queue_free() - Free a sysv ipc msg queue LSM blob
382143fad282SPaul Moore  * @msq: sysv ipc permission structure
382243fad282SPaul Moore  *
382343fad282SPaul Moore  * Deallocate security field @perm->security for the message queue.
382443fad282SPaul Moore  */
security_msg_queue_free(struct kern_ipc_perm * msq)3825d8c6e854SEric W. Biederman void security_msg_queue_free(struct kern_ipc_perm *msq)
382620510f2fSJames Morris {
3827f25fce3eSCasey Schaufler 	call_void_hook(msg_queue_free_security, msq);
3828ecd5f82eSCasey Schaufler 	kfree(msq->security);
3829ecd5f82eSCasey Schaufler 	msq->security = NULL;
383020510f2fSJames Morris }
383120510f2fSJames Morris 
383243fad282SPaul Moore /**
383343fad282SPaul Moore  * security_msg_queue_associate() - Check if a msg queue operation is allowed
383443fad282SPaul Moore  * @msq: sysv ipc permission structure
383543fad282SPaul Moore  * @msqflg: operation flags
383643fad282SPaul Moore  *
383743fad282SPaul Moore  * Check permission when a message queue is requested through the msgget system
383843fad282SPaul Moore  * call. This hook is only called when returning the message queue identifier
383943fad282SPaul Moore  * for an existing message queue, not when a new message queue is created.
384043fad282SPaul Moore  *
384143fad282SPaul Moore  * Return: Return 0 if permission is granted.
384243fad282SPaul Moore  */
security_msg_queue_associate(struct kern_ipc_perm * msq,int msqflg)3843d8c6e854SEric W. Biederman int security_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg)
384420510f2fSJames Morris {
3845260017f3SOndrej Mosnacek 	return call_int_hook(msg_queue_associate, msq, msqflg);
384620510f2fSJames Morris }
384720510f2fSJames Morris 
384843fad282SPaul Moore /**
384943fad282SPaul Moore  * security_msg_queue_msgctl() - Check if a msg queue operation is allowed
385043fad282SPaul Moore  * @msq: sysv ipc permission structure
385143fad282SPaul Moore  * @cmd: operation
385243fad282SPaul Moore  *
385343fad282SPaul Moore  * Check permission when a message control operation specified by @cmd is to be
385443fad282SPaul Moore  * performed on the message queue with permissions.
385543fad282SPaul Moore  *
385643fad282SPaul Moore  * Return: Returns 0 if permission is granted.
385743fad282SPaul Moore  */
security_msg_queue_msgctl(struct kern_ipc_perm * msq,int cmd)3858d8c6e854SEric W. Biederman int security_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd)
385920510f2fSJames Morris {
3860260017f3SOndrej Mosnacek 	return call_int_hook(msg_queue_msgctl, msq, cmd);
386120510f2fSJames Morris }
386220510f2fSJames Morris 
386343fad282SPaul Moore /**
386443fad282SPaul Moore  * security_msg_queue_msgsnd() - Check if sending a sysv ipc message is allowed
386543fad282SPaul Moore  * @msq: sysv ipc permission structure
386643fad282SPaul Moore  * @msg: message
386743fad282SPaul Moore  * @msqflg: operation flags
386843fad282SPaul Moore  *
386943fad282SPaul Moore  * Check permission before a message, @msg, is enqueued on the message queue
387043fad282SPaul Moore  * with permissions specified in @msq.
387143fad282SPaul Moore  *
387243fad282SPaul Moore  * Return: Returns 0 if permission is granted.
387343fad282SPaul Moore  */
security_msg_queue_msgsnd(struct kern_ipc_perm * msq,struct msg_msg * msg,int msqflg)3874d8c6e854SEric W. Biederman int security_msg_queue_msgsnd(struct kern_ipc_perm *msq,
387520510f2fSJames Morris 			      struct msg_msg *msg, int msqflg)
387620510f2fSJames Morris {
3877260017f3SOndrej Mosnacek 	return call_int_hook(msg_queue_msgsnd, msq, msg, msqflg);
387820510f2fSJames Morris }
387920510f2fSJames Morris 
388043fad282SPaul Moore /**
388143fad282SPaul Moore  * security_msg_queue_msgrcv() - Check if receiving a sysv ipc msg is allowed
388243fad282SPaul Moore  * @msq: sysv ipc permission structure
388343fad282SPaul Moore  * @msg: message
388443fad282SPaul Moore  * @target: target task
388543fad282SPaul Moore  * @type: type of message requested
388643fad282SPaul Moore  * @mode: operation flags
388743fad282SPaul Moore  *
388843fad282SPaul Moore  * Check permission before a message, @msg, is removed from the message	queue.
388943fad282SPaul Moore  * The @target task structure contains a pointer to the process that will be
389043fad282SPaul Moore  * receiving the message (not equal to the current process when inline receives
389143fad282SPaul Moore  * are being performed).
389243fad282SPaul Moore  *
389343fad282SPaul Moore  * Return: Returns 0 if permission is granted.
389443fad282SPaul Moore  */
security_msg_queue_msgrcv(struct kern_ipc_perm * msq,struct msg_msg * msg,struct task_struct * target,long type,int mode)3895d8c6e854SEric W. Biederman int security_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg,
389620510f2fSJames Morris 			      struct task_struct *target, long type, int mode)
389720510f2fSJames Morris {
3898260017f3SOndrej Mosnacek 	return call_int_hook(msg_queue_msgrcv, msq, msg, target, type, mode);
389920510f2fSJames Morris }
390020510f2fSJames Morris 
390143fad282SPaul Moore /**
390243fad282SPaul Moore  * security_shm_alloc() - Allocate a sysv shm LSM blob
390343fad282SPaul Moore  * @shp: sysv ipc permission structure
390443fad282SPaul Moore  *
390543fad282SPaul Moore  * Allocate and attach a security structure to the @shp security field.  The
390643fad282SPaul Moore  * security field is initialized to NULL when the structure is first created.
390743fad282SPaul Moore  *
390843fad282SPaul Moore  * Return: Returns 0 if operation was successful and permission is granted.
390943fad282SPaul Moore  */
security_shm_alloc(struct kern_ipc_perm * shp)39107191adffSEric W. Biederman int security_shm_alloc(struct kern_ipc_perm *shp)
391120510f2fSJames Morris {
3912ecd5f82eSCasey Schaufler 	int rc = lsm_ipc_alloc(shp);
3913ecd5f82eSCasey Schaufler 
3914ecd5f82eSCasey Schaufler 	if (unlikely(rc))
3915ecd5f82eSCasey Schaufler 		return rc;
3916260017f3SOndrej Mosnacek 	rc = call_int_hook(shm_alloc_security, shp);
3917ecd5f82eSCasey Schaufler 	if (unlikely(rc))
3918ecd5f82eSCasey Schaufler 		security_shm_free(shp);
3919ecd5f82eSCasey Schaufler 	return rc;
392020510f2fSJames Morris }
392120510f2fSJames Morris 
392243fad282SPaul Moore /**
392343fad282SPaul Moore  * security_shm_free() - Free a sysv shm LSM blob
392443fad282SPaul Moore  * @shp: sysv ipc permission structure
392543fad282SPaul Moore  *
392643fad282SPaul Moore  * Deallocate the security structure @perm->security for the memory segment.
392743fad282SPaul Moore  */
security_shm_free(struct kern_ipc_perm * shp)39287191adffSEric W. Biederman void security_shm_free(struct kern_ipc_perm *shp)
392920510f2fSJames Morris {
3930f25fce3eSCasey Schaufler 	call_void_hook(shm_free_security, shp);
3931ecd5f82eSCasey Schaufler 	kfree(shp->security);
3932ecd5f82eSCasey Schaufler 	shp->security = NULL;
393320510f2fSJames Morris }
393420510f2fSJames Morris 
393543fad282SPaul Moore /**
393643fad282SPaul Moore  * security_shm_associate() - Check if a sysv shm operation is allowed
393743fad282SPaul Moore  * @shp: sysv ipc permission structure
393843fad282SPaul Moore  * @shmflg: operation flags
393943fad282SPaul Moore  *
394043fad282SPaul Moore  * Check permission when a shared memory region is requested through the shmget
394143fad282SPaul Moore  * system call. This hook is only called when returning the shared memory
394243fad282SPaul Moore  * region identifier for an existing region, not when a new shared memory
394343fad282SPaul Moore  * region is created.
394443fad282SPaul Moore  *
394543fad282SPaul Moore  * Return: Returns 0 if permission is granted.
394643fad282SPaul Moore  */
security_shm_associate(struct kern_ipc_perm * shp,int shmflg)39477191adffSEric W. Biederman int security_shm_associate(struct kern_ipc_perm *shp, int shmflg)
394820510f2fSJames Morris {
3949260017f3SOndrej Mosnacek 	return call_int_hook(shm_associate, shp, shmflg);
395020510f2fSJames Morris }
395120510f2fSJames Morris 
395243fad282SPaul Moore /**
395343fad282SPaul Moore  * security_shm_shmctl() - Check if a sysv shm operation is allowed
395443fad282SPaul Moore  * @shp: sysv ipc permission structure
395543fad282SPaul Moore  * @cmd: operation
395643fad282SPaul Moore  *
395743fad282SPaul Moore  * Check permission when a shared memory control operation specified by @cmd is
395843fad282SPaul Moore  * to be performed on the shared memory region with permissions in @shp.
395943fad282SPaul Moore  *
396043fad282SPaul Moore  * Return: Return 0 if permission is granted.
396143fad282SPaul Moore  */
security_shm_shmctl(struct kern_ipc_perm * shp,int cmd)39627191adffSEric W. Biederman int security_shm_shmctl(struct kern_ipc_perm *shp, int cmd)
396320510f2fSJames Morris {
3964260017f3SOndrej Mosnacek 	return call_int_hook(shm_shmctl, shp, cmd);
396520510f2fSJames Morris }
396620510f2fSJames Morris 
396743fad282SPaul Moore /**
396843fad282SPaul Moore  * security_shm_shmat() - Check if a sysv shm attach operation is allowed
396943fad282SPaul Moore  * @shp: sysv ipc permission structure
397043fad282SPaul Moore  * @shmaddr: address of memory region to attach
397143fad282SPaul Moore  * @shmflg: operation flags
397243fad282SPaul Moore  *
397343fad282SPaul Moore  * Check permissions prior to allowing the shmat system call to attach the
397443fad282SPaul Moore  * shared memory segment with permissions @shp to the data segment of the
397543fad282SPaul Moore  * calling process. The attaching address is specified by @shmaddr.
397643fad282SPaul Moore  *
397743fad282SPaul Moore  * Return: Returns 0 if permission is granted.
397843fad282SPaul Moore  */
security_shm_shmat(struct kern_ipc_perm * shp,char __user * shmaddr,int shmflg)397963c1845bSPaul Moore int security_shm_shmat(struct kern_ipc_perm *shp,
398063c1845bSPaul Moore 		       char __user *shmaddr, int shmflg)
398120510f2fSJames Morris {
3982260017f3SOndrej Mosnacek 	return call_int_hook(shm_shmat, shp, shmaddr, shmflg);
398320510f2fSJames Morris }
398420510f2fSJames Morris 
398543fad282SPaul Moore /**
398643fad282SPaul Moore  * security_sem_alloc() - Allocate a sysv semaphore LSM blob
398743fad282SPaul Moore  * @sma: sysv ipc permission structure
398843fad282SPaul Moore  *
398943fad282SPaul Moore  * Allocate and attach a security structure to the @sma security field. The
399043fad282SPaul Moore  * security field is initialized to NULL when the structure is first created.
399143fad282SPaul Moore  *
399243fad282SPaul Moore  * Return: Returns 0 if operation was successful and permission is granted.
399343fad282SPaul Moore  */
security_sem_alloc(struct kern_ipc_perm * sma)3994aefad959SEric W. Biederman int security_sem_alloc(struct kern_ipc_perm *sma)
399520510f2fSJames Morris {
3996ecd5f82eSCasey Schaufler 	int rc = lsm_ipc_alloc(sma);
3997ecd5f82eSCasey Schaufler 
3998ecd5f82eSCasey Schaufler 	if (unlikely(rc))
3999ecd5f82eSCasey Schaufler 		return rc;
4000260017f3SOndrej Mosnacek 	rc = call_int_hook(sem_alloc_security, sma);
4001ecd5f82eSCasey Schaufler 	if (unlikely(rc))
4002ecd5f82eSCasey Schaufler 		security_sem_free(sma);
4003ecd5f82eSCasey Schaufler 	return rc;
400420510f2fSJames Morris }
400520510f2fSJames Morris 
400643fad282SPaul Moore /**
400743fad282SPaul Moore  * security_sem_free() - Free a sysv semaphore LSM blob
400843fad282SPaul Moore  * @sma: sysv ipc permission structure
400943fad282SPaul Moore  *
401043fad282SPaul Moore  * Deallocate security structure @sma->security for the semaphore.
401143fad282SPaul Moore  */
security_sem_free(struct kern_ipc_perm * sma)4012aefad959SEric W. Biederman void security_sem_free(struct kern_ipc_perm *sma)
401320510f2fSJames Morris {
4014f25fce3eSCasey Schaufler 	call_void_hook(sem_free_security, sma);
4015ecd5f82eSCasey Schaufler 	kfree(sma->security);
4016ecd5f82eSCasey Schaufler 	sma->security = NULL;
401720510f2fSJames Morris }
401820510f2fSJames Morris 
401943fad282SPaul Moore /**
402043fad282SPaul Moore  * security_sem_associate() - Check if a sysv semaphore operation is allowed
402143fad282SPaul Moore  * @sma: sysv ipc permission structure
402243fad282SPaul Moore  * @semflg: operation flags
402343fad282SPaul Moore  *
402443fad282SPaul Moore  * Check permission when a semaphore is requested through the semget system
402543fad282SPaul Moore  * call. This hook is only called when returning the semaphore identifier for
402643fad282SPaul Moore  * an existing semaphore, not when a new one must be created.
402743fad282SPaul Moore  *
402843fad282SPaul Moore  * Return: Returns 0 if permission is granted.
402943fad282SPaul Moore  */
security_sem_associate(struct kern_ipc_perm * sma,int semflg)4030aefad959SEric W. Biederman int security_sem_associate(struct kern_ipc_perm *sma, int semflg)
403120510f2fSJames Morris {
4032260017f3SOndrej Mosnacek 	return call_int_hook(sem_associate, sma, semflg);
403320510f2fSJames Morris }
403420510f2fSJames Morris 
403543fad282SPaul Moore /**
40361e2523d7SPaul Moore  * security_sem_semctl() - Check if a sysv semaphore operation is allowed
403743fad282SPaul Moore  * @sma: sysv ipc permission structure
403843fad282SPaul Moore  * @cmd: operation
403943fad282SPaul Moore  *
404043fad282SPaul Moore  * Check permission when a semaphore operation specified by @cmd is to be
404143fad282SPaul Moore  * performed on the semaphore.
404243fad282SPaul Moore  *
404343fad282SPaul Moore  * Return: Returns 0 if permission is granted.
404443fad282SPaul Moore  */
security_sem_semctl(struct kern_ipc_perm * sma,int cmd)4045aefad959SEric W. Biederman int security_sem_semctl(struct kern_ipc_perm *sma, int cmd)
404620510f2fSJames Morris {
4047260017f3SOndrej Mosnacek 	return call_int_hook(sem_semctl, sma, cmd);
404820510f2fSJames Morris }
404920510f2fSJames Morris 
405043fad282SPaul Moore /**
405143fad282SPaul Moore  * security_sem_semop() - Check if a sysv semaphore operation is allowed
405243fad282SPaul Moore  * @sma: sysv ipc permission structure
405343fad282SPaul Moore  * @sops: operations to perform
405443fad282SPaul Moore  * @nsops: number of operations
405543fad282SPaul Moore  * @alter: flag indicating changes will be made
405643fad282SPaul Moore  *
405743fad282SPaul Moore  * Check permissions before performing operations on members of the semaphore
405843fad282SPaul Moore  * set. If the @alter flag is nonzero, the semaphore set may be modified.
405943fad282SPaul Moore  *
406043fad282SPaul Moore  * Return: Returns 0 if permission is granted.
406143fad282SPaul Moore  */
security_sem_semop(struct kern_ipc_perm * sma,struct sembuf * sops,unsigned nsops,int alter)4062aefad959SEric W. Biederman int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops,
406320510f2fSJames Morris 		       unsigned nsops, int alter)
406420510f2fSJames Morris {
4065260017f3SOndrej Mosnacek 	return call_int_hook(sem_semop, sma, sops, nsops, alter);
406620510f2fSJames Morris }
406720510f2fSJames Morris 
4068916e3258SPaul Moore /**
4069916e3258SPaul Moore  * security_d_instantiate() - Populate an inode's LSM state based on a dentry
4070916e3258SPaul Moore  * @dentry: dentry
4071916e3258SPaul Moore  * @inode: inode
4072916e3258SPaul Moore  *
4073916e3258SPaul Moore  * Fill in @inode security information for a @dentry if allowed.
4074916e3258SPaul Moore  */
security_d_instantiate(struct dentry * dentry,struct inode * inode)407520510f2fSJames Morris void security_d_instantiate(struct dentry *dentry, struct inode *inode)
407620510f2fSJames Morris {
407720510f2fSJames Morris 	if (unlikely(inode && IS_PRIVATE(inode)))
407820510f2fSJames Morris 		return;
4079f25fce3eSCasey Schaufler 	call_void_hook(d_instantiate, dentry, inode);
408020510f2fSJames Morris }
408120510f2fSJames Morris EXPORT_SYMBOL(security_d_instantiate);
408220510f2fSJames Morris 
4083a04a1198SCasey Schaufler /*
4084a04a1198SCasey Schaufler  * Please keep this in sync with it's counterpart in security/lsm_syscalls.c
4085a04a1198SCasey Schaufler  */
4086a04a1198SCasey Schaufler 
4087a04a1198SCasey Schaufler /**
4088a04a1198SCasey Schaufler  * security_getselfattr - Read an LSM attribute of the current process.
4089a04a1198SCasey Schaufler  * @attr: which attribute to return
4090a04a1198SCasey Schaufler  * @uctx: the user-space destination for the information, or NULL
4091a04a1198SCasey Schaufler  * @size: pointer to the size of space available to receive the data
4092a04a1198SCasey Schaufler  * @flags: special handling options. LSM_FLAG_SINGLE indicates that only
4093a04a1198SCasey Schaufler  * attributes associated with the LSM identified in the passed @ctx be
4094a04a1198SCasey Schaufler  * reported.
4095a04a1198SCasey Schaufler  *
4096a04a1198SCasey Schaufler  * A NULL value for @uctx can be used to get both the number of attributes
4097a04a1198SCasey Schaufler  * and the size of the data.
4098a04a1198SCasey Schaufler  *
4099a04a1198SCasey Schaufler  * Returns the number of attributes found on success, negative value
4100a04a1198SCasey Schaufler  * on error. @size is reset to the total size of the data.
4101a04a1198SCasey Schaufler  * If @size is insufficient to contain the data -E2BIG is returned.
4102a04a1198SCasey Schaufler  */
security_getselfattr(unsigned int attr,struct lsm_ctx __user * uctx,u32 __user * size,u32 flags)4103a04a1198SCasey Schaufler int security_getselfattr(unsigned int attr, struct lsm_ctx __user *uctx,
4104a5a858f6SCasey Schaufler 			 u32 __user *size, u32 flags)
4105a04a1198SCasey Schaufler {
4106417c5643SKP Singh 	struct lsm_static_call *scall;
4107a04a1198SCasey Schaufler 	struct lsm_ctx lctx = { .id = LSM_ID_UNDEF, };
4108a04a1198SCasey Schaufler 	u8 __user *base = (u8 __user *)uctx;
4109a5a858f6SCasey Schaufler 	u32 entrysize;
4110a5a858f6SCasey Schaufler 	u32 total = 0;
4111a5a858f6SCasey Schaufler 	u32 left;
4112a04a1198SCasey Schaufler 	bool toobig = false;
4113a04a1198SCasey Schaufler 	bool single = false;
4114a04a1198SCasey Schaufler 	int count = 0;
4115a04a1198SCasey Schaufler 	int rc;
4116a04a1198SCasey Schaufler 
4117a04a1198SCasey Schaufler 	if (attr == LSM_ATTR_UNDEF)
4118a04a1198SCasey Schaufler 		return -EINVAL;
4119a04a1198SCasey Schaufler 	if (size == NULL)
4120a04a1198SCasey Schaufler 		return -EINVAL;
4121a04a1198SCasey Schaufler 	if (get_user(left, size))
4122a04a1198SCasey Schaufler 		return -EFAULT;
4123a04a1198SCasey Schaufler 
4124a04a1198SCasey Schaufler 	if (flags) {
4125a04a1198SCasey Schaufler 		/*
4126a04a1198SCasey Schaufler 		 * Only flag supported is LSM_FLAG_SINGLE
4127a04a1198SCasey Schaufler 		 */
4128fdcf699bSPaul Moore 		if (flags != LSM_FLAG_SINGLE || !uctx)
4129a04a1198SCasey Schaufler 			return -EINVAL;
4130fdcf699bSPaul Moore 		if (copy_from_user(&lctx, uctx, sizeof(lctx)))
4131a04a1198SCasey Schaufler 			return -EFAULT;
4132a04a1198SCasey Schaufler 		/*
4133a04a1198SCasey Schaufler 		 * If the LSM ID isn't specified it is an error.
4134a04a1198SCasey Schaufler 		 */
4135a04a1198SCasey Schaufler 		if (lctx.id == LSM_ID_UNDEF)
4136a04a1198SCasey Schaufler 			return -EINVAL;
4137a04a1198SCasey Schaufler 		single = true;
4138a04a1198SCasey Schaufler 	}
4139a04a1198SCasey Schaufler 
4140a04a1198SCasey Schaufler 	/*
4141a04a1198SCasey Schaufler 	 * In the usual case gather all the data from the LSMs.
4142a04a1198SCasey Schaufler 	 * In the single case only get the data from the LSM specified.
4143a04a1198SCasey Schaufler 	 */
4144417c5643SKP Singh 	lsm_for_each_hook(scall, getselfattr) {
4145417c5643SKP Singh 		if (single && lctx.id != scall->hl->lsmid->id)
4146a04a1198SCasey Schaufler 			continue;
4147a04a1198SCasey Schaufler 		entrysize = left;
4148a04a1198SCasey Schaufler 		if (base)
4149a04a1198SCasey Schaufler 			uctx = (struct lsm_ctx __user *)(base + total);
4150417c5643SKP Singh 		rc = scall->hl->hook.getselfattr(attr, uctx, &entrysize, flags);
4151241d6a66SColin Ian King 		if (rc == -EOPNOTSUPP)
4152a04a1198SCasey Schaufler 			continue;
4153a04a1198SCasey Schaufler 		if (rc == -E2BIG) {
4154dc46db78SPaul Moore 			rc = 0;
4155a04a1198SCasey Schaufler 			left = 0;
4156dc46db78SPaul Moore 			toobig = true;
4157a04a1198SCasey Schaufler 		} else if (rc < 0)
4158a04a1198SCasey Schaufler 			return rc;
4159a04a1198SCasey Schaufler 		else
4160a04a1198SCasey Schaufler 			left -= entrysize;
4161a04a1198SCasey Schaufler 
4162a04a1198SCasey Schaufler 		total += entrysize;
4163a04a1198SCasey Schaufler 		count += rc;
4164a04a1198SCasey Schaufler 		if (single)
4165a04a1198SCasey Schaufler 			break;
4166a04a1198SCasey Schaufler 	}
4167a04a1198SCasey Schaufler 	if (put_user(total, size))
4168a04a1198SCasey Schaufler 		return -EFAULT;
4169a04a1198SCasey Schaufler 	if (toobig)
4170a04a1198SCasey Schaufler 		return -E2BIG;
4171a04a1198SCasey Schaufler 	if (count == 0)
4172a04a1198SCasey Schaufler 		return LSM_RET_DEFAULT(getselfattr);
4173a04a1198SCasey Schaufler 	return count;
4174a04a1198SCasey Schaufler }
4175a04a1198SCasey Schaufler 
4176a04a1198SCasey Schaufler /*
4177a04a1198SCasey Schaufler  * Please keep this in sync with it's counterpart in security/lsm_syscalls.c
4178a04a1198SCasey Schaufler  */
4179a04a1198SCasey Schaufler 
4180a04a1198SCasey Schaufler /**
4181a04a1198SCasey Schaufler  * security_setselfattr - Set an LSM attribute on the current process.
4182a04a1198SCasey Schaufler  * @attr: which attribute to set
4183a04a1198SCasey Schaufler  * @uctx: the user-space source for the information
4184a04a1198SCasey Schaufler  * @size: the size of the data
4185a04a1198SCasey Schaufler  * @flags: reserved for future use, must be 0
4186a04a1198SCasey Schaufler  *
4187a04a1198SCasey Schaufler  * Set an LSM attribute for the current process. The LSM, attribute
4188a04a1198SCasey Schaufler  * and new value are included in @uctx.
4189a04a1198SCasey Schaufler  *
4190a04a1198SCasey Schaufler  * Returns 0 on success, -EINVAL if the input is inconsistent, -EFAULT
4191a04a1198SCasey Schaufler  * if the user buffer is inaccessible, E2BIG if size is too big, or an
4192a04a1198SCasey Schaufler  * LSM specific failure.
4193a04a1198SCasey Schaufler  */
security_setselfattr(unsigned int attr,struct lsm_ctx __user * uctx,u32 size,u32 flags)4194a04a1198SCasey Schaufler int security_setselfattr(unsigned int attr, struct lsm_ctx __user *uctx,
4195a5a858f6SCasey Schaufler 			 u32 size, u32 flags)
4196a04a1198SCasey Schaufler {
4197417c5643SKP Singh 	struct lsm_static_call *scall;
4198a04a1198SCasey Schaufler 	struct lsm_ctx *lctx;
4199a04a1198SCasey Schaufler 	int rc = LSM_RET_DEFAULT(setselfattr);
4200d8bdd795SJann Horn 	u64 required_len;
4201a04a1198SCasey Schaufler 
4202a04a1198SCasey Schaufler 	if (flags)
4203a04a1198SCasey Schaufler 		return -EINVAL;
4204a04a1198SCasey Schaufler 	if (size < sizeof(*lctx))
4205a04a1198SCasey Schaufler 		return -EINVAL;
4206a04a1198SCasey Schaufler 	if (size > PAGE_SIZE)
4207a04a1198SCasey Schaufler 		return -E2BIG;
4208a04a1198SCasey Schaufler 
42099ba8802cSPaul Moore 	lctx = memdup_user(uctx, size);
42109ba8802cSPaul Moore 	if (IS_ERR(lctx))
42119ba8802cSPaul Moore 		return PTR_ERR(lctx);
4212a04a1198SCasey Schaufler 
4213d8bdd795SJann Horn 	if (size < lctx->len ||
4214d8bdd795SJann Horn 	    check_add_overflow(sizeof(*lctx), lctx->ctx_len, &required_len) ||
4215d8bdd795SJann Horn 	    lctx->len < required_len) {
4216a04a1198SCasey Schaufler 		rc = -EINVAL;
4217a04a1198SCasey Schaufler 		goto free_out;
4218a04a1198SCasey Schaufler 	}
4219a04a1198SCasey Schaufler 
4220417c5643SKP Singh 	lsm_for_each_hook(scall, setselfattr)
4221417c5643SKP Singh 		if ((scall->hl->lsmid->id) == lctx->id) {
4222417c5643SKP Singh 			rc = scall->hl->hook.setselfattr(attr, lctx, size, flags);
4223a04a1198SCasey Schaufler 			break;
4224a04a1198SCasey Schaufler 		}
4225a04a1198SCasey Schaufler 
4226a04a1198SCasey Schaufler free_out:
4227a04a1198SCasey Schaufler 	kfree(lctx);
4228a04a1198SCasey Schaufler 	return rc;
4229a04a1198SCasey Schaufler }
4230a04a1198SCasey Schaufler 
4231916e3258SPaul Moore /**
4232916e3258SPaul Moore  * security_getprocattr() - Read an attribute for a task
4233916e3258SPaul Moore  * @p: the task
4234267c068eSCasey Schaufler  * @lsmid: LSM identification
4235916e3258SPaul Moore  * @name: attribute name
4236916e3258SPaul Moore  * @value: attribute value
4237916e3258SPaul Moore  *
4238916e3258SPaul Moore  * Read attribute @name for task @p and store it into @value if allowed.
4239916e3258SPaul Moore  *
4240916e3258SPaul Moore  * Return: Returns the length of @value on success, a negative value otherwise.
4241916e3258SPaul Moore  */
security_getprocattr(struct task_struct * p,int lsmid,const char * name,char ** value)4242267c068eSCasey Schaufler int security_getprocattr(struct task_struct *p, int lsmid, const char *name,
4243267c068eSCasey Schaufler 			 char **value)
424420510f2fSJames Morris {
4245417c5643SKP Singh 	struct lsm_static_call *scall;
42466d9c939dSCasey Schaufler 
4247417c5643SKP Singh 	lsm_for_each_hook(scall, getprocattr) {
4248417c5643SKP Singh 		if (lsmid != 0 && lsmid != scall->hl->lsmid->id)
42496d9c939dSCasey Schaufler 			continue;
4250417c5643SKP Singh 		return scall->hl->hook.getprocattr(p, name, value);
42516d9c939dSCasey Schaufler 	}
425298e828a0SKP Singh 	return LSM_RET_DEFAULT(getprocattr);
425320510f2fSJames Morris }
425420510f2fSJames Morris 
4255916e3258SPaul Moore /**
4256916e3258SPaul Moore  * security_setprocattr() - Set an attribute for a task
4257267c068eSCasey Schaufler  * @lsmid: LSM identification
4258916e3258SPaul Moore  * @name: attribute name
4259916e3258SPaul Moore  * @value: attribute value
4260916e3258SPaul Moore  * @size: attribute value size
4261916e3258SPaul Moore  *
4262916e3258SPaul Moore  * Write (set) the current task's attribute @name to @value, size @size if
4263916e3258SPaul Moore  * allowed.
4264916e3258SPaul Moore  *
4265916e3258SPaul Moore  * Return: Returns bytes written on success, a negative value otherwise.
4266916e3258SPaul Moore  */
security_setprocattr(int lsmid,const char * name,void * value,size_t size)4267267c068eSCasey Schaufler int security_setprocattr(int lsmid, const char *name, void *value, size_t size)
426820510f2fSJames Morris {
4269417c5643SKP Singh 	struct lsm_static_call *scall;
42706d9c939dSCasey Schaufler 
4271417c5643SKP Singh 	lsm_for_each_hook(scall, setprocattr) {
4272417c5643SKP Singh 		if (lsmid != 0 && lsmid != scall->hl->lsmid->id)
42736d9c939dSCasey Schaufler 			continue;
4274417c5643SKP Singh 		return scall->hl->hook.setprocattr(name, value, size);
42756d9c939dSCasey Schaufler 	}
427698e828a0SKP Singh 	return LSM_RET_DEFAULT(setprocattr);
427720510f2fSJames Morris }
427820510f2fSJames Morris 
42792bcf51bfSPaul Moore /**
42802bcf51bfSPaul Moore  * security_netlink_send() - Save info and check if netlink sending is allowed
42812bcf51bfSPaul Moore  * @sk: sending socket
42822bcf51bfSPaul Moore  * @skb: netlink message
42832bcf51bfSPaul Moore  *
42842bcf51bfSPaul Moore  * Save security information for a netlink message so that permission checking
42852bcf51bfSPaul Moore  * can be performed when the message is processed.  The security information
42862bcf51bfSPaul Moore  * can be saved using the eff_cap field of the netlink_skb_parms structure.
42872bcf51bfSPaul Moore  * Also may be used to provide fine grained control over message transmission.
42882bcf51bfSPaul Moore  *
42892bcf51bfSPaul Moore  * Return: Returns 0 if the information was successfully saved and message is
42902bcf51bfSPaul Moore  *         allowed to be transmitted.
42912bcf51bfSPaul Moore  */
security_netlink_send(struct sock * sk,struct sk_buff * skb)429220510f2fSJames Morris int security_netlink_send(struct sock *sk, struct sk_buff *skb)
429320510f2fSJames Morris {
4294260017f3SOndrej Mosnacek 	return call_int_hook(netlink_send, sk, skb);
429520510f2fSJames Morris }
429620510f2fSJames Morris 
4297e261301cSPaul Moore /**
4298936615f6SPairman Guo  * security_ismaclabel() - Check if the named attribute is a MAC label
4299e261301cSPaul Moore  * @name: full extended attribute name
4300e261301cSPaul Moore  *
4301e261301cSPaul Moore  * Check if the extended attribute specified by @name represents a MAC label.
4302e261301cSPaul Moore  *
4303e261301cSPaul Moore  * Return: Returns 1 if name is a MAC attribute otherwise returns 0.
4304e261301cSPaul Moore  */
security_ismaclabel(const char * name)4305746df9b5SDavid Quigley int security_ismaclabel(const char *name)
4306746df9b5SDavid Quigley {
4307260017f3SOndrej Mosnacek 	return call_int_hook(ismaclabel, name);
4308746df9b5SDavid Quigley }
4309746df9b5SDavid Quigley EXPORT_SYMBOL(security_ismaclabel);
4310746df9b5SDavid Quigley 
4311e261301cSPaul Moore /**
4312e261301cSPaul Moore  * security_secid_to_secctx() - Convert a secid to a secctx
4313e261301cSPaul Moore  * @secid: secid
43142d470c77SCasey Schaufler  * @cp: the LSM context
4315e261301cSPaul Moore  *
43162d470c77SCasey Schaufler  * Convert secid to security context.  If @cp is NULL the length of the
43172d470c77SCasey Schaufler  * result will be returned, but no data will be returned.  This
4318e261301cSPaul Moore  * does mean that the length could change between calls to check the length and
43192d470c77SCasey Schaufler  * the next call which actually allocates and returns the data.
4320e261301cSPaul Moore  *
43212d470c77SCasey Schaufler  * Return: Return length of data on success, error on failure.
4322e261301cSPaul Moore  */
security_secid_to_secctx(u32 secid,struct lsm_context * cp)43232d470c77SCasey Schaufler int security_secid_to_secctx(u32 secid, struct lsm_context *cp)
432420510f2fSJames Morris {
43252d470c77SCasey Schaufler 	return call_int_hook(secid_to_secctx, secid, cp);
432620510f2fSJames Morris }
432720510f2fSJames Morris EXPORT_SYMBOL(security_secid_to_secctx);
432820510f2fSJames Morris 
4329e261301cSPaul Moore /**
43306f2f724fSCasey Schaufler  * security_lsmprop_to_secctx() - Convert a lsm_prop to a secctx
43316f2f724fSCasey Schaufler  * @prop: lsm specific information
43322d470c77SCasey Schaufler  * @cp: the LSM context
43336f2f724fSCasey Schaufler  *
43342d470c77SCasey Schaufler  * Convert a @prop entry to security context.  If @cp is NULL the
43352d470c77SCasey Schaufler  * length of the result will be returned. This does mean that the
43362d470c77SCasey Schaufler  * length could change between calls to check the length and the
43372d470c77SCasey Schaufler  * next call which actually allocates and returns the @cp.
43386f2f724fSCasey Schaufler  *
43392d470c77SCasey Schaufler  * Return: Return length of data on success, error on failure.
43406f2f724fSCasey Schaufler  */
security_lsmprop_to_secctx(struct lsm_prop * prop,struct lsm_context * cp)43412d470c77SCasey Schaufler int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp)
43426f2f724fSCasey Schaufler {
43432d470c77SCasey Schaufler 	return call_int_hook(lsmprop_to_secctx, prop, cp);
43446f2f724fSCasey Schaufler }
43456f2f724fSCasey Schaufler EXPORT_SYMBOL(security_lsmprop_to_secctx);
43466f2f724fSCasey Schaufler 
43476f2f724fSCasey Schaufler /**
4348e261301cSPaul Moore  * security_secctx_to_secid() - Convert a secctx to a secid
4349e261301cSPaul Moore  * @secdata: secctx
4350e261301cSPaul Moore  * @seclen: length of secctx
4351e261301cSPaul Moore  * @secid: secid
4352e261301cSPaul Moore  *
4353e261301cSPaul Moore  * Convert security context to secid.
4354e261301cSPaul Moore  *
4355e261301cSPaul Moore  * Return: Returns 0 on success, error on failure.
4356e261301cSPaul Moore  */
security_secctx_to_secid(const char * secdata,u32 seclen,u32 * secid)43577bf570dcSDavid Howells int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
435863cb3449SDavid Howells {
4359b1d9e6b0SCasey Schaufler 	*secid = 0;
4360260017f3SOndrej Mosnacek 	return call_int_hook(secctx_to_secid, secdata, seclen, secid);
436163cb3449SDavid Howells }
436263cb3449SDavid Howells EXPORT_SYMBOL(security_secctx_to_secid);
436363cb3449SDavid Howells 
4364e261301cSPaul Moore /**
4365e261301cSPaul Moore  * security_release_secctx() - Free a secctx buffer
43666fba8981SCasey Schaufler  * @cp: the security context
4367e261301cSPaul Moore  *
4368e261301cSPaul Moore  * Release the security context.
4369e261301cSPaul Moore  */
security_release_secctx(struct lsm_context * cp)43706fba8981SCasey Schaufler void security_release_secctx(struct lsm_context *cp)
437120510f2fSJames Morris {
43726fba8981SCasey Schaufler 	call_void_hook(release_secctx, cp);
43736fba8981SCasey Schaufler 	memset(cp, 0, sizeof(*cp));
437420510f2fSJames Morris }
437520510f2fSJames Morris EXPORT_SYMBOL(security_release_secctx);
437620510f2fSJames Morris 
4377e261301cSPaul Moore /**
4378e261301cSPaul Moore  * security_inode_invalidate_secctx() - Invalidate an inode's security label
4379e261301cSPaul Moore  * @inode: inode
4380e261301cSPaul Moore  *
4381e261301cSPaul Moore  * Notify the security module that it must revalidate the security context of
4382e261301cSPaul Moore  * an inode.
4383e261301cSPaul Moore  */
security_inode_invalidate_secctx(struct inode * inode)43846f3be9f5SAndreas Gruenbacher void security_inode_invalidate_secctx(struct inode *inode)
43856f3be9f5SAndreas Gruenbacher {
43866f3be9f5SAndreas Gruenbacher 	call_void_hook(inode_invalidate_secctx, inode);
43876f3be9f5SAndreas Gruenbacher }
43886f3be9f5SAndreas Gruenbacher EXPORT_SYMBOL(security_inode_invalidate_secctx);
43896f3be9f5SAndreas Gruenbacher 
4390e261301cSPaul Moore /**
4391e5085606SPaul Moore  * security_inode_notifysecctx() - Notify the LSM of an inode's security label
4392e261301cSPaul Moore  * @inode: inode
4393e261301cSPaul Moore  * @ctx: secctx
4394e261301cSPaul Moore  * @ctxlen: length of secctx
4395e261301cSPaul Moore  *
4396e261301cSPaul Moore  * Notify the security module of what the security context of an inode should
4397e261301cSPaul Moore  * be.  Initializes the incore security context managed by the security module
4398e261301cSPaul Moore  * for this inode.  Example usage: NFS client invokes this hook to initialize
4399e261301cSPaul Moore  * the security context in its incore inode to the value provided by the server
4400e261301cSPaul Moore  * for the file when the server returned the file's attributes to the client.
4401e261301cSPaul Moore  * Must be called with inode->i_mutex locked.
4402e261301cSPaul Moore  *
4403e261301cSPaul Moore  * Return: Returns 0 on success, error on failure.
4404e261301cSPaul Moore  */
security_inode_notifysecctx(struct inode * inode,void * ctx,u32 ctxlen)44051ee65e37SDavid P. Quigley int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
44061ee65e37SDavid P. Quigley {
4407260017f3SOndrej Mosnacek 	return call_int_hook(inode_notifysecctx, inode, ctx, ctxlen);
44081ee65e37SDavid P. Quigley }
44091ee65e37SDavid P. Quigley EXPORT_SYMBOL(security_inode_notifysecctx);
44101ee65e37SDavid P. Quigley 
4411e261301cSPaul Moore /**
4412e261301cSPaul Moore  * security_inode_setsecctx() - Change the security label of an inode
4413e261301cSPaul Moore  * @dentry: inode
4414e261301cSPaul Moore  * @ctx: secctx
4415e261301cSPaul Moore  * @ctxlen: length of secctx
4416e261301cSPaul Moore  *
4417e261301cSPaul Moore  * Change the security context of an inode.  Updates the incore security
4418e261301cSPaul Moore  * context managed by the security module and invokes the fs code as needed
4419e261301cSPaul Moore  * (via __vfs_setxattr_noperm) to update any backing xattrs that represent the
4420e261301cSPaul Moore  * context.  Example usage: NFS server invokes this hook to change the security
4421e261301cSPaul Moore  * context in its incore inode and on the backing filesystem to a value
4422e261301cSPaul Moore  * provided by the client on a SETATTR operation.  Must be called with
4423e261301cSPaul Moore  * inode->i_mutex locked.
4424e261301cSPaul Moore  *
4425e261301cSPaul Moore  * Return: Returns 0 on success, error on failure.
4426e261301cSPaul Moore  */
security_inode_setsecctx(struct dentry * dentry,void * ctx,u32 ctxlen)44271ee65e37SDavid P. Quigley int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
44281ee65e37SDavid P. Quigley {
4429260017f3SOndrej Mosnacek 	return call_int_hook(inode_setsecctx, dentry, ctx, ctxlen);
44301ee65e37SDavid P. Quigley }
44311ee65e37SDavid P. Quigley EXPORT_SYMBOL(security_inode_setsecctx);
44321ee65e37SDavid P. Quigley 
4433e261301cSPaul Moore /**
4434e261301cSPaul Moore  * security_inode_getsecctx() - Get the security label of an inode
4435e261301cSPaul Moore  * @inode: inode
443676ecf306SCasey Schaufler  * @cp: security context
4437e261301cSPaul Moore  *
443876ecf306SCasey Schaufler  * On success, returns 0 and fills out @cp with the security context
443976ecf306SCasey Schaufler  * for the given @inode.
4440e261301cSPaul Moore  *
4441e261301cSPaul Moore  * Return: Returns 0 on success, error on failure.
4442e261301cSPaul Moore  */
security_inode_getsecctx(struct inode * inode,struct lsm_context * cp)444376ecf306SCasey Schaufler int security_inode_getsecctx(struct inode *inode, struct lsm_context *cp)
44441ee65e37SDavid P. Quigley {
444576ecf306SCasey Schaufler 	memset(cp, 0, sizeof(*cp));
444676ecf306SCasey Schaufler 	return call_int_hook(inode_getsecctx, inode, cp);
44471ee65e37SDavid P. Quigley }
44481ee65e37SDavid P. Quigley EXPORT_SYMBOL(security_inode_getsecctx);
44491ee65e37SDavid P. Quigley 
4450344fa64eSDavid Howells #ifdef CONFIG_WATCH_QUEUE
4451e261301cSPaul Moore /**
4452e261301cSPaul Moore  * security_post_notification() - Check if a watch notification can be posted
4453e261301cSPaul Moore  * @w_cred: credentials of the task that set the watch
4454e261301cSPaul Moore  * @cred: credentials of the task which triggered the watch
4455e261301cSPaul Moore  * @n: the notification
4456e261301cSPaul Moore  *
4457e261301cSPaul Moore  * Check to see if a watch notification can be posted to a particular queue.
4458e261301cSPaul Moore  *
4459e261301cSPaul Moore  * Return: Returns 0 if permission is granted.
4460e261301cSPaul Moore  */
security_post_notification(const struct cred * w_cred,const struct cred * cred,struct watch_notification * n)4461344fa64eSDavid Howells int security_post_notification(const struct cred *w_cred,
4462344fa64eSDavid Howells 			       const struct cred *cred,
4463344fa64eSDavid Howells 			       struct watch_notification *n)
4464344fa64eSDavid Howells {
4465260017f3SOndrej Mosnacek 	return call_int_hook(post_notification, w_cred, cred, n);
4466344fa64eSDavid Howells }
4467344fa64eSDavid Howells #endif /* CONFIG_WATCH_QUEUE */
4468344fa64eSDavid Howells 
4469998f5040SDavid Howells #ifdef CONFIG_KEY_NOTIFICATIONS
4470e261301cSPaul Moore /**
4471e261301cSPaul Moore  * security_watch_key() - Check if a task is allowed to watch for key events
4472e261301cSPaul Moore  * @key: the key to watch
4473e261301cSPaul Moore  *
4474e261301cSPaul Moore  * Check to see if a process is allowed to watch for event notifications from
4475e261301cSPaul Moore  * a key or keyring.
4476e261301cSPaul Moore  *
4477e261301cSPaul Moore  * Return: Returns 0 if permission is granted.
4478e261301cSPaul Moore  */
security_watch_key(struct key * key)4479998f5040SDavid Howells int security_watch_key(struct key *key)
4480998f5040SDavid Howells {
4481260017f3SOndrej Mosnacek 	return call_int_hook(watch_key, key);
4482998f5040SDavid Howells }
448363c1845bSPaul Moore #endif /* CONFIG_KEY_NOTIFICATIONS */
4484998f5040SDavid Howells 
448520510f2fSJames Morris #ifdef CONFIG_SECURITY_NETWORK
44862c2442fdSPaul Moore /**
44872c2442fdSPaul Moore  * security_unix_stream_connect() - Check if a AF_UNIX stream is allowed
44882c2442fdSPaul Moore  * @sock: originating sock
44892c2442fdSPaul Moore  * @other: peer sock
44902c2442fdSPaul Moore  * @newsk: new sock
44912c2442fdSPaul Moore  *
44922c2442fdSPaul Moore  * Check permissions before establishing a Unix domain stream connection
44932c2442fdSPaul Moore  * between @sock and @other.
44942c2442fdSPaul Moore  *
44952c2442fdSPaul Moore  * The @unix_stream_connect and @unix_may_send hooks were necessary because
44962c2442fdSPaul Moore  * Linux provides an alternative to the conventional file name space for Unix
44972c2442fdSPaul Moore  * domain sockets.  Whereas binding and connecting to sockets in the file name
44982c2442fdSPaul Moore  * space is mediated by the typical file permissions (and caught by the mknod
44992c2442fdSPaul Moore  * and permission hooks in inode_security_ops), binding and connecting to
45002c2442fdSPaul Moore  * sockets in the abstract name space is completely unmediated.  Sufficient
45012c2442fdSPaul Moore  * control of Unix domain sockets in the abstract name space isn't possible
45022c2442fdSPaul Moore  * using only the socket layer hooks, since we need to know the actual target
45032c2442fdSPaul Moore  * socket, which is not looked up until we are inside the af_unix code.
45042c2442fdSPaul Moore  *
45052c2442fdSPaul Moore  * Return: Returns 0 if permission is granted.
45062c2442fdSPaul Moore  */
security_unix_stream_connect(struct sock * sock,struct sock * other,struct sock * newsk)450763c1845bSPaul Moore int security_unix_stream_connect(struct sock *sock, struct sock *other,
450863c1845bSPaul Moore 				 struct sock *newsk)
450920510f2fSJames Morris {
4510260017f3SOndrej Mosnacek 	return call_int_hook(unix_stream_connect, sock, other, newsk);
451120510f2fSJames Morris }
451220510f2fSJames Morris EXPORT_SYMBOL(security_unix_stream_connect);
451320510f2fSJames Morris 
45142c2442fdSPaul Moore /**
45152c2442fdSPaul Moore  * security_unix_may_send() - Check if AF_UNIX socket can send datagrams
45162c2442fdSPaul Moore  * @sock: originating sock
45172c2442fdSPaul Moore  * @other: peer sock
45182c2442fdSPaul Moore  *
45192c2442fdSPaul Moore  * Check permissions before connecting or sending datagrams from @sock to
45202c2442fdSPaul Moore  * @other.
45212c2442fdSPaul Moore  *
45222c2442fdSPaul Moore  * The @unix_stream_connect and @unix_may_send hooks were necessary because
45232c2442fdSPaul Moore  * Linux provides an alternative to the conventional file name space for Unix
45242c2442fdSPaul Moore  * domain sockets.  Whereas binding and connecting to sockets in the file name
45252c2442fdSPaul Moore  * space is mediated by the typical file permissions (and caught by the mknod
45262c2442fdSPaul Moore  * and permission hooks in inode_security_ops), binding and connecting to
45272c2442fdSPaul Moore  * sockets in the abstract name space is completely unmediated.  Sufficient
45282c2442fdSPaul Moore  * control of Unix domain sockets in the abstract name space isn't possible
45292c2442fdSPaul Moore  * using only the socket layer hooks, since we need to know the actual target
45302c2442fdSPaul Moore  * socket, which is not looked up until we are inside the af_unix code.
45312c2442fdSPaul Moore  *
45322c2442fdSPaul Moore  * Return: Returns 0 if permission is granted.
45332c2442fdSPaul Moore  */
security_unix_may_send(struct socket * sock,struct socket * other)453420510f2fSJames Morris int security_unix_may_send(struct socket *sock,  struct socket *other)
453520510f2fSJames Morris {
4536260017f3SOndrej Mosnacek 	return call_int_hook(unix_may_send, sock, other);
453720510f2fSJames Morris }
453820510f2fSJames Morris EXPORT_SYMBOL(security_unix_may_send);
453920510f2fSJames Morris 
45406b6bbe8cSPaul Moore /**
45416b6bbe8cSPaul Moore  * security_socket_create() - Check if creating a new socket is allowed
45426b6bbe8cSPaul Moore  * @family: protocol family
45436b6bbe8cSPaul Moore  * @type: communications type
45446b6bbe8cSPaul Moore  * @protocol: requested protocol
45456b6bbe8cSPaul Moore  * @kern: set to 1 if a kernel socket is requested
45466b6bbe8cSPaul Moore  *
45476b6bbe8cSPaul Moore  * Check permissions prior to creating a new socket.
45486b6bbe8cSPaul Moore  *
45496b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
45506b6bbe8cSPaul Moore  */
security_socket_create(int family,int type,int protocol,int kern)455120510f2fSJames Morris int security_socket_create(int family, int type, int protocol, int kern)
455220510f2fSJames Morris {
4553260017f3SOndrej Mosnacek 	return call_int_hook(socket_create, family, type, protocol, kern);
455420510f2fSJames Morris }
455520510f2fSJames Morris 
45566b6bbe8cSPaul Moore /**
45571e2523d7SPaul Moore  * security_socket_post_create() - Initialize a newly created socket
45586b6bbe8cSPaul Moore  * @sock: socket
45596b6bbe8cSPaul Moore  * @family: protocol family
45606b6bbe8cSPaul Moore  * @type: communications type
45616b6bbe8cSPaul Moore  * @protocol: requested protocol
45626b6bbe8cSPaul Moore  * @kern: set to 1 if a kernel socket is requested
45636b6bbe8cSPaul Moore  *
45646b6bbe8cSPaul Moore  * This hook allows a module to update or allocate a per-socket security
45656b6bbe8cSPaul Moore  * structure. Note that the security field was not added directly to the socket
45666b6bbe8cSPaul Moore  * structure, but rather, the socket security information is stored in the
45676b6bbe8cSPaul Moore  * associated inode.  Typically, the inode alloc_security hook will allocate
45686b6bbe8cSPaul Moore  * and attach security information to SOCK_INODE(sock)->i_security.  This hook
45696b6bbe8cSPaul Moore  * may be used to update the SOCK_INODE(sock)->i_security field with additional
45706b6bbe8cSPaul Moore  * information that wasn't available when the inode was allocated.
45716b6bbe8cSPaul Moore  *
45726b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
45736b6bbe8cSPaul Moore  */
security_socket_post_create(struct socket * sock,int family,int type,int protocol,int kern)457420510f2fSJames Morris int security_socket_post_create(struct socket *sock, int family,
457520510f2fSJames Morris 				int type, int protocol, int kern)
457620510f2fSJames Morris {
4577260017f3SOndrej Mosnacek 	return call_int_hook(socket_post_create, sock, family, type,
457820510f2fSJames Morris 			     protocol, kern);
457920510f2fSJames Morris }
458020510f2fSJames Morris 
45816b6bbe8cSPaul Moore /**
45826b6bbe8cSPaul Moore  * security_socket_socketpair() - Check if creating a socketpair is allowed
45836b6bbe8cSPaul Moore  * @socka: first socket
45846b6bbe8cSPaul Moore  * @sockb: second socket
45856b6bbe8cSPaul Moore  *
45866b6bbe8cSPaul Moore  * Check permissions before creating a fresh pair of sockets.
45876b6bbe8cSPaul Moore  *
45886b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted and the connection was
45896b6bbe8cSPaul Moore  *         established.
45906b6bbe8cSPaul Moore  */
security_socket_socketpair(struct socket * socka,struct socket * sockb)4591aae7cfcbSDavid Herrmann int security_socket_socketpair(struct socket *socka, struct socket *sockb)
4592aae7cfcbSDavid Herrmann {
4593260017f3SOndrej Mosnacek 	return call_int_hook(socket_socketpair, socka, sockb);
4594aae7cfcbSDavid Herrmann }
4595aae7cfcbSDavid Herrmann EXPORT_SYMBOL(security_socket_socketpair);
4596aae7cfcbSDavid Herrmann 
45976b6bbe8cSPaul Moore /**
45986b6bbe8cSPaul Moore  * security_socket_bind() - Check if a socket bind operation is allowed
45996b6bbe8cSPaul Moore  * @sock: socket
46006b6bbe8cSPaul Moore  * @address: requested bind address
46016b6bbe8cSPaul Moore  * @addrlen: length of address
46026b6bbe8cSPaul Moore  *
46036b6bbe8cSPaul Moore  * Check permission before socket protocol layer bind operation is performed
46046b6bbe8cSPaul Moore  * and the socket @sock is bound to the address specified in the @address
46056b6bbe8cSPaul Moore  * parameter.
46066b6bbe8cSPaul Moore  *
46076b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
46086b6bbe8cSPaul Moore  */
security_socket_bind(struct socket * sock,struct sockaddr * address,int addrlen)460963c1845bSPaul Moore int security_socket_bind(struct socket *sock,
461063c1845bSPaul Moore 			 struct sockaddr *address, int addrlen)
461120510f2fSJames Morris {
4612260017f3SOndrej Mosnacek 	return call_int_hook(socket_bind, sock, address, addrlen);
461320510f2fSJames Morris }
461420510f2fSJames Morris 
46156b6bbe8cSPaul Moore /**
46166b6bbe8cSPaul Moore  * security_socket_connect() - Check if a socket connect operation is allowed
46176b6bbe8cSPaul Moore  * @sock: socket
46186b6bbe8cSPaul Moore  * @address: address of remote connection point
46196b6bbe8cSPaul Moore  * @addrlen: length of address
46206b6bbe8cSPaul Moore  *
46216b6bbe8cSPaul Moore  * Check permission before socket protocol layer connect operation attempts to
46226b6bbe8cSPaul Moore  * connect socket @sock to a remote address, @address.
46236b6bbe8cSPaul Moore  *
46246b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
46256b6bbe8cSPaul Moore  */
security_socket_connect(struct socket * sock,struct sockaddr * address,int addrlen)462663c1845bSPaul Moore int security_socket_connect(struct socket *sock,
462763c1845bSPaul Moore 			    struct sockaddr *address, int addrlen)
462820510f2fSJames Morris {
4629260017f3SOndrej Mosnacek 	return call_int_hook(socket_connect, sock, address, addrlen);
463020510f2fSJames Morris }
463120510f2fSJames Morris 
46326b6bbe8cSPaul Moore /**
46336b6bbe8cSPaul Moore  * security_socket_listen() - Check if a socket is allowed to listen
46346b6bbe8cSPaul Moore  * @sock: socket
46356b6bbe8cSPaul Moore  * @backlog: connection queue size
46366b6bbe8cSPaul Moore  *
46376b6bbe8cSPaul Moore  * Check permission before socket protocol layer listen operation.
46386b6bbe8cSPaul Moore  *
46396b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
46406b6bbe8cSPaul Moore  */
security_socket_listen(struct socket * sock,int backlog)464120510f2fSJames Morris int security_socket_listen(struct socket *sock, int backlog)
464220510f2fSJames Morris {
4643260017f3SOndrej Mosnacek 	return call_int_hook(socket_listen, sock, backlog);
464420510f2fSJames Morris }
464520510f2fSJames Morris 
46466b6bbe8cSPaul Moore /**
46476b6bbe8cSPaul Moore  * security_socket_accept() - Check if a socket is allowed to accept connections
46486b6bbe8cSPaul Moore  * @sock: listening socket
46496b6bbe8cSPaul Moore  * @newsock: newly creation connection socket
46506b6bbe8cSPaul Moore  *
46516b6bbe8cSPaul Moore  * Check permission before accepting a new connection.  Note that the new
46526b6bbe8cSPaul Moore  * socket, @newsock, has been created and some information copied to it, but
46536b6bbe8cSPaul Moore  * the accept operation has not actually been performed.
46546b6bbe8cSPaul Moore  *
46556b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
46566b6bbe8cSPaul Moore  */
security_socket_accept(struct socket * sock,struct socket * newsock)465720510f2fSJames Morris int security_socket_accept(struct socket *sock, struct socket *newsock)
465820510f2fSJames Morris {
4659260017f3SOndrej Mosnacek 	return call_int_hook(socket_accept, sock, newsock);
466020510f2fSJames Morris }
466120510f2fSJames Morris 
46626b6bbe8cSPaul Moore /**
4663936615f6SPairman Guo  * security_socket_sendmsg() - Check if sending a message is allowed
46646b6bbe8cSPaul Moore  * @sock: sending socket
46656b6bbe8cSPaul Moore  * @msg: message to send
46666b6bbe8cSPaul Moore  * @size: size of message
46676b6bbe8cSPaul Moore  *
46686b6bbe8cSPaul Moore  * Check permission before transmitting a message to another socket.
46696b6bbe8cSPaul Moore  *
46706b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
46716b6bbe8cSPaul Moore  */
security_socket_sendmsg(struct socket * sock,struct msghdr * msg,int size)467220510f2fSJames Morris int security_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size)
467320510f2fSJames Morris {
4674260017f3SOndrej Mosnacek 	return call_int_hook(socket_sendmsg, sock, msg, size);
467520510f2fSJames Morris }
467620510f2fSJames Morris 
46776b6bbe8cSPaul Moore /**
46786b6bbe8cSPaul Moore  * security_socket_recvmsg() - Check if receiving a message is allowed
46796b6bbe8cSPaul Moore  * @sock: receiving socket
46806b6bbe8cSPaul Moore  * @msg: message to receive
46816b6bbe8cSPaul Moore  * @size: size of message
46826b6bbe8cSPaul Moore  * @flags: operational flags
46836b6bbe8cSPaul Moore  *
46846b6bbe8cSPaul Moore  * Check permission before receiving a message from a socket.
46856b6bbe8cSPaul Moore  *
46866b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
46876b6bbe8cSPaul Moore  */
security_socket_recvmsg(struct socket * sock,struct msghdr * msg,int size,int flags)468820510f2fSJames Morris int security_socket_recvmsg(struct socket *sock, struct msghdr *msg,
468920510f2fSJames Morris 			    int size, int flags)
469020510f2fSJames Morris {
4691260017f3SOndrej Mosnacek 	return call_int_hook(socket_recvmsg, sock, msg, size, flags);
469220510f2fSJames Morris }
469320510f2fSJames Morris 
46946b6bbe8cSPaul Moore /**
46956b6bbe8cSPaul Moore  * security_socket_getsockname() - Check if reading the socket addr is allowed
46966b6bbe8cSPaul Moore  * @sock: socket
46976b6bbe8cSPaul Moore  *
46986b6bbe8cSPaul Moore  * Check permission before reading the local address (name) of the socket
46996b6bbe8cSPaul Moore  * object.
47006b6bbe8cSPaul Moore  *
47016b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
47026b6bbe8cSPaul Moore  */
security_socket_getsockname(struct socket * sock)470320510f2fSJames Morris int security_socket_getsockname(struct socket *sock)
470420510f2fSJames Morris {
4705260017f3SOndrej Mosnacek 	return call_int_hook(socket_getsockname, sock);
470620510f2fSJames Morris }
470720510f2fSJames Morris 
47086b6bbe8cSPaul Moore /**
47096b6bbe8cSPaul Moore  * security_socket_getpeername() - Check if reading the peer's addr is allowed
47106b6bbe8cSPaul Moore  * @sock: socket
47116b6bbe8cSPaul Moore  *
47126b6bbe8cSPaul Moore  * Check permission before the remote address (name) of a socket object.
47136b6bbe8cSPaul Moore  *
47146b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
47156b6bbe8cSPaul Moore  */
security_socket_getpeername(struct socket * sock)471620510f2fSJames Morris int security_socket_getpeername(struct socket *sock)
471720510f2fSJames Morris {
4718260017f3SOndrej Mosnacek 	return call_int_hook(socket_getpeername, sock);
471920510f2fSJames Morris }
472020510f2fSJames Morris 
47216b6bbe8cSPaul Moore /**
47226b6bbe8cSPaul Moore  * security_socket_getsockopt() - Check if reading a socket option is allowed
47236b6bbe8cSPaul Moore  * @sock: socket
47246b6bbe8cSPaul Moore  * @level: option's protocol level
47256b6bbe8cSPaul Moore  * @optname: option name
47266b6bbe8cSPaul Moore  *
47276b6bbe8cSPaul Moore  * Check permissions before retrieving the options associated with socket
47286b6bbe8cSPaul Moore  * @sock.
47296b6bbe8cSPaul Moore  *
47306b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
47316b6bbe8cSPaul Moore  */
security_socket_getsockopt(struct socket * sock,int level,int optname)473220510f2fSJames Morris int security_socket_getsockopt(struct socket *sock, int level, int optname)
473320510f2fSJames Morris {
4734260017f3SOndrej Mosnacek 	return call_int_hook(socket_getsockopt, sock, level, optname);
473520510f2fSJames Morris }
473620510f2fSJames Morris 
47376b6bbe8cSPaul Moore /**
47386b6bbe8cSPaul Moore  * security_socket_setsockopt() - Check if setting a socket option is allowed
47396b6bbe8cSPaul Moore  * @sock: socket
47406b6bbe8cSPaul Moore  * @level: option's protocol level
47416b6bbe8cSPaul Moore  * @optname: option name
47426b6bbe8cSPaul Moore  *
47436b6bbe8cSPaul Moore  * Check permissions before setting the options associated with socket @sock.
47446b6bbe8cSPaul Moore  *
47456b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
47466b6bbe8cSPaul Moore  */
security_socket_setsockopt(struct socket * sock,int level,int optname)474720510f2fSJames Morris int security_socket_setsockopt(struct socket *sock, int level, int optname)
474820510f2fSJames Morris {
4749260017f3SOndrej Mosnacek 	return call_int_hook(socket_setsockopt, sock, level, optname);
475020510f2fSJames Morris }
475120510f2fSJames Morris 
47526b6bbe8cSPaul Moore /**
47536b6bbe8cSPaul Moore  * security_socket_shutdown() - Checks if shutting down the socket is allowed
47546b6bbe8cSPaul Moore  * @sock: socket
47556b6bbe8cSPaul Moore  * @how: flag indicating how sends and receives are handled
47566b6bbe8cSPaul Moore  *
47576b6bbe8cSPaul Moore  * Checks permission before all or part of a connection on the socket @sock is
47586b6bbe8cSPaul Moore  * shut down.
47596b6bbe8cSPaul Moore  *
47606b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
47616b6bbe8cSPaul Moore  */
security_socket_shutdown(struct socket * sock,int how)476220510f2fSJames Morris int security_socket_shutdown(struct socket *sock, int how)
476320510f2fSJames Morris {
4764260017f3SOndrej Mosnacek 	return call_int_hook(socket_shutdown, sock, how);
476520510f2fSJames Morris }
476620510f2fSJames Morris 
47676b6bbe8cSPaul Moore /**
47686b6bbe8cSPaul Moore  * security_sock_rcv_skb() - Check if an incoming network packet is allowed
47696b6bbe8cSPaul Moore  * @sk: destination sock
47706b6bbe8cSPaul Moore  * @skb: incoming packet
47716b6bbe8cSPaul Moore  *
47726b6bbe8cSPaul Moore  * Check permissions on incoming network packets.  This hook is distinct from
47736b6bbe8cSPaul Moore  * Netfilter's IP input hooks since it is the first time that the incoming
47746b6bbe8cSPaul Moore  * sk_buff @skb has been associated with a particular socket, @sk.  Must not
47756b6bbe8cSPaul Moore  * sleep inside this hook because some callers hold spinlocks.
47766b6bbe8cSPaul Moore  *
47776b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
47786b6bbe8cSPaul Moore  */
security_sock_rcv_skb(struct sock * sk,struct sk_buff * skb)477920510f2fSJames Morris int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
478020510f2fSJames Morris {
4781260017f3SOndrej Mosnacek 	return call_int_hook(socket_sock_rcv_skb, sk, skb);
478220510f2fSJames Morris }
478320510f2fSJames Morris EXPORT_SYMBOL(security_sock_rcv_skb);
478420510f2fSJames Morris 
47856b6bbe8cSPaul Moore /**
47866b6bbe8cSPaul Moore  * security_socket_getpeersec_stream() - Get the remote peer label
47876b6bbe8cSPaul Moore  * @sock: socket
47886b6bbe8cSPaul Moore  * @optval: destination buffer
47896b6bbe8cSPaul Moore  * @optlen: size of peer label copied into the buffer
47906b6bbe8cSPaul Moore  * @len: maximum size of the destination buffer
47916b6bbe8cSPaul Moore  *
47926b6bbe8cSPaul Moore  * This hook allows the security module to provide peer socket security state
47936b6bbe8cSPaul Moore  * for unix or connected tcp sockets to userspace via getsockopt SO_GETPEERSEC.
47946b6bbe8cSPaul Moore  * For tcp sockets this can be meaningful if the socket is associated with an
47956b6bbe8cSPaul Moore  * ipsec SA.
47966b6bbe8cSPaul Moore  *
47976b6bbe8cSPaul Moore  * Return: Returns 0 if all is well, otherwise, typical getsockopt return
47986b6bbe8cSPaul Moore  *         values.
47996b6bbe8cSPaul Moore  */
security_socket_getpeersec_stream(struct socket * sock,sockptr_t optval,sockptr_t optlen,unsigned int len)4800b10b9c34SPaul Moore int security_socket_getpeersec_stream(struct socket *sock, sockptr_t optval,
4801b10b9c34SPaul Moore 				      sockptr_t optlen, unsigned int len)
480220510f2fSJames Morris {
4803260017f3SOndrej Mosnacek 	return call_int_hook(socket_getpeersec_stream, sock, optval, optlen,
48045a287d3dSOndrej Mosnacek 			     len);
480520510f2fSJames Morris }
480620510f2fSJames Morris 
48076b6bbe8cSPaul Moore /**
48086b6bbe8cSPaul Moore  * security_socket_getpeersec_dgram() - Get the remote peer label
48096b6bbe8cSPaul Moore  * @sock: socket
48106b6bbe8cSPaul Moore  * @skb: datagram packet
48116b6bbe8cSPaul Moore  * @secid: remote peer label secid
48126b6bbe8cSPaul Moore  *
48136b6bbe8cSPaul Moore  * This hook allows the security module to provide peer socket security state
48146b6bbe8cSPaul Moore  * for udp sockets on a per-packet basis to userspace via getsockopt
48156b6bbe8cSPaul Moore  * SO_GETPEERSEC. The application must first have indicated the IP_PASSSEC
48166b6bbe8cSPaul Moore  * option via getsockopt. It can then retrieve the security state returned by
48176b6bbe8cSPaul Moore  * this hook for a packet via the SCM_SECURITY ancillary message type.
48186b6bbe8cSPaul Moore  *
48196b6bbe8cSPaul Moore  * Return: Returns 0 on success, error on failure.
48206b6bbe8cSPaul Moore  */
security_socket_getpeersec_dgram(struct socket * sock,struct sk_buff * skb,u32 * secid)482163c1845bSPaul Moore int security_socket_getpeersec_dgram(struct socket *sock,
482263c1845bSPaul Moore 				     struct sk_buff *skb, u32 *secid)
482320510f2fSJames Morris {
4824260017f3SOndrej Mosnacek 	return call_int_hook(socket_getpeersec_dgram, sock, skb, secid);
482520510f2fSJames Morris }
482620510f2fSJames Morris EXPORT_SYMBOL(security_socket_getpeersec_dgram);
482720510f2fSJames Morris 
48286b6bbe8cSPaul Moore /**
48292aff9d20SCasey Schaufler  * lsm_sock_alloc - allocate a composite sock blob
48302aff9d20SCasey Schaufler  * @sock: the sock that needs a blob
483109001284SCasey Schaufler  * @gfp: allocation mode
48322aff9d20SCasey Schaufler  *
48332aff9d20SCasey Schaufler  * Allocate the sock blob for all the modules
48342aff9d20SCasey Schaufler  *
48352aff9d20SCasey Schaufler  * Returns 0, or -ENOMEM if memory can't be allocated.
48362aff9d20SCasey Schaufler  */
lsm_sock_alloc(struct sock * sock,gfp_t gfp)483709001284SCasey Schaufler static int lsm_sock_alloc(struct sock *sock, gfp_t gfp)
48382aff9d20SCasey Schaufler {
483909001284SCasey Schaufler 	return lsm_blob_alloc(&sock->sk_security, blob_sizes.lbs_sock, gfp);
48402aff9d20SCasey Schaufler }
48412aff9d20SCasey Schaufler 
48422aff9d20SCasey Schaufler /**
48436b6bbe8cSPaul Moore  * security_sk_alloc() - Allocate and initialize a sock's LSM blob
48446b6bbe8cSPaul Moore  * @sk: sock
48456b6bbe8cSPaul Moore  * @family: protocol family
48461e2523d7SPaul Moore  * @priority: gfp flags
48476b6bbe8cSPaul Moore  *
48486b6bbe8cSPaul Moore  * Allocate and attach a security structure to the sk->sk_security field, which
48496b6bbe8cSPaul Moore  * is used to copy security attributes between local stream sockets.
48506b6bbe8cSPaul Moore  *
48516b6bbe8cSPaul Moore  * Return: Returns 0 on success, error on failure.
48526b6bbe8cSPaul Moore  */
security_sk_alloc(struct sock * sk,int family,gfp_t priority)485320510f2fSJames Morris int security_sk_alloc(struct sock *sk, int family, gfp_t priority)
485420510f2fSJames Morris {
48552aff9d20SCasey Schaufler 	int rc = lsm_sock_alloc(sk, priority);
48562aff9d20SCasey Schaufler 
48572aff9d20SCasey Schaufler 	if (unlikely(rc))
48582aff9d20SCasey Schaufler 		return rc;
48592aff9d20SCasey Schaufler 	rc = call_int_hook(sk_alloc_security, sk, family, priority);
48602aff9d20SCasey Schaufler 	if (unlikely(rc))
48612aff9d20SCasey Schaufler 		security_sk_free(sk);
48622aff9d20SCasey Schaufler 	return rc;
486320510f2fSJames Morris }
486420510f2fSJames Morris 
48656b6bbe8cSPaul Moore /**
48666b6bbe8cSPaul Moore  * security_sk_free() - Free the sock's LSM blob
48676b6bbe8cSPaul Moore  * @sk: sock
48686b6bbe8cSPaul Moore  *
48696b6bbe8cSPaul Moore  * Deallocate security structure.
48706b6bbe8cSPaul Moore  */
security_sk_free(struct sock * sk)487120510f2fSJames Morris void security_sk_free(struct sock *sk)
487220510f2fSJames Morris {
4873f25fce3eSCasey Schaufler 	call_void_hook(sk_free_security, sk);
48742aff9d20SCasey Schaufler 	kfree(sk->sk_security);
48752aff9d20SCasey Schaufler 	sk->sk_security = NULL;
487620510f2fSJames Morris }
487720510f2fSJames Morris 
48786b6bbe8cSPaul Moore /**
48796b6bbe8cSPaul Moore  * security_sk_clone() - Clone a sock's LSM state
48806b6bbe8cSPaul Moore  * @sk: original sock
48816b6bbe8cSPaul Moore  * @newsk: target sock
48826b6bbe8cSPaul Moore  *
48836b6bbe8cSPaul Moore  * Clone/copy security structure.
48846b6bbe8cSPaul Moore  */
security_sk_clone(const struct sock * sk,struct sock * newsk)488520510f2fSJames Morris void security_sk_clone(const struct sock *sk, struct sock *newsk)
488620510f2fSJames Morris {
4887f25fce3eSCasey Schaufler 	call_void_hook(sk_clone_security, sk, newsk);
488820510f2fSJames Morris }
48896230c9b4SPaul Moore EXPORT_SYMBOL(security_sk_clone);
489020510f2fSJames Morris 
4891bd1f5934SKhadija Kamran /**
4892bd1f5934SKhadija Kamran  * security_sk_classify_flow() - Set a flow's secid based on socket
4893bd1f5934SKhadija Kamran  * @sk: original socket
4894bd1f5934SKhadija Kamran  * @flic: target flow
4895bd1f5934SKhadija Kamran  *
4896bd1f5934SKhadija Kamran  * Set the target flow's secid to socket's secid.
4897bd1f5934SKhadija Kamran  */
security_sk_classify_flow(const struct sock * sk,struct flowi_common * flic)48985b52ad34SGuillaume Nault void security_sk_classify_flow(const struct sock *sk, struct flowi_common *flic)
489920510f2fSJames Morris {
49003df98d79SPaul Moore 	call_void_hook(sk_getsecid, sk, &flic->flowic_secid);
490120510f2fSJames Morris }
490220510f2fSJames Morris EXPORT_SYMBOL(security_sk_classify_flow);
490320510f2fSJames Morris 
49046b6bbe8cSPaul Moore /**
49056b6bbe8cSPaul Moore  * security_req_classify_flow() - Set a flow's secid based on request_sock
49066b6bbe8cSPaul Moore  * @req: request_sock
49076b6bbe8cSPaul Moore  * @flic: target flow
49086b6bbe8cSPaul Moore  *
49096b6bbe8cSPaul Moore  * Sets @flic's secid to @req's secid.
49106b6bbe8cSPaul Moore  */
security_req_classify_flow(const struct request_sock * req,struct flowi_common * flic)49113df98d79SPaul Moore void security_req_classify_flow(const struct request_sock *req,
49123df98d79SPaul Moore 				struct flowi_common *flic)
491320510f2fSJames Morris {
49143df98d79SPaul Moore 	call_void_hook(req_classify_flow, req, flic);
491520510f2fSJames Morris }
491620510f2fSJames Morris EXPORT_SYMBOL(security_req_classify_flow);
491720510f2fSJames Morris 
49186b6bbe8cSPaul Moore /**
49196b6bbe8cSPaul Moore  * security_sock_graft() - Reconcile LSM state when grafting a sock on a socket
49206b6bbe8cSPaul Moore  * @sk: sock being grafted
49211e2523d7SPaul Moore  * @parent: target parent socket
49226b6bbe8cSPaul Moore  *
49231e2523d7SPaul Moore  * Sets @parent's inode secid to @sk's secid and update @sk with any necessary
49241e2523d7SPaul Moore  * LSM state from @parent.
49256b6bbe8cSPaul Moore  */
security_sock_graft(struct sock * sk,struct socket * parent)492620510f2fSJames Morris void security_sock_graft(struct sock *sk, struct socket *parent)
492720510f2fSJames Morris {
4928f25fce3eSCasey Schaufler 	call_void_hook(sock_graft, sk, parent);
492920510f2fSJames Morris }
493020510f2fSJames Morris EXPORT_SYMBOL(security_sock_graft);
493120510f2fSJames Morris 
49326b6bbe8cSPaul Moore /**
49336b6bbe8cSPaul Moore  * security_inet_conn_request() - Set request_sock state using incoming connect
49346b6bbe8cSPaul Moore  * @sk: parent listening sock
49356b6bbe8cSPaul Moore  * @skb: incoming connection
49366b6bbe8cSPaul Moore  * @req: new request_sock
49376b6bbe8cSPaul Moore  *
49386b6bbe8cSPaul Moore  * Initialize the @req LSM state based on @sk and the incoming connect in @skb.
49396b6bbe8cSPaul Moore  *
49406b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
49416b6bbe8cSPaul Moore  */
security_inet_conn_request(const struct sock * sk,struct sk_buff * skb,struct request_sock * req)494241dd9596SFlorian Westphal int security_inet_conn_request(const struct sock *sk,
494320510f2fSJames Morris 			       struct sk_buff *skb, struct request_sock *req)
494420510f2fSJames Morris {
4945260017f3SOndrej Mosnacek 	return call_int_hook(inet_conn_request, sk, skb, req);
494620510f2fSJames Morris }
494720510f2fSJames Morris EXPORT_SYMBOL(security_inet_conn_request);
494820510f2fSJames Morris 
49496b6bbe8cSPaul Moore /**
49506b6bbe8cSPaul Moore  * security_inet_csk_clone() - Set new sock LSM state based on request_sock
49516b6bbe8cSPaul Moore  * @newsk: new sock
49526b6bbe8cSPaul Moore  * @req: connection request_sock
49536b6bbe8cSPaul Moore  *
49546b6bbe8cSPaul Moore  * Set that LSM state of @sock using the LSM state from @req.
49556b6bbe8cSPaul Moore  */
security_inet_csk_clone(struct sock * newsk,const struct request_sock * req)495620510f2fSJames Morris void security_inet_csk_clone(struct sock *newsk,
495720510f2fSJames Morris 			     const struct request_sock *req)
495820510f2fSJames Morris {
4959f25fce3eSCasey Schaufler 	call_void_hook(inet_csk_clone, newsk, req);
496020510f2fSJames Morris }
496120510f2fSJames Morris 
49626b6bbe8cSPaul Moore /**
49636b6bbe8cSPaul Moore  * security_inet_conn_established() - Update sock's LSM state with connection
49646b6bbe8cSPaul Moore  * @sk: sock
49656b6bbe8cSPaul Moore  * @skb: connection packet
49666b6bbe8cSPaul Moore  *
49676b6bbe8cSPaul Moore  * Update @sock's LSM state to represent a new connection from @skb.
49686b6bbe8cSPaul Moore  */
security_inet_conn_established(struct sock * sk,struct sk_buff * skb)496920510f2fSJames Morris void security_inet_conn_established(struct sock *sk,
497020510f2fSJames Morris 				    struct sk_buff *skb)
497120510f2fSJames Morris {
4972f25fce3eSCasey Schaufler 	call_void_hook(inet_conn_established, sk, skb);
497320510f2fSJames Morris }
497472e89f50SRichard Haines EXPORT_SYMBOL(security_inet_conn_established);
497520510f2fSJames Morris 
49766b6bbe8cSPaul Moore /**
49776b6bbe8cSPaul Moore  * security_secmark_relabel_packet() - Check if setting a secmark is allowed
49786b6bbe8cSPaul Moore  * @secid: new secmark value
49796b6bbe8cSPaul Moore  *
49806b6bbe8cSPaul Moore  * Check if the process should be allowed to relabel packets to @secid.
49816b6bbe8cSPaul Moore  *
49826b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
49836b6bbe8cSPaul Moore  */
security_secmark_relabel_packet(u32 secid)49842606fd1fSEric Paris int security_secmark_relabel_packet(u32 secid)
49852606fd1fSEric Paris {
4986260017f3SOndrej Mosnacek 	return call_int_hook(secmark_relabel_packet, secid);
49872606fd1fSEric Paris }
49882606fd1fSEric Paris EXPORT_SYMBOL(security_secmark_relabel_packet);
49892606fd1fSEric Paris 
49906b6bbe8cSPaul Moore /**
49916b6bbe8cSPaul Moore  * security_secmark_refcount_inc() - Increment the secmark labeling rule count
49926b6bbe8cSPaul Moore  *
49936b6bbe8cSPaul Moore  * Tells the LSM to increment the number of secmark labeling rules loaded.
49946b6bbe8cSPaul Moore  */
security_secmark_refcount_inc(void)49952606fd1fSEric Paris void security_secmark_refcount_inc(void)
49962606fd1fSEric Paris {
4997f25fce3eSCasey Schaufler 	call_void_hook(secmark_refcount_inc);
49982606fd1fSEric Paris }
49992606fd1fSEric Paris EXPORT_SYMBOL(security_secmark_refcount_inc);
50002606fd1fSEric Paris 
50016b6bbe8cSPaul Moore /**
50026b6bbe8cSPaul Moore  * security_secmark_refcount_dec() - Decrement the secmark labeling rule count
50036b6bbe8cSPaul Moore  *
50046b6bbe8cSPaul Moore  * Tells the LSM to decrement the number of secmark labeling rules loaded.
50056b6bbe8cSPaul Moore  */
security_secmark_refcount_dec(void)50062606fd1fSEric Paris void security_secmark_refcount_dec(void)
50072606fd1fSEric Paris {
5008f25fce3eSCasey Schaufler 	call_void_hook(secmark_refcount_dec);
50092606fd1fSEric Paris }
50102606fd1fSEric Paris EXPORT_SYMBOL(security_secmark_refcount_dec);
50112606fd1fSEric Paris 
50126b6bbe8cSPaul Moore /**
50136b6bbe8cSPaul Moore  * security_tun_dev_alloc_security() - Allocate a LSM blob for a TUN device
50146b6bbe8cSPaul Moore  * @security: pointer to the LSM blob
50156b6bbe8cSPaul Moore  *
50166b6bbe8cSPaul Moore  * This hook allows a module to allocate a security structure for a TUN	device,
50176b6bbe8cSPaul Moore  * returning the pointer in @security.
50186b6bbe8cSPaul Moore  *
50196b6bbe8cSPaul Moore  * Return: Returns a zero on success, negative values on failure.
50206b6bbe8cSPaul Moore  */
security_tun_dev_alloc_security(void ** security)50215dbbaf2dSPaul Moore int security_tun_dev_alloc_security(void **security)
50225dbbaf2dSPaul Moore {
5023a39c0f77SCasey Schaufler 	int rc;
5024a39c0f77SCasey Schaufler 
5025a39c0f77SCasey Schaufler 	rc = lsm_blob_alloc(security, blob_sizes.lbs_tun_dev, GFP_KERNEL);
5026a39c0f77SCasey Schaufler 	if (rc)
5027a39c0f77SCasey Schaufler 		return rc;
5028a39c0f77SCasey Schaufler 
5029a39c0f77SCasey Schaufler 	rc = call_int_hook(tun_dev_alloc_security, *security);
5030a39c0f77SCasey Schaufler 	if (rc) {
5031a39c0f77SCasey Schaufler 		kfree(*security);
5032a39c0f77SCasey Schaufler 		*security = NULL;
5033a39c0f77SCasey Schaufler 	}
5034a39c0f77SCasey Schaufler 	return rc;
50355dbbaf2dSPaul Moore }
50365dbbaf2dSPaul Moore EXPORT_SYMBOL(security_tun_dev_alloc_security);
50375dbbaf2dSPaul Moore 
50386b6bbe8cSPaul Moore /**
50396b6bbe8cSPaul Moore  * security_tun_dev_free_security() - Free a TUN device LSM blob
50406b6bbe8cSPaul Moore  * @security: LSM blob
50416b6bbe8cSPaul Moore  *
50426b6bbe8cSPaul Moore  * This hook allows a module to free the security structure for a TUN device.
50436b6bbe8cSPaul Moore  */
security_tun_dev_free_security(void * security)50445dbbaf2dSPaul Moore void security_tun_dev_free_security(void *security)
50455dbbaf2dSPaul Moore {
5046a39c0f77SCasey Schaufler 	kfree(security);
50475dbbaf2dSPaul Moore }
50485dbbaf2dSPaul Moore EXPORT_SYMBOL(security_tun_dev_free_security);
50495dbbaf2dSPaul Moore 
50506b6bbe8cSPaul Moore /**
50516b6bbe8cSPaul Moore  * security_tun_dev_create() - Check if creating a TUN device is allowed
50526b6bbe8cSPaul Moore  *
50536b6bbe8cSPaul Moore  * Check permissions prior to creating a new TUN device.
50546b6bbe8cSPaul Moore  *
50556b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
50566b6bbe8cSPaul Moore  */
security_tun_dev_create(void)50572b980dbdSPaul Moore int security_tun_dev_create(void)
50582b980dbdSPaul Moore {
5059260017f3SOndrej Mosnacek 	return call_int_hook(tun_dev_create);
50602b980dbdSPaul Moore }
50612b980dbdSPaul Moore EXPORT_SYMBOL(security_tun_dev_create);
50622b980dbdSPaul Moore 
50636b6bbe8cSPaul Moore /**
50646b6bbe8cSPaul Moore  * security_tun_dev_attach_queue() - Check if attaching a TUN queue is allowed
50656b6bbe8cSPaul Moore  * @security: TUN device LSM blob
50666b6bbe8cSPaul Moore  *
50676b6bbe8cSPaul Moore  * Check permissions prior to attaching to a TUN device queue.
50686b6bbe8cSPaul Moore  *
50696b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
50706b6bbe8cSPaul Moore  */
security_tun_dev_attach_queue(void * security)50715dbbaf2dSPaul Moore int security_tun_dev_attach_queue(void *security)
50722b980dbdSPaul Moore {
5073260017f3SOndrej Mosnacek 	return call_int_hook(tun_dev_attach_queue, security);
50742b980dbdSPaul Moore }
50755dbbaf2dSPaul Moore EXPORT_SYMBOL(security_tun_dev_attach_queue);
50762b980dbdSPaul Moore 
50776b6bbe8cSPaul Moore /**
50786b6bbe8cSPaul Moore  * security_tun_dev_attach() - Update TUN device LSM state on attach
50796b6bbe8cSPaul Moore  * @sk: associated sock
50806b6bbe8cSPaul Moore  * @security: TUN device LSM blob
50816b6bbe8cSPaul Moore  *
50826b6bbe8cSPaul Moore  * This hook can be used by the module to update any security state associated
50836b6bbe8cSPaul Moore  * with the TUN device's sock structure.
50846b6bbe8cSPaul Moore  *
50856b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
50866b6bbe8cSPaul Moore  */
security_tun_dev_attach(struct sock * sk,void * security)50875dbbaf2dSPaul Moore int security_tun_dev_attach(struct sock *sk, void *security)
50882b980dbdSPaul Moore {
5089260017f3SOndrej Mosnacek 	return call_int_hook(tun_dev_attach, sk, security);
50902b980dbdSPaul Moore }
50912b980dbdSPaul Moore EXPORT_SYMBOL(security_tun_dev_attach);
50922b980dbdSPaul Moore 
50936b6bbe8cSPaul Moore /**
50946b6bbe8cSPaul Moore  * security_tun_dev_open() - Update TUN device LSM state on open
50956b6bbe8cSPaul Moore  * @security: TUN device LSM blob
50966b6bbe8cSPaul Moore  *
50976b6bbe8cSPaul Moore  * This hook can be used by the module to update any security state associated
50986b6bbe8cSPaul Moore  * with the TUN device's security structure.
50996b6bbe8cSPaul Moore  *
51006b6bbe8cSPaul Moore  * Return: Returns 0 if permission is granted.
51016b6bbe8cSPaul Moore  */
security_tun_dev_open(void * security)51025dbbaf2dSPaul Moore int security_tun_dev_open(void *security)
51035dbbaf2dSPaul Moore {
5104260017f3SOndrej Mosnacek 	return call_int_hook(tun_dev_open, security);
51055dbbaf2dSPaul Moore }
51065dbbaf2dSPaul Moore EXPORT_SYMBOL(security_tun_dev_open);
51075dbbaf2dSPaul Moore 
51084a49f592SPaul Moore /**
51094a49f592SPaul Moore  * security_sctp_assoc_request() - Update the LSM on a SCTP association req
51104a49f592SPaul Moore  * @asoc: SCTP association
51114a49f592SPaul Moore  * @skb: packet requesting the association
51124a49f592SPaul Moore  *
51134a49f592SPaul Moore  * Passes the @asoc and @chunk->skb of the association INIT packet to the LSM.
51144a49f592SPaul Moore  *
51154a49f592SPaul Moore  * Return: Returns 0 on success, error on failure.
51164a49f592SPaul Moore  */
security_sctp_assoc_request(struct sctp_association * asoc,struct sk_buff * skb)511763c1845bSPaul Moore int security_sctp_assoc_request(struct sctp_association *asoc,
511863c1845bSPaul Moore 				struct sk_buff *skb)
511972e89f50SRichard Haines {
5120260017f3SOndrej Mosnacek 	return call_int_hook(sctp_assoc_request, asoc, skb);
512172e89f50SRichard Haines }
512272e89f50SRichard Haines EXPORT_SYMBOL(security_sctp_assoc_request);
512372e89f50SRichard Haines 
51244a49f592SPaul Moore /**
51254a49f592SPaul Moore  * security_sctp_bind_connect() - Validate a list of addrs for a SCTP option
51264a49f592SPaul Moore  * @sk: socket
51274a49f592SPaul Moore  * @optname: SCTP option to validate
51284a49f592SPaul Moore  * @address: list of IP addresses to validate
51294a49f592SPaul Moore  * @addrlen: length of the address list
51304a49f592SPaul Moore  *
51314a49f592SPaul Moore  * Validiate permissions required for each address associated with sock	@sk.
51324a49f592SPaul Moore  * Depending on @optname, the addresses will be treated as either a connect or
51334a49f592SPaul Moore  * bind service. The @addrlen is calculated on each IPv4 and IPv6 address using
51344a49f592SPaul Moore  * sizeof(struct sockaddr_in) or sizeof(struct sockaddr_in6).
51354a49f592SPaul Moore  *
51364a49f592SPaul Moore  * Return: Returns 0 on success, error on failure.
51374a49f592SPaul Moore  */
security_sctp_bind_connect(struct sock * sk,int optname,struct sockaddr * address,int addrlen)513872e89f50SRichard Haines int security_sctp_bind_connect(struct sock *sk, int optname,
513972e89f50SRichard Haines 			       struct sockaddr *address, int addrlen)
514072e89f50SRichard Haines {
5141260017f3SOndrej Mosnacek 	return call_int_hook(sctp_bind_connect, sk, optname, address, addrlen);
514272e89f50SRichard Haines }
514372e89f50SRichard Haines EXPORT_SYMBOL(security_sctp_bind_connect);
514472e89f50SRichard Haines 
51454a49f592SPaul Moore /**
51464a49f592SPaul Moore  * security_sctp_sk_clone() - Clone a SCTP sock's LSM state
51474a49f592SPaul Moore  * @asoc: SCTP association
51484a49f592SPaul Moore  * @sk: original sock
51494a49f592SPaul Moore  * @newsk: target sock
51504a49f592SPaul Moore  *
51514a49f592SPaul Moore  * Called whenever a new socket is created by accept(2) (i.e. a TCP style
51524a49f592SPaul Moore  * socket) or when a socket is 'peeled off' e.g userspace calls
51534a49f592SPaul Moore  * sctp_peeloff(3).
51544a49f592SPaul Moore  */
security_sctp_sk_clone(struct sctp_association * asoc,struct sock * sk,struct sock * newsk)5155c081d53fSXin Long void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk,
515672e89f50SRichard Haines 			    struct sock *newsk)
515772e89f50SRichard Haines {
5158c081d53fSXin Long 	call_void_hook(sctp_sk_clone, asoc, sk, newsk);
515972e89f50SRichard Haines }
516072e89f50SRichard Haines EXPORT_SYMBOL(security_sctp_sk_clone);
516172e89f50SRichard Haines 
51624a49f592SPaul Moore /**
51634a49f592SPaul Moore  * security_sctp_assoc_established() - Update LSM state when assoc established
51644a49f592SPaul Moore  * @asoc: SCTP association
51654a49f592SPaul Moore  * @skb: packet establishing the association
51664a49f592SPaul Moore  *
51674a49f592SPaul Moore  * Passes the @asoc and @chunk->skb of the association COOKIE_ACK packet to the
51684a49f592SPaul Moore  * security module.
51694a49f592SPaul Moore  *
51704a49f592SPaul Moore  * Return: Returns 0 if permission is granted.
51714a49f592SPaul Moore  */
security_sctp_assoc_established(struct sctp_association * asoc,struct sk_buff * skb)51725e50f5d4SOndrej Mosnacek int security_sctp_assoc_established(struct sctp_association *asoc,
51735e50f5d4SOndrej Mosnacek 				    struct sk_buff *skb)
51745e50f5d4SOndrej Mosnacek {
5175260017f3SOndrej Mosnacek 	return call_int_hook(sctp_assoc_established, asoc, skb);
51765e50f5d4SOndrej Mosnacek }
51775e50f5d4SOndrej Mosnacek EXPORT_SYMBOL(security_sctp_assoc_established);
51785e50f5d4SOndrej Mosnacek 
5179e3d9387fSPaolo Abeni /**
5180e3d9387fSPaolo Abeni  * security_mptcp_add_subflow() - Inherit the LSM label from the MPTCP socket
5181e3d9387fSPaolo Abeni  * @sk: the owning MPTCP socket
5182e3d9387fSPaolo Abeni  * @ssk: the new subflow
5183e3d9387fSPaolo Abeni  *
5184e3d9387fSPaolo Abeni  * Update the labeling for the given MPTCP subflow, to match the one of the
5185e3d9387fSPaolo Abeni  * owning MPTCP socket. This hook has to be called after the socket creation and
5186e3d9387fSPaolo Abeni  * initialization via the security_socket_create() and
5187e3d9387fSPaolo Abeni  * security_socket_post_create() LSM hooks.
5188e3d9387fSPaolo Abeni  *
5189e3d9387fSPaolo Abeni  * Return: Returns 0 on success or a negative error code on failure.
5190e3d9387fSPaolo Abeni  */
security_mptcp_add_subflow(struct sock * sk,struct sock * ssk)5191e3d9387fSPaolo Abeni int security_mptcp_add_subflow(struct sock *sk, struct sock *ssk)
5192e3d9387fSPaolo Abeni {
5193260017f3SOndrej Mosnacek 	return call_int_hook(mptcp_add_subflow, sk, ssk);
5194e3d9387fSPaolo Abeni }
5195e3d9387fSPaolo Abeni 
519620510f2fSJames Morris #endif	/* CONFIG_SECURITY_NETWORK */
519720510f2fSJames Morris 
5198d291f1a6SDaniel Jurgens #ifdef CONFIG_SECURITY_INFINIBAND
5199ac318aedSPaul Moore /**
5200ac318aedSPaul Moore  * security_ib_pkey_access() - Check if access to an IB pkey is allowed
5201ac318aedSPaul Moore  * @sec: LSM blob
5202ac318aedSPaul Moore  * @subnet_prefix: subnet prefix of the port
5203ac318aedSPaul Moore  * @pkey: IB pkey
5204ac318aedSPaul Moore  *
52054432b507SPaul Moore  * Check permission to access a pkey when modifying a QP.
5206ac318aedSPaul Moore  *
5207ac318aedSPaul Moore  * Return: Returns 0 if permission is granted.
5208ac318aedSPaul Moore  */
security_ib_pkey_access(void * sec,u64 subnet_prefix,u16 pkey)5209d291f1a6SDaniel Jurgens int security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey)
5210d291f1a6SDaniel Jurgens {
5211260017f3SOndrej Mosnacek 	return call_int_hook(ib_pkey_access, sec, subnet_prefix, pkey);
5212d291f1a6SDaniel Jurgens }
5213d291f1a6SDaniel Jurgens EXPORT_SYMBOL(security_ib_pkey_access);
5214d291f1a6SDaniel Jurgens 
5215ac318aedSPaul Moore /**
5216ac318aedSPaul Moore  * security_ib_endport_manage_subnet() - Check if SMPs traffic is allowed
5217ac318aedSPaul Moore  * @sec: LSM blob
5218ac318aedSPaul Moore  * @dev_name: IB device name
5219ac318aedSPaul Moore  * @port_num: port number
5220ac318aedSPaul Moore  *
5221ac318aedSPaul Moore  * Check permissions to send and receive SMPs on a end port.
5222ac318aedSPaul Moore  *
5223ac318aedSPaul Moore  * Return: Returns 0 if permission is granted.
5224ac318aedSPaul Moore  */
security_ib_endport_manage_subnet(void * sec,const char * dev_name,u8 port_num)522563c1845bSPaul Moore int security_ib_endport_manage_subnet(void *sec,
522663c1845bSPaul Moore 				      const char *dev_name, u8 port_num)
522747a2b338SDaniel Jurgens {
5228260017f3SOndrej Mosnacek 	return call_int_hook(ib_endport_manage_subnet, sec, dev_name, port_num);
522947a2b338SDaniel Jurgens }
523047a2b338SDaniel Jurgens EXPORT_SYMBOL(security_ib_endport_manage_subnet);
523147a2b338SDaniel Jurgens 
5232ac318aedSPaul Moore /**
5233ac318aedSPaul Moore  * security_ib_alloc_security() - Allocate an Infiniband LSM blob
5234ac318aedSPaul Moore  * @sec: LSM blob
5235ac318aedSPaul Moore  *
5236ac318aedSPaul Moore  * Allocate a security structure for Infiniband objects.
5237ac318aedSPaul Moore  *
5238ac318aedSPaul Moore  * Return: Returns 0 on success, non-zero on failure.
5239ac318aedSPaul Moore  */
security_ib_alloc_security(void ** sec)5240d291f1a6SDaniel Jurgens int security_ib_alloc_security(void **sec)
5241d291f1a6SDaniel Jurgens {
524266de33a0SCasey Schaufler 	int rc;
524366de33a0SCasey Schaufler 
524466de33a0SCasey Schaufler 	rc = lsm_blob_alloc(sec, blob_sizes.lbs_ib, GFP_KERNEL);
524566de33a0SCasey Schaufler 	if (rc)
524666de33a0SCasey Schaufler 		return rc;
524766de33a0SCasey Schaufler 
524866de33a0SCasey Schaufler 	rc = call_int_hook(ib_alloc_security, *sec);
524966de33a0SCasey Schaufler 	if (rc) {
525066de33a0SCasey Schaufler 		kfree(*sec);
525166de33a0SCasey Schaufler 		*sec = NULL;
525266de33a0SCasey Schaufler 	}
525366de33a0SCasey Schaufler 	return rc;
5254d291f1a6SDaniel Jurgens }
5255d291f1a6SDaniel Jurgens EXPORT_SYMBOL(security_ib_alloc_security);
5256d291f1a6SDaniel Jurgens 
5257ac318aedSPaul Moore /**
5258ac318aedSPaul Moore  * security_ib_free_security() - Free an Infiniband LSM blob
5259ac318aedSPaul Moore  * @sec: LSM blob
5260ac318aedSPaul Moore  *
5261ac318aedSPaul Moore  * Deallocate an Infiniband security structure.
5262ac318aedSPaul Moore  */
security_ib_free_security(void * sec)5263d291f1a6SDaniel Jurgens void security_ib_free_security(void *sec)
5264d291f1a6SDaniel Jurgens {
526566de33a0SCasey Schaufler 	kfree(sec);
5266d291f1a6SDaniel Jurgens }
5267d291f1a6SDaniel Jurgens EXPORT_SYMBOL(security_ib_free_security);
5268d291f1a6SDaniel Jurgens #endif	/* CONFIG_SECURITY_INFINIBAND */
5269d291f1a6SDaniel Jurgens 
527020510f2fSJames Morris #ifdef CONFIG_SECURITY_NETWORK_XFRM
5271742b9945SPaul Moore /**
5272742b9945SPaul Moore  * security_xfrm_policy_alloc() - Allocate a xfrm policy LSM blob
5273742b9945SPaul Moore  * @ctxp: xfrm security context being added to the SPD
5274742b9945SPaul Moore  * @sec_ctx: security label provided by userspace
5275742b9945SPaul Moore  * @gfp: gfp flags
5276742b9945SPaul Moore  *
5277742b9945SPaul Moore  * Allocate a security structure to the xp->security field; the security field
5278742b9945SPaul Moore  * is initialized to NULL when the xfrm_policy is allocated.
5279742b9945SPaul Moore  *
5280742b9945SPaul Moore  * Return:  Return 0 if operation was successful.
5281742b9945SPaul Moore  */
security_xfrm_policy_alloc(struct xfrm_sec_ctx ** ctxp,struct xfrm_user_sec_ctx * sec_ctx,gfp_t gfp)528252a4c640SNikolay Aleksandrov int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
528352a4c640SNikolay Aleksandrov 			       struct xfrm_user_sec_ctx *sec_ctx,
528452a4c640SNikolay Aleksandrov 			       gfp_t gfp)
528520510f2fSJames Morris {
5286260017f3SOndrej Mosnacek 	return call_int_hook(xfrm_policy_alloc_security, ctxp, sec_ctx, gfp);
528720510f2fSJames Morris }
528820510f2fSJames Morris EXPORT_SYMBOL(security_xfrm_policy_alloc);
528920510f2fSJames Morris 
5290742b9945SPaul Moore /**
5291742b9945SPaul Moore  * security_xfrm_policy_clone() - Clone xfrm policy LSM state
5292742b9945SPaul Moore  * @old_ctx: xfrm security context
5293742b9945SPaul Moore  * @new_ctxp: target xfrm security context
5294742b9945SPaul Moore  *
5295742b9945SPaul Moore  * Allocate a security structure in new_ctxp that contains the information from
5296742b9945SPaul Moore  * the old_ctx structure.
5297742b9945SPaul Moore  *
5298742b9945SPaul Moore  * Return: Return 0 if operation was successful.
5299742b9945SPaul Moore  */
security_xfrm_policy_clone(struct xfrm_sec_ctx * old_ctx,struct xfrm_sec_ctx ** new_ctxp)530003e1ad7bSPaul Moore int security_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
530103e1ad7bSPaul Moore 			       struct xfrm_sec_ctx **new_ctxp)
530220510f2fSJames Morris {
5303260017f3SOndrej Mosnacek 	return call_int_hook(xfrm_policy_clone_security, old_ctx, new_ctxp);
530420510f2fSJames Morris }
530520510f2fSJames Morris 
5306742b9945SPaul Moore /**
5307742b9945SPaul Moore  * security_xfrm_policy_free() - Free a xfrm security context
5308742b9945SPaul Moore  * @ctx: xfrm security context
5309742b9945SPaul Moore  *
5310742b9945SPaul Moore  * Free LSM resources associated with @ctx.
5311742b9945SPaul Moore  */
security_xfrm_policy_free(struct xfrm_sec_ctx * ctx)531203e1ad7bSPaul Moore void security_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
531320510f2fSJames Morris {
5314f25fce3eSCasey Schaufler 	call_void_hook(xfrm_policy_free_security, ctx);
531520510f2fSJames Morris }
531620510f2fSJames Morris EXPORT_SYMBOL(security_xfrm_policy_free);
531720510f2fSJames Morris 
5318742b9945SPaul Moore /**
5319742b9945SPaul Moore  * security_xfrm_policy_delete() - Check if deleting a xfrm policy is allowed
5320742b9945SPaul Moore  * @ctx: xfrm security context
5321742b9945SPaul Moore  *
5322742b9945SPaul Moore  * Authorize deletion of a SPD entry.
5323742b9945SPaul Moore  *
5324742b9945SPaul Moore  * Return: Returns 0 if permission is granted.
5325742b9945SPaul Moore  */
security_xfrm_policy_delete(struct xfrm_sec_ctx * ctx)532603e1ad7bSPaul Moore int security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
532720510f2fSJames Morris {
5328260017f3SOndrej Mosnacek 	return call_int_hook(xfrm_policy_delete_security, ctx);
532920510f2fSJames Morris }
533020510f2fSJames Morris 
5331742b9945SPaul Moore /**
5332742b9945SPaul Moore  * security_xfrm_state_alloc() - Allocate a xfrm state LSM blob
5333742b9945SPaul Moore  * @x: xfrm state being added to the SAD
5334742b9945SPaul Moore  * @sec_ctx: security label provided by userspace
5335742b9945SPaul Moore  *
5336742b9945SPaul Moore  * Allocate a security structure to the @x->security field; the security field
5337742b9945SPaul Moore  * is initialized to NULL when the xfrm_state is allocated. Set the context to
5338742b9945SPaul Moore  * correspond to @sec_ctx.
5339742b9945SPaul Moore  *
5340742b9945SPaul Moore  * Return: Return 0 if operation was successful.
5341742b9945SPaul Moore  */
security_xfrm_state_alloc(struct xfrm_state * x,struct xfrm_user_sec_ctx * sec_ctx)53422e5aa866SPaul Moore int security_xfrm_state_alloc(struct xfrm_state *x,
53432e5aa866SPaul Moore 			      struct xfrm_user_sec_ctx *sec_ctx)
534420510f2fSJames Morris {
5345260017f3SOndrej Mosnacek 	return call_int_hook(xfrm_state_alloc, x, sec_ctx);
534620510f2fSJames Morris }
534720510f2fSJames Morris EXPORT_SYMBOL(security_xfrm_state_alloc);
534820510f2fSJames Morris 
5349742b9945SPaul Moore /**
5350742b9945SPaul Moore  * security_xfrm_state_alloc_acquire() - Allocate a xfrm state LSM blob
5351742b9945SPaul Moore  * @x: xfrm state being added to the SAD
5352742b9945SPaul Moore  * @polsec: associated policy's security context
5353742b9945SPaul Moore  * @secid: secid from the flow
5354742b9945SPaul Moore  *
5355742b9945SPaul Moore  * Allocate a security structure to the x->security field; the security field
5356742b9945SPaul Moore  * is initialized to NULL when the xfrm_state is allocated.  Set the context to
5357742b9945SPaul Moore  * correspond to secid.
5358742b9945SPaul Moore  *
5359742b9945SPaul Moore  * Return: Returns 0 if operation was successful.
5360742b9945SPaul Moore  */
security_xfrm_state_alloc_acquire(struct xfrm_state * x,struct xfrm_sec_ctx * polsec,u32 secid)536120510f2fSJames Morris int security_xfrm_state_alloc_acquire(struct xfrm_state *x,
536220510f2fSJames Morris 				      struct xfrm_sec_ctx *polsec, u32 secid)
536320510f2fSJames Morris {
5364260017f3SOndrej Mosnacek 	return call_int_hook(xfrm_state_alloc_acquire, x, polsec, secid);
536520510f2fSJames Morris }
536620510f2fSJames Morris 
5367742b9945SPaul Moore /**
5368742b9945SPaul Moore  * security_xfrm_state_delete() - Check if deleting a xfrm state is allowed
5369742b9945SPaul Moore  * @x: xfrm state
5370742b9945SPaul Moore  *
5371742b9945SPaul Moore  * Authorize deletion of x->security.
5372742b9945SPaul Moore  *
5373742b9945SPaul Moore  * Return: Returns 0 if permission is granted.
5374742b9945SPaul Moore  */
security_xfrm_state_delete(struct xfrm_state * x)537520510f2fSJames Morris int security_xfrm_state_delete(struct xfrm_state *x)
537620510f2fSJames Morris {
5377260017f3SOndrej Mosnacek 	return call_int_hook(xfrm_state_delete_security, x);
537820510f2fSJames Morris }
537920510f2fSJames Morris EXPORT_SYMBOL(security_xfrm_state_delete);
538020510f2fSJames Morris 
5381742b9945SPaul Moore /**
5382742b9945SPaul Moore  * security_xfrm_state_free() - Free a xfrm state
5383742b9945SPaul Moore  * @x: xfrm state
5384742b9945SPaul Moore  *
5385742b9945SPaul Moore  * Deallocate x->security.
5386742b9945SPaul Moore  */
security_xfrm_state_free(struct xfrm_state * x)538720510f2fSJames Morris void security_xfrm_state_free(struct xfrm_state *x)
538820510f2fSJames Morris {
5389f25fce3eSCasey Schaufler 	call_void_hook(xfrm_state_free_security, x);
539020510f2fSJames Morris }
539120510f2fSJames Morris 
5392742b9945SPaul Moore /**
5393742b9945SPaul Moore  * security_xfrm_policy_lookup() - Check if using a xfrm policy is allowed
5394742b9945SPaul Moore  * @ctx: target xfrm security context
5395742b9945SPaul Moore  * @fl_secid: flow secid used to authorize access
5396742b9945SPaul Moore  *
5397742b9945SPaul Moore  * Check permission when a flow selects a xfrm_policy for processing XFRMs on a
5398742b9945SPaul Moore  * packet.  The hook is called when selecting either a per-socket policy or a
5399742b9945SPaul Moore  * generic xfrm policy.
5400742b9945SPaul Moore  *
5401742b9945SPaul Moore  * Return: Return 0 if permission is granted, -ESRCH otherwise, or -errno on
5402742b9945SPaul Moore  *         other errors.
5403742b9945SPaul Moore  */
security_xfrm_policy_lookup(struct xfrm_sec_ctx * ctx,u32 fl_secid)54048a922805SZhongjun Tan int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid)
540520510f2fSJames Morris {
5406260017f3SOndrej Mosnacek 	return call_int_hook(xfrm_policy_lookup, ctx, fl_secid);
540720510f2fSJames Morris }
540820510f2fSJames Morris 
5409742b9945SPaul Moore /**
5410742b9945SPaul Moore  * security_xfrm_state_pol_flow_match() - Check for a xfrm match
5411742b9945SPaul Moore  * @x: xfrm state to match
54121e2523d7SPaul Moore  * @xp: xfrm policy to check for a match
5413742b9945SPaul Moore  * @flic: flow to check for a match.
5414742b9945SPaul Moore  *
5415742b9945SPaul Moore  * Check @xp and @flic for a match with @x.
5416742b9945SPaul Moore  *
5417742b9945SPaul Moore  * Return: Returns 1 if there is a match.
5418742b9945SPaul Moore  */
security_xfrm_state_pol_flow_match(struct xfrm_state * x,struct xfrm_policy * xp,const struct flowi_common * flic)541920510f2fSJames Morris int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
5420e33f7704SDavid S. Miller 				       struct xfrm_policy *xp,
54213df98d79SPaul Moore 				       const struct flowi_common *flic)
542220510f2fSJames Morris {
5423417c5643SKP Singh 	struct lsm_static_call *scall;
542498e828a0SKP Singh 	int rc = LSM_RET_DEFAULT(xfrm_state_pol_flow_match);
5425b1d9e6b0SCasey Schaufler 
5426b1d9e6b0SCasey Schaufler 	/*
5427b1d9e6b0SCasey Schaufler 	 * Since this function is expected to return 0 or 1, the judgment
5428b1d9e6b0SCasey Schaufler 	 * becomes difficult if multiple LSMs supply this call. Fortunately,
5429b1d9e6b0SCasey Schaufler 	 * we can use the first LSM's judgment because currently only SELinux
5430b1d9e6b0SCasey Schaufler 	 * supplies this call.
5431b1d9e6b0SCasey Schaufler 	 *
5432b1d9e6b0SCasey Schaufler 	 * For speed optimization, we explicitly break the loop rather than
5433b1d9e6b0SCasey Schaufler 	 * using the macro
5434b1d9e6b0SCasey Schaufler 	 */
5435417c5643SKP Singh 	lsm_for_each_hook(scall, xfrm_state_pol_flow_match) {
5436417c5643SKP Singh 		rc = scall->hl->hook.xfrm_state_pol_flow_match(x, xp, flic);
5437b1d9e6b0SCasey Schaufler 		break;
5438b1d9e6b0SCasey Schaufler 	}
5439b1d9e6b0SCasey Schaufler 	return rc;
544020510f2fSJames Morris }
544120510f2fSJames Morris 
5442742b9945SPaul Moore /**
5443742b9945SPaul Moore  * security_xfrm_decode_session() - Determine the xfrm secid for a packet
5444742b9945SPaul Moore  * @skb: xfrm packet
5445742b9945SPaul Moore  * @secid: secid
5446742b9945SPaul Moore  *
5447742b9945SPaul Moore  * Decode the packet in @skb and return the security label in @secid.
5448742b9945SPaul Moore  *
5449742b9945SPaul Moore  * Return: Return 0 if all xfrms used have the same secid.
5450742b9945SPaul Moore  */
security_xfrm_decode_session(struct sk_buff * skb,u32 * secid)545120510f2fSJames Morris int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid)
545220510f2fSJames Morris {
5453260017f3SOndrej Mosnacek 	return call_int_hook(xfrm_decode_session, skb, secid, 1);
545420510f2fSJames Morris }
545520510f2fSJames Morris 
security_skb_classify_flow(struct sk_buff * skb,struct flowi_common * flic)54563df98d79SPaul Moore void security_skb_classify_flow(struct sk_buff *skb, struct flowi_common *flic)
545720510f2fSJames Morris {
5458260017f3SOndrej Mosnacek 	int rc = call_int_hook(xfrm_decode_session, skb, &flic->flowic_secid,
5459f25fce3eSCasey Schaufler 			       0);
546020510f2fSJames Morris 
546120510f2fSJames Morris 	BUG_ON(rc);
546220510f2fSJames Morris }
546320510f2fSJames Morris EXPORT_SYMBOL(security_skb_classify_flow);
546420510f2fSJames Morris #endif	/* CONFIG_SECURITY_NETWORK_XFRM */
546520510f2fSJames Morris 
546620510f2fSJames Morris #ifdef CONFIG_KEYS
5467ecc419a4SPaul Moore /**
5468ecc419a4SPaul Moore  * security_key_alloc() - Allocate and initialize a kernel key LSM blob
5469ecc419a4SPaul Moore  * @key: key
5470ecc419a4SPaul Moore  * @cred: credentials
5471ecc419a4SPaul Moore  * @flags: allocation flags
5472ecc419a4SPaul Moore  *
5473ecc419a4SPaul Moore  * Permit allocation of a key and assign security data. Note that key does not
5474ecc419a4SPaul Moore  * have a serial number assigned at this point.
5475ecc419a4SPaul Moore  *
5476ecc419a4SPaul Moore  * Return: Return 0 if permission is granted, -ve error otherwise.
5477ecc419a4SPaul Moore  */
security_key_alloc(struct key * key,const struct cred * cred,unsigned long flags)5478d84f4f99SDavid Howells int security_key_alloc(struct key *key, const struct cred *cred,
5479d84f4f99SDavid Howells 		       unsigned long flags)
548020510f2fSJames Morris {
54815f8d28f6SCasey Schaufler 	int rc = lsm_key_alloc(key);
54825f8d28f6SCasey Schaufler 
54835f8d28f6SCasey Schaufler 	if (unlikely(rc))
54845f8d28f6SCasey Schaufler 		return rc;
54855f8d28f6SCasey Schaufler 	rc = call_int_hook(key_alloc, key, cred, flags);
54865f8d28f6SCasey Schaufler 	if (unlikely(rc))
54875f8d28f6SCasey Schaufler 		security_key_free(key);
54885f8d28f6SCasey Schaufler 	return rc;
548920510f2fSJames Morris }
549020510f2fSJames Morris 
5491ecc419a4SPaul Moore /**
5492ecc419a4SPaul Moore  * security_key_free() - Free a kernel key LSM blob
5493ecc419a4SPaul Moore  * @key: key
5494ecc419a4SPaul Moore  *
5495ecc419a4SPaul Moore  * Notification of destruction; free security data.
5496ecc419a4SPaul Moore  */
security_key_free(struct key * key)549720510f2fSJames Morris void security_key_free(struct key *key)
549820510f2fSJames Morris {
54995f8d28f6SCasey Schaufler 	kfree(key->security);
55005f8d28f6SCasey Schaufler 	key->security = NULL;
550120510f2fSJames Morris }
550220510f2fSJames Morris 
5503ecc419a4SPaul Moore /**
5504ecc419a4SPaul Moore  * security_key_permission() - Check if a kernel key operation is allowed
5505ecc419a4SPaul Moore  * @key_ref: key reference
5506ecc419a4SPaul Moore  * @cred: credentials of actor requesting access
5507ecc419a4SPaul Moore  * @need_perm: requested permissions
5508ecc419a4SPaul Moore  *
5509ecc419a4SPaul Moore  * See whether a specific operational right is granted to a process on a key.
5510ecc419a4SPaul Moore  *
5511ecc419a4SPaul Moore  * Return: Return 0 if permission is granted, -ve error otherwise.
5512ecc419a4SPaul Moore  */
security_key_permission(key_ref_t key_ref,const struct cred * cred,enum key_need_perm need_perm)55138c0637e9SDavid Howells int security_key_permission(key_ref_t key_ref, const struct cred *cred,
55148c0637e9SDavid Howells 			    enum key_need_perm need_perm)
551520510f2fSJames Morris {
5516260017f3SOndrej Mosnacek 	return call_int_hook(key_permission, key_ref, cred, need_perm);
551720510f2fSJames Morris }
551820510f2fSJames Morris 
5519ecc419a4SPaul Moore /**
5520ecc419a4SPaul Moore  * security_key_getsecurity() - Get the key's security label
5521ecc419a4SPaul Moore  * @key: key
5522b3816cf8SPaul Moore  * @buffer: security label buffer
5523ecc419a4SPaul Moore  *
5524ecc419a4SPaul Moore  * Get a textual representation of the security context attached to a key for
5525ecc419a4SPaul Moore  * the purposes of honouring KEYCTL_GETSECURITY.  This function allocates the
5526ecc419a4SPaul Moore  * storage for the NUL-terminated string and the caller should free it.
5527ecc419a4SPaul Moore  *
5528b3816cf8SPaul Moore  * Return: Returns the length of @buffer (including terminating NUL) or -ve if
5529ecc419a4SPaul Moore  *         an error occurs.  May also return 0 (and a NULL buffer pointer) if
5530ecc419a4SPaul Moore  *         there is no security label assigned to the key.
5531ecc419a4SPaul Moore  */
security_key_getsecurity(struct key * key,char ** buffer)5532b3816cf8SPaul Moore int security_key_getsecurity(struct key *key, char **buffer)
553370a5bb72SDavid Howells {
5534b3816cf8SPaul Moore 	*buffer = NULL;
5535260017f3SOndrej Mosnacek 	return call_int_hook(key_getsecurity, key, buffer);
553670a5bb72SDavid Howells }
5537b8d99703SRoberto Sassu 
5538b8d99703SRoberto Sassu /**
5539b8d99703SRoberto Sassu  * security_key_post_create_or_update() - Notification of key create or update
5540b8d99703SRoberto Sassu  * @keyring: keyring to which the key is linked to
5541b8d99703SRoberto Sassu  * @key: created or updated key
5542b8d99703SRoberto Sassu  * @payload: data used to instantiate or update the key
5543b8d99703SRoberto Sassu  * @payload_len: length of payload
5544b8d99703SRoberto Sassu  * @flags: key flags
5545b8d99703SRoberto Sassu  * @create: flag indicating whether the key was created or updated
5546b8d99703SRoberto Sassu  *
5547b8d99703SRoberto Sassu  * Notify the caller of a key creation or update.
5548b8d99703SRoberto Sassu  */
security_key_post_create_or_update(struct key * keyring,struct key * key,const void * payload,size_t payload_len,unsigned long flags,bool create)5549b8d99703SRoberto Sassu void security_key_post_create_or_update(struct key *keyring, struct key *key,
5550b8d99703SRoberto Sassu 					const void *payload, size_t payload_len,
5551b8d99703SRoberto Sassu 					unsigned long flags, bool create)
5552b8d99703SRoberto Sassu {
5553b8d99703SRoberto Sassu 	call_void_hook(key_post_create_or_update, keyring, key, payload,
5554b8d99703SRoberto Sassu 		       payload_len, flags, create);
555570a5bb72SDavid Howells }
555620510f2fSJames Morris #endif	/* CONFIG_KEYS */
555703d37d25SAhmed S. Darwish 
555803d37d25SAhmed S. Darwish #ifdef CONFIG_AUDIT
5559b14faf9cSPaul Moore /**
5560b14faf9cSPaul Moore  * security_audit_rule_init() - Allocate and init an LSM audit rule struct
5561b14faf9cSPaul Moore  * @field: audit action
5562b14faf9cSPaul Moore  * @op: rule operator
5563b14faf9cSPaul Moore  * @rulestr: rule context
5564b14faf9cSPaul Moore  * @lsmrule: receive buffer for audit rule struct
55659a95c5bfSGUO Zihua  * @gfp: GFP flag used for kmalloc
5566b14faf9cSPaul Moore  *
5567b14faf9cSPaul Moore  * Allocate and initialize an LSM audit rule structure.
5568b14faf9cSPaul Moore  *
5569b14faf9cSPaul Moore  * Return: Return 0 if @lsmrule has been successfully set, -EINVAL in case of
5570b14faf9cSPaul Moore  *         an invalid rule.
5571b14faf9cSPaul Moore  */
security_audit_rule_init(u32 field,u32 op,char * rulestr,void ** lsmrule,gfp_t gfp)55729a95c5bfSGUO Zihua int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule,
55739a95c5bfSGUO Zihua 			     gfp_t gfp)
557403d37d25SAhmed S. Darwish {
55759a95c5bfSGUO Zihua 	return call_int_hook(audit_rule_init, field, op, rulestr, lsmrule, gfp);
557603d37d25SAhmed S. Darwish }
557703d37d25SAhmed S. Darwish 
5578b14faf9cSPaul Moore /**
5579b14faf9cSPaul Moore  * security_audit_rule_known() - Check if an audit rule contains LSM fields
5580b14faf9cSPaul Moore  * @krule: audit rule
5581b14faf9cSPaul Moore  *
5582b14faf9cSPaul Moore  * Specifies whether given @krule contains any fields related to the current
5583b14faf9cSPaul Moore  * LSM.
5584b14faf9cSPaul Moore  *
5585b14faf9cSPaul Moore  * Return: Returns 1 in case of relation found, 0 otherwise.
5586b14faf9cSPaul Moore  */
security_audit_rule_known(struct audit_krule * krule)558703d37d25SAhmed S. Darwish int security_audit_rule_known(struct audit_krule *krule)
558803d37d25SAhmed S. Darwish {
5589260017f3SOndrej Mosnacek 	return call_int_hook(audit_rule_known, krule);
559003d37d25SAhmed S. Darwish }
559103d37d25SAhmed S. Darwish 
5592b14faf9cSPaul Moore /**
5593b14faf9cSPaul Moore  * security_audit_rule_free() - Free an LSM audit rule struct
5594b14faf9cSPaul Moore  * @lsmrule: audit rule struct
5595b14faf9cSPaul Moore  *
5596b14faf9cSPaul Moore  * Deallocate the LSM audit rule structure previously allocated by
5597b14faf9cSPaul Moore  * audit_rule_init().
5598b14faf9cSPaul Moore  */
security_audit_rule_free(void * lsmrule)559903d37d25SAhmed S. Darwish void security_audit_rule_free(void *lsmrule)
560003d37d25SAhmed S. Darwish {
5601f25fce3eSCasey Schaufler 	call_void_hook(audit_rule_free, lsmrule);
560203d37d25SAhmed S. Darwish }
560303d37d25SAhmed S. Darwish 
5604b14faf9cSPaul Moore /**
5605b14faf9cSPaul Moore  * security_audit_rule_match() - Check if a label matches an audit rule
5606870b7fdcSCasey Schaufler  * @prop: security label
5607b14faf9cSPaul Moore  * @field: LSM audit field
5608b14faf9cSPaul Moore  * @op: matching operator
5609b14faf9cSPaul Moore  * @lsmrule: audit rule
5610b14faf9cSPaul Moore  *
5611b14faf9cSPaul Moore  * Determine if given @secid matches a rule previously approved by
5612b14faf9cSPaul Moore  * security_audit_rule_known().
5613b14faf9cSPaul Moore  *
5614b14faf9cSPaul Moore  * Return: Returns 1 if secid matches the rule, 0 if it does not, -ERRNO on
5615b14faf9cSPaul Moore  *         failure.
5616b14faf9cSPaul Moore  */
security_audit_rule_match(struct lsm_prop * prop,u32 field,u32 op,void * lsmrule)5617870b7fdcSCasey Schaufler int security_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op,
5618870b7fdcSCasey Schaufler 			      void *lsmrule)
561903d37d25SAhmed S. Darwish {
5620870b7fdcSCasey Schaufler 	return call_int_hook(audit_rule_match, prop, field, op, lsmrule);
562103d37d25SAhmed S. Darwish }
562203d37d25SAhmed S. Darwish #endif /* CONFIG_AUDIT */
5623afdb09c7SChenbo Feng 
5624afdb09c7SChenbo Feng #ifdef CONFIG_BPF_SYSCALL
562555e85320SPaul Moore /**
562655e85320SPaul Moore  * security_bpf() - Check if the bpf syscall operation is allowed
562755e85320SPaul Moore  * @cmd: command
562855e85320SPaul Moore  * @attr: bpf attribute
562955e85320SPaul Moore  * @size: size
5630*082f1db0SBlaise Boscaccy  * @kernel: whether or not call originated from kernel
563155e85320SPaul Moore  *
563255e85320SPaul Moore  * Do a initial check for all bpf syscalls after the attribute is copied into
563355e85320SPaul Moore  * the kernel. The actual security module can implement their own rules to
563455e85320SPaul Moore  * check the specific cmd they need.
563555e85320SPaul Moore  *
563655e85320SPaul Moore  * Return: Returns 0 if permission is granted.
563755e85320SPaul Moore  */
security_bpf(int cmd,union bpf_attr * attr,unsigned int size,bool kernel)5638*082f1db0SBlaise Boscaccy int security_bpf(int cmd, union bpf_attr *attr, unsigned int size, bool kernel)
5639afdb09c7SChenbo Feng {
5640*082f1db0SBlaise Boscaccy 	return call_int_hook(bpf, cmd, attr, size, kernel);
5641afdb09c7SChenbo Feng }
564255e85320SPaul Moore 
564355e85320SPaul Moore /**
564455e85320SPaul Moore  * security_bpf_map() - Check if access to a bpf map is allowed
564555e85320SPaul Moore  * @map: bpf map
564655e85320SPaul Moore  * @fmode: mode
564755e85320SPaul Moore  *
564855e85320SPaul Moore  * Do a check when the kernel generates and returns a file descriptor for eBPF
564955e85320SPaul Moore  * maps.
565055e85320SPaul Moore  *
565155e85320SPaul Moore  * Return: Returns 0 if permission is granted.
565255e85320SPaul Moore  */
security_bpf_map(struct bpf_map * map,fmode_t fmode)5653afdb09c7SChenbo Feng int security_bpf_map(struct bpf_map *map, fmode_t fmode)
5654afdb09c7SChenbo Feng {
5655260017f3SOndrej Mosnacek 	return call_int_hook(bpf_map, map, fmode);
5656afdb09c7SChenbo Feng }
565755e85320SPaul Moore 
565855e85320SPaul Moore /**
565955e85320SPaul Moore  * security_bpf_prog() - Check if access to a bpf program is allowed
566055e85320SPaul Moore  * @prog: bpf program
566155e85320SPaul Moore  *
566255e85320SPaul Moore  * Do a check when the kernel generates and returns a file descriptor for eBPF
566355e85320SPaul Moore  * programs.
566455e85320SPaul Moore  *
566555e85320SPaul Moore  * Return: Returns 0 if permission is granted.
566655e85320SPaul Moore  */
security_bpf_prog(struct bpf_prog * prog)5667afdb09c7SChenbo Feng int security_bpf_prog(struct bpf_prog *prog)
5668afdb09c7SChenbo Feng {
5669260017f3SOndrej Mosnacek 	return call_int_hook(bpf_prog, prog);
5670afdb09c7SChenbo Feng }
567155e85320SPaul Moore 
567255e85320SPaul Moore /**
5673a2431c7eSAndrii Nakryiko  * security_bpf_map_create() - Check if BPF map creation is allowed
5674a2431c7eSAndrii Nakryiko  * @map: BPF map object
5675a2431c7eSAndrii Nakryiko  * @attr: BPF syscall attributes used to create BPF map
5676a2431c7eSAndrii Nakryiko  * @token: BPF token used to grant user access
5677*082f1db0SBlaise Boscaccy  * @kernel: whether or not call originated from kernel
567855e85320SPaul Moore  *
5679a2431c7eSAndrii Nakryiko  * Do a check when the kernel creates a new BPF map. This is also the
5680a2431c7eSAndrii Nakryiko  * point where LSM blob is allocated for LSMs that need them.
568155e85320SPaul Moore  *
568255e85320SPaul Moore  * Return: Returns 0 on success, error on failure.
568355e85320SPaul Moore  */
security_bpf_map_create(struct bpf_map * map,union bpf_attr * attr,struct bpf_token * token,bool kernel)5684a2431c7eSAndrii Nakryiko int security_bpf_map_create(struct bpf_map *map, union bpf_attr *attr,
5685*082f1db0SBlaise Boscaccy 			    struct bpf_token *token, bool kernel)
5686afdb09c7SChenbo Feng {
5687*082f1db0SBlaise Boscaccy 	return call_int_hook(bpf_map_create, map, attr, token, kernel);
5688afdb09c7SChenbo Feng }
568955e85320SPaul Moore 
569055e85320SPaul Moore /**
56911b67772eSAndrii Nakryiko  * security_bpf_prog_load() - Check if loading of BPF program is allowed
56921b67772eSAndrii Nakryiko  * @prog: BPF program object
56931b67772eSAndrii Nakryiko  * @attr: BPF syscall attributes used to create BPF program
56941b67772eSAndrii Nakryiko  * @token: BPF token used to grant user access to BPF subsystem
5695*082f1db0SBlaise Boscaccy  * @kernel: whether or not call originated from kernel
569655e85320SPaul Moore  *
56971b67772eSAndrii Nakryiko  * Perform an access control check when the kernel loads a BPF program and
56981b67772eSAndrii Nakryiko  * allocates associated BPF program object. This hook is also responsible for
56991b67772eSAndrii Nakryiko  * allocating any required LSM state for the BPF program.
570055e85320SPaul Moore  *
570155e85320SPaul Moore  * Return: Returns 0 on success, error on failure.
570255e85320SPaul Moore  */
security_bpf_prog_load(struct bpf_prog * prog,union bpf_attr * attr,struct bpf_token * token,bool kernel)57031b67772eSAndrii Nakryiko int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr,
5704*082f1db0SBlaise Boscaccy 			   struct bpf_token *token, bool kernel)
5705afdb09c7SChenbo Feng {
5706*082f1db0SBlaise Boscaccy 	return call_int_hook(bpf_prog_load, prog, attr, token, kernel);
5707afdb09c7SChenbo Feng }
570855e85320SPaul Moore 
570955e85320SPaul Moore /**
5710f568a3d4SAndrii Nakryiko  * security_bpf_token_create() - Check if creating of BPF token is allowed
5711f568a3d4SAndrii Nakryiko  * @token: BPF token object
5712f568a3d4SAndrii Nakryiko  * @attr: BPF syscall attributes used to create BPF token
5713f568a3d4SAndrii Nakryiko  * @path: path pointing to BPF FS mount point from which BPF token is created
5714f568a3d4SAndrii Nakryiko  *
5715f568a3d4SAndrii Nakryiko  * Do a check when the kernel instantiates a new BPF token object from BPF FS
5716f568a3d4SAndrii Nakryiko  * instance. This is also the point where LSM blob can be allocated for LSMs.
5717f568a3d4SAndrii Nakryiko  *
5718f568a3d4SAndrii Nakryiko  * Return: Returns 0 on success, error on failure.
5719f568a3d4SAndrii Nakryiko  */
security_bpf_token_create(struct bpf_token * token,union bpf_attr * attr,const struct path * path)5720f568a3d4SAndrii Nakryiko int security_bpf_token_create(struct bpf_token *token, union bpf_attr *attr,
5721433d7ce2SAndrii Nakryiko 			      const struct path *path)
5722f568a3d4SAndrii Nakryiko {
5723cc4a875cSLinus Torvalds 	return call_int_hook(bpf_token_create, token, attr, path);
5724f568a3d4SAndrii Nakryiko }
5725f568a3d4SAndrii Nakryiko 
5726f568a3d4SAndrii Nakryiko /**
5727f568a3d4SAndrii Nakryiko  * security_bpf_token_cmd() - Check if BPF token is allowed to delegate
5728f568a3d4SAndrii Nakryiko  * requested BPF syscall command
5729f568a3d4SAndrii Nakryiko  * @token: BPF token object
5730f568a3d4SAndrii Nakryiko  * @cmd: BPF syscall command requested to be delegated by BPF token
5731f568a3d4SAndrii Nakryiko  *
5732f568a3d4SAndrii Nakryiko  * Do a check when the kernel decides whether provided BPF token should allow
5733f568a3d4SAndrii Nakryiko  * delegation of requested BPF syscall command.
5734f568a3d4SAndrii Nakryiko  *
5735f568a3d4SAndrii Nakryiko  * Return: Returns 0 on success, error on failure.
5736f568a3d4SAndrii Nakryiko  */
security_bpf_token_cmd(const struct bpf_token * token,enum bpf_cmd cmd)5737f568a3d4SAndrii Nakryiko int security_bpf_token_cmd(const struct bpf_token *token, enum bpf_cmd cmd)
5738f568a3d4SAndrii Nakryiko {
5739cc4a875cSLinus Torvalds 	return call_int_hook(bpf_token_cmd, token, cmd);
5740f568a3d4SAndrii Nakryiko }
5741f568a3d4SAndrii Nakryiko 
5742f568a3d4SAndrii Nakryiko /**
5743f568a3d4SAndrii Nakryiko  * security_bpf_token_capable() - Check if BPF token is allowed to delegate
5744f568a3d4SAndrii Nakryiko  * requested BPF-related capability
5745f568a3d4SAndrii Nakryiko  * @token: BPF token object
5746f568a3d4SAndrii Nakryiko  * @cap: capabilities requested to be delegated by BPF token
5747f568a3d4SAndrii Nakryiko  *
5748f568a3d4SAndrii Nakryiko  * Do a check when the kernel decides whether provided BPF token should allow
5749f568a3d4SAndrii Nakryiko  * delegation of requested BPF-related capabilities.
5750f568a3d4SAndrii Nakryiko  *
5751f568a3d4SAndrii Nakryiko  * Return: Returns 0 on success, error on failure.
5752f568a3d4SAndrii Nakryiko  */
security_bpf_token_capable(const struct bpf_token * token,int cap)5753f568a3d4SAndrii Nakryiko int security_bpf_token_capable(const struct bpf_token *token, int cap)
5754f568a3d4SAndrii Nakryiko {
5755cc4a875cSLinus Torvalds 	return call_int_hook(bpf_token_capable, token, cap);
5756f568a3d4SAndrii Nakryiko }
5757f568a3d4SAndrii Nakryiko 
5758f568a3d4SAndrii Nakryiko /**
575955e85320SPaul Moore  * security_bpf_map_free() - Free a bpf map's LSM blob
576055e85320SPaul Moore  * @map: bpf map
576155e85320SPaul Moore  *
576255e85320SPaul Moore  * Clean up the security information stored inside bpf map.
576355e85320SPaul Moore  */
security_bpf_map_free(struct bpf_map * map)5764afdb09c7SChenbo Feng void security_bpf_map_free(struct bpf_map *map)
5765afdb09c7SChenbo Feng {
5766a2431c7eSAndrii Nakryiko 	call_void_hook(bpf_map_free, map);
5767afdb09c7SChenbo Feng }
576855e85320SPaul Moore 
576955e85320SPaul Moore /**
57701b67772eSAndrii Nakryiko  * security_bpf_prog_free() - Free a BPF program's LSM blob
57711b67772eSAndrii Nakryiko  * @prog: BPF program struct
577255e85320SPaul Moore  *
57731b67772eSAndrii Nakryiko  * Clean up the security information stored inside BPF program.
577455e85320SPaul Moore  */
security_bpf_prog_free(struct bpf_prog * prog)57751b67772eSAndrii Nakryiko void security_bpf_prog_free(struct bpf_prog *prog)
5776afdb09c7SChenbo Feng {
57771b67772eSAndrii Nakryiko 	call_void_hook(bpf_prog_free, prog);
5778afdb09c7SChenbo Feng }
5779f568a3d4SAndrii Nakryiko 
5780f568a3d4SAndrii Nakryiko /**
5781f568a3d4SAndrii Nakryiko  * security_bpf_token_free() - Free a BPF token's LSM blob
5782f568a3d4SAndrii Nakryiko  * @token: BPF token struct
5783f568a3d4SAndrii Nakryiko  *
5784f568a3d4SAndrii Nakryiko  * Clean up the security information stored inside BPF token.
5785f568a3d4SAndrii Nakryiko  */
security_bpf_token_free(struct bpf_token * token)5786f568a3d4SAndrii Nakryiko void security_bpf_token_free(struct bpf_token *token)
5787f568a3d4SAndrii Nakryiko {
5788f568a3d4SAndrii Nakryiko 	call_void_hook(bpf_token_free, token);
5789f568a3d4SAndrii Nakryiko }
5790afdb09c7SChenbo Feng #endif /* CONFIG_BPF_SYSCALL */
57919e47d31dSMatthew Garrett 
5792e261301cSPaul Moore /**
5793e261301cSPaul Moore  * security_locked_down() - Check if a kernel feature is allowed
5794e261301cSPaul Moore  * @what: requested kernel feature
5795e261301cSPaul Moore  *
5796e261301cSPaul Moore  * Determine whether a kernel feature that potentially enables arbitrary code
5797e261301cSPaul Moore  * execution in kernel space should be permitted.
5798e261301cSPaul Moore  *
5799e261301cSPaul Moore  * Return: Returns 0 if permission is granted.
5800e261301cSPaul Moore  */
security_locked_down(enum lockdown_reason what)58019e47d31dSMatthew Garrett int security_locked_down(enum lockdown_reason what)
58029e47d31dSMatthew Garrett {
5803260017f3SOndrej Mosnacek 	return call_int_hook(locked_down, what);
58049e47d31dSMatthew Garrett }
58059e47d31dSMatthew Garrett EXPORT_SYMBOL(security_locked_down);
5806da97e184SJoel Fernandes (Google) 
5807b55d26bdSDeven Bowers /**
5808b55d26bdSDeven Bowers  * security_bdev_alloc() - Allocate a block device LSM blob
5809b55d26bdSDeven Bowers  * @bdev: block device
5810b55d26bdSDeven Bowers  *
5811b55d26bdSDeven Bowers  * Allocate and attach a security structure to @bdev->bd_security.  The
5812b55d26bdSDeven Bowers  * security field is initialized to NULL when the bdev structure is
5813b55d26bdSDeven Bowers  * allocated.
5814b55d26bdSDeven Bowers  *
5815b55d26bdSDeven Bowers  * Return: Return 0 if operation was successful.
5816b55d26bdSDeven Bowers  */
security_bdev_alloc(struct block_device * bdev)5817b55d26bdSDeven Bowers int security_bdev_alloc(struct block_device *bdev)
5818b55d26bdSDeven Bowers {
5819b55d26bdSDeven Bowers 	int rc = 0;
5820b55d26bdSDeven Bowers 
5821b55d26bdSDeven Bowers 	rc = lsm_bdev_alloc(bdev);
5822b55d26bdSDeven Bowers 	if (unlikely(rc))
5823b55d26bdSDeven Bowers 		return rc;
5824b55d26bdSDeven Bowers 
5825b55d26bdSDeven Bowers 	rc = call_int_hook(bdev_alloc_security, bdev);
5826b55d26bdSDeven Bowers 	if (unlikely(rc))
5827b55d26bdSDeven Bowers 		security_bdev_free(bdev);
5828b55d26bdSDeven Bowers 
5829b55d26bdSDeven Bowers 	return rc;
5830b55d26bdSDeven Bowers }
5831b55d26bdSDeven Bowers EXPORT_SYMBOL(security_bdev_alloc);
5832b55d26bdSDeven Bowers 
5833b55d26bdSDeven Bowers /**
5834b55d26bdSDeven Bowers  * security_bdev_free() - Free a block device's LSM blob
5835b55d26bdSDeven Bowers  * @bdev: block device
5836b55d26bdSDeven Bowers  *
5837b55d26bdSDeven Bowers  * Deallocate the bdev security structure and set @bdev->bd_security to NULL.
5838b55d26bdSDeven Bowers  */
security_bdev_free(struct block_device * bdev)5839b55d26bdSDeven Bowers void security_bdev_free(struct block_device *bdev)
5840b55d26bdSDeven Bowers {
5841b55d26bdSDeven Bowers 	if (!bdev->bd_security)
5842b55d26bdSDeven Bowers 		return;
5843b55d26bdSDeven Bowers 
5844b55d26bdSDeven Bowers 	call_void_hook(bdev_free_security, bdev);
5845b55d26bdSDeven Bowers 
5846b55d26bdSDeven Bowers 	kfree(bdev->bd_security);
5847b55d26bdSDeven Bowers 	bdev->bd_security = NULL;
5848b55d26bdSDeven Bowers }
5849b55d26bdSDeven Bowers EXPORT_SYMBOL(security_bdev_free);
5850b55d26bdSDeven Bowers 
5851b55d26bdSDeven Bowers /**
5852b55d26bdSDeven Bowers  * security_bdev_setintegrity() - Set the device's integrity data
5853b55d26bdSDeven Bowers  * @bdev: block device
5854b55d26bdSDeven Bowers  * @type: type of integrity, e.g. hash digest, signature, etc
5855b55d26bdSDeven Bowers  * @value: the integrity value
5856b55d26bdSDeven Bowers  * @size: size of the integrity value
5857b55d26bdSDeven Bowers  *
5858b55d26bdSDeven Bowers  * Register a verified integrity measurement of a bdev with LSMs.
5859b55d26bdSDeven Bowers  * LSMs should free the previously saved data if @value is NULL.
5860b55d26bdSDeven Bowers  * Please note that the new hook should be invoked every time the security
5861b55d26bdSDeven Bowers  * information is updated to keep these data current. For example, in dm-verity,
5862b55d26bdSDeven Bowers  * if the mapping table is reloaded and configured to use a different dm-verity
5863e155858dSDeven Bowers  * target with a new roothash and signing information, the previously stored
5864e155858dSDeven Bowers  * data in the LSM blob will become obsolete. It is crucial to re-invoke the
5865e155858dSDeven Bowers  * hook to refresh these data and ensure they are up to date. This necessity
5866e155858dSDeven Bowers  * arises from the design of device-mapper, where a device-mapper device is
5867e155858dSDeven Bowers  * first created, and then targets are subsequently loaded into it. These
5868e155858dSDeven Bowers  * targets can be modified multiple times during the device's lifetime.
5869e155858dSDeven Bowers  * Therefore, while the LSM blob is allocated during the creation of the block
5870e155858dSDeven Bowers  * device, its actual contents are not initialized at this stage and can change
5871e155858dSDeven Bowers  * substantially over time. This includes alterations from data that the LSMs
5872e155858dSDeven Bowers  * 'trusts' to those they do not, making it essential to handle these changes
5873e155858dSDeven Bowers  * correctly. Failure to address this dynamic aspect could potentially allow
5874e155858dSDeven Bowers  * for bypassing LSM checks.
5875b55d26bdSDeven Bowers  *
5876b55d26bdSDeven Bowers  * Return: Returns 0 on success, negative values on failure.
5877b55d26bdSDeven Bowers  */
security_bdev_setintegrity(struct block_device * bdev,enum lsm_integrity_type type,const void * value,size_t size)5878b55d26bdSDeven Bowers int security_bdev_setintegrity(struct block_device *bdev,
5879b55d26bdSDeven Bowers 			       enum lsm_integrity_type type, const void *value,
5880b55d26bdSDeven Bowers 			       size_t size)
5881b55d26bdSDeven Bowers {
5882b55d26bdSDeven Bowers 	return call_int_hook(bdev_setintegrity, bdev, type, value, size);
5883b55d26bdSDeven Bowers }
5884b55d26bdSDeven Bowers EXPORT_SYMBOL(security_bdev_setintegrity);
5885b55d26bdSDeven Bowers 
5886da97e184SJoel Fernandes (Google) #ifdef CONFIG_PERF_EVENTS
5887452b670cSPaul Moore /**
5888452b670cSPaul Moore  * security_perf_event_open() - Check if a perf event open is allowed
5889452b670cSPaul Moore  * @type: type of event
5890452b670cSPaul Moore  *
5891452b670cSPaul Moore  * Check whether the @type of perf_event_open syscall is allowed.
5892452b670cSPaul Moore  *
5893452b670cSPaul Moore  * Return: Returns 0 if permission is granted.
5894452b670cSPaul Moore  */
security_perf_event_open(int type)5895452b670cSPaul Moore int security_perf_event_open(int type)
5896da97e184SJoel Fernandes (Google) {
5897da97e184SJoel Fernandes (Google) 	return call_int_hook(perf_event_open, type);
5898260017f3SOndrej Mosnacek }
5899da97e184SJoel Fernandes (Google) 
5900da97e184SJoel Fernandes (Google) /**
5901452b670cSPaul Moore  * security_perf_event_alloc() - Allocate a perf event LSM blob
5902452b670cSPaul Moore  * @event: perf event
5903452b670cSPaul Moore  *
5904452b670cSPaul Moore  * Allocate and save perf_event security info.
5905452b670cSPaul Moore  *
5906452b670cSPaul Moore  * Return: Returns 0 on success, error on failure.
5907452b670cSPaul Moore  */
security_perf_event_alloc(struct perf_event * event)5908452b670cSPaul Moore int security_perf_event_alloc(struct perf_event *event)
5909da97e184SJoel Fernandes (Google) {
5910da97e184SJoel Fernandes (Google) 	int rc;
591161a1dcdcSCasey Schaufler 
591261a1dcdcSCasey Schaufler 	rc = lsm_blob_alloc(&event->security, blob_sizes.lbs_perf_event,
591361a1dcdcSCasey Schaufler 			    GFP_KERNEL);
591461a1dcdcSCasey Schaufler 	if (rc)
591561a1dcdcSCasey Schaufler 		return rc;
591661a1dcdcSCasey Schaufler 
591761a1dcdcSCasey Schaufler 	rc = call_int_hook(perf_event_alloc, event);
591861a1dcdcSCasey Schaufler 	if (rc) {
591961a1dcdcSCasey Schaufler 		kfree(event->security);
592061a1dcdcSCasey Schaufler 		event->security = NULL;
592161a1dcdcSCasey Schaufler 	}
592261a1dcdcSCasey Schaufler 	return rc;
592361a1dcdcSCasey Schaufler }
5924da97e184SJoel Fernandes (Google) 
5925da97e184SJoel Fernandes (Google) /**
5926452b670cSPaul Moore  * security_perf_event_free() - Free a perf event LSM blob
5927452b670cSPaul Moore  * @event: perf event
5928452b670cSPaul Moore  *
5929452b670cSPaul Moore  * Release (free) perf_event security info.
5930452b670cSPaul Moore  */
security_perf_event_free(struct perf_event * event)5931452b670cSPaul Moore void security_perf_event_free(struct perf_event *event)
5932da97e184SJoel Fernandes (Google) {
5933da97e184SJoel Fernandes (Google) 	kfree(event->security);
593461a1dcdcSCasey Schaufler 	event->security = NULL;
593561a1dcdcSCasey Schaufler }
5936da97e184SJoel Fernandes (Google) 
5937da97e184SJoel Fernandes (Google) /**
5938452b670cSPaul Moore  * security_perf_event_read() - Check if reading a perf event label is allowed
5939452b670cSPaul Moore  * @event: perf event
5940452b670cSPaul Moore  *
5941452b670cSPaul Moore  * Read perf_event security info if allowed.
5942452b670cSPaul Moore  *
5943452b670cSPaul Moore  * Return: Returns 0 if permission is granted.
5944452b670cSPaul Moore  */
security_perf_event_read(struct perf_event * event)5945452b670cSPaul Moore int security_perf_event_read(struct perf_event *event)
5946da97e184SJoel Fernandes (Google) {
5947da97e184SJoel Fernandes (Google) 	return call_int_hook(perf_event_read, event);
5948260017f3SOndrej Mosnacek }
5949da97e184SJoel Fernandes (Google) 
5950da97e184SJoel Fernandes (Google) /**
5951452b670cSPaul Moore  * security_perf_event_write() - Check if writing a perf event label is allowed
5952452b670cSPaul Moore  * @event: perf event
5953452b670cSPaul Moore  *
5954452b670cSPaul Moore  * Write perf_event security info if allowed.
5955452b670cSPaul Moore  *
5956452b670cSPaul Moore  * Return: Returns 0 if permission is granted.
5957452b670cSPaul Moore  */
security_perf_event_write(struct perf_event * event)5958452b670cSPaul Moore int security_perf_event_write(struct perf_event *event)
5959da97e184SJoel Fernandes (Google) {
5960da97e184SJoel Fernandes (Google) 	return call_int_hook(perf_event_write, event);
5961260017f3SOndrej Mosnacek }
5962da97e184SJoel Fernandes (Google) #endif /* CONFIG_PERF_EVENTS */
5963da97e184SJoel Fernandes (Google) 
5964cdc1404aSPaul Moore #ifdef CONFIG_IO_URING
5965cdc1404aSPaul Moore /**
59661cd2aca6SPaul Moore  * security_uring_override_creds() - Check if overriding creds is allowed
59671cd2aca6SPaul Moore  * @new: new credentials
59681cd2aca6SPaul Moore  *
59691cd2aca6SPaul Moore  * Check if the current task, executing an io_uring operation, is allowed to
59701cd2aca6SPaul Moore  * override it's credentials with @new.
59711cd2aca6SPaul Moore  *
59721cd2aca6SPaul Moore  * Return: Returns 0 if permission is granted.
59731cd2aca6SPaul Moore  */
security_uring_override_creds(const struct cred * new)59741cd2aca6SPaul Moore int security_uring_override_creds(const struct cred *new)
5975cdc1404aSPaul Moore {
5976cdc1404aSPaul Moore 	return call_int_hook(uring_override_creds, new);
5977260017f3SOndrej Mosnacek }
5978cdc1404aSPaul Moore 
5979cdc1404aSPaul Moore /**
59801cd2aca6SPaul Moore  * security_uring_sqpoll() - Check if IORING_SETUP_SQPOLL is allowed
59811cd2aca6SPaul Moore  *
59821cd2aca6SPaul Moore  * Check whether the current task is allowed to spawn a io_uring polling thread
59831cd2aca6SPaul Moore  * (IORING_SETUP_SQPOLL).
59841cd2aca6SPaul Moore  *
59851cd2aca6SPaul Moore  * Return: Returns 0 if permission is granted.
59861cd2aca6SPaul Moore  */
security_uring_sqpoll(void)59871cd2aca6SPaul Moore int security_uring_sqpoll(void)
5988cdc1404aSPaul Moore {
5989cdc1404aSPaul Moore 	return call_int_hook(uring_sqpoll);
5990260017f3SOndrej Mosnacek }
5991cdc1404aSPaul Moore 
59921cd2aca6SPaul Moore /**
59931cd2aca6SPaul Moore  * security_uring_cmd() - Check if a io_uring passthrough command is allowed
59941cd2aca6SPaul Moore  * @ioucmd: command
59951cd2aca6SPaul Moore  *
59961cd2aca6SPaul Moore  * Check whether the file_operations uring_cmd is allowed to run.
59971cd2aca6SPaul Moore  *
59981cd2aca6SPaul Moore  * Return: Returns 0 if permission is granted.
59991cd2aca6SPaul Moore  */
security_uring_cmd(struct io_uring_cmd * ioucmd)60001cd2aca6SPaul Moore int security_uring_cmd(struct io_uring_cmd *ioucmd)
60012a584012SLuis Chamberlain {
60022a584012SLuis Chamberlain 	return call_int_hook(uring_cmd, ioucmd);
6003260017f3SOndrej Mosnacek }
60042a584012SLuis Chamberlain 
6005cdc1404aSPaul Moore /**
60062fea0c26SFan Wu  * security_uring_allowed() - Check if io_uring_setup() is allowed
60072fea0c26SFan Wu  *
60082fea0c26SFan Wu  * Check whether the current task is allowed to call io_uring_setup().
60092fea0c26SFan Wu  *
60102fea0c26SFan Wu  * Return: Returns 0 if permission is granted.
60112fea0c26SFan Wu  */
security_uring_allowed(void)60122fea0c26SFan Wu int security_uring_allowed(void)
60132fea0c26SFan Wu {
60142fea0c26SFan Wu 	return call_int_hook(uring_allowed);
60152fea0c26SFan Wu }
6016 #endif /* CONFIG_IO_URING */
6017 
6018 /**
6019  * security_initramfs_populated() - Notify LSMs that initramfs has been loaded
6020  *
6021  * Tells the LSMs the initramfs has been unpacked into the rootfs.
6022  */
security_initramfs_populated(void)6023 void security_initramfs_populated(void)
6024 {
6025 	call_void_hook(initramfs_populated);
6026 }
6027