root/security/integrity/ima/ima_fs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. default_canonical_fmt_setup
  2. ima_show_htable_value
  3. ima_show_htable_violations
  4. ima_show_measurements_count
  5. ima_measurements_start
  6. ima_measurements_next
  7. ima_measurements_stop
  8. ima_putc
  9. ima_measurements_show
  10. ima_measurements_open
  11. ima_print_digest
  12. ima_ascii_measurements_show
  13. ima_ascii_measurements_open
  14. ima_read_policy
  15. ima_write_policy
  16. ima_open_policy
  17. ima_release_policy
  18. ima_fs_init

   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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  16 
  17 #include <linux/fcntl.h>
  18 #include <linux/slab.h>
  19 #include <linux/init.h>
  20 #include <linux/seq_file.h>
  21 #include <linux/rculist.h>
  22 #include <linux/rcupdate.h>
  23 #include <linux/parser.h>
  24 #include <linux/vmalloc.h>
  25 
  26 #include "ima.h"
  27 
  28 static DEFINE_MUTEX(ima_write_mutex);
  29 
  30 bool ima_canonical_fmt;
  31 static int __init default_canonical_fmt_setup(char *str)
  32 {
  33 #ifdef __BIG_ENDIAN
  34         ima_canonical_fmt = true;
  35 #endif
  36         return 1;
  37 }
  38 __setup("ima_canonical_fmt", default_canonical_fmt_setup);
  39 
  40 static int valid_policy = 1;
  41 
  42 static ssize_t ima_show_htable_value(char __user *buf, size_t count,
  43                                      loff_t *ppos, atomic_long_t *val)
  44 {
  45         char tmpbuf[32];        /* greater than largest 'long' string value */
  46         ssize_t len;
  47 
  48         len = scnprintf(tmpbuf, sizeof(tmpbuf), "%li\n", atomic_long_read(val));
  49         return simple_read_from_buffer(buf, count, ppos, tmpbuf, len);
  50 }
  51 
  52 static ssize_t ima_show_htable_violations(struct file *filp,
  53                                           char __user *buf,
  54                                           size_t count, loff_t *ppos)
  55 {
  56         return ima_show_htable_value(buf, count, ppos, &ima_htable.violations);
  57 }
  58 
  59 static const struct file_operations ima_htable_violations_ops = {
  60         .read = ima_show_htable_violations,
  61         .llseek = generic_file_llseek,
  62 };
  63 
  64 static ssize_t ima_show_measurements_count(struct file *filp,
  65                                            char __user *buf,
  66                                            size_t count, loff_t *ppos)
  67 {
  68         return ima_show_htable_value(buf, count, ppos, &ima_htable.len);
  69 
  70 }
  71 
  72 static const struct file_operations ima_measurements_count_ops = {
  73         .read = ima_show_measurements_count,
  74         .llseek = generic_file_llseek,
  75 };
  76 
  77 /* returns pointer to hlist_node */
  78 static void *ima_measurements_start(struct seq_file *m, loff_t *pos)
  79 {
  80         loff_t l = *pos;
  81         struct ima_queue_entry *qe;
  82 
  83         /* we need a lock since pos could point beyond last element */
  84         rcu_read_lock();
  85         list_for_each_entry_rcu(qe, &ima_measurements, later) {
  86                 if (!l--) {
  87                         rcu_read_unlock();
  88                         return qe;
  89                 }
  90         }
  91         rcu_read_unlock();
  92         return NULL;
  93 }
  94 
  95 static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos)
  96 {
  97         struct ima_queue_entry *qe = v;
  98 
  99         /* lock protects when reading beyond last element
 100          * against concurrent list-extension
 101          */
 102         rcu_read_lock();
 103         qe = list_entry_rcu(qe->later.next, struct ima_queue_entry, later);
 104         rcu_read_unlock();
 105         (*pos)++;
 106 
 107         return (&qe->later == &ima_measurements) ? NULL : qe;
 108 }
 109 
 110 static void ima_measurements_stop(struct seq_file *m, void *v)
 111 {
 112 }
 113 
 114 void ima_putc(struct seq_file *m, void *data, int datalen)
 115 {
 116         while (datalen--)
 117                 seq_putc(m, *(char *)data++);
 118 }
 119 
 120 /* print format:
 121  *       32bit-le=pcr#
 122  *       char[20]=template digest
 123  *       32bit-le=template name size
 124  *       char[n]=template name
 125  *       [eventdata length]
 126  *       eventdata[n]=template specific data
 127  */
 128 int ima_measurements_show(struct seq_file *m, void *v)
 129 {
 130         /* the list never shrinks, so we don't need a lock here */
 131         struct ima_queue_entry *qe = v;
 132         struct ima_template_entry *e;
 133         char *template_name;
 134         u32 pcr, namelen, template_data_len; /* temporary fields */
 135         bool is_ima_template = false;
 136         int i;
 137 
 138         /* get entry */
 139         e = qe->entry;
 140         if (e == NULL)
 141                 return -1;
 142 
 143         template_name = (e->template_desc->name[0] != '\0') ?
 144             e->template_desc->name : e->template_desc->fmt;
 145 
 146         /*
 147          * 1st: PCRIndex
 148          * PCR used defaults to the same (config option) in
 149          * little-endian format, unless set in policy
 150          */
 151         pcr = !ima_canonical_fmt ? e->pcr : cpu_to_le32(e->pcr);
 152         ima_putc(m, &pcr, sizeof(e->pcr));
 153 
 154         /* 2nd: template digest */
 155         ima_putc(m, e->digest, TPM_DIGEST_SIZE);
 156 
 157         /* 3rd: template name size */
 158         namelen = !ima_canonical_fmt ? strlen(template_name) :
 159                 cpu_to_le32(strlen(template_name));
 160         ima_putc(m, &namelen, sizeof(namelen));
 161 
 162         /* 4th:  template name */
 163         ima_putc(m, template_name, strlen(template_name));
 164 
 165         /* 5th:  template length (except for 'ima' template) */
 166         if (strcmp(template_name, IMA_TEMPLATE_IMA_NAME) == 0)
 167                 is_ima_template = true;
 168 
 169         if (!is_ima_template) {
 170                 template_data_len = !ima_canonical_fmt ? e->template_data_len :
 171                         cpu_to_le32(e->template_data_len);
 172                 ima_putc(m, &template_data_len, sizeof(e->template_data_len));
 173         }
 174 
 175         /* 6th:  template specific data */
 176         for (i = 0; i < e->template_desc->num_fields; i++) {
 177                 enum ima_show_type show = IMA_SHOW_BINARY;
 178                 const struct ima_template_field *field =
 179                         e->template_desc->fields[i];
 180 
 181                 if (is_ima_template && strcmp(field->field_id, "d") == 0)
 182                         show = IMA_SHOW_BINARY_NO_FIELD_LEN;
 183                 if (is_ima_template && strcmp(field->field_id, "n") == 0)
 184                         show = IMA_SHOW_BINARY_OLD_STRING_FMT;
 185                 field->field_show(m, show, &e->template_data[i]);
 186         }
 187         return 0;
 188 }
 189 
 190 static const struct seq_operations ima_measurments_seqops = {
 191         .start = ima_measurements_start,
 192         .next = ima_measurements_next,
 193         .stop = ima_measurements_stop,
 194         .show = ima_measurements_show
 195 };
 196 
 197 static int ima_measurements_open(struct inode *inode, struct file *file)
 198 {
 199         return seq_open(file, &ima_measurments_seqops);
 200 }
 201 
 202 static const struct file_operations ima_measurements_ops = {
 203         .open = ima_measurements_open,
 204         .read = seq_read,
 205         .llseek = seq_lseek,
 206         .release = seq_release,
 207 };
 208 
 209 void ima_print_digest(struct seq_file *m, u8 *digest, u32 size)
 210 {
 211         u32 i;
 212 
 213         for (i = 0; i < size; i++)
 214                 seq_printf(m, "%02x", *(digest + i));
 215 }
 216 
 217 /* print in ascii */
 218 static int ima_ascii_measurements_show(struct seq_file *m, void *v)
 219 {
 220         /* the list never shrinks, so we don't need a lock here */
 221         struct ima_queue_entry *qe = v;
 222         struct ima_template_entry *e;
 223         char *template_name;
 224         int i;
 225 
 226         /* get entry */
 227         e = qe->entry;
 228         if (e == NULL)
 229                 return -1;
 230 
 231         template_name = (e->template_desc->name[0] != '\0') ?
 232             e->template_desc->name : e->template_desc->fmt;
 233 
 234         /* 1st: PCR used (config option) */
 235         seq_printf(m, "%2d ", e->pcr);
 236 
 237         /* 2nd: SHA1 template hash */
 238         ima_print_digest(m, e->digest, TPM_DIGEST_SIZE);
 239 
 240         /* 3th:  template name */
 241         seq_printf(m, " %s", template_name);
 242 
 243         /* 4th:  template specific data */
 244         for (i = 0; i < e->template_desc->num_fields; i++) {
 245                 seq_puts(m, " ");
 246                 if (e->template_data[i].len == 0)
 247                         continue;
 248 
 249                 e->template_desc->fields[i]->field_show(m, IMA_SHOW_ASCII,
 250                                                         &e->template_data[i]);
 251         }
 252         seq_puts(m, "\n");
 253         return 0;
 254 }
 255 
 256 static const struct seq_operations ima_ascii_measurements_seqops = {
 257         .start = ima_measurements_start,
 258         .next = ima_measurements_next,
 259         .stop = ima_measurements_stop,
 260         .show = ima_ascii_measurements_show
 261 };
 262 
 263 static int ima_ascii_measurements_open(struct inode *inode, struct file *file)
 264 {
 265         return seq_open(file, &ima_ascii_measurements_seqops);
 266 }
 267 
 268 static const struct file_operations ima_ascii_measurements_ops = {
 269         .open = ima_ascii_measurements_open,
 270         .read = seq_read,
 271         .llseek = seq_lseek,
 272         .release = seq_release,
 273 };
 274 
 275 static ssize_t ima_read_policy(char *path)
 276 {
 277         void *data;
 278         char *datap;
 279         loff_t size;
 280         int rc, pathlen = strlen(path);
 281 
 282         char *p;
 283 
 284         /* remove \n */
 285         datap = path;
 286         strsep(&datap, "\n");
 287 
 288         rc = kernel_read_file_from_path(path, &data, &size, 0, READING_POLICY);
 289         if (rc < 0) {
 290                 pr_err("Unable to open file: %s (%d)", path, rc);
 291                 return rc;
 292         }
 293 
 294         datap = data;
 295         while (size > 0 && (p = strsep(&datap, "\n"))) {
 296                 pr_debug("rule: %s\n", p);
 297                 rc = ima_parse_add_rule(p);
 298                 if (rc < 0)
 299                         break;
 300                 size -= rc;
 301         }
 302 
 303         vfree(data);
 304         if (rc < 0)
 305                 return rc;
 306         else if (size)
 307                 return -EINVAL;
 308         else
 309                 return pathlen;
 310 }
 311 
 312 static ssize_t ima_write_policy(struct file *file, const char __user *buf,
 313                                 size_t datalen, loff_t *ppos)
 314 {
 315         char *data;
 316         ssize_t result;
 317 
 318         if (datalen >= PAGE_SIZE)
 319                 datalen = PAGE_SIZE - 1;
 320 
 321         /* No partial writes. */
 322         result = -EINVAL;
 323         if (*ppos != 0)
 324                 goto out;
 325 
 326         data = memdup_user_nul(buf, datalen);
 327         if (IS_ERR(data)) {
 328                 result = PTR_ERR(data);
 329                 goto out;
 330         }
 331 
 332         result = mutex_lock_interruptible(&ima_write_mutex);
 333         if (result < 0)
 334                 goto out_free;
 335 
 336         if (data[0] == '/') {
 337                 result = ima_read_policy(data);
 338         } else if (ima_appraise & IMA_APPRAISE_POLICY) {
 339                 pr_err("signed policy file (specified as an absolute pathname) required\n");
 340                 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
 341                                     "policy_update", "signed policy required",
 342                                     1, 0);
 343                 result = -EACCES;
 344         } else {
 345                 result = ima_parse_add_rule(data);
 346         }
 347         mutex_unlock(&ima_write_mutex);
 348 out_free:
 349         kfree(data);
 350 out:
 351         if (result < 0)
 352                 valid_policy = 0;
 353 
 354         return result;
 355 }
 356 
 357 static struct dentry *ima_dir;
 358 static struct dentry *ima_symlink;
 359 static struct dentry *binary_runtime_measurements;
 360 static struct dentry *ascii_runtime_measurements;
 361 static struct dentry *runtime_measurements_count;
 362 static struct dentry *violations;
 363 static struct dentry *ima_policy;
 364 
 365 enum ima_fs_flags {
 366         IMA_FS_BUSY,
 367 };
 368 
 369 static unsigned long ima_fs_flags;
 370 
 371 #ifdef  CONFIG_IMA_READ_POLICY
 372 static const struct seq_operations ima_policy_seqops = {
 373                 .start = ima_policy_start,
 374                 .next = ima_policy_next,
 375                 .stop = ima_policy_stop,
 376                 .show = ima_policy_show,
 377 };
 378 #endif
 379 
 380 /*
 381  * ima_open_policy: sequentialize access to the policy file
 382  */
 383 static int ima_open_policy(struct inode *inode, struct file *filp)
 384 {
 385         if (!(filp->f_flags & O_WRONLY)) {
 386 #ifndef CONFIG_IMA_READ_POLICY
 387                 return -EACCES;
 388 #else
 389                 if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
 390                         return -EACCES;
 391                 if (!capable(CAP_SYS_ADMIN))
 392                         return -EPERM;
 393                 return seq_open(filp, &ima_policy_seqops);
 394 #endif
 395         }
 396         if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags))
 397                 return -EBUSY;
 398         return 0;
 399 }
 400 
 401 /*
 402  * ima_release_policy - start using the new measure policy rules.
 403  *
 404  * Initially, ima_measure points to the default policy rules, now
 405  * point to the new policy rules, and remove the securityfs policy file,
 406  * assuming a valid policy.
 407  */
 408 static int ima_release_policy(struct inode *inode, struct file *file)
 409 {
 410         const char *cause = valid_policy ? "completed" : "failed";
 411 
 412         if ((file->f_flags & O_ACCMODE) == O_RDONLY)
 413                 return seq_release(inode, file);
 414 
 415         if (valid_policy && ima_check_policy() < 0) {
 416                 cause = "failed";
 417                 valid_policy = 0;
 418         }
 419 
 420         pr_info("policy update %s\n", cause);
 421         integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
 422                             "policy_update", cause, !valid_policy, 0);
 423 
 424         if (!valid_policy) {
 425                 ima_delete_rules();
 426                 valid_policy = 1;
 427                 clear_bit(IMA_FS_BUSY, &ima_fs_flags);
 428                 return 0;
 429         }
 430 
 431         ima_update_policy();
 432 #if !defined(CONFIG_IMA_WRITE_POLICY) && !defined(CONFIG_IMA_READ_POLICY)
 433         securityfs_remove(ima_policy);
 434         ima_policy = NULL;
 435 #elif defined(CONFIG_IMA_WRITE_POLICY)
 436         clear_bit(IMA_FS_BUSY, &ima_fs_flags);
 437 #elif defined(CONFIG_IMA_READ_POLICY)
 438         inode->i_mode &= ~S_IWUSR;
 439 #endif
 440         return 0;
 441 }
 442 
 443 static const struct file_operations ima_measure_policy_ops = {
 444         .open = ima_open_policy,
 445         .write = ima_write_policy,
 446         .read = seq_read,
 447         .release = ima_release_policy,
 448         .llseek = generic_file_llseek,
 449 };
 450 
 451 int __init ima_fs_init(void)
 452 {
 453         ima_dir = securityfs_create_dir("ima", integrity_dir);
 454         if (IS_ERR(ima_dir))
 455                 return -1;
 456 
 457         ima_symlink = securityfs_create_symlink("ima", NULL, "integrity/ima",
 458                                                 NULL);
 459         if (IS_ERR(ima_symlink))
 460                 goto out;
 461 
 462         binary_runtime_measurements =
 463             securityfs_create_file("binary_runtime_measurements",
 464                                    S_IRUSR | S_IRGRP, ima_dir, NULL,
 465                                    &ima_measurements_ops);
 466         if (IS_ERR(binary_runtime_measurements))
 467                 goto out;
 468 
 469         ascii_runtime_measurements =
 470             securityfs_create_file("ascii_runtime_measurements",
 471                                    S_IRUSR | S_IRGRP, ima_dir, NULL,
 472                                    &ima_ascii_measurements_ops);
 473         if (IS_ERR(ascii_runtime_measurements))
 474                 goto out;
 475 
 476         runtime_measurements_count =
 477             securityfs_create_file("runtime_measurements_count",
 478                                    S_IRUSR | S_IRGRP, ima_dir, NULL,
 479                                    &ima_measurements_count_ops);
 480         if (IS_ERR(runtime_measurements_count))
 481                 goto out;
 482 
 483         violations =
 484             securityfs_create_file("violations", S_IRUSR | S_IRGRP,
 485                                    ima_dir, NULL, &ima_htable_violations_ops);
 486         if (IS_ERR(violations))
 487                 goto out;
 488 
 489         ima_policy = securityfs_create_file("policy", POLICY_FILE_FLAGS,
 490                                             ima_dir, NULL,
 491                                             &ima_measure_policy_ops);
 492         if (IS_ERR(ima_policy))
 493                 goto out;
 494 
 495         return 0;
 496 out:
 497         securityfs_remove(violations);
 498         securityfs_remove(runtime_measurements_count);
 499         securityfs_remove(ascii_runtime_measurements);
 500         securityfs_remove(binary_runtime_measurements);
 501         securityfs_remove(ima_symlink);
 502         securityfs_remove(ima_dir);
 503         securityfs_remove(ima_policy);
 504         return -1;
 505 }

/* [<][>][^][v][top][bottom][index][help] */