~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/security/integrity/ima/ima_fs.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * Copyright (C) 2005,2006,2007,2008 IBM Corporation
  4  *
  5  * Authors:
  6  * Kylene Hall <kjhall@us.ibm.com>
  7  * Reiner Sailer <sailer@us.ibm.com>
  8  * Mimi Zohar <zohar@us.ibm.com>
  9  *
 10  * File: ima_fs.c
 11  *      implemenents security file system for reporting
 12  *      current measurement list and IMA statistics
 13  */
 14 
 15 #include <linux/fcntl.h>
 16 #include <linux/kernel_read_file.h>
 17 #include <linux/slab.h>
 18 #include <linux/init.h>
 19 #include <linux/seq_file.h>
 20 #include <linux/rculist.h>
 21 #include <linux/rcupdate.h>
 22 #include <linux/parser.h>
 23 #include <linux/vmalloc.h>
 24 
 25 #include "ima.h"
 26 
 27 static DEFINE_MUTEX(ima_write_mutex);
 28 
 29 bool ima_canonical_fmt;
 30 static int __init default_canonical_fmt_setup(char *str)
 31 {
 32 #ifdef __BIG_ENDIAN
 33         ima_canonical_fmt = true;
 34 #endif
 35         return 1;
 36 }
 37 __setup("ima_canonical_fmt", default_canonical_fmt_setup);
 38 
 39 static int valid_policy = 1;
 40 
 41 static ssize_t ima_show_htable_value(char __user *buf, size_t count,
 42                                      loff_t *ppos, atomic_long_t *val)
 43 {
 44         char tmpbuf[32];        /* greater than largest 'long' string value */
 45         ssize_t len;
 46 
 47         len = scnprintf(tmpbuf, sizeof(tmpbuf), "%li\n", atomic_long_read(val));
 48         return simple_read_from_buffer(buf, count, ppos, tmpbuf, len);
 49 }
 50 
 51 static ssize_t ima_show_htable_violations(struct file *filp,
 52                                           char __user *buf,
 53                                           size_t count, loff_t *ppos)
 54 {
 55         return ima_show_htable_value(buf, count, ppos, &ima_htable.violations);
 56 }
 57 
 58 static const struct file_operations ima_htable_violations_ops = {
 59         .read = ima_show_htable_violations,
 60         .llseek = generic_file_llseek,
 61 };
 62 
 63 static ssize_t ima_show_measurements_count(struct file *filp,
 64                                            char __user *buf,
 65                                            size_t count, loff_t *ppos)
 66 {
 67         return ima_show_htable_value(buf, count, ppos, &ima_htable.len);
 68 
 69 }
 70 
 71 static const struct file_operations ima_measurements_count_ops = {
 72         .read = ima_show_measurements_count,
 73         .llseek = generic_file_llseek,
 74 };
 75 
 76 /* returns pointer to hlist_node */
 77 static void *ima_measurements_start(struct seq_file *m, loff_t *pos)
 78 {
 79         loff_t l = *pos;
 80         struct ima_queue_entry *qe;
 81 
 82         /* we need a lock since pos could point beyond last element */
 83         rcu_read_lock();
 84         list_for_each_entry_rcu(qe, &ima_measurements, later) {
 85                 if (!l--) {
 86                         rcu_read_unlock();
 87                         return qe;
 88                 }
 89         }
 90         rcu_read_unlock();
 91         return NULL;
 92 }
 93 
 94 static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos)
 95 {
 96         struct ima_queue_entry *qe = v;
 97 
 98         /* lock protects when reading beyond last element
 99          * against concurrent list-extension
100          */
101         rcu_read_lock();
102         qe = list_entry_rcu(qe->later.next, struct ima_queue_entry, later);
103         rcu_read_unlock();
104         (*pos)++;
105 
106         return (&qe->later == &ima_measurements) ? NULL : qe;
107 }
108 
109 static void ima_measurements_stop(struct seq_file *m, void *v)
110 {
111 }
112 
113 void ima_putc(struct seq_file *m, void *data, int datalen)
114 {
115         while (datalen--)
116                 seq_putc(m, *(char *)data++);
117 }
118 
119 static struct dentry **ascii_securityfs_measurement_lists __ro_after_init;
120 static struct dentry **binary_securityfs_measurement_lists __ro_after_init;
121 static int securityfs_measurement_list_count __ro_after_init;
122 
123 static void lookup_template_data_hash_algo(int *algo_idx, enum hash_algo *algo,
124                                            struct seq_file *m,
125                                            struct dentry **lists)
126 {
127         struct dentry *dentry;
128         int i;
129 
130         dentry = file_dentry(m->file);
131 
132         for (i = 0; i < securityfs_measurement_list_count; i++) {
133                 if (dentry == lists[i]) {
134                         *algo_idx = i;
135                         *algo = ima_algo_array[i].algo;
136                         break;
137                 }
138         }
139 }
140 
141 /* print format:
142  *       32bit-le=pcr#
143  *       char[n]=template digest
144  *       32bit-le=template name size
145  *       char[n]=template name
146  *       [eventdata length]
147  *       eventdata[n]=template specific data
148  */
149 int ima_measurements_show(struct seq_file *m, void *v)
150 {
151         /* the list never shrinks, so we don't need a lock here */
152         struct ima_queue_entry *qe = v;
153         struct ima_template_entry *e;
154         char *template_name;
155         u32 pcr, namelen, template_data_len; /* temporary fields */
156         bool is_ima_template = false;
157         enum hash_algo algo;
158         int i, algo_idx;
159 
160         algo_idx = ima_sha1_idx;
161         algo = HASH_ALGO_SHA1;
162 
163         if (m->file != NULL)
164                 lookup_template_data_hash_algo(&algo_idx, &algo, m,
165                                                binary_securityfs_measurement_lists);
166 
167         /* get entry */
168         e = qe->entry;
169         if (e == NULL)
170                 return -1;
171 
172         template_name = (e->template_desc->name[0] != '\0') ?
173             e->template_desc->name : e->template_desc->fmt;
174 
175         /*
176          * 1st: PCRIndex
177          * PCR used defaults to the same (config option) in
178          * little-endian format, unless set in policy
179          */
180         pcr = !ima_canonical_fmt ? e->pcr : (__force u32)cpu_to_le32(e->pcr);
181         ima_putc(m, &pcr, sizeof(e->pcr));
182 
183         /* 2nd: template digest */
184         ima_putc(m, e->digests[algo_idx].digest, hash_digest_size[algo]);
185 
186         /* 3rd: template name size */
187         namelen = !ima_canonical_fmt ? strlen(template_name) :
188                 (__force u32)cpu_to_le32(strlen(template_name));
189         ima_putc(m, &namelen, sizeof(namelen));
190 
191         /* 4th:  template name */
192         ima_putc(m, template_name, strlen(template_name));
193 
194         /* 5th:  template length (except for 'ima' template) */
195         if (strcmp(template_name, IMA_TEMPLATE_IMA_NAME) == 0)
196                 is_ima_template = true;
197 
198         if (!is_ima_template) {
199                 template_data_len = !ima_canonical_fmt ? e->template_data_len :
200                         (__force u32)cpu_to_le32(e->template_data_len);
201                 ima_putc(m, &template_data_len, sizeof(e->template_data_len));
202         }
203 
204         /* 6th:  template specific data */
205         for (i = 0; i < e->template_desc->num_fields; i++) {
206                 enum ima_show_type show = IMA_SHOW_BINARY;
207                 const struct ima_template_field *field =
208                         e->template_desc->fields[i];
209 
210                 if (is_ima_template && strcmp(field->field_id, "d") == 0)
211                         show = IMA_SHOW_BINARY_NO_FIELD_LEN;
212                 if (is_ima_template && strcmp(field->field_id, "n") == 0)
213                         show = IMA_SHOW_BINARY_OLD_STRING_FMT;
214                 field->field_show(m, show, &e->template_data[i]);
215         }
216         return 0;
217 }
218 
219 static const struct seq_operations ima_measurments_seqops = {
220         .start = ima_measurements_start,
221         .next = ima_measurements_next,
222         .stop = ima_measurements_stop,
223         .show = ima_measurements_show
224 };
225 
226 static int ima_measurements_open(struct inode *inode, struct file *file)
227 {
228         return seq_open(file, &ima_measurments_seqops);
229 }
230 
231 static const struct file_operations ima_measurements_ops = {
232         .open = ima_measurements_open,
233         .read = seq_read,
234         .llseek = seq_lseek,
235         .release = seq_release,
236 };
237 
238 void ima_print_digest(struct seq_file *m, u8 *digest, u32 size)
239 {
240         u32 i;
241 
242         for (i = 0; i < size; i++)
243                 seq_printf(m, "%02x", *(digest + i));
244 }
245 
246 /* print in ascii */
247 static int ima_ascii_measurements_show(struct seq_file *m, void *v)
248 {
249         /* the list never shrinks, so we don't need a lock here */
250         struct ima_queue_entry *qe = v;
251         struct ima_template_entry *e;
252         char *template_name;
253         enum hash_algo algo;
254         int i, algo_idx;
255 
256         algo_idx = ima_sha1_idx;
257         algo = HASH_ALGO_SHA1;
258 
259         if (m->file != NULL)
260                 lookup_template_data_hash_algo(&algo_idx, &algo, m,
261                                                ascii_securityfs_measurement_lists);
262 
263         /* get entry */
264         e = qe->entry;
265         if (e == NULL)
266                 return -1;
267 
268         template_name = (e->template_desc->name[0] != '\0') ?
269             e->template_desc->name : e->template_desc->fmt;
270 
271         /* 1st: PCR used (config option) */
272         seq_printf(m, "%2d ", e->pcr);
273 
274         /* 2nd: template hash */
275         ima_print_digest(m, e->digests[algo_idx].digest, hash_digest_size[algo]);
276 
277         /* 3th:  template name */
278         seq_printf(m, " %s", template_name);
279 
280         /* 4th:  template specific data */
281         for (i = 0; i < e->template_desc->num_fields; i++) {
282                 seq_puts(m, " ");
283                 if (e->template_data[i].len == 0)
284                         continue;
285 
286                 e->template_desc->fields[i]->field_show(m, IMA_SHOW_ASCII,
287                                                         &e->template_data[i]);
288         }
289         seq_puts(m, "\n");
290         return 0;
291 }
292 
293 static const struct seq_operations ima_ascii_measurements_seqops = {
294         .start = ima_measurements_start,
295         .next = ima_measurements_next,
296         .stop = ima_measurements_stop,
297         .show = ima_ascii_measurements_show
298 };
299 
300 static int ima_ascii_measurements_open(struct inode *inode, struct file *file)
301 {
302         return seq_open(file, &ima_ascii_measurements_seqops);
303 }
304 
305 static const struct file_operations ima_ascii_measurements_ops = {
306         .open = ima_ascii_measurements_open,
307         .read = seq_read,
308         .llseek = seq_lseek,
309         .release = seq_release,
310 };
311 
312 static ssize_t ima_read_policy(char *path)
313 {
314         void *data = NULL;
315         char *datap;
316         size_t size;
317         int rc, pathlen = strlen(path);
318 
319         char *p;
320 
321         /* remove \n */
322         datap = path;
323         strsep(&datap, "\n");
324 
325         rc = kernel_read_file_from_path(path, 0, &data, INT_MAX, NULL,
326                                         READING_POLICY);
327         if (rc < 0) {
328                 pr_err("Unable to open file: %s (%d)", path, rc);
329                 return rc;
330         }
331         size = rc;
332         rc = 0;
333 
334         datap = data;
335         while (size > 0 && (p = strsep(&datap, "\n"))) {
336                 pr_debug("rule: %s\n", p);
337                 rc = ima_parse_add_rule(p);
338                 if (rc < 0)
339                         break;
340                 size -= rc;
341         }
342 
343         vfree(data);
344         if (rc < 0)
345                 return rc;
346         else if (size)
347                 return -EINVAL;
348         else
349                 return pathlen;
350 }
351 
352 static ssize_t ima_write_policy(struct file *file, const char __user *buf,
353                                 size_t datalen, loff_t *ppos)
354 {
355         char *data;
356         ssize_t result;
357 
358         if (datalen >= PAGE_SIZE)
359                 datalen = PAGE_SIZE - 1;
360 
361         /* No partial writes. */
362         result = -EINVAL;
363         if (*ppos != 0)
364                 goto out;
365 
366         data = memdup_user_nul(buf, datalen);
367         if (IS_ERR(data)) {
368                 result = PTR_ERR(data);
369                 goto out;
370         }
371 
372         result = mutex_lock_interruptible(&ima_write_mutex);
373         if (result < 0)
374                 goto out_free;
375 
376         if (data[0] == '/') {
377                 result = ima_read_policy(data);
378         } else if (ima_appraise & IMA_APPRAISE_POLICY) {
379                 pr_err("signed policy file (specified as an absolute pathname) required\n");
380                 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
381                                     "policy_update", "signed policy required",
382                                     1, 0);
383                 result = -EACCES;
384         } else {
385                 result = ima_parse_add_rule(data);
386         }
387         mutex_unlock(&ima_write_mutex);
388 out_free:
389         kfree(data);
390 out:
391         if (result < 0)
392                 valid_policy = 0;
393 
394         return result;
395 }
396 
397 static struct dentry *ima_dir;
398 static struct dentry *ima_symlink;
399 static struct dentry *binary_runtime_measurements;
400 static struct dentry *ascii_runtime_measurements;
401 static struct dentry *runtime_measurements_count;
402 static struct dentry *violations;
403 static struct dentry *ima_policy;
404 
405 enum ima_fs_flags {
406         IMA_FS_BUSY,
407 };
408 
409 static unsigned long ima_fs_flags;
410 
411 #ifdef  CONFIG_IMA_READ_POLICY
412 static const struct seq_operations ima_policy_seqops = {
413                 .start = ima_policy_start,
414                 .next = ima_policy_next,
415                 .stop = ima_policy_stop,
416                 .show = ima_policy_show,
417 };
418 #endif
419 
420 static void __init remove_securityfs_measurement_lists(struct dentry **lists)
421 {
422         int i;
423 
424         if (lists) {
425                 for (i = 0; i < securityfs_measurement_list_count; i++)
426                         securityfs_remove(lists[i]);
427 
428                 kfree(lists);
429         }
430 }
431 
432 static int __init create_securityfs_measurement_lists(void)
433 {
434         char file_name[NAME_MAX + 1];
435         struct dentry *dentry;
436         u16 algo;
437         int i;
438 
439         securityfs_measurement_list_count = NR_BANKS(ima_tpm_chip);
440 
441         if (ima_sha1_idx >= NR_BANKS(ima_tpm_chip))
442                 securityfs_measurement_list_count++;
443 
444         ascii_securityfs_measurement_lists =
445             kcalloc(securityfs_measurement_list_count, sizeof(struct dentry *),
446                     GFP_KERNEL);
447         if (!ascii_securityfs_measurement_lists)
448                 return -ENOMEM;
449 
450         binary_securityfs_measurement_lists =
451             kcalloc(securityfs_measurement_list_count, sizeof(struct dentry *),
452                     GFP_KERNEL);
453         if (!binary_securityfs_measurement_lists)
454                 return -ENOMEM;
455 
456         for (i = 0; i < securityfs_measurement_list_count; i++) {
457                 algo = ima_algo_array[i].algo;
458 
459                 sprintf(file_name, "ascii_runtime_measurements_%s",
460                         hash_algo_name[algo]);
461                 dentry = securityfs_create_file(file_name, S_IRUSR | S_IRGRP,
462                                                 ima_dir, NULL,
463                                                 &ima_ascii_measurements_ops);
464                 if (IS_ERR(dentry))
465                         return PTR_ERR(dentry);
466 
467                 ascii_securityfs_measurement_lists[i] = dentry;
468 
469                 sprintf(file_name, "binary_runtime_measurements_%s",
470                         hash_algo_name[algo]);
471                 dentry = securityfs_create_file(file_name, S_IRUSR | S_IRGRP,
472                                                 ima_dir, NULL,
473                                                 &ima_measurements_ops);
474                 if (IS_ERR(dentry))
475                         return PTR_ERR(dentry);
476 
477                 binary_securityfs_measurement_lists[i] = dentry;
478         }
479 
480         return 0;
481 }
482 
483 /*
484  * ima_open_policy: sequentialize access to the policy file
485  */
486 static int ima_open_policy(struct inode *inode, struct file *filp)
487 {
488         if (!(filp->f_flags & O_WRONLY)) {
489 #ifndef CONFIG_IMA_READ_POLICY
490                 return -EACCES;
491 #else
492                 if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
493                         return -EACCES;
494                 if (!capable(CAP_SYS_ADMIN))
495                         return -EPERM;
496                 return seq_open(filp, &ima_policy_seqops);
497 #endif
498         }
499         if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags))
500                 return -EBUSY;
501         return 0;
502 }
503 
504 /*
505  * ima_release_policy - start using the new measure policy rules.
506  *
507  * Initially, ima_measure points to the default policy rules, now
508  * point to the new policy rules, and remove the securityfs policy file,
509  * assuming a valid policy.
510  */
511 static int ima_release_policy(struct inode *inode, struct file *file)
512 {
513         const char *cause = valid_policy ? "completed" : "failed";
514 
515         if ((file->f_flags & O_ACCMODE) == O_RDONLY)
516                 return seq_release(inode, file);
517 
518         if (valid_policy && ima_check_policy() < 0) {
519                 cause = "failed";
520                 valid_policy = 0;
521         }
522 
523         pr_info("policy update %s\n", cause);
524         integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
525                             "policy_update", cause, !valid_policy, 0);
526 
527         if (!valid_policy) {
528                 ima_delete_rules();
529                 valid_policy = 1;
530                 clear_bit(IMA_FS_BUSY, &ima_fs_flags);
531                 return 0;
532         }
533 
534         ima_update_policy();
535 #if !defined(CONFIG_IMA_WRITE_POLICY) && !defined(CONFIG_IMA_READ_POLICY)
536         securityfs_remove(ima_policy);
537         ima_policy = NULL;
538 #elif defined(CONFIG_IMA_WRITE_POLICY)
539         clear_bit(IMA_FS_BUSY, &ima_fs_flags);
540 #elif defined(CONFIG_IMA_READ_POLICY)
541         inode->i_mode &= ~S_IWUSR;
542 #endif
543         return 0;
544 }
545 
546 static const struct file_operations ima_measure_policy_ops = {
547         .open = ima_open_policy,
548         .write = ima_write_policy,
549         .read = seq_read,
550         .release = ima_release_policy,
551         .llseek = generic_file_llseek,
552 };
553 
554 int __init ima_fs_init(void)
555 {
556         int ret;
557 
558         ascii_securityfs_measurement_lists = NULL;
559         binary_securityfs_measurement_lists = NULL;
560 
561         ima_dir = securityfs_create_dir("ima", integrity_dir);
562         if (IS_ERR(ima_dir))
563                 return PTR_ERR(ima_dir);
564 
565         ima_symlink = securityfs_create_symlink("ima", NULL, "integrity/ima",
566                                                 NULL);
567         if (IS_ERR(ima_symlink)) {
568                 ret = PTR_ERR(ima_symlink);
569                 goto out;
570         }
571 
572         ret = create_securityfs_measurement_lists();
573         if (ret != 0)
574                 goto out;
575 
576         binary_runtime_measurements =
577             securityfs_create_symlink("binary_runtime_measurements", ima_dir,
578                                       "binary_runtime_measurements_sha1", NULL);
579         if (IS_ERR(binary_runtime_measurements)) {
580                 ret = PTR_ERR(binary_runtime_measurements);
581                 goto out;
582         }
583 
584         ascii_runtime_measurements =
585             securityfs_create_symlink("ascii_runtime_measurements", ima_dir,
586                                       "ascii_runtime_measurements_sha1", NULL);
587         if (IS_ERR(ascii_runtime_measurements)) {
588                 ret = PTR_ERR(ascii_runtime_measurements);
589                 goto out;
590         }
591 
592         runtime_measurements_count =
593             securityfs_create_file("runtime_measurements_count",
594                                    S_IRUSR | S_IRGRP, ima_dir, NULL,
595                                    &ima_measurements_count_ops);
596         if (IS_ERR(runtime_measurements_count)) {
597                 ret = PTR_ERR(runtime_measurements_count);
598                 goto out;
599         }
600 
601         violations =
602             securityfs_create_file("violations", S_IRUSR | S_IRGRP,
603                                    ima_dir, NULL, &ima_htable_violations_ops);
604         if (IS_ERR(violations)) {
605                 ret = PTR_ERR(violations);
606                 goto out;
607         }
608 
609         ima_policy = securityfs_create_file("policy", POLICY_FILE_FLAGS,
610                                             ima_dir, NULL,
611                                             &ima_measure_policy_ops);
612         if (IS_ERR(ima_policy)) {
613                 ret = PTR_ERR(ima_policy);
614                 goto out;
615         }
616 
617         return 0;
618 out:
619         securityfs_remove(ima_policy);
620         securityfs_remove(violations);
621         securityfs_remove(runtime_measurements_count);
622         securityfs_remove(ascii_runtime_measurements);
623         securityfs_remove(binary_runtime_measurements);
624         remove_securityfs_measurement_lists(ascii_securityfs_measurement_lists);
625         remove_securityfs_measurement_lists(binary_securityfs_measurement_lists);
626         securityfs_measurement_list_count = 0;
627         securityfs_remove(ima_symlink);
628         securityfs_remove(ima_dir);
629 
630         return ret;
631 }
632 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php