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#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17 18#include <linux/uaccess.h> 19#include <linux/module.h> 20#include "evm.h" 21 22static struct dentry *evm_init_tpm; 23 24/** 25 * evm_read_key - read() for <securityfs>/evm 26 * 27 * @filp: file pointer, not actually used 28 * @buf: where to put the result 29 * @count: maximum to send along 30 * @ppos: where to start 31 * 32 * Returns number of bytes read or error code, as appropriate 33 */ 34static ssize_t evm_read_key(struct file *filp, char __user *buf, 35 size_t count, loff_t *ppos) 36{ 37 char temp[80]; 38 ssize_t rc; 39 40 if (*ppos != 0) 41 return 0; 42 43 sprintf(temp, "%d", evm_initialized); 44 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); 45 46 return rc; 47} 48 49/** 50 * evm_write_key - write() for <securityfs>/evm 51 * @file: file pointer, not actually used 52 * @buf: where to get the data from 53 * @count: bytes sent 54 * @ppos: where to start 55 * 56 * Used to signal that key is on the kernel key ring. 57 * - get the integrity hmac key from the kernel key ring 58 * - create list of hmac protected extended attributes 59 * Returns number of bytes written or error code, as appropriate 60 */ 61static ssize_t evm_write_key(struct file *file, const char __user *buf, 62 size_t count, loff_t *ppos) 63{ 64 char temp[80]; 65 int i, error; 66 67 if (!capable(CAP_SYS_ADMIN) || evm_initialized) 68 return -EPERM; 69 70 if (count >= sizeof(temp) || count == 0) 71 return -EINVAL; 72 73 if (copy_from_user(temp, buf, count) != 0) 74 return -EFAULT; 75 76 temp[count] = '\0'; 77 78 if ((sscanf(temp, "%d", &i) != 1) || (i != 1)) 79 return -EINVAL; 80 81 error = evm_init_key(); 82 if (!error) { 83 evm_initialized = 1; 84 pr_info("initialized\n"); 85 } else 86 pr_err("initialization failed\n"); 87 return count; 88} 89 90static const struct file_operations evm_key_ops = { 91 .read = evm_read_key, 92 .write = evm_write_key, 93}; 94 95int __init evm_init_secfs(void) 96{ 97 int error = 0; 98 99 evm_init_tpm = securityfs_create_file("evm", S_IRUSR | S_IRGRP, 100 NULL, NULL, &evm_key_ops); 101 if (!evm_init_tpm || IS_ERR(evm_init_tpm)) 102 error = -EFAULT; 103 return error; 104} 105