1/* 2 * Copyright (C) 2005,2006,2007,2008 IBM Corporation 3 * 4 * Authors: 5 * Reiner Sailer <sailer@watson.ibm.com> 6 * Serge Hallyn <serue@us.ibm.com> 7 * Kylene Hall <kylene@us.ibm.com> 8 * Mimi Zohar <zohar@us.ibm.com> 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License as 12 * published by the Free Software Foundation, version 2 of the 13 * License. 14 * 15 * File: ima_main.c 16 * implements the IMA hooks: ima_bprm_check, ima_file_mmap, 17 * and ima_file_check. 18 */ 19#include <linux/module.h> 20#include <linux/file.h> 21#include <linux/binfmts.h> 22#include <linux/mount.h> 23#include <linux/mman.h> 24#include <linux/slab.h> 25 26#include "ima.h" 27 28int ima_initialized; 29 30char *ima_hash = "sha1"; 31static int __init hash_setup(char *str) 32{ 33 if (strncmp(str, "md5", 3) == 0) 34 ima_hash = "md5"; 35 return 1; 36} 37__setup("ima_hash=", hash_setup); 38 39struct ima_imbalance { 40 struct hlist_node node; 41 unsigned long fsmagic; 42}; 43 44/* 45 * ima_limit_imbalance - emit one imbalance message per filesystem type 46 * 47 * Maintain list of filesystem types that do not measure files properly. 48 * Return false if unknown, true if known. 49 */ 50static bool ima_limit_imbalance(struct file *file) 51{ 52 static DEFINE_SPINLOCK(ima_imbalance_lock); 53 static HLIST_HEAD(ima_imbalance_list); 54 55 struct super_block *sb = file->f_dentry->d_sb; 56 struct ima_imbalance *entry; 57 struct hlist_node *node; 58 bool found = false; 59 60 rcu_read_lock(); 61 hlist_for_each_entry_rcu(entry, node, &ima_imbalance_list, node) { 62 if (entry->fsmagic == sb->s_magic) { 63 found = true; 64 break; 65 } 66 } 67 rcu_read_unlock(); 68 if (found) 69 goto out; 70 71 entry = kmalloc(sizeof(*entry), GFP_NOFS); 72 if (!entry) 73 goto out; 74 entry->fsmagic = sb->s_magic; 75 spin_lock(&ima_imbalance_lock); 76 /* 77 * we could have raced and something else might have added this fs 78 * to the list, but we don't really care 79 */ 80 hlist_add_head_rcu(&entry->node, &ima_imbalance_list); 81 spin_unlock(&ima_imbalance_lock); 82 printk(KERN_INFO "IMA: unmeasured files on fsmagic: %lX\n", 83 entry->fsmagic); 84out: 85 return found; 86} 87 88/* ima_read_write_check - reflect possible reading/writing errors in the PCR. 89 * 90 * When opening a file for read, if the file is already open for write, 91 * the file could change, resulting in a file measurement error. 92 * 93 * Opening a file for write, if the file is already open for read, results 94 * in a time of measure, time of use (ToMToU) error. 95 * 96 * In either case invalidate the PCR. 97 */ 98enum iint_pcr_error { TOMTOU, OPEN_WRITERS }; 99static void ima_read_write_check(enum iint_pcr_error error, 100 struct ima_iint_cache *iint, 101 struct inode *inode, 102 const unsigned char *filename) 103{ 104 switch (error) { 105 case TOMTOU: 106 if (iint->readcount > 0) 107 ima_add_violation(inode, filename, "invalid_pcr", 108 "ToMToU"); 109 break; 110 case OPEN_WRITERS: 111 if (iint->writecount > 0) 112 ima_add_violation(inode, filename, "invalid_pcr", 113 "open_writers"); 114 break; 115 } 116} 117 118/* 119 * Update the counts given an fmode_t 120 */ 121static void ima_inc_counts(struct ima_iint_cache *iint, fmode_t mode) 122{ 123 BUG_ON(!mutex_is_locked(&iint->mutex)); 124 125 iint->opencount++; 126 if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) 127 iint->readcount++; 128 if (mode & FMODE_WRITE) 129 iint->writecount++; 130} 131 132/* 133 * ima_counts_get - increment file counts 134 * 135 * Maintain read/write counters for all files, but only 136 * invalidate the PCR for measured files: 137 * - Opening a file for write when already open for read, 138 * results in a time of measure, time of use (ToMToU) error. 139 * - Opening a file for read when already open for write, 140 * could result in a file measurement error. 141 * 142 */ 143void ima_counts_get(struct file *file) 144{ 145 struct dentry *dentry = file->f_path.dentry; 146 struct inode *inode = dentry->d_inode; 147 fmode_t mode = file->f_mode; 148 struct ima_iint_cache *iint; 149 int rc; 150 151 if (!iint_initialized || !S_ISREG(inode->i_mode)) 152 return; 153 iint = ima_iint_find_get(inode); 154 if (!iint) 155 return; 156 mutex_lock(&iint->mutex); 157 if (!ima_initialized) 158 goto out; 159 rc = ima_must_measure(iint, inode, MAY_READ, FILE_CHECK); 160 if (rc < 0) 161 goto out; 162 163 if (mode & FMODE_WRITE) { 164 ima_read_write_check(TOMTOU, iint, inode, dentry->d_name.name); 165 goto out; 166 } 167 ima_read_write_check(OPEN_WRITERS, iint, inode, dentry->d_name.name); 168out: 169 ima_inc_counts(iint, file->f_mode); 170 mutex_unlock(&iint->mutex); 171 172 kref_put(&iint->refcount, iint_free); 173} 174 175/* 176 * Decrement ima counts 177 */ 178static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode, 179 struct file *file) 180{ 181 mode_t mode = file->f_mode; 182 BUG_ON(!mutex_is_locked(&iint->mutex)); 183 184 iint->opencount--; 185 if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) 186 iint->readcount--; 187 if (mode & FMODE_WRITE) { 188 iint->writecount--; 189 if (iint->writecount == 0) { 190 if (iint->version != inode->i_version) 191 iint->flags &= ~IMA_MEASURED; 192 } 193 } 194 195 if (((iint->opencount < 0) || 196 (iint->readcount < 0) || 197 (iint->writecount < 0)) && 198 !ima_limit_imbalance(file)) { 199 printk(KERN_INFO "%s: open/free imbalance (r:%ld w:%ld o:%ld)\n", 200 __func__, iint->readcount, iint->writecount, 201 iint->opencount); 202 dump_stack(); 203 } 204} 205 206/** 207 * ima_file_free - called on __fput() 208 * @file: pointer to file structure being freed 209 * 210 * Flag files that changed, based on i_version; 211 * and decrement the iint readcount/writecount. 212 */ 213void ima_file_free(struct file *file) 214{ 215 struct inode *inode = file->f_dentry->d_inode; 216 struct ima_iint_cache *iint; 217 218 if (!iint_initialized || !S_ISREG(inode->i_mode)) 219 return; 220 iint = ima_iint_find_get(inode); 221 if (!iint) 222 return; 223 224 mutex_lock(&iint->mutex); 225 ima_dec_counts(iint, inode, file); 226 mutex_unlock(&iint->mutex); 227 kref_put(&iint->refcount, iint_free); 228} 229 230static int process_measurement(struct file *file, const unsigned char *filename, 231 int mask, int function) 232{ 233 struct inode *inode = file->f_dentry->d_inode; 234 struct ima_iint_cache *iint; 235 int rc = 0; 236 237 if (!ima_initialized || !S_ISREG(inode->i_mode)) 238 return 0; 239 iint = ima_iint_find_get(inode); 240 if (!iint) 241 return -ENOMEM; 242 243 mutex_lock(&iint->mutex); 244 rc = ima_must_measure(iint, inode, mask, function); 245 if (rc != 0) 246 goto out; 247 248 rc = ima_collect_measurement(iint, file); 249 if (!rc) 250 ima_store_measurement(iint, file, filename); 251out: 252 mutex_unlock(&iint->mutex); 253 kref_put(&iint->refcount, iint_free); 254 return rc; 255} 256 257/** 258 * ima_file_mmap - based on policy, collect/store measurement. 259 * @file: pointer to the file to be measured (May be NULL) 260 * @prot: contains the protection that will be applied by the kernel. 261 * 262 * Measure files being mmapped executable based on the ima_must_measure() 263 * policy decision. 264 * 265 * Return 0 on success, an error code on failure. 266 * (Based on the results of appraise_measurement().) 267 */ 268int ima_file_mmap(struct file *file, unsigned long prot) 269{ 270 int rc; 271 272 if (!file) 273 return 0; 274 if (prot & PROT_EXEC) 275 rc = process_measurement(file, file->f_dentry->d_name.name, 276 MAY_EXEC, FILE_MMAP); 277 return 0; 278} 279 280/** 281 * ima_bprm_check - based on policy, collect/store measurement. 282 * @bprm: contains the linux_binprm structure 283 * 284 * The OS protects against an executable file, already open for write, 285 * from being executed in deny_write_access() and an executable file, 286 * already open for execute, from being modified in get_write_access(). 287 * So we can be certain that what we verify and measure here is actually 288 * what is being executed. 289 * 290 * Return 0 on success, an error code on failure. 291 * (Based on the results of appraise_measurement().) 292 */ 293int ima_bprm_check(struct linux_binprm *bprm) 294{ 295 int rc; 296 297 rc = process_measurement(bprm->file, bprm->filename, 298 MAY_EXEC, BPRM_CHECK); 299 return 0; 300} 301 302/** 303 * ima_path_check - based on policy, collect/store measurement. 304 * @file: pointer to the file to be measured 305 * @mask: contains MAY_READ, MAY_WRITE or MAY_EXECUTE 306 * 307 * Measure files based on the ima_must_measure() policy decision. 308 * 309 * Always return 0 and audit dentry_open failures. 310 * (Return code will be based upon measurement appraisal.) 311 */ 312int ima_file_check(struct file *file, int mask) 313{ 314 int rc; 315 316 rc = process_measurement(file, file->f_dentry->d_name.name, 317 mask & (MAY_READ | MAY_WRITE | MAY_EXEC), 318 FILE_CHECK); 319 return 0; 320} 321EXPORT_SYMBOL_GPL(ima_file_check); 322 323static int __init init_ima(void) 324{ 325 int error; 326 327 error = ima_init(); 328 ima_initialized = 1; 329 return error; 330} 331 332static void __exit cleanup_ima(void) 333{ 334 ima_cleanup(); 335} 336 337late_initcall(init_ima); /* Start IMA after the TPM is available */ 338 339MODULE_DESCRIPTION("Integrity Measurement Architecture"); 340MODULE_LICENSE("GPL"); 341