1 /* 2 * Copyright (C) 2010 IBM Corporation 3 * 4 * Authors: 5 * Mimi Zohar <zohar@us.ibm.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, version 2 of the License. 10 * 11 * File: evm_secfs.c 12 * - Used to signal when key is on keyring 13 * - Get the key and enable EVM 14 */ 15 16 #include <linux/uaccess.h> 17 #include <linux/module.h> 18 #include "evm.h" 19 20 static struct dentry *evm_init_tpm; 21 22 /** 23 * evm_read_key - read() for <securityfs>/evm 24 * 25 * @filp: file pointer, not actually used 26 * @buf: where to put the result 27 * @count: maximum to send along 28 * @ppos: where to start 29 * 30 * Returns number of bytes read or error code, as appropriate 31 */ 32 static ssize_t evm_read_key(struct file *filp, char __user *buf, 33 size_t count, loff_t *ppos) 34 { 35 char temp[80]; 36 ssize_t rc; 37 38 if (*ppos != 0) 39 return 0; 40 41 sprintf(temp, "%d", evm_initialized); 42 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); 43 44 return rc; 45 } 46 47 /** 48 * evm_write_key - write() for <securityfs>/evm 49 * @file: file pointer, not actually used 50 * @buf: where to get the data from 51 * @count: bytes sent 52 * @ppos: where to start 53 * 54 * Used to signal that key is on the kernel key ring. 55 * - get the integrity hmac key from the kernel key ring 56 * - create list of hmac protected extended attributes 57 * Returns number of bytes written or error code, as appropriate 58 */ 59 static ssize_t evm_write_key(struct file *file, const char __user *buf, 60 size_t count, loff_t *ppos) 61 { 62 char temp[80]; 63 int i, error; 64 65 if (!capable(CAP_SYS_ADMIN) || evm_initialized) 66 return -EPERM; 67 68 if (count >= sizeof(temp) || count == 0) 69 return -EINVAL; 70 71 if (copy_from_user(temp, buf, count) != 0) 72 return -EFAULT; 73 74 temp[count] = '\0'; 75 76 if ((sscanf(temp, "%d", &i) != 1) || (i != 1)) 77 return -EINVAL; 78 79 error = evm_init_key(); 80 if (!error) { 81 evm_initialized = 1; 82 pr_info("EVM: initialized\n"); 83 } else 84 pr_err("EVM: initialization failed\n"); 85 return count; 86 } 87 88 static const struct file_operations evm_key_ops = { 89 .read = evm_read_key, 90 .write = evm_write_key, 91 }; 92 93 int __init evm_init_secfs(void) 94 { 95 int error = 0; 96 97 evm_init_tpm = securityfs_create_file("evm", S_IRUSR | S_IRGRP, 98 NULL, NULL, &evm_key_ops); 99 if (!evm_init_tpm || IS_ERR(evm_init_tpm)) 100 error = -EFAULT; 101 return error; 102 } 103