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