Blame view

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