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