Blame view

security/tomoyo/file.c 28.9 KB
b69a54ee5   Kentaro Takeda   File operation re...
1
2
3
  /*
   * security/tomoyo/file.c
   *
0f2a55d5b   Tetsuo Handa   TOMOYO: Update ke...
4
   * Copyright (C) 2005-2011  NTT DATA CORPORATION
b69a54ee5   Kentaro Takeda   File operation re...
5
6
7
   */
  
  #include "common.h"
5a0e3ad6a   Tejun Heo   include cleanup: ...
8
  #include <linux/slab.h>
b69a54ee5   Kentaro Takeda   File operation re...
9

0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
10
11
12
  /*
   * Mapping table from "enum tomoyo_path_acl_index" to "enum tomoyo_mac_index".
   */
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
13
  static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = {
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
14
15
16
  	[TOMOYO_TYPE_EXECUTE]    = TOMOYO_MAC_FILE_EXECUTE,
  	[TOMOYO_TYPE_READ]       = TOMOYO_MAC_FILE_OPEN,
  	[TOMOYO_TYPE_WRITE]      = TOMOYO_MAC_FILE_OPEN,
7c75964f4   Tetsuo Handa   TOMOYO: Cleanup p...
17
  	[TOMOYO_TYPE_APPEND]     = TOMOYO_MAC_FILE_OPEN,
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
18
  	[TOMOYO_TYPE_UNLINK]     = TOMOYO_MAC_FILE_UNLINK,
7c75964f4   Tetsuo Handa   TOMOYO: Cleanup p...
19
  	[TOMOYO_TYPE_GETATTR]    = TOMOYO_MAC_FILE_GETATTR,
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
20
21
22
  	[TOMOYO_TYPE_RMDIR]      = TOMOYO_MAC_FILE_RMDIR,
  	[TOMOYO_TYPE_TRUNCATE]   = TOMOYO_MAC_FILE_TRUNCATE,
  	[TOMOYO_TYPE_SYMLINK]    = TOMOYO_MAC_FILE_SYMLINK,
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
23
24
25
  	[TOMOYO_TYPE_CHROOT]     = TOMOYO_MAC_FILE_CHROOT,
  	[TOMOYO_TYPE_UMOUNT]     = TOMOYO_MAC_FILE_UMOUNT,
  };
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
26
27
28
  /*
   * Mapping table from "enum tomoyo_mkdev_acl_index" to "enum tomoyo_mac_index".
   */
0d2171d71   Tetsuo Handa   TOMOYO: Rename di...
29
  const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION] = {
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
30
31
32
  	[TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK,
  	[TOMOYO_TYPE_MKCHAR]  = TOMOYO_MAC_FILE_MKCHAR,
  };
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
33
34
35
  /*
   * Mapping table from "enum tomoyo_path2_acl_index" to "enum tomoyo_mac_index".
   */
0d2171d71   Tetsuo Handa   TOMOYO: Rename di...
36
  const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = {
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
37
38
39
40
  	[TOMOYO_TYPE_LINK]       = TOMOYO_MAC_FILE_LINK,
  	[TOMOYO_TYPE_RENAME]     = TOMOYO_MAC_FILE_RENAME,
  	[TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT,
  };
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
41
42
43
44
  /*
   * Mapping table from "enum tomoyo_path_number_acl_index" to
   * "enum tomoyo_mac_index".
   */
0d2171d71   Tetsuo Handa   TOMOYO: Rename di...
45
  const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
46
47
48
49
50
51
52
53
54
  	[TOMOYO_TYPE_CREATE] = TOMOYO_MAC_FILE_CREATE,
  	[TOMOYO_TYPE_MKDIR]  = TOMOYO_MAC_FILE_MKDIR,
  	[TOMOYO_TYPE_MKFIFO] = TOMOYO_MAC_FILE_MKFIFO,
  	[TOMOYO_TYPE_MKSOCK] = TOMOYO_MAC_FILE_MKSOCK,
  	[TOMOYO_TYPE_IOCTL]  = TOMOYO_MAC_FILE_IOCTL,
  	[TOMOYO_TYPE_CHMOD]  = TOMOYO_MAC_FILE_CHMOD,
  	[TOMOYO_TYPE_CHOWN]  = TOMOYO_MAC_FILE_CHOWN,
  	[TOMOYO_TYPE_CHGRP]  = TOMOYO_MAC_FILE_CHGRP,
  };
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
55
56
57
58
59
60
61
  /**
   * tomoyo_put_name_union - Drop reference on "struct tomoyo_name_union".
   *
   * @ptr: Pointer to "struct tomoyo_name_union".
   *
   * Returns nothing.
   */
7762fbfff   Tetsuo Handa   TOMOYO: Add pathn...
62
63
  void tomoyo_put_name_union(struct tomoyo_name_union *ptr)
  {
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
64
65
  	tomoyo_put_group(ptr->group);
  	tomoyo_put_name(ptr->filename);
7762fbfff   Tetsuo Handa   TOMOYO: Add pathn...
66
  }
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
67
68
69
70
71
72
73
74
  /**
   * tomoyo_compare_name_union - Check whether a name matches "struct tomoyo_name_union" or not.
   *
   * @name: Pointer to "struct tomoyo_path_info".
   * @ptr:  Pointer to "struct tomoyo_name_union".
   *
   * Returns "struct tomoyo_path_info" if @name matches @ptr, NULL otherwise.
   */
484ca79c6   Tetsuo Handa   TOMOYO: Use pathn...
75
76
77
  const struct tomoyo_path_info *
  tomoyo_compare_name_union(const struct tomoyo_path_info *name,
  			  const struct tomoyo_name_union *ptr)
7762fbfff   Tetsuo Handa   TOMOYO: Add pathn...
78
  {
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
79
  	if (ptr->group)
3f6296363   Tetsuo Handa   TOMOYO: Allow wil...
80
  		return tomoyo_path_matches_group(name, ptr->group);
484ca79c6   Tetsuo Handa   TOMOYO: Use pathn...
81
82
83
  	if (tomoyo_path_matches_pattern(name, ptr->filename))
  		return ptr->filename;
  	return NULL;
7762fbfff   Tetsuo Handa   TOMOYO: Add pathn...
84
  }
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
85
86
87
88
89
90
91
  /**
   * tomoyo_put_number_union - Drop reference on "struct tomoyo_number_union".
   *
   * @ptr: Pointer to "struct tomoyo_number_union".
   *
   * Returns nothing.
   */
4c3e9e2de   Tetsuo Handa   TOMOYO: Add numer...
92
93
  void tomoyo_put_number_union(struct tomoyo_number_union *ptr)
  {
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
94
  	tomoyo_put_group(ptr->group);
4c3e9e2de   Tetsuo Handa   TOMOYO: Add numer...
95
  }
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
96
97
98
99
100
101
102
103
  /**
   * tomoyo_compare_number_union - Check whether a value matches "struct tomoyo_number_union" or not.
   *
   * @value: Number to check.
   * @ptr:   Pointer to "struct tomoyo_number_union".
   *
   * Returns true if @value matches @ptr, false otherwise.
   */
4c3e9e2de   Tetsuo Handa   TOMOYO: Add numer...
104
105
106
  bool tomoyo_compare_number_union(const unsigned long value,
  				 const struct tomoyo_number_union *ptr)
  {
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
107
  	if (ptr->group)
4c3e9e2de   Tetsuo Handa   TOMOYO: Add numer...
108
109
110
  		return tomoyo_number_matches_group(value, value, ptr->group);
  	return value >= ptr->values[0] && value <= ptr->values[1];
  }
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
111
112
113
114
115
116
117
118
119
120
  /**
   * tomoyo_add_slash - Add trailing '/' if needed.
   *
   * @buf: Pointer to "struct tomoyo_path_info".
   *
   * Returns nothing.
   *
   * @buf must be generated by tomoyo_encode() because this function does not
   * allocate memory for adding '/'.
   */
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
121
122
123
124
125
126
127
128
129
130
  static void tomoyo_add_slash(struct tomoyo_path_info *buf)
  {
  	if (buf->is_dir)
  		return;
  	/*
  	 * This is OK because tomoyo_encode() reserves space for appending "/".
  	 */
  	strcat((char *) buf->name, "/");
  	tomoyo_fill_path_info(buf);
  }
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
131
  /**
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
132
   * tomoyo_get_realpath - Get realpath.
b69a54ee5   Kentaro Takeda   File operation re...
133
   *
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
134
   * @buf:  Pointer to "struct tomoyo_path_info".
b69a54ee5   Kentaro Takeda   File operation re...
135
136
   * @path: Pointer to "struct path".
   *
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
137
   * Returns true on success, false otherwise.
b69a54ee5   Kentaro Takeda   File operation re...
138
   */
3f7036a07   Al Viro   switch security_i...
139
  static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, const struct path *path)
b69a54ee5   Kentaro Takeda   File operation re...
140
  {
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
141
142
143
144
  	buf->name = tomoyo_realpath_from_path(path);
  	if (buf->name) {
  		tomoyo_fill_path_info(buf);
  		return true;
b69a54ee5   Kentaro Takeda   File operation re...
145
  	}
0f2a55d5b   Tetsuo Handa   TOMOYO: Update ke...
146
  	return false;
b69a54ee5   Kentaro Takeda   File operation re...
147
  }
99a852596   Tetsuo Handa   TOMOYO: Use callb...
148
149
150
151
152
153
154
155
156
  /**
   * tomoyo_audit_path_log - Audit path request log.
   *
   * @r: Pointer to "struct tomoyo_request_info".
   *
   * Returns 0 on success, negative value otherwise.
   */
  static int tomoyo_audit_path_log(struct tomoyo_request_info *r)
  {
eadd99cc8   Tetsuo Handa   TOMOYO: Add audit...
157
158
159
160
  	return tomoyo_supervisor(r, "file %s %s
  ", tomoyo_path_keyword
  				 [r->param.path.operation],
  				 r->param.path.filename->name);
99a852596   Tetsuo Handa   TOMOYO: Use callb...
161
162
163
164
165
166
167
168
169
170
171
  }
  
  /**
   * tomoyo_audit_path2_log - Audit path/path request log.
   *
   * @r: Pointer to "struct tomoyo_request_info".
   *
   * Returns 0 on success, negative value otherwise.
   */
  static int tomoyo_audit_path2_log(struct tomoyo_request_info *r)
  {
2c47ab935   Tetsuo Handa   TOMOYO: Cleanup p...
172
173
174
  	return tomoyo_supervisor(r, "file %s %s %s
  ", tomoyo_mac_keywords
  				 [tomoyo_pp2mac[r->param.path2.operation]],
eadd99cc8   Tetsuo Handa   TOMOYO: Add audit...
175
176
  				 r->param.path2.filename1->name,
  				 r->param.path2.filename2->name);
99a852596   Tetsuo Handa   TOMOYO: Use callb...
177
178
179
180
181
182
183
184
185
186
187
  }
  
  /**
   * tomoyo_audit_mkdev_log - Audit path/number/number/number request log.
   *
   * @r: Pointer to "struct tomoyo_request_info".
   *
   * Returns 0 on success, negative value otherwise.
   */
  static int tomoyo_audit_mkdev_log(struct tomoyo_request_info *r)
  {
eadd99cc8   Tetsuo Handa   TOMOYO: Add audit...
188
189
  	return tomoyo_supervisor(r, "file %s %s 0%o %u %u
  ",
2c47ab935   Tetsuo Handa   TOMOYO: Cleanup p...
190
191
  				 tomoyo_mac_keywords
  				 [tomoyo_pnnn2mac[r->param.mkdev.operation]],
eadd99cc8   Tetsuo Handa   TOMOYO: Add audit...
192
193
194
  				 r->param.mkdev.filename->name,
  				 r->param.mkdev.mode, r->param.mkdev.major,
  				 r->param.mkdev.minor);
99a852596   Tetsuo Handa   TOMOYO: Use callb...
195
196
197
198
199
  }
  
  /**
   * tomoyo_audit_path_number_log - Audit path/number request log.
   *
b5bc60b4c   Tetsuo Handa   TOMOYO: Cleanup p...
200
   * @r: Pointer to "struct tomoyo_request_info".
99a852596   Tetsuo Handa   TOMOYO: Use callb...
201
202
203
204
205
206
207
   *
   * Returns 0 on success, negative value otherwise.
   */
  static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r)
  {
  	const u8 type = r->param.path_number.operation;
  	u8 radix;
99a852596   Tetsuo Handa   TOMOYO: Use callb...
208
  	char buffer[64];
99a852596   Tetsuo Handa   TOMOYO: Use callb...
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
  	switch (type) {
  	case TOMOYO_TYPE_CREATE:
  	case TOMOYO_TYPE_MKDIR:
  	case TOMOYO_TYPE_MKFIFO:
  	case TOMOYO_TYPE_MKSOCK:
  	case TOMOYO_TYPE_CHMOD:
  		radix = TOMOYO_VALUE_TYPE_OCTAL;
  		break;
  	case TOMOYO_TYPE_IOCTL:
  		radix = TOMOYO_VALUE_TYPE_HEXADECIMAL;
  		break;
  	default:
  		radix = TOMOYO_VALUE_TYPE_DECIMAL;
  		break;
  	}
  	tomoyo_print_ulong(buffer, sizeof(buffer), r->param.path_number.number,
  			   radix);
2c47ab935   Tetsuo Handa   TOMOYO: Cleanup p...
226
227
228
  	return tomoyo_supervisor(r, "file %s %s %s
  ", tomoyo_mac_keywords
  				 [tomoyo_pn2mac[type]],
eadd99cc8   Tetsuo Handa   TOMOYO: Add audit...
229
  				 r->param.path_number.filename->name, buffer);
b69a54ee5   Kentaro Takeda   File operation re...
230
  }
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
231
232
233
234
235
236
237
238
239
240
241
242
  /**
   * tomoyo_check_path_acl - Check permission for path operation.
   *
   * @r:   Pointer to "struct tomoyo_request_info".
   * @ptr: Pointer to "struct tomoyo_acl_info".
   *
   * Returns true if granted, false otherwise.
   *
   * To be able to use wildcard for domain transition, this function sets
   * matching entry on success. Since the caller holds tomoyo_read_lock(),
   * it is safe to set matching entry.
   */
484ca79c6   Tetsuo Handa   TOMOYO: Use pathn...
243
  static bool tomoyo_check_path_acl(struct tomoyo_request_info *r,
99a852596   Tetsuo Handa   TOMOYO: Use callb...
244
  				  const struct tomoyo_acl_info *ptr)
b69a54ee5   Kentaro Takeda   File operation re...
245
  {
99a852596   Tetsuo Handa   TOMOYO: Use callb...
246
247
  	const struct tomoyo_path_acl *acl = container_of(ptr, typeof(*acl),
  							 head);
484ca79c6   Tetsuo Handa   TOMOYO: Use pathn...
248
249
250
251
252
253
254
  	if (acl->perm & (1 << r->param.path.operation)) {
  		r->param.path.matched_path =
  			tomoyo_compare_name_union(r->param.path.filename,
  						  &acl->name);
  		return r->param.path.matched_path != NULL;
  	}
  	return false;
99a852596   Tetsuo Handa   TOMOYO: Use callb...
255
  }
b69a54ee5   Kentaro Takeda   File operation re...
256

0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
257
258
259
260
261
262
263
264
  /**
   * tomoyo_check_path_number_acl - Check permission for path number operation.
   *
   * @r:   Pointer to "struct tomoyo_request_info".
   * @ptr: Pointer to "struct tomoyo_acl_info".
   *
   * Returns true if granted, false otherwise.
   */
484ca79c6   Tetsuo Handa   TOMOYO: Use pathn...
265
  static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r,
99a852596   Tetsuo Handa   TOMOYO: Use callb...
266
267
268
269
270
271
272
273
274
275
  					 const struct tomoyo_acl_info *ptr)
  {
  	const struct tomoyo_path_number_acl *acl =
  		container_of(ptr, typeof(*acl), head);
  	return (acl->perm & (1 << r->param.path_number.operation)) &&
  		tomoyo_compare_number_union(r->param.path_number.number,
  					    &acl->number) &&
  		tomoyo_compare_name_union(r->param.path_number.filename,
  					  &acl->name);
  }
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
276
277
278
279
280
281
282
283
  /**
   * tomoyo_check_path2_acl - Check permission for path path operation.
   *
   * @r:   Pointer to "struct tomoyo_request_info".
   * @ptr: Pointer to "struct tomoyo_acl_info".
   *
   * Returns true if granted, false otherwise.
   */
484ca79c6   Tetsuo Handa   TOMOYO: Use pathn...
284
  static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r,
99a852596   Tetsuo Handa   TOMOYO: Use callb...
285
286
287
288
289
290
291
292
293
  				   const struct tomoyo_acl_info *ptr)
  {
  	const struct tomoyo_path2_acl *acl =
  		container_of(ptr, typeof(*acl), head);
  	return (acl->perm & (1 << r->param.path2.operation)) &&
  		tomoyo_compare_name_union(r->param.path2.filename1, &acl->name1)
  		&& tomoyo_compare_name_union(r->param.path2.filename2,
  					     &acl->name2);
  }
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
294
295
296
297
298
299
300
301
  /**
   * tomoyo_check_mkdev_acl - Check permission for path number number number operation.
   *
   * @r:   Pointer to "struct tomoyo_request_info".
   * @ptr: Pointer to "struct tomoyo_acl_info".
   *
   * Returns true if granted, false otherwise.
   */
484ca79c6   Tetsuo Handa   TOMOYO: Use pathn...
302
  static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r,
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
303
  				   const struct tomoyo_acl_info *ptr)
99a852596   Tetsuo Handa   TOMOYO: Use callb...
304
  {
75093152a   Tetsuo Handa   TOMOYO: Rename sy...
305
  	const struct tomoyo_mkdev_acl *acl =
99a852596   Tetsuo Handa   TOMOYO: Use callb...
306
307
308
309
310
311
312
313
314
315
  		container_of(ptr, typeof(*acl), head);
  	return (acl->perm & (1 << r->param.mkdev.operation)) &&
  		tomoyo_compare_number_union(r->param.mkdev.mode,
  					    &acl->mode) &&
  		tomoyo_compare_number_union(r->param.mkdev.major,
  					    &acl->major) &&
  		tomoyo_compare_number_union(r->param.mkdev.minor,
  					    &acl->minor) &&
  		tomoyo_compare_name_union(r->param.mkdev.filename,
  					  &acl->name);
b69a54ee5   Kentaro Takeda   File operation re...
316
  }
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
317
318
319
320
321
322
323
324
  /**
   * tomoyo_same_path_acl - Check for duplicated "struct tomoyo_path_acl" entry.
   *
   * @a: Pointer to "struct tomoyo_acl_info".
   * @b: Pointer to "struct tomoyo_acl_info".
   *
   * Returns true if @a == @b except permission bits, false otherwise.
   */
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
325
326
327
328
329
  static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a,
  				 const struct tomoyo_acl_info *b)
  {
  	const struct tomoyo_path_acl *p1 = container_of(a, typeof(*p1), head);
  	const struct tomoyo_path_acl *p2 = container_of(b, typeof(*p2), head);
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
330
  	return tomoyo_same_name_union(&p1->name, &p2->name);
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
331
  }
7c75964f4   Tetsuo Handa   TOMOYO: Cleanup p...
332
333
334
335
336
337
338
339
340
  /**
   * tomoyo_merge_path_acl - Merge duplicated "struct tomoyo_path_acl" entry.
   *
   * @a:         Pointer to "struct tomoyo_acl_info".
   * @b:         Pointer to "struct tomoyo_acl_info".
   * @is_delete: True for @a &= ~@b, false for @a |= @b.
   *
   * Returns true if @a is empty, false otherwise.
   */
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
341
342
343
344
345
346
347
348
  static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a,
  				  struct tomoyo_acl_info *b,
  				  const bool is_delete)
  {
  	u16 * const a_perm = &container_of(a, struct tomoyo_path_acl, head)
  		->perm;
  	u16 perm = *a_perm;
  	const u16 b_perm = container_of(b, struct tomoyo_path_acl, head)->perm;
7c75964f4   Tetsuo Handa   TOMOYO: Cleanup p...
349
  	if (is_delete)
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
350
  		perm &= ~b_perm;
7c75964f4   Tetsuo Handa   TOMOYO: Cleanup p...
351
  	else
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
352
  		perm |= b_perm;
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
353
354
355
  	*a_perm = perm;
  	return !perm;
  }
b69a54ee5   Kentaro Takeda   File operation re...
356
  /**
7ef612331   Tetsuo Handa   TOMOYO: Use short...
357
   * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list.
b69a54ee5   Kentaro Takeda   File operation re...
358
   *
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
359
360
   * @perm:  Permission.
   * @param: Pointer to "struct tomoyo_acl_param".
b69a54ee5   Kentaro Takeda   File operation re...
361
362
   *
   * Returns 0 on success, negative value otherwise.
fdb8ebb72   Tetsuo Handa   TOMOYO: Use RCU p...
363
364
   *
   * Caller holds tomoyo_read_lock().
b69a54ee5   Kentaro Takeda   File operation re...
365
   */
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
366
367
  static int tomoyo_update_path_acl(const u16 perm,
  				  struct tomoyo_acl_param *param)
b69a54ee5   Kentaro Takeda   File operation re...
368
  {
9e4b50e93   Tetsuo Handa   TOMOYO: Use stack...
369
370
  	struct tomoyo_path_acl e = {
  		.head.type = TOMOYO_TYPE_PATH_ACL,
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
371
  		.perm = perm
9e4b50e93   Tetsuo Handa   TOMOYO: Use stack...
372
  	};
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
373
  	int error;
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
374
375
376
377
378
379
  	if (!tomoyo_parse_name_union(param, &e.name))
  		error = -EINVAL;
  	else
  		error = tomoyo_update_domain(&e.head, sizeof(e), param,
  					     tomoyo_same_path_acl,
  					     tomoyo_merge_path_acl);
7762fbfff   Tetsuo Handa   TOMOYO: Add pathn...
380
  	tomoyo_put_name_union(&e.name);
b69a54ee5   Kentaro Takeda   File operation re...
381
382
  	return error;
  }
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
383
384
385
386
387
388
389
390
  /**
   * tomoyo_same_mkdev_acl - Check for duplicated "struct tomoyo_mkdev_acl" entry.
   *
   * @a: Pointer to "struct tomoyo_acl_info".
   * @b: Pointer to "struct tomoyo_acl_info".
   *
   * Returns true if @a == @b except permission bits, false otherwise.
   */
75093152a   Tetsuo Handa   TOMOYO: Rename sy...
391
  static bool tomoyo_same_mkdev_acl(const struct tomoyo_acl_info *a,
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
392
393
  					 const struct tomoyo_acl_info *b)
  {
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
394
395
396
397
398
399
  	const struct tomoyo_mkdev_acl *p1 = container_of(a, typeof(*p1), head);
  	const struct tomoyo_mkdev_acl *p2 = container_of(b, typeof(*p2), head);
  	return tomoyo_same_name_union(&p1->name, &p2->name) &&
  		tomoyo_same_number_union(&p1->mode, &p2->mode) &&
  		tomoyo_same_number_union(&p1->major, &p2->major) &&
  		tomoyo_same_number_union(&p1->minor, &p2->minor);
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
400
  }
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
401
402
403
404
405
406
407
408
409
  /**
   * tomoyo_merge_mkdev_acl - Merge duplicated "struct tomoyo_mkdev_acl" entry.
   *
   * @a:         Pointer to "struct tomoyo_acl_info".
   * @b:         Pointer to "struct tomoyo_acl_info".
   * @is_delete: True for @a &= ~@b, false for @a |= @b.
   *
   * Returns true if @a is empty, false otherwise.
   */
75093152a   Tetsuo Handa   TOMOYO: Rename sy...
410
  static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a,
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
411
412
  				   struct tomoyo_acl_info *b,
  				   const bool is_delete)
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
413
  {
75093152a   Tetsuo Handa   TOMOYO: Rename sy...
414
  	u8 *const a_perm = &container_of(a, struct tomoyo_mkdev_acl,
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
415
416
  					 head)->perm;
  	u8 perm = *a_perm;
75093152a   Tetsuo Handa   TOMOYO: Rename sy...
417
  	const u8 b_perm = container_of(b, struct tomoyo_mkdev_acl, head)
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
418
419
420
421
422
423
424
425
  		->perm;
  	if (is_delete)
  		perm &= ~b_perm;
  	else
  		perm |= b_perm;
  	*a_perm = perm;
  	return !perm;
  }
b69a54ee5   Kentaro Takeda   File operation re...
426
  /**
75093152a   Tetsuo Handa   TOMOYO: Rename sy...
427
   * tomoyo_update_mkdev_acl - Update "struct tomoyo_mkdev_acl" list.
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
428
   *
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
429
430
   * @perm:  Permission.
   * @param: Pointer to "struct tomoyo_acl_param".
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
431
432
   *
   * Returns 0 on success, negative value otherwise.
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
433
434
   *
   * Caller holds tomoyo_read_lock().
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
435
   */
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
436
437
  static int tomoyo_update_mkdev_acl(const u8 perm,
  				   struct tomoyo_acl_param *param)
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
438
  {
75093152a   Tetsuo Handa   TOMOYO: Rename sy...
439
440
  	struct tomoyo_mkdev_acl e = {
  		.head.type = TOMOYO_TYPE_MKDEV_ACL,
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
441
  		.perm = perm
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
442
  	};
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
443
444
445
446
447
448
449
450
451
452
  	int error;
  	if (!tomoyo_parse_name_union(param, &e.name) ||
  	    !tomoyo_parse_number_union(param, &e.mode) ||
  	    !tomoyo_parse_number_union(param, &e.major) ||
  	    !tomoyo_parse_number_union(param, &e.minor))
  		error = -EINVAL;
  	else
  		error = tomoyo_update_domain(&e.head, sizeof(e), param,
  					     tomoyo_same_mkdev_acl,
  					     tomoyo_merge_mkdev_acl);
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
453
454
455
456
457
458
  	tomoyo_put_name_union(&e.name);
  	tomoyo_put_number_union(&e.mode);
  	tomoyo_put_number_union(&e.major);
  	tomoyo_put_number_union(&e.minor);
  	return error;
  }
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
459
460
461
462
463
464
465
466
  /**
   * tomoyo_same_path2_acl - Check for duplicated "struct tomoyo_path2_acl" entry.
   *
   * @a: Pointer to "struct tomoyo_acl_info".
   * @b: Pointer to "struct tomoyo_acl_info".
   *
   * Returns true if @a == @b except permission bits, false otherwise.
   */
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
467
468
469
470
471
  static bool tomoyo_same_path2_acl(const struct tomoyo_acl_info *a,
  				  const struct tomoyo_acl_info *b)
  {
  	const struct tomoyo_path2_acl *p1 = container_of(a, typeof(*p1), head);
  	const struct tomoyo_path2_acl *p2 = container_of(b, typeof(*p2), head);
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
472
473
  	return tomoyo_same_name_union(&p1->name1, &p2->name1) &&
  		tomoyo_same_name_union(&p1->name2, &p2->name2);
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
474
  }
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
475
476
477
478
479
480
481
482
483
  /**
   * tomoyo_merge_path2_acl - Merge duplicated "struct tomoyo_path2_acl" entry.
   *
   * @a:         Pointer to "struct tomoyo_acl_info".
   * @b:         Pointer to "struct tomoyo_acl_info".
   * @is_delete: True for @a &= ~@b, false for @a |= @b.
   *
   * Returns true if @a is empty, false otherwise.
   */
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
  static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a,
  				   struct tomoyo_acl_info *b,
  				   const bool is_delete)
  {
  	u8 * const a_perm = &container_of(a, struct tomoyo_path2_acl, head)
  		->perm;
  	u8 perm = *a_perm;
  	const u8 b_perm = container_of(b, struct tomoyo_path2_acl, head)->perm;
  	if (is_delete)
  		perm &= ~b_perm;
  	else
  		perm |= b_perm;
  	*a_perm = perm;
  	return !perm;
  }
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
499
  /**
7ef612331   Tetsuo Handa   TOMOYO: Use short...
500
   * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list.
b69a54ee5   Kentaro Takeda   File operation re...
501
   *
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
502
503
   * @perm:  Permission.
   * @param: Pointer to "struct tomoyo_acl_param".
b69a54ee5   Kentaro Takeda   File operation re...
504
505
   *
   * Returns 0 on success, negative value otherwise.
fdb8ebb72   Tetsuo Handa   TOMOYO: Use RCU p...
506
507
   *
   * Caller holds tomoyo_read_lock().
b69a54ee5   Kentaro Takeda   File operation re...
508
   */
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
509
510
  static int tomoyo_update_path2_acl(const u8 perm,
  				   struct tomoyo_acl_param *param)
b69a54ee5   Kentaro Takeda   File operation re...
511
  {
9e4b50e93   Tetsuo Handa   TOMOYO: Use stack...
512
513
  	struct tomoyo_path2_acl e = {
  		.head.type = TOMOYO_TYPE_PATH2_ACL,
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
514
  		.perm = perm
9e4b50e93   Tetsuo Handa   TOMOYO: Use stack...
515
  	};
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
516
517
518
519
520
521
522
523
  	int error;
  	if (!tomoyo_parse_name_union(param, &e.name1) ||
  	    !tomoyo_parse_name_union(param, &e.name2))
  		error = -EINVAL;
  	else
  		error = tomoyo_update_domain(&e.head, sizeof(e), param,
  					     tomoyo_same_path2_acl,
  					     tomoyo_merge_path2_acl);
7762fbfff   Tetsuo Handa   TOMOYO: Add pathn...
524
525
  	tomoyo_put_name_union(&e.name1);
  	tomoyo_put_name_union(&e.name2);
b69a54ee5   Kentaro Takeda   File operation re...
526
527
528
529
  	return error;
  }
  
  /**
cb0abe6a5   Tetsuo Handa   TOMOYO: Use struc...
530
   * tomoyo_path_permission - Check permission for single path operation.
b69a54ee5   Kentaro Takeda   File operation re...
531
   *
cb0abe6a5   Tetsuo Handa   TOMOYO: Use struc...
532
   * @r:         Pointer to "struct tomoyo_request_info".
b69a54ee5   Kentaro Takeda   File operation re...
533
534
   * @operation: Type of operation.
   * @filename:  Filename to check.
b69a54ee5   Kentaro Takeda   File operation re...
535
536
   *
   * Returns 0 on success, negative value otherwise.
fdb8ebb72   Tetsuo Handa   TOMOYO: Use RCU p...
537
538
   *
   * Caller holds tomoyo_read_lock().
b69a54ee5   Kentaro Takeda   File operation re...
539
   */
778c4a4d6   Tetsuo Handa   TOMOYO: Fix make ...
540
541
  static int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
  				  const struct tomoyo_path_info *filename)
b69a54ee5   Kentaro Takeda   File operation re...
542
  {
b69a54ee5   Kentaro Takeda   File operation re...
543
  	int error;
b69a54ee5   Kentaro Takeda   File operation re...
544

57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
545
  	r->type = tomoyo_p2mac[operation];
bd03a3e4c   Tetsuo Handa   TOMOYO: Add polic...
546
  	r->mode = tomoyo_get_mode(r->domain->ns, r->profile, r->type);
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
547
548
  	if (r->mode == TOMOYO_CONFIG_DISABLED)
  		return 0;
cf6e9a646   Tetsuo Handa   TOMOYO: Pass para...
549
550
551
  	r->param_type = TOMOYO_TYPE_PATH_ACL;
  	r->param.path.filename = filename;
  	r->param.path.operation = operation;
17fcfbd9d   Tetsuo Handa   TOMOYO: Add inter...
552
  	do {
99a852596   Tetsuo Handa   TOMOYO: Use callb...
553
  		tomoyo_check_acl(r, tomoyo_check_path_acl);
99a852596   Tetsuo Handa   TOMOYO: Use callb...
554
  		error = tomoyo_audit_path_log(r);
6bce98edc   Tetsuo Handa   TOMOYO: Allow spe...
555
  	} while (error == TOMOYO_RETRY_REQUEST);
b69a54ee5   Kentaro Takeda   File operation re...
556
557
  	return error;
  }
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
558
  /**
6bce98edc   Tetsuo Handa   TOMOYO: Allow spe...
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
   * tomoyo_execute_permission - Check permission for execute operation.
   *
   * @r:         Pointer to "struct tomoyo_request_info".
   * @filename:  Filename to check.
   *
   * Returns 0 on success, negative value otherwise.
   *
   * Caller holds tomoyo_read_lock().
   */
  int tomoyo_execute_permission(struct tomoyo_request_info *r,
  			      const struct tomoyo_path_info *filename)
  {
  	/*
  	 * Unlike other permission checks, this check is done regardless of
  	 * profile mode settings in order to check for domain transition
  	 * preference.
  	 */
  	r->type = TOMOYO_MAC_FILE_EXECUTE;
  	r->mode = tomoyo_get_mode(r->domain->ns, r->profile, r->type);
  	r->param_type = TOMOYO_TYPE_PATH_ACL;
  	r->param.path.filename = filename;
  	r->param.path.operation = TOMOYO_TYPE_EXECUTE;
  	tomoyo_check_acl(r, tomoyo_check_path_acl);
  	r->ee->transition = r->matched_acl && r->matched_acl->cond ?
  		r->matched_acl->cond->transit : NULL;
  	if (r->mode != TOMOYO_CONFIG_DISABLED)
  		return tomoyo_audit_path_log(r);
  	return 0;
  }
  
  /**
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
590
591
592
593
594
595
596
   * tomoyo_same_path_number_acl - Check for duplicated "struct tomoyo_path_number_acl" entry.
   *
   * @a: Pointer to "struct tomoyo_acl_info".
   * @b: Pointer to "struct tomoyo_acl_info".
   *
   * Returns true if @a == @b except permission bits, false otherwise.
   */
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
597
598
599
600
601
602
603
  static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a,
  					const struct tomoyo_acl_info *b)
  {
  	const struct tomoyo_path_number_acl *p1 = container_of(a, typeof(*p1),
  							       head);
  	const struct tomoyo_path_number_acl *p2 = container_of(b, typeof(*p2),
  							       head);
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
604
605
  	return tomoyo_same_name_union(&p1->name, &p2->name) &&
  		tomoyo_same_number_union(&p1->number, &p2->number);
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
606
  }
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
607
608
609
610
611
612
613
614
615
  /**
   * tomoyo_merge_path_number_acl - Merge duplicated "struct tomoyo_path_number_acl" entry.
   *
   * @a:         Pointer to "struct tomoyo_acl_info".
   * @b:         Pointer to "struct tomoyo_acl_info".
   * @is_delete: True for @a &= ~@b, false for @a |= @b.
   *
   * Returns true if @a is empty, false otherwise.
   */
237ab459f   Tetsuo Handa   TOMOYO: Use callb...
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
  static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a,
  					 struct tomoyo_acl_info *b,
  					 const bool is_delete)
  {
  	u8 * const a_perm = &container_of(a, struct tomoyo_path_number_acl,
  					  head)->perm;
  	u8 perm = *a_perm;
  	const u8 b_perm = container_of(b, struct tomoyo_path_number_acl, head)
  		->perm;
  	if (is_delete)
  		perm &= ~b_perm;
  	else
  		perm |= b_perm;
  	*a_perm = perm;
  	return !perm;
  }
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
632
633
634
  /**
   * tomoyo_update_path_number_acl - Update ioctl/chmod/chown/chgrp ACL.
   *
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
635
636
   * @perm:  Permission.
   * @param: Pointer to "struct tomoyo_acl_param".
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
637
638
639
   *
   * Returns 0 on success, negative value otherwise.
   */
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
640
641
  static int tomoyo_update_path_number_acl(const u8 perm,
  					 struct tomoyo_acl_param *param)
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
642
  {
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
643
644
  	struct tomoyo_path_number_acl e = {
  		.head.type = TOMOYO_TYPE_PATH_NUMBER_ACL,
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
645
  		.perm = perm
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
646
  	};
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
647
648
649
650
651
652
653
654
  	int error;
  	if (!tomoyo_parse_name_union(param, &e.name) ||
  	    !tomoyo_parse_number_union(param, &e.number))
  		error = -EINVAL;
  	else
  		error = tomoyo_update_domain(&e.head, sizeof(e), param,
  					     tomoyo_same_path_number_acl,
  					     tomoyo_merge_path_number_acl);
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
655
656
657
658
659
660
  	tomoyo_put_name_union(&e.name);
  	tomoyo_put_number_union(&e.number);
  	return error;
  }
  
  /**
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
661
662
663
664
665
666
667
668
   * tomoyo_path_number_perm - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp".
   *
   * @type:   Type of operation.
   * @path:   Pointer to "struct path".
   * @number: Number.
   *
   * Returns 0 on success, negative value otherwise.
   */
e6641eddf   Al Viro   tomoyo: constify ...
669
  int tomoyo_path_number_perm(const u8 type, const struct path *path,
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
670
671
672
  			    unsigned long number)
  {
  	struct tomoyo_request_info r;
97fb35e41   Tetsuo Handa   TOMOYO: Enable co...
673
674
675
  	struct tomoyo_obj_info obj = {
  		.path1 = *path,
  	};
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
676
  	int error = -ENOMEM;
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
677
  	struct tomoyo_path_info buf;
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
678
  	int idx;
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
679
  	if (tomoyo_init_request_info(&r, NULL, tomoyo_pn2mac[type])
5625f2e32   Tetsuo Handa   TOMOYO: Change pa...
680
  	    == TOMOYO_CONFIG_DISABLED || !path->dentry)
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
681
682
  		return 0;
  	idx = tomoyo_read_lock();
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
683
  	if (!tomoyo_get_realpath(&buf, path))
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
684
  		goto out;
97fb35e41   Tetsuo Handa   TOMOYO: Enable co...
685
  	r.obj = &obj;
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
686
687
  	if (type == TOMOYO_TYPE_MKDIR)
  		tomoyo_add_slash(&buf);
cb917cf51   Tetsuo Handa   TOMOYO: Merge fun...
688
689
690
691
692
693
694
695
  	r.param_type = TOMOYO_TYPE_PATH_NUMBER_ACL;
  	r.param.path_number.operation = type;
  	r.param.path_number.filename = &buf;
  	r.param.path_number.number = number;
  	do {
  		tomoyo_check_acl(&r, tomoyo_check_path_number_acl);
  		error = tomoyo_audit_path_number_log(&r);
  	} while (error == TOMOYO_RETRY_REQUEST);
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
696
  	kfree(buf.name);
cb917cf51   Tetsuo Handa   TOMOYO: Merge fun...
697
   out:
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
698
699
700
701
702
703
704
  	tomoyo_read_unlock(idx);
  	if (r.mode != TOMOYO_CONFIG_ENFORCING)
  		error = 0;
  	return error;
  }
  
  /**
b69a54ee5   Kentaro Takeda   File operation re...
705
706
707
708
709
710
711
712
713
   * tomoyo_check_open_permission - Check permission for "read" and "write".
   *
   * @domain: Pointer to "struct tomoyo_domain_info".
   * @path:   Pointer to "struct path".
   * @flag:   Flags for open().
   *
   * Returns 0 on success, negative value otherwise.
   */
  int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
e6641eddf   Al Viro   tomoyo: constify ...
714
  				 const struct path *path, const int flag)
b69a54ee5   Kentaro Takeda   File operation re...
715
716
  {
  	const u8 acc_mode = ACC_MODE(flag);
eae61f3c8   Tetsuo Handa   TOMOYO: Fix memor...
717
  	int error = 0;
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
718
  	struct tomoyo_path_info buf;
cb0abe6a5   Tetsuo Handa   TOMOYO: Use struc...
719
  	struct tomoyo_request_info r;
97fb35e41   Tetsuo Handa   TOMOYO: Enable co...
720
721
722
  	struct tomoyo_obj_info obj = {
  		.path1 = *path,
  	};
fdb8ebb72   Tetsuo Handa   TOMOYO: Use RCU p...
723
  	int idx;
b69a54ee5   Kentaro Takeda   File operation re...
724

57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
725
726
  	buf.name = NULL;
  	r.mode = TOMOYO_CONFIG_DISABLED;
fdb8ebb72   Tetsuo Handa   TOMOYO: Use RCU p...
727
  	idx = tomoyo_read_lock();
7c75964f4   Tetsuo Handa   TOMOYO: Cleanup p...
728
729
  	if (acc_mode &&
  	    tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN)
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
730
731
732
733
734
  	    != TOMOYO_CONFIG_DISABLED) {
  		if (!tomoyo_get_realpath(&buf, path)) {
  			error = -ENOMEM;
  			goto out;
  		}
97fb35e41   Tetsuo Handa   TOMOYO: Enable co...
735
  		r.obj = &obj;
7c75964f4   Tetsuo Handa   TOMOYO: Cleanup p...
736
737
738
739
740
741
742
  		if (acc_mode & MAY_READ)
  			error = tomoyo_path_permission(&r, TOMOYO_TYPE_READ,
  						       &buf);
  		if (!error && (acc_mode & MAY_WRITE))
  			error = tomoyo_path_permission(&r, (flag & O_APPEND) ?
  						       TOMOYO_TYPE_APPEND :
  						       TOMOYO_TYPE_WRITE,
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
743
  						       &buf);
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
744
  	}
b69a54ee5   Kentaro Takeda   File operation re...
745
   out:
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
746
  	kfree(buf.name);
fdb8ebb72   Tetsuo Handa   TOMOYO: Use RCU p...
747
  	tomoyo_read_unlock(idx);
cb0abe6a5   Tetsuo Handa   TOMOYO: Use struc...
748
  	if (r.mode != TOMOYO_CONFIG_ENFORCING)
b69a54ee5   Kentaro Takeda   File operation re...
749
750
751
752
753
  		error = 0;
  	return error;
  }
  
  /**
7c75964f4   Tetsuo Handa   TOMOYO: Cleanup p...
754
   * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "append", "chroot" and "unmount".
b69a54ee5   Kentaro Takeda   File operation re...
755
   *
b69a54ee5   Kentaro Takeda   File operation re...
756
757
   * @operation: Type of operation.
   * @path:      Pointer to "struct path".
97fb35e41   Tetsuo Handa   TOMOYO: Enable co...
758
759
   * @target:    Symlink's target if @operation is TOMOYO_TYPE_SYMLINK,
   *             NULL otherwise.
b69a54ee5   Kentaro Takeda   File operation re...
760
761
762
   *
   * Returns 0 on success, negative value otherwise.
   */
3f7036a07   Al Viro   switch security_i...
763
  int tomoyo_path_perm(const u8 operation, const struct path *path, const char *target)
b69a54ee5   Kentaro Takeda   File operation re...
764
  {
cb0abe6a5   Tetsuo Handa   TOMOYO: Use struc...
765
  	struct tomoyo_request_info r;
97fb35e41   Tetsuo Handa   TOMOYO: Enable co...
766
767
768
  	struct tomoyo_obj_info obj = {
  		.path1 = *path,
  	};
7c75964f4   Tetsuo Handa   TOMOYO: Cleanup p...
769
770
771
  	int error;
  	struct tomoyo_path_info buf;
  	bool is_enforce;
97fb35e41   Tetsuo Handa   TOMOYO: Enable co...
772
  	struct tomoyo_path_info symlink_target;
fdb8ebb72   Tetsuo Handa   TOMOYO: Use RCU p...
773
  	int idx;
b69a54ee5   Kentaro Takeda   File operation re...
774

57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
775
776
  	if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation])
  	    == TOMOYO_CONFIG_DISABLED)
b69a54ee5   Kentaro Takeda   File operation re...
777
  		return 0;
7c75964f4   Tetsuo Handa   TOMOYO: Cleanup p...
778
779
  	is_enforce = (r.mode == TOMOYO_CONFIG_ENFORCING);
  	error = -ENOMEM;
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
780
  	buf.name = NULL;
fdb8ebb72   Tetsuo Handa   TOMOYO: Use RCU p...
781
  	idx = tomoyo_read_lock();
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
782
  	if (!tomoyo_get_realpath(&buf, path))
b69a54ee5   Kentaro Takeda   File operation re...
783
  		goto out;
97fb35e41   Tetsuo Handa   TOMOYO: Enable co...
784
  	r.obj = &obj;
b69a54ee5   Kentaro Takeda   File operation re...
785
  	switch (operation) {
7ef612331   Tetsuo Handa   TOMOYO: Use short...
786
787
  	case TOMOYO_TYPE_RMDIR:
  	case TOMOYO_TYPE_CHROOT:
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
788
789
  		tomoyo_add_slash(&buf);
  		break;
97fb35e41   Tetsuo Handa   TOMOYO: Enable co...
790
791
792
793
794
795
796
  	case TOMOYO_TYPE_SYMLINK:
  		symlink_target.name = tomoyo_encode(target);
  		if (!symlink_target.name)
  			goto out;
  		tomoyo_fill_path_info(&symlink_target);
  		obj.symlink_target = &symlink_target;
  		break;
b69a54ee5   Kentaro Takeda   File operation re...
797
  	}
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
798
  	error = tomoyo_path_permission(&r, operation, &buf);
97fb35e41   Tetsuo Handa   TOMOYO: Enable co...
799
800
  	if (operation == TOMOYO_TYPE_SYMLINK)
  		kfree(symlink_target.name);
b69a54ee5   Kentaro Takeda   File operation re...
801
   out:
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
802
  	kfree(buf.name);
fdb8ebb72   Tetsuo Handa   TOMOYO: Use RCU p...
803
  	tomoyo_read_unlock(idx);
7c75964f4   Tetsuo Handa   TOMOYO: Cleanup p...
804
  	if (!is_enforce)
b69a54ee5   Kentaro Takeda   File operation re...
805
806
807
808
809
  		error = 0;
  	return error;
  }
  
  /**
75093152a   Tetsuo Handa   TOMOYO: Rename sy...
810
   * tomoyo_mkdev_perm - Check permission for "mkblock" and "mkchar".
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
811
812
813
814
815
816
817
818
   *
   * @operation: Type of operation. (TOMOYO_TYPE_MKCHAR or TOMOYO_TYPE_MKBLOCK)
   * @path:      Pointer to "struct path".
   * @mode:      Create mode.
   * @dev:       Device number.
   *
   * Returns 0 on success, negative value otherwise.
   */
e6641eddf   Al Viro   tomoyo: constify ...
819
  int tomoyo_mkdev_perm(const u8 operation, const struct path *path,
0df7e8b8f   Tetsuo Handa   TOMOYO: Cleanup p...
820
  		      const unsigned int mode, unsigned int dev)
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
821
822
  {
  	struct tomoyo_request_info r;
97fb35e41   Tetsuo Handa   TOMOYO: Enable co...
823
824
825
  	struct tomoyo_obj_info obj = {
  		.path1 = *path,
  	};
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
826
  	int error = -ENOMEM;
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
827
  	struct tomoyo_path_info buf;
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
828
  	int idx;
5625f2e32   Tetsuo Handa   TOMOYO: Change pa...
829
  	if (tomoyo_init_request_info(&r, NULL, tomoyo_pnnn2mac[operation])
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
830
  	    == TOMOYO_CONFIG_DISABLED)
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
831
832
833
  		return 0;
  	idx = tomoyo_read_lock();
  	error = -ENOMEM;
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
834
  	if (tomoyo_get_realpath(&buf, path)) {
97fb35e41   Tetsuo Handa   TOMOYO: Enable co...
835
  		r.obj = &obj;
cf6e9a646   Tetsuo Handa   TOMOYO: Pass para...
836
  		dev = new_decode_dev(dev);
75093152a   Tetsuo Handa   TOMOYO: Rename sy...
837
  		r.param_type = TOMOYO_TYPE_MKDEV_ACL;
cf6e9a646   Tetsuo Handa   TOMOYO: Pass para...
838
839
840
841
842
  		r.param.mkdev.filename = &buf;
  		r.param.mkdev.operation = operation;
  		r.param.mkdev.mode = mode;
  		r.param.mkdev.major = MAJOR(dev);
  		r.param.mkdev.minor = MINOR(dev);
99a852596   Tetsuo Handa   TOMOYO: Use callb...
843
844
  		tomoyo_check_acl(&r, tomoyo_check_mkdev_acl);
  		error = tomoyo_audit_mkdev_log(&r);
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
845
  		kfree(buf.name);
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
846
847
848
849
850
851
852
853
  	}
  	tomoyo_read_unlock(idx);
  	if (r.mode != TOMOYO_CONFIG_ENFORCING)
  		error = 0;
  	return error;
  }
  
  /**
7ef612331   Tetsuo Handa   TOMOYO: Use short...
854
   * tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root".
b69a54ee5   Kentaro Takeda   File operation re...
855
   *
b69a54ee5   Kentaro Takeda   File operation re...
856
857
858
859
860
861
   * @operation: Type of operation.
   * @path1:      Pointer to "struct path".
   * @path2:      Pointer to "struct path".
   *
   * Returns 0 on success, negative value otherwise.
   */
e6641eddf   Al Viro   tomoyo: constify ...
862
863
  int tomoyo_path2_perm(const u8 operation, const struct path *path1,
  		      const struct path *path2)
b69a54ee5   Kentaro Takeda   File operation re...
864
865
  {
  	int error = -ENOMEM;
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
866
867
  	struct tomoyo_path_info buf1;
  	struct tomoyo_path_info buf2;
cb0abe6a5   Tetsuo Handa   TOMOYO: Use struc...
868
  	struct tomoyo_request_info r;
97fb35e41   Tetsuo Handa   TOMOYO: Enable co...
869
870
871
872
  	struct tomoyo_obj_info obj = {
  		.path1 = *path1,
  		.path2 = *path2,
  	};
fdb8ebb72   Tetsuo Handa   TOMOYO: Use RCU p...
873
  	int idx;
b69a54ee5   Kentaro Takeda   File operation re...
874

5625f2e32   Tetsuo Handa   TOMOYO: Change pa...
875
  	if (tomoyo_init_request_info(&r, NULL, tomoyo_pp2mac[operation])
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
876
  	    == TOMOYO_CONFIG_DISABLED)
b69a54ee5   Kentaro Takeda   File operation re...
877
  		return 0;
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
878
879
  	buf1.name = NULL;
  	buf2.name = NULL;
fdb8ebb72   Tetsuo Handa   TOMOYO: Use RCU p...
880
  	idx = tomoyo_read_lock();
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
881
882
  	if (!tomoyo_get_realpath(&buf1, path1) ||
  	    !tomoyo_get_realpath(&buf2, path2))
b69a54ee5   Kentaro Takeda   File operation re...
883
  		goto out;
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
884
  	switch (operation) {
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
885
  	case TOMOYO_TYPE_RENAME:
0f2a55d5b   Tetsuo Handa   TOMOYO: Update ke...
886
  	case TOMOYO_TYPE_LINK:
e656a8eb2   David Howells   TOMOYO: Use d_is_...
887
  		if (!d_is_dir(path1->dentry))
0f2a55d5b   Tetsuo Handa   TOMOYO: Update ke...
888
889
890
891
892
  			break;
  		/* fall through */
  	case TOMOYO_TYPE_PIVOT_ROOT:
  		tomoyo_add_slash(&buf1);
  		tomoyo_add_slash(&buf2);
57c2590fb   Tetsuo Handa   TOMOYO: Update pr...
893
  		break;
0f2a55d5b   Tetsuo Handa   TOMOYO: Update ke...
894
  	}
97fb35e41   Tetsuo Handa   TOMOYO: Enable co...
895
  	r.obj = &obj;
cf6e9a646   Tetsuo Handa   TOMOYO: Pass para...
896
897
898
899
  	r.param_type = TOMOYO_TYPE_PATH2_ACL;
  	r.param.path2.operation = operation;
  	r.param.path2.filename1 = &buf1;
  	r.param.path2.filename2 = &buf2;
17fcfbd9d   Tetsuo Handa   TOMOYO: Add inter...
900
  	do {
99a852596   Tetsuo Handa   TOMOYO: Use callb...
901
902
903
  		tomoyo_check_acl(&r, tomoyo_check_path2_acl);
  		error = tomoyo_audit_path2_log(&r);
  	} while (error == TOMOYO_RETRY_REQUEST);
b69a54ee5   Kentaro Takeda   File operation re...
904
   out:
c8c57e842   Tetsuo Handa   TOMOYO: Support l...
905
906
  	kfree(buf1.name);
  	kfree(buf2.name);
fdb8ebb72   Tetsuo Handa   TOMOYO: Use RCU p...
907
  	tomoyo_read_unlock(idx);
cb0abe6a5   Tetsuo Handa   TOMOYO: Use struc...
908
  	if (r.mode != TOMOYO_CONFIG_ENFORCING)
b69a54ee5   Kentaro Takeda   File operation re...
909
910
911
  		error = 0;
  	return error;
  }
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
912
913
  
  /**
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
   * tomoyo_same_mount_acl - Check for duplicated "struct tomoyo_mount_acl" entry.
   *
   * @a: Pointer to "struct tomoyo_acl_info".
   * @b: Pointer to "struct tomoyo_acl_info".
   *
   * Returns true if @a == @b, false otherwise.
   */
  static bool tomoyo_same_mount_acl(const struct tomoyo_acl_info *a,
  				  const struct tomoyo_acl_info *b)
  {
  	const struct tomoyo_mount_acl *p1 = container_of(a, typeof(*p1), head);
  	const struct tomoyo_mount_acl *p2 = container_of(b, typeof(*p2), head);
  	return tomoyo_same_name_union(&p1->dev_name, &p2->dev_name) &&
  		tomoyo_same_name_union(&p1->dir_name, &p2->dir_name) &&
  		tomoyo_same_name_union(&p1->fs_type, &p2->fs_type) &&
  		tomoyo_same_number_union(&p1->flags, &p2->flags);
  }
  
  /**
   * tomoyo_update_mount_acl - Write "struct tomoyo_mount_acl" list.
   *
   * @param: Pointer to "struct tomoyo_acl_param".
   *
   * Returns 0 on success, negative value otherwise.
   *
   * Caller holds tomoyo_read_lock().
   */
  static int tomoyo_update_mount_acl(struct tomoyo_acl_param *param)
  {
  	struct tomoyo_mount_acl e = { .head.type = TOMOYO_TYPE_MOUNT_ACL };
  	int error;
  	if (!tomoyo_parse_name_union(param, &e.dev_name) ||
  	    !tomoyo_parse_name_union(param, &e.dir_name) ||
  	    !tomoyo_parse_name_union(param, &e.fs_type) ||
  	    !tomoyo_parse_number_union(param, &e.flags))
  		error = -EINVAL;
  	else
  		error = tomoyo_update_domain(&e.head, sizeof(e), param,
  					     tomoyo_same_mount_acl, NULL);
  	tomoyo_put_name_union(&e.dev_name);
  	tomoyo_put_name_union(&e.dir_name);
  	tomoyo_put_name_union(&e.fs_type);
  	tomoyo_put_number_union(&e.flags);
  	return error;
  }
  
  /**
e2bf69077   Tetsuo Handa   TOMOYO: Rename sy...
961
   * tomoyo_write_file - Update file related list.
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
962
   *
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
963
   * @param: Pointer to "struct tomoyo_acl_param".
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
964
965
966
967
968
   *
   * Returns 0 on success, negative value otherwise.
   *
   * Caller holds tomoyo_read_lock().
   */
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
969
  int tomoyo_write_file(struct tomoyo_acl_param *param)
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
970
  {
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
971
  	u16 perm = 0;
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
972
  	u8 type;
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
973
974
975
976
977
978
979
  	const char *operation = tomoyo_read_token(param);
  	for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++)
  		if (tomoyo_permstr(operation, tomoyo_path_keyword[type]))
  			perm |= 1 << type;
  	if (perm)
  		return tomoyo_update_path_acl(perm, param);
  	for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++)
2c47ab935   Tetsuo Handa   TOMOYO: Cleanup p...
980
981
  		if (tomoyo_permstr(operation,
  				   tomoyo_mac_keywords[tomoyo_pp2mac[type]]))
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
982
983
984
985
986
  			perm |= 1 << type;
  	if (perm)
  		return tomoyo_update_path2_acl(perm, param);
  	for (type = 0; type < TOMOYO_MAX_PATH_NUMBER_OPERATION; type++)
  		if (tomoyo_permstr(operation,
2c47ab935   Tetsuo Handa   TOMOYO: Cleanup p...
987
  				   tomoyo_mac_keywords[tomoyo_pn2mac[type]]))
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
988
989
990
991
  			perm |= 1 << type;
  	if (perm)
  		return tomoyo_update_path_number_acl(perm, param);
  	for (type = 0; type < TOMOYO_MAX_MKDEV_OPERATION; type++)
2c47ab935   Tetsuo Handa   TOMOYO: Cleanup p...
992
993
  		if (tomoyo_permstr(operation,
  				   tomoyo_mac_keywords[tomoyo_pnnn2mac[type]]))
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
994
995
996
  			perm |= 1 << type;
  	if (perm)
  		return tomoyo_update_mkdev_acl(perm, param);
2c47ab935   Tetsuo Handa   TOMOYO: Cleanup p...
997
998
  	if (tomoyo_permstr(operation,
  			   tomoyo_mac_keywords[TOMOYO_MAC_FILE_MOUNT]))
a238cf5b8   Tetsuo Handa   TOMOYO: Use struc...
999
  		return tomoyo_update_mount_acl(param);
a1f9bb6a3   Tetsuo Handa   TOMOYO: Split fil...
1000
1001
  	return -EINVAL;
  }