1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved.
4 */
5 #include <linux/fs.h>
6 #include <linux/namei.h>
7 #include <linux/types.h>
8 #include <linux/dcache.h>
9 #include <linux/security.h>
10
11 #include "ipe.h"
12 #include "policy.h"
13 #include "eval.h"
14 #include "fs.h"
15
16 #define MAX_VERSION_SIZE ARRAY_SIZE("65535.65535.65535")
17
18 /**
19 * struct ipefs_file - defines a file in securityfs.
20 *
21 * @name: file name inside the policy subdirectory
22 * @access: file permissions
23 * @fops: &file_operations specific to this file
24 */
25 struct ipefs_file {
26 const char *name;
27 umode_t access;
28 const struct file_operations *fops;
29 };
30
31 /**
32 * read_pkcs7() - Read handler for "ipe/policies/$name/pkcs7".
33 * @f: Supplies a file structure representing the securityfs node.
34 * @data: Supplies a buffer passed to the write syscall.
35 * @len: Supplies the length of @data.
36 * @offset: unused.
37 *
38 * @data will be populated with the pkcs7 blob representing the policy
39 * on success. If the policy is unsigned (like the boot policy), this
40 * will return -ENOENT.
41 *
42 * Return:
43 * * Length of buffer written - Success
44 * * %-ENOENT - Policy initializing/deleted or is unsigned
45 */
read_pkcs7(struct file * f,char __user * data,size_t len,loff_t * offset)46 static ssize_t read_pkcs7(struct file *f, char __user *data,
47 size_t len, loff_t *offset)
48 {
49 const struct ipe_policy *p = NULL;
50 struct inode *root = NULL;
51 int rc = 0;
52
53 root = d_inode(f->f_path.dentry->d_parent);
54
55 inode_lock_shared(root);
56 p = (struct ipe_policy *)root->i_private;
57 if (!p) {
58 rc = -ENOENT;
59 goto out;
60 }
61
62 if (!p->pkcs7) {
63 rc = -ENOENT;
64 goto out;
65 }
66
67 rc = simple_read_from_buffer(data, len, offset, p->pkcs7, p->pkcs7len);
68
69 out:
70 inode_unlock_shared(root);
71
72 return rc;
73 }
74
75 /**
76 * read_policy() - Read handler for "ipe/policies/$name/policy".
77 * @f: Supplies a file structure representing the securityfs node.
78 * @data: Supplies a buffer passed to the write syscall.
79 * @len: Supplies the length of @data.
80 * @offset: unused.
81 *
82 * @data will be populated with the plain-text version of the policy
83 * on success.
84 *
85 * Return:
86 * * Length of buffer written - Success
87 * * %-ENOENT - Policy initializing/deleted
88 */
read_policy(struct file * f,char __user * data,size_t len,loff_t * offset)89 static ssize_t read_policy(struct file *f, char __user *data,
90 size_t len, loff_t *offset)
91 {
92 const struct ipe_policy *p = NULL;
93 struct inode *root = NULL;
94 int rc = 0;
95
96 root = d_inode(f->f_path.dentry->d_parent);
97
98 inode_lock_shared(root);
99 p = (struct ipe_policy *)root->i_private;
100 if (!p) {
101 rc = -ENOENT;
102 goto out;
103 }
104
105 rc = simple_read_from_buffer(data, len, offset, p->text, p->textlen);
106
107 out:
108 inode_unlock_shared(root);
109
110 return rc;
111 }
112
113 /**
114 * read_name() - Read handler for "ipe/policies/$name/name".
115 * @f: Supplies a file structure representing the securityfs node.
116 * @data: Supplies a buffer passed to the write syscall.
117 * @len: Supplies the length of @data.
118 * @offset: unused.
119 *
120 * @data will be populated with the policy_name attribute on success.
121 *
122 * Return:
123 * * Length of buffer written - Success
124 * * %-ENOENT - Policy initializing/deleted
125 */
read_name(struct file * f,char __user * data,size_t len,loff_t * offset)126 static ssize_t read_name(struct file *f, char __user *data,
127 size_t len, loff_t *offset)
128 {
129 const struct ipe_policy *p = NULL;
130 struct inode *root = NULL;
131 int rc = 0;
132
133 root = d_inode(f->f_path.dentry->d_parent);
134
135 inode_lock_shared(root);
136 p = (struct ipe_policy *)root->i_private;
137 if (!p) {
138 rc = -ENOENT;
139 goto out;
140 }
141
142 rc = simple_read_from_buffer(data, len, offset, p->parsed->name,
143 strlen(p->parsed->name));
144
145 out:
146 inode_unlock_shared(root);
147
148 return rc;
149 }
150
151 /**
152 * read_version() - Read handler for "ipe/policies/$name/version".
153 * @f: Supplies a file structure representing the securityfs node.
154 * @data: Supplies a buffer passed to the write syscall.
155 * @len: Supplies the length of @data.
156 * @offset: unused.
157 *
158 * @data will be populated with the version string on success.
159 *
160 * Return:
161 * * Length of buffer written - Success
162 * * %-ENOENT - Policy initializing/deleted
163 */
read_version(struct file * f,char __user * data,size_t len,loff_t * offset)164 static ssize_t read_version(struct file *f, char __user *data,
165 size_t len, loff_t *offset)
166 {
167 char buffer[MAX_VERSION_SIZE] = { 0 };
168 const struct ipe_policy *p = NULL;
169 struct inode *root = NULL;
170 size_t strsize = 0;
171 ssize_t rc = 0;
172
173 root = d_inode(f->f_path.dentry->d_parent);
174
175 inode_lock_shared(root);
176 p = (struct ipe_policy *)root->i_private;
177 if (!p) {
178 rc = -ENOENT;
179 goto out;
180 }
181
182 strsize = scnprintf(buffer, ARRAY_SIZE(buffer), "%hu.%hu.%hu",
183 p->parsed->version.major, p->parsed->version.minor,
184 p->parsed->version.rev);
185
186 rc = simple_read_from_buffer(data, len, offset, buffer, strsize);
187
188 out:
189 inode_unlock_shared(root);
190
191 return rc;
192 }
193
194 /**
195 * setactive() - Write handler for "ipe/policies/$name/active".
196 * @f: Supplies a file structure representing the securityfs node.
197 * @data: Supplies a buffer passed to the write syscall.
198 * @len: Supplies the length of @data.
199 * @offset: unused.
200 *
201 * Return:
202 * * Length of buffer written - Success
203 * * %-EPERM - Insufficient permission
204 * * %-EINVAL - Invalid input
205 * * %-ENOENT - Policy initializing/deleted
206 */
setactive(struct file * f,const char __user * data,size_t len,loff_t * offset)207 static ssize_t setactive(struct file *f, const char __user *data,
208 size_t len, loff_t *offset)
209 {
210 const struct ipe_policy *p = NULL;
211 struct inode *root = NULL;
212 bool value = false;
213 int rc = 0;
214
215 if (!file_ns_capable(f, &init_user_ns, CAP_MAC_ADMIN))
216 return -EPERM;
217
218 rc = kstrtobool_from_user(data, len, &value);
219 if (rc)
220 return rc;
221
222 if (!value)
223 return -EINVAL;
224
225 root = d_inode(f->f_path.dentry->d_parent);
226 inode_lock(root);
227
228 p = (struct ipe_policy *)root->i_private;
229 if (!p) {
230 rc = -ENOENT;
231 goto out;
232 }
233
234 rc = ipe_set_active_pol(p);
235
236 out:
237 inode_unlock(root);
238 return (rc < 0) ? rc : len;
239 }
240
241 /**
242 * getactive() - Read handler for "ipe/policies/$name/active".
243 * @f: Supplies a file structure representing the securityfs node.
244 * @data: Supplies a buffer passed to the write syscall.
245 * @len: Supplies the length of @data.
246 * @offset: unused.
247 *
248 * @data will be populated with the 1 or 0 depending on if the
249 * corresponding policy is active.
250 *
251 * Return:
252 * * Length of buffer written - Success
253 * * %-ENOENT - Policy initializing/deleted
254 */
getactive(struct file * f,char __user * data,size_t len,loff_t * offset)255 static ssize_t getactive(struct file *f, char __user *data,
256 size_t len, loff_t *offset)
257 {
258 const struct ipe_policy *p = NULL;
259 struct inode *root = NULL;
260 const char *str;
261 int rc = 0;
262
263 root = d_inode(f->f_path.dentry->d_parent);
264
265 inode_lock_shared(root);
266 p = (struct ipe_policy *)root->i_private;
267 if (!p) {
268 inode_unlock_shared(root);
269 return -ENOENT;
270 }
271 inode_unlock_shared(root);
272
273 str = (p == rcu_access_pointer(ipe_active_policy)) ? "1" : "0";
274 rc = simple_read_from_buffer(data, len, offset, str, 1);
275
276 return rc;
277 }
278
279 /**
280 * update_policy() - Write handler for "ipe/policies/$name/update".
281 * @f: Supplies a file structure representing the securityfs node.
282 * @data: Supplies a buffer passed to the write syscall.
283 * @len: Supplies the length of @data.
284 * @offset: unused.
285 *
286 * On success this updates the policy represented by $name,
287 * in-place.
288 *
289 * Return: Length of buffer written on success. If an error occurs,
290 * the function will return the -errno.
291 */
update_policy(struct file * f,const char __user * data,size_t len,loff_t * offset)292 static ssize_t update_policy(struct file *f, const char __user *data,
293 size_t len, loff_t *offset)
294 {
295 struct inode *root = NULL;
296 char *copy = NULL;
297 int rc = 0;
298
299 if (!file_ns_capable(f, &init_user_ns, CAP_MAC_ADMIN))
300 return -EPERM;
301
302 copy = memdup_user(data, len);
303 if (IS_ERR(copy))
304 return PTR_ERR(copy);
305
306 root = d_inode(f->f_path.dentry->d_parent);
307 inode_lock(root);
308 rc = ipe_update_policy(root, NULL, 0, copy, len);
309 inode_unlock(root);
310
311 kfree(copy);
312 if (rc)
313 return rc;
314
315 return len;
316 }
317
318 /**
319 * delete_policy() - write handler for "ipe/policies/$name/delete".
320 * @f: Supplies a file structure representing the securityfs node.
321 * @data: Supplies a buffer passed to the write syscall.
322 * @len: Supplies the length of @data.
323 * @offset: unused.
324 *
325 * On success this deletes the policy represented by $name.
326 *
327 * Return:
328 * * Length of buffer written - Success
329 * * %-EPERM - Insufficient permission/deleting active policy
330 * * %-EINVAL - Invalid input
331 * * %-ENOENT - Policy initializing/deleted
332 */
delete_policy(struct file * f,const char __user * data,size_t len,loff_t * offset)333 static ssize_t delete_policy(struct file *f, const char __user *data,
334 size_t len, loff_t *offset)
335 {
336 struct ipe_policy *ap = NULL;
337 struct ipe_policy *p = NULL;
338 struct inode *root = NULL;
339 bool value = false;
340 int rc = 0;
341
342 if (!file_ns_capable(f, &init_user_ns, CAP_MAC_ADMIN))
343 return -EPERM;
344
345 rc = kstrtobool_from_user(data, len, &value);
346 if (rc)
347 return rc;
348
349 if (!value)
350 return -EINVAL;
351
352 root = d_inode(f->f_path.dentry->d_parent);
353 inode_lock(root);
354 p = (struct ipe_policy *)root->i_private;
355 if (!p) {
356 inode_unlock(root);
357 return -ENOENT;
358 }
359
360 mutex_lock(&ipe_policy_lock);
361 ap = rcu_dereference_protected(ipe_active_policy,
362 lockdep_is_held(&ipe_policy_lock));
363 if (p == ap) {
364 mutex_unlock(&ipe_policy_lock);
365 inode_unlock(root);
366 return -EPERM;
367 }
368 mutex_unlock(&ipe_policy_lock);
369
370 root->i_private = NULL;
371 inode_unlock(root);
372
373 synchronize_rcu();
374 ipe_free_policy(p);
375
376 return len;
377 }
378
379 static const struct file_operations content_fops = {
380 .read = read_policy,
381 };
382
383 static const struct file_operations pkcs7_fops = {
384 .read = read_pkcs7,
385 };
386
387 static const struct file_operations name_fops = {
388 .read = read_name,
389 };
390
391 static const struct file_operations ver_fops = {
392 .read = read_version,
393 };
394
395 static const struct file_operations active_fops = {
396 .write = setactive,
397 .read = getactive,
398 };
399
400 static const struct file_operations update_fops = {
401 .write = update_policy,
402 };
403
404 static const struct file_operations delete_fops = {
405 .write = delete_policy,
406 };
407
408 /*
409 * policy_subdir - files under a policy subdirectory
410 */
411 static const struct ipefs_file policy_subdir[] = {
412 { "pkcs7", 0444, &pkcs7_fops },
413 { "policy", 0444, &content_fops },
414 { "name", 0444, &name_fops },
415 { "version", 0444, &ver_fops },
416 { "active", 0600, &active_fops },
417 { "update", 0200, &update_fops },
418 { "delete", 0200, &delete_fops },
419 };
420
421 /**
422 * ipe_del_policyfs_node() - Delete a securityfs entry for @p.
423 * @p: Supplies a pointer to the policy to delete a securityfs entry for.
424 */
ipe_del_policyfs_node(struct ipe_policy * p)425 void ipe_del_policyfs_node(struct ipe_policy *p)
426 {
427 securityfs_recursive_remove(p->policyfs);
428 p->policyfs = NULL;
429 }
430
431 /**
432 * ipe_new_policyfs_node() - Create a securityfs entry for @p.
433 * @p: Supplies a pointer to the policy to create a securityfs entry for.
434 *
435 * Return: %0 on success. If an error occurs, the function will return
436 * the -errno.
437 */
ipe_new_policyfs_node(struct ipe_policy * p)438 int ipe_new_policyfs_node(struct ipe_policy *p)
439 {
440 const struct ipefs_file *f = NULL;
441 struct dentry *policyfs = NULL;
442 struct inode *root = NULL;
443 struct dentry *d = NULL;
444 size_t i = 0;
445 int rc = 0;
446
447 if (p->policyfs)
448 return 0;
449
450 policyfs = securityfs_create_dir(p->parsed->name, policy_root);
451 if (IS_ERR(policyfs))
452 return PTR_ERR(policyfs);
453
454 root = d_inode(policyfs);
455
456 for (i = 0; i < ARRAY_SIZE(policy_subdir); ++i) {
457 f = &policy_subdir[i];
458
459 d = securityfs_create_file(f->name, f->access, policyfs,
460 NULL, f->fops);
461 if (IS_ERR(d)) {
462 rc = PTR_ERR(d);
463 goto err;
464 }
465 }
466
467 inode_lock(root);
468 p->policyfs = policyfs;
469 root->i_private = p;
470 inode_unlock(root);
471
472 return 0;
473 err:
474 securityfs_recursive_remove(policyfs);
475 return rc;
476 }
477