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