Commit | Line | Data |
---|---|---|
3c4ed7bd CS |
1 | /* |
2 | * Linux Security Module interfaces | |
3 | * | |
4 | * Copyright (C) 2001 WireX Communications, Inc <chris@wirex.com> | |
5 | * Copyright (C) 2001 Greg Kroah-Hartman <greg@kroah.com> | |
6 | * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com> | |
7 | * Copyright (C) 2001 James Morris <jmorris@intercode.com.au> | |
8 | * Copyright (C) 2001 Silicon Graphics, Inc. (Trust Technology Group) | |
9 | * Copyright (C) 2015 Intel Corporation. | |
10 | * Copyright (C) 2015 Casey Schaufler <casey@schaufler-ca.com> | |
d291f1a6 | 11 | * Copyright (C) 2016 Mellanox Techonologies |
3c4ed7bd CS |
12 | * |
13 | * This program is free software; you can redistribute it and/or modify | |
14 | * it under the terms of the GNU General Public License as published by | |
15 | * the Free Software Foundation; either version 2 of the License, or | |
16 | * (at your option) any later version. | |
17 | * | |
18 | * Due to this file being licensed under the GPL there is controversy over | |
19 | * whether this permits you to write a module that #includes this file | |
20 | * without placing your module under the GPL. Please consult a lawyer for | |
21 | * advice before doing this. | |
22 | * | |
23 | */ | |
24 | ||
25 | #ifndef __LINUX_LSM_HOOKS_H | |
26 | #define __LINUX_LSM_HOOKS_H | |
27 | ||
a04a1198 | 28 | #include <uapi/linux/lsm.h> |
3c4ed7bd | 29 | #include <linux/security.h> |
b1d9e6b0 CS |
30 | #include <linux/init.h> |
31 | #include <linux/rculist.h> | |
6bcdfd2c | 32 | #include <linux/xattr.h> |
417c5643 KS |
33 | #include <linux/static_call.h> |
34 | #include <linux/unroll.h> | |
35 | #include <linux/jump_label.h> | |
36 | #include <linux/lsm_count.h> | |
3c4ed7bd | 37 | |
b1d9e6b0 | 38 | union security_list_options { |
98e828a0 KS |
39 | #define LSM_HOOK(RET, DEFAULT, NAME, ...) RET (*NAME)(__VA_ARGS__); |
40 | #include "lsm_hook_defs.h" | |
41 | #undef LSM_HOOK | |
417c5643 | 42 | void *lsm_func_addr; |
3c4ed7bd CS |
43 | }; |
44 | ||
417c5643 KS |
45 | /* |
46 | * @key: static call key as defined by STATIC_CALL_KEY | |
47 | * @trampoline: static call trampoline as defined by STATIC_CALL_TRAMP | |
48 | * @hl: The security_hook_list as initialized by the owning LSM. | |
49 | * @active: Enabled when the static call has an LSM hook associated. | |
50 | */ | |
51 | struct lsm_static_call { | |
52 | struct static_call_key *key; | |
53 | void *trampoline; | |
54 | struct security_hook_list *hl; | |
55 | /* this needs to be true or false based on what the key defaults to */ | |
56 | struct static_key_false *active; | |
3859a271 | 57 | } __randomize_layout; |
e20b043a | 58 | |
417c5643 KS |
59 | /* |
60 | * Table of the static calls for each LSM hook. | |
61 | * Once the LSMs are initialized, their callbacks will be copied to these | |
62 | * tables such that the calls are filled backwards (from last to first). | |
63 | * This way, we can jump directly to the first used static call, and execute | |
64 | * all of them after. This essentially makes the entry point | |
65 | * dynamic to adapt the number of static calls to the number of callbacks. | |
66 | */ | |
67 | struct lsm_static_calls_table { | |
68 | #define LSM_HOOK(RET, DEFAULT, NAME, ...) \ | |
69 | struct lsm_static_call NAME[MAX_LSM_COUNT]; | |
70 | #include <linux/lsm_hook_defs.h> | |
71 | #undef LSM_HOOK | |
72 | } __packed __randomize_layout; | |
73 | ||
f3b8788c CS |
74 | /** |
75 | * struct lsm_id - Identify a Linux Security Module. | |
76 | * @lsm: name of the LSM, must be approved by the LSM maintainers | |
77 | * @id: LSM ID number from uapi/linux/lsm.h | |
78 | * | |
79 | * Contains the information that identifies the LSM. | |
80 | */ | |
81 | struct lsm_id { | |
711f5c5c PM |
82 | const char *name; |
83 | u64 id; | |
f3b8788c CS |
84 | }; |
85 | ||
b1d9e6b0 CS |
86 | /* |
87 | * Security module hook list structure. | |
88 | * For use with generic list macros for common operations. | |
417c5643 KS |
89 | * |
90 | * struct security_hook_list - Contents of a cacheable, mappable object. | |
91 | * @scalls: The beginning of the array of static calls assigned to this hook. | |
92 | * @hook: The callback for the hook. | |
93 | * @lsm: The name of the lsm that owns this hook. | |
b1d9e6b0 CS |
94 | */ |
95 | struct security_hook_list { | |
417c5643 | 96 | struct lsm_static_call *scalls; |
711f5c5c PM |
97 | union security_list_options hook; |
98 | const struct lsm_id *lsmid; | |
3859a271 | 99 | } __randomize_layout; |
b1d9e6b0 | 100 | |
bbd3662a CS |
101 | /* |
102 | * Security blob size or offset data. | |
103 | */ | |
104 | struct lsm_blob_sizes { | |
711f5c5c PM |
105 | int lbs_cred; |
106 | int lbs_file; | |
107 | int lbs_ib; | |
108 | int lbs_inode; | |
109 | int lbs_sock; | |
110 | int lbs_superblock; | |
111 | int lbs_ipc; | |
112 | int lbs_key; | |
113 | int lbs_msg_msg; | |
114 | int lbs_perf_event; | |
115 | int lbs_task; | |
116 | int lbs_xattr_count; /* number of xattr slots in new_xattrs array */ | |
117 | int lbs_tun_dev; | |
b55d26bd | 118 | int lbs_bdev; |
bbd3662a CS |
119 | }; |
120 | ||
98e828a0 KS |
121 | /* |
122 | * LSM_RET_VOID is used as the default value in LSM_HOOK definitions for void | |
123 | * LSM hooks (in include/linux/lsm_hook_defs.h). | |
124 | */ | |
125 | #define LSM_RET_VOID ((void) 0) | |
126 | ||
e20b043a CS |
127 | /* |
128 | * Initializing a security_hook_list structure takes | |
129 | * up a lot of space in a source file. This macro takes | |
130 | * care of the common case and reduces the amount of | |
131 | * text involved. | |
e20b043a | 132 | */ |
417c5643 KS |
133 | #define LSM_HOOK_INIT(NAME, HOOK) \ |
134 | { \ | |
135 | .scalls = static_calls_table.NAME, \ | |
136 | .hook = { .NAME = HOOK } \ | |
137 | } | |
b1d9e6b0 | 138 | |
d69dece5 | 139 | extern void security_add_hooks(struct security_hook_list *hooks, int count, |
f3b8788c | 140 | const struct lsm_id *lsmid); |
3c4ed7bd | 141 | |
47008e51 | 142 | #define LSM_FLAG_LEGACY_MAJOR BIT(0) |
14bd99c8 | 143 | #define LSM_FLAG_EXCLUSIVE BIT(1) |
47008e51 | 144 | |
e2bc445b KC |
145 | enum lsm_order { |
146 | LSM_ORDER_FIRST = -1, /* This is only for capabilities. */ | |
147 | LSM_ORDER_MUTABLE = 0, | |
42994ee3 | 148 | LSM_ORDER_LAST = 1, /* This is only for integrity. */ |
e2bc445b KC |
149 | }; |
150 | ||
5b89c1bd | 151 | struct lsm_info { |
07aed2f2 | 152 | const char *name; /* Required. */ |
e2bc445b | 153 | enum lsm_order order; /* Optional: default is LSM_ORDER_MUTABLE */ |
47008e51 | 154 | unsigned long flags; /* Optional: flags describing LSM */ |
a8027fb0 | 155 | int *enabled; /* Optional: controlled by CONFIG_LSM */ |
5b89c1bd | 156 | int (*init)(void); /* Required. */ |
bbd3662a | 157 | struct lsm_blob_sizes *blobs; /* Optional: for blob sharing. */ |
5b89c1bd KC |
158 | }; |
159 | ||
3d6e5f6d | 160 | #define DEFINE_LSM(lsm) \ |
5b89c1bd | 161 | static struct lsm_info __lsm_##lsm \ |
33def849 | 162 | __used __section(".lsm_info.init") \ |
3d6e5f6d | 163 | __aligned(sizeof(unsigned long)) |
5b89c1bd | 164 | |
e6b1db98 MG |
165 | #define DEFINE_EARLY_LSM(lsm) \ |
166 | static struct lsm_info __early_lsm_##lsm \ | |
33def849 | 167 | __used __section(".early_lsm_info.init") \ |
e6b1db98 MG |
168 | __aligned(sizeof(unsigned long)) |
169 | ||
711f5c5c PM |
170 | /* DO NOT tamper with these variables outside of the LSM framework */ |
171 | extern char *lsm_names; | |
711f5c5c PM |
172 | extern struct lsm_static_calls_table static_calls_table __ro_after_init; |
173 | extern struct lsm_info __start_lsm_info[], __end_lsm_info[]; | |
174 | extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[]; | |
175 | ||
176 | /** | |
177 | * lsm_get_xattr_slot - Return the next available slot and increment the index | |
178 | * @xattrs: array storing LSM-provided xattrs | |
179 | * @xattr_count: number of already stored xattrs (updated) | |
180 | * | |
181 | * Retrieve the first available slot in the @xattrs array to fill with an xattr, | |
182 | * and increment @xattr_count. | |
183 | * | |
184 | * Return: The slot to fill in @xattrs if non-NULL, NULL otherwise. | |
185 | */ | |
186 | static inline struct xattr *lsm_get_xattr_slot(struct xattr *xattrs, | |
187 | int *xattr_count) | |
188 | { | |
189 | if (unlikely(!xattrs)) | |
190 | return NULL; | |
191 | return &xattrs[(*xattr_count)++]; | |
192 | } | |
afb1cbe3 | 193 | |
3c4ed7bd | 194 | #endif /* ! __LINUX_LSM_HOOKS_H */ |