Blame view

security/tomoyo/securityfs_if.c 7.29 KB
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
1
  /*
0f2a55d5b   Tetsuo Handa   TOMOYO: Update ke...
2
   * security/tomoyo/securityfs_if.c
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
3
   *
0f2a55d5b   Tetsuo Handa   TOMOYO: Update ke...
4
   * Copyright (C) 2005-2011  NTT DATA CORPORATION
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
5
6
7
8
9
10
   */
  
  #include <linux/security.h>
  #include "common.h"
  
  /**
731d37aa7   Tetsuo Handa   TOMOYO: Allow dom...
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
   * tomoyo_check_task_acl - Check permission for task operation.
   *
   * @r:   Pointer to "struct tomoyo_request_info".
   * @ptr: Pointer to "struct tomoyo_acl_info".
   *
   * Returns true if granted, false otherwise.
   */
  static bool tomoyo_check_task_acl(struct tomoyo_request_info *r,
  				  const struct tomoyo_acl_info *ptr)
  {
  	const struct tomoyo_task_acl *acl = container_of(ptr, typeof(*acl),
  							 head);
  	return !tomoyo_pathcmp(r->param.task.domainname, acl->domainname);
  }
  
  /**
   * tomoyo_write_self - write() for /sys/kernel/security/tomoyo/self_domain interface.
   *
   * @file:  Pointer to "struct file".
   * @buf:   Domainname to transit to.
   * @count: Size of @buf.
   * @ppos:  Unused.
   *
   * Returns @count on success, negative value otherwise.
   *
   * If domain transition was permitted but the domain transition failed, this
   * function returns error rather than terminating current thread with SIGKILL.
   */
  static ssize_t tomoyo_write_self(struct file *file, const char __user *buf,
  			      size_t count, loff_t *ppos)
  {
  	char *data;
  	int error;
  	if (!count || count >= TOMOYO_EXEC_TMPSIZE - 10)
  		return -ENOMEM;
16e5c1fc3   Al Viro   convert a bunch o...
46
47
48
  	data = memdup_user_nul(buf, count);
  	if (IS_ERR(data))
  		return PTR_ERR(data);
731d37aa7   Tetsuo Handa   TOMOYO: Allow dom...
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
  	tomoyo_normalize_line(data);
  	if (tomoyo_correct_domain(data)) {
  		const int idx = tomoyo_read_lock();
  		struct tomoyo_path_info name;
  		struct tomoyo_request_info r;
  		name.name = data;
  		tomoyo_fill_path_info(&name);
  		/* Check "task manual_domain_transition" permission. */
  		tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_EXECUTE);
  		r.param_type = TOMOYO_TYPE_MANUAL_TASK_ACL;
  		r.param.task.domainname = &name;
  		tomoyo_check_acl(&r, tomoyo_check_task_acl);
  		if (!r.granted)
  			error = -EPERM;
  		else {
  			struct tomoyo_domain_info *new_domain =
  				tomoyo_assign_domain(data, true);
  			if (!new_domain) {
  				error = -ENOENT;
  			} else {
  				struct cred *cred = prepare_creds();
  				if (!cred) {
  					error = -ENOMEM;
  				} else {
  					struct tomoyo_domain_info *old_domain =
  						cred->security;
  					cred->security = new_domain;
  					atomic_inc(&new_domain->users);
  					atomic_dec(&old_domain->users);
  					commit_creds(cred);
  					error = 0;
  				}
  			}
  		}
  		tomoyo_read_unlock(idx);
  	} else
  		error = -EINVAL;
731d37aa7   Tetsuo Handa   TOMOYO: Allow dom...
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
  	kfree(data);
  	return error ? error : count;
  }
  
  /**
   * tomoyo_read_self - read() for /sys/kernel/security/tomoyo/self_domain interface.
   *
   * @file:  Pointer to "struct file".
   * @buf:   Domainname which current thread belongs to.
   * @count: Size of @buf.
   * @ppos:  Bytes read by now.
   *
   * Returns read size on success, negative value otherwise.
   */
  static ssize_t tomoyo_read_self(struct file *file, char __user *buf,
  				size_t count, loff_t *ppos)
  {
  	const char *domain = tomoyo_domain()->domainname->name;
  	loff_t len = strlen(domain);
  	loff_t pos = *ppos;
  	if (pos >= len || !count)
  		return 0;
  	len -= pos;
  	if (count < len)
  		len = count;
  	if (copy_to_user(buf, domain + pos, len))
  		return -EFAULT;
  	*ppos += len;
  	return len;
  }
  
  /* Operations for /sys/kernel/security/tomoyo/self_domain interface. */
  static const struct file_operations tomoyo_self_operations = {
  	.write = tomoyo_write_self,
  	.read  = tomoyo_read_self,
  };
  
  /**
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
124
125
126
127
128
129
130
131
132
   * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface.
   *
   * @inode: Pointer to "struct inode".
   * @file:  Pointer to "struct file".
   *
   * Returns 0 on success, negative value otherwise.
   */
  static int tomoyo_open(struct inode *inode, struct file *file)
  {
496ad9aa8   Al Viro   new helper: file_...
133
  	const int key = ((u8 *) file_inode(file)->i_private)
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
134
135
136
137
138
139
140
  		- ((u8 *) NULL);
  	return tomoyo_open_control(key, file);
  }
  
  /**
   * tomoyo_release - close() for /sys/kernel/security/tomoyo/ interface.
   *
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
141
142
   * @file:  Pointer to "struct file".
   *
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
143
144
145
   */
  static int tomoyo_release(struct inode *inode, struct file *file)
  {
e53cfda5d   Al Viro   tomoyo_close_cont...
146
147
  	tomoyo_close_control(file->private_data);
  	return 0;
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
148
149
150
  }
  
  /**
b5bc60b4c   Tetsuo Handa   TOMOYO: Cleanup p...
151
   * tomoyo_poll - poll() for /sys/kernel/security/tomoyo/ interface.
0849e3ba5   Tetsuo Handa   TOMOYO: Add missi...
152
153
   *
   * @file: Pointer to "struct file".
6041e8346   Tetsuo Handa   TOMOYO: Return ap...
154
   * @wait: Pointer to "poll_table". Maybe NULL.
0849e3ba5   Tetsuo Handa   TOMOYO: Add missi...
155
   *
6041e8346   Tetsuo Handa   TOMOYO: Return ap...
156
157
   * Returns POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM if ready to read/write,
   * POLLOUT | POLLWRNORM otherwise.
0849e3ba5   Tetsuo Handa   TOMOYO: Add missi...
158
159
160
161
162
163
164
   */
  static unsigned int tomoyo_poll(struct file *file, poll_table *wait)
  {
  	return tomoyo_poll_control(file, wait);
  }
  
  /**
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
165
166
167
168
169
170
171
172
173
174
175
176
   * tomoyo_read - read() for /sys/kernel/security/tomoyo/ interface.
   *
   * @file:  Pointer to "struct file".
   * @buf:   Pointer to buffer.
   * @count: Size of @buf.
   * @ppos:  Unused.
   *
   * Returns bytes read on success, negative value otherwise.
   */
  static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count,
  			   loff_t *ppos)
  {
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
177
  	return tomoyo_read_control(file->private_data, buf, count);
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
  }
  
  /**
   * tomoyo_write - write() for /sys/kernel/security/tomoyo/ interface.
   *
   * @file:  Pointer to "struct file".
   * @buf:   Pointer to buffer.
   * @count: Size of @buf.
   * @ppos:  Unused.
   *
   * Returns @count on success, negative value otherwise.
   */
  static ssize_t tomoyo_write(struct file *file, const char __user *buf,
  			    size_t count, loff_t *ppos)
  {
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
193
  	return tomoyo_write_control(file->private_data, buf, count);
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
194
195
196
197
198
199
200
201
202
203
204
205
  }
  
  /*
   * tomoyo_operations is a "struct file_operations" which is used for handling
   * /sys/kernel/security/tomoyo/ interface.
   *
   * Some files under /sys/kernel/security/tomoyo/ directory accept open(O_RDWR).
   * See tomoyo_io_buffer for internals.
   */
  static const struct file_operations tomoyo_operations = {
  	.open    = tomoyo_open,
  	.release = tomoyo_release,
0849e3ba5   Tetsuo Handa   TOMOYO: Add missi...
206
  	.poll    = tomoyo_poll,
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
207
208
  	.read    = tomoyo_read,
  	.write   = tomoyo_write,
7e2deb7ce   Tetsuo Handa   TOMOYO: Explicitl...
209
  	.llseek  = noop_llseek,
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
210
211
212
213
214
215
216
217
218
219
220
221
  };
  
  /**
   * tomoyo_create_entry - Create interface files under /sys/kernel/security/tomoyo/ directory.
   *
   * @name:   The name of the interface file.
   * @mode:   The permission of the interface file.
   * @parent: The parent directory.
   * @key:    Type of interface.
   *
   * Returns nothing.
   */
52ef0c042   Al Viro   switch securityfs...
222
  static void __init tomoyo_create_entry(const char *name, const umode_t mode,
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
  				       struct dentry *parent, const u8 key)
  {
  	securityfs_create_file(name, mode, parent, ((u8 *) NULL) + key,
  			       &tomoyo_operations);
  }
  
  /**
   * tomoyo_initerface_init - Initialize /sys/kernel/security/tomoyo/ interface.
   *
   * Returns 0.
   */
  static int __init tomoyo_initerface_init(void)
  {
  	struct dentry *tomoyo_dir;
  
  	/* Don't create securityfs entries unless registered. */
  	if (current_cred()->security != &tomoyo_kernel_domain)
  		return 0;
  
  	tomoyo_dir = securityfs_create_dir("tomoyo", NULL);
  	tomoyo_create_entry("query",            0600, tomoyo_dir,
  			    TOMOYO_QUERY);
  	tomoyo_create_entry("domain_policy",    0600, tomoyo_dir,
  			    TOMOYO_DOMAINPOLICY);
  	tomoyo_create_entry("exception_policy", 0600, tomoyo_dir,
  			    TOMOYO_EXCEPTIONPOLICY);
eadd99cc8   Tetsuo Handa   TOMOYO: Add audit...
249
250
  	tomoyo_create_entry("audit",            0400, tomoyo_dir,
  			    TOMOYO_AUDIT);
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
251
252
  	tomoyo_create_entry(".process_status",  0600, tomoyo_dir,
  			    TOMOYO_PROCESS_STATUS);
b22b8b9fd   Tetsuo Handa   TOMOYO: Rename me...
253
254
  	tomoyo_create_entry("stat",             0644, tomoyo_dir,
  			    TOMOYO_STAT);
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
255
256
257
258
259
260
  	tomoyo_create_entry("profile",          0600, tomoyo_dir,
  			    TOMOYO_PROFILE);
  	tomoyo_create_entry("manager",          0600, tomoyo_dir,
  			    TOMOYO_MANAGER);
  	tomoyo_create_entry("version",          0400, tomoyo_dir,
  			    TOMOYO_VERSION);
731d37aa7   Tetsuo Handa   TOMOYO: Allow dom...
261
262
  	securityfs_create_file("self_domain", 0666, tomoyo_dir, NULL,
  			       &tomoyo_self_operations);
778c4a4d6   Tetsuo Handa   TOMOYO: Fix make ...
263
  	tomoyo_load_builtin_policy();
c3ef1500e   Tetsuo Handa   TOMOYO: Split fil...
264
265
266
267
  	return 0;
  }
  
  fs_initcall(tomoyo_initerface_init);