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 */
read_pkcs7(struct file * f,char __user * data,size_t len,loff_t * offset)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 */
read_policy(struct file * f,char __user * data,size_t len,loff_t * offset)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 */
read_name(struct file * f,char __user * data,size_t len,loff_t * offset)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 */
read_version(struct file * f,char __user * data,size_t len,loff_t * offset)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 */
setactive(struct file * f,const char __user * data,size_t len,loff_t * offset)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 */
getactive(struct file * f,char __user * data,size_t len,loff_t * offset)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 */
update_policy(struct file * f,const char __user * data,size_t len,loff_t * offset)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 */
delete_policy(struct file * f,const char __user * data,size_t len,loff_t * offset)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 */
ipe_del_policyfs_node(struct ipe_policy * p)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 */
ipe_new_policyfs_node(struct ipe_policy * p)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