Blame view
security/tomoyo/file.c
33.2 KB
b69a54ee5 File operation re... |
1 2 3 |
/* * security/tomoyo/file.c * |
c3ef1500e TOMOYO: Split fil... |
4 |
* Pathname restriction functions. |
b69a54ee5 File operation re... |
5 |
* |
c3ef1500e TOMOYO: Split fil... |
6 |
* Copyright (C) 2005-2010 NTT DATA CORPORATION |
b69a54ee5 File operation re... |
7 8 9 |
*/ #include "common.h" |
5a0e3ad6a include cleanup: ... |
10 |
#include <linux/slab.h> |
b69a54ee5 File operation re... |
11 |
|
a1f9bb6a3 TOMOYO: Split fil... |
12 |
/* Keyword array for operations with one pathname. */ |
71c282362 TOMOYO: Remove wr... |
13 |
const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = { |
7ef612331 TOMOYO: Use short... |
14 15 16 17 |
[TOMOYO_TYPE_READ_WRITE] = "read/write", [TOMOYO_TYPE_EXECUTE] = "execute", [TOMOYO_TYPE_READ] = "read", [TOMOYO_TYPE_WRITE] = "write", |
7ef612331 TOMOYO: Use short... |
18 |
[TOMOYO_TYPE_UNLINK] = "unlink", |
7ef612331 TOMOYO: Use short... |
19 |
[TOMOYO_TYPE_RMDIR] = "rmdir", |
7ef612331 TOMOYO: Use short... |
20 21 22 |
[TOMOYO_TYPE_TRUNCATE] = "truncate", [TOMOYO_TYPE_SYMLINK] = "symlink", [TOMOYO_TYPE_REWRITE] = "rewrite", |
7ef612331 TOMOYO: Use short... |
23 |
[TOMOYO_TYPE_CHROOT] = "chroot", |
7ef612331 TOMOYO: Use short... |
24 |
[TOMOYO_TYPE_UMOUNT] = "unmount", |
b69a54ee5 File operation re... |
25 |
}; |
a1f9bb6a3 TOMOYO: Split fil... |
26 |
/* Keyword array for operations with one pathname and three numbers. */ |
71c282362 TOMOYO: Remove wr... |
27 |
const char *tomoyo_mkdev_keyword[TOMOYO_MAX_MKDEV_OPERATION] = { |
a1f9bb6a3 TOMOYO: Split fil... |
28 29 30 31 32 |
[TOMOYO_TYPE_MKBLOCK] = "mkblock", [TOMOYO_TYPE_MKCHAR] = "mkchar", }; /* Keyword array for operations with two pathnames. */ |
71c282362 TOMOYO: Remove wr... |
33 |
const char *tomoyo_path2_keyword[TOMOYO_MAX_PATH2_OPERATION] = { |
a1f9bb6a3 TOMOYO: Split fil... |
34 35 |
[TOMOYO_TYPE_LINK] = "link", [TOMOYO_TYPE_RENAME] = "rename", |
7ef612331 TOMOYO: Use short... |
36 |
[TOMOYO_TYPE_PIVOT_ROOT] = "pivot_root", |
b69a54ee5 File operation re... |
37 |
}; |
a1f9bb6a3 TOMOYO: Split fil... |
38 |
/* Keyword array for operations with one pathname and one number. */ |
71c282362 TOMOYO: Remove wr... |
39 |
const char *tomoyo_path_number_keyword[TOMOYO_MAX_PATH_NUMBER_OPERATION] = { |
a1f9bb6a3 TOMOYO: Split fil... |
40 41 42 43 44 45 46 47 48 |
[TOMOYO_TYPE_CREATE] = "create", [TOMOYO_TYPE_MKDIR] = "mkdir", [TOMOYO_TYPE_MKFIFO] = "mkfifo", [TOMOYO_TYPE_MKSOCK] = "mksock", [TOMOYO_TYPE_IOCTL] = "ioctl", [TOMOYO_TYPE_CHMOD] = "chmod", [TOMOYO_TYPE_CHOWN] = "chown", [TOMOYO_TYPE_CHGRP] = "chgrp", }; |
57c2590fb TOMOYO: Update pr... |
49 50 51 52 53 54 55 56 57 58 59 60 61 |
static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = { [TOMOYO_TYPE_READ_WRITE] = TOMOYO_MAC_FILE_OPEN, [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE, [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN, [TOMOYO_TYPE_WRITE] = TOMOYO_MAC_FILE_OPEN, [TOMOYO_TYPE_UNLINK] = TOMOYO_MAC_FILE_UNLINK, [TOMOYO_TYPE_RMDIR] = TOMOYO_MAC_FILE_RMDIR, [TOMOYO_TYPE_TRUNCATE] = TOMOYO_MAC_FILE_TRUNCATE, [TOMOYO_TYPE_SYMLINK] = TOMOYO_MAC_FILE_SYMLINK, [TOMOYO_TYPE_REWRITE] = TOMOYO_MAC_FILE_REWRITE, [TOMOYO_TYPE_CHROOT] = TOMOYO_MAC_FILE_CHROOT, [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT, }; |
75093152a TOMOYO: Rename sy... |
62 |
static const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION] = { |
57c2590fb TOMOYO: Update pr... |
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
[TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK, [TOMOYO_TYPE_MKCHAR] = TOMOYO_MAC_FILE_MKCHAR, }; static const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = { [TOMOYO_TYPE_LINK] = TOMOYO_MAC_FILE_LINK, [TOMOYO_TYPE_RENAME] = TOMOYO_MAC_FILE_RENAME, [TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT, }; static const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = { [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, }; |
7762fbfff TOMOYO: Add pathn... |
83 84 85 86 87 |
void tomoyo_put_name_union(struct tomoyo_name_union *ptr) { if (!ptr) return; if (ptr->is_group) |
a98aa4deb TOMOYO: Merge tom... |
88 |
tomoyo_put_group(ptr->group); |
7762fbfff TOMOYO: Add pathn... |
89 90 91 |
else tomoyo_put_name(ptr->filename); } |
484ca79c6 TOMOYO: Use pathn... |
92 93 94 |
const struct tomoyo_path_info * tomoyo_compare_name_union(const struct tomoyo_path_info *name, const struct tomoyo_name_union *ptr) |
7762fbfff TOMOYO: Add pathn... |
95 96 |
{ if (ptr->is_group) |
3f6296363 TOMOYO: Allow wil... |
97 |
return tomoyo_path_matches_group(name, ptr->group); |
484ca79c6 TOMOYO: Use pathn... |
98 99 100 |
if (tomoyo_path_matches_pattern(name, ptr->filename)) return ptr->filename; return NULL; |
7762fbfff TOMOYO: Add pathn... |
101 |
} |
4c3e9e2de TOMOYO: Add numer... |
102 103 104 |
void tomoyo_put_number_union(struct tomoyo_number_union *ptr) { if (ptr && ptr->is_group) |
a98aa4deb TOMOYO: Merge tom... |
105 |
tomoyo_put_group(ptr->group); |
4c3e9e2de TOMOYO: Add numer... |
106 107 108 109 110 111 112 113 114 |
} bool tomoyo_compare_number_union(const unsigned long value, const struct tomoyo_number_union *ptr) { if (ptr->is_group) return tomoyo_number_matches_group(value, value, ptr->group); return value >= ptr->values[0] && value <= ptr->values[1]; } |
c8c57e842 TOMOYO: Support l... |
115 116 117 118 119 120 121 122 123 124 |
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 TOMOYO: Split fil... |
125 |
/** |
b69a54ee5 File operation re... |
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
* tomoyo_strendswith - Check whether the token ends with the given token. * * @name: The token to check. * @tail: The token to find. * * Returns true if @name ends with @tail, false otherwise. */ static bool tomoyo_strendswith(const char *name, const char *tail) { int len; if (!name || !tail) return false; len = strlen(name) - strlen(tail); return len >= 0 && !strcmp(name + len, tail); } /** |
c8c57e842 TOMOYO: Support l... |
144 |
* tomoyo_get_realpath - Get realpath. |
b69a54ee5 File operation re... |
145 |
* |
c8c57e842 TOMOYO: Support l... |
146 |
* @buf: Pointer to "struct tomoyo_path_info". |
b69a54ee5 File operation re... |
147 148 |
* @path: Pointer to "struct path". * |
c8c57e842 TOMOYO: Support l... |
149 |
* Returns true on success, false otherwise. |
b69a54ee5 File operation re... |
150 |
*/ |
c8c57e842 TOMOYO: Support l... |
151 |
static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, struct path *path) |
b69a54ee5 File operation re... |
152 |
{ |
c8c57e842 TOMOYO: Support l... |
153 154 155 156 |
buf->name = tomoyo_realpath_from_path(path); if (buf->name) { tomoyo_fill_path_info(buf); return true; |
b69a54ee5 File operation re... |
157 |
} |
c8c57e842 TOMOYO: Support l... |
158 |
return false; |
b69a54ee5 File operation re... |
159 |
} |
99a852596 TOMOYO: Use callb... |
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
/** * 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) { const char *operation = tomoyo_path_keyword[r->param.path.operation]; const struct tomoyo_path_info *filename = r->param.path.filename; if (r->granted) return 0; tomoyo_warn_log(r, "%s %s", operation, filename->name); return tomoyo_supervisor(r, "allow_%s %s ", operation, |
e2bf69077 TOMOYO: Rename sy... |
176 |
tomoyo_pattern(filename)); |
99a852596 TOMOYO: Use callb... |
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
} /** * 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) { const char *operation = tomoyo_path2_keyword[r->param.path2.operation]; const struct tomoyo_path_info *filename1 = r->param.path2.filename1; const struct tomoyo_path_info *filename2 = r->param.path2.filename2; if (r->granted) return 0; tomoyo_warn_log(r, "%s %s %s", operation, filename1->name, filename2->name); return tomoyo_supervisor(r, "allow_%s %s %s ", operation, |
e2bf69077 TOMOYO: Rename sy... |
197 198 |
tomoyo_pattern(filename1), tomoyo_pattern(filename2)); |
99a852596 TOMOYO: Use callb... |
199 200 201 202 203 204 205 206 207 208 209 |
} /** * 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) { |
71c282362 TOMOYO: Remove wr... |
210 |
const char *operation = tomoyo_mkdev_keyword[r->param.mkdev.operation]; |
99a852596 TOMOYO: Use callb... |
211 212 213 214 215 216 217 218 219 220 |
const struct tomoyo_path_info *filename = r->param.mkdev.filename; const unsigned int major = r->param.mkdev.major; const unsigned int minor = r->param.mkdev.minor; const unsigned int mode = r->param.mkdev.mode; if (r->granted) return 0; tomoyo_warn_log(r, "%s %s 0%o %u %u", operation, filename->name, mode, major, minor); return tomoyo_supervisor(r, "allow_%s %s 0%o %u %u ", operation, |
e2bf69077 TOMOYO: Rename sy... |
221 |
tomoyo_pattern(filename), mode, major, minor); |
99a852596 TOMOYO: Use callb... |
222 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 249 250 251 252 253 254 255 256 257 258 259 260 |
} /** * tomoyo_audit_path_number_log - Audit path/number request log. * * @r: Pointer to "struct tomoyo_request_info". * @error: Error code. * * 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; const struct tomoyo_path_info *filename = r->param.path_number.filename; const char *operation = tomoyo_path_number_keyword[type]; char buffer[64]; if (r->granted) return 0; 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); tomoyo_warn_log(r, "%s %s %s", operation, filename->name, buffer); return tomoyo_supervisor(r, "allow_%s %s %s ", operation, |
e2bf69077 TOMOYO: Rename sy... |
261 |
tomoyo_pattern(filename), buffer); |
99a852596 TOMOYO: Use callb... |
262 |
} |
36f5e1ffb TOMOYO: Use callb... |
263 264 265 |
static bool tomoyo_same_globally_readable(const struct tomoyo_acl_head *a, const struct tomoyo_acl_head *b) { |
e2bf69077 TOMOYO: Rename sy... |
266 |
return container_of(a, struct tomoyo_readable_file, |
36f5e1ffb TOMOYO: Use callb... |
267 |
head)->filename == |
e2bf69077 TOMOYO: Rename sy... |
268 |
container_of(b, struct tomoyo_readable_file, |
36f5e1ffb TOMOYO: Use callb... |
269 270 |
head)->filename; } |
b69a54ee5 File operation re... |
271 |
/** |
e2bf69077 TOMOYO: Rename sy... |
272 |
* tomoyo_update_globally_readable_entry - Update "struct tomoyo_readable_file" list. |
b69a54ee5 File operation re... |
273 274 275 276 277 |
* * @filename: Filename unconditionally permitted to open() for reading. * @is_delete: True if it is a delete request. * * Returns 0 on success, negative value otherwise. |
fdb8ebb72 TOMOYO: Use RCU p... |
278 279 |
* * Caller holds tomoyo_read_lock(). |
b69a54ee5 File operation re... |
280 281 282 283 |
*/ static int tomoyo_update_globally_readable_entry(const char *filename, const bool is_delete) { |
e2bf69077 TOMOYO: Rename sy... |
284 |
struct tomoyo_readable_file e = { }; |
36f5e1ffb TOMOYO: Use callb... |
285 |
int error; |
b69a54ee5 File operation re... |
286 |
|
75093152a TOMOYO: Rename sy... |
287 |
if (!tomoyo_correct_word(filename)) |
b69a54ee5 File operation re... |
288 |
return -EINVAL; |
9e4b50e93 TOMOYO: Use stack... |
289 290 |
e.filename = tomoyo_get_name(filename); if (!e.filename) |
b69a54ee5 File operation re... |
291 |
return -ENOMEM; |
36f5e1ffb TOMOYO: Use callb... |
292 |
error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
a230f9e71 TOMOYO: Use array... |
293 294 |
&tomoyo_policy_list [TOMOYO_ID_GLOBALLY_READABLE], |
36f5e1ffb TOMOYO: Use callb... |
295 |
tomoyo_same_globally_readable); |
9e4b50e93 TOMOYO: Use stack... |
296 |
tomoyo_put_name(e.filename); |
b69a54ee5 File operation re... |
297 298 299 300 |
return error; } /** |
75093152a TOMOYO: Rename sy... |
301 |
* tomoyo_globally_readable_file - Check if the file is unconditionnaly permitted to be open()ed for reading. |
b69a54ee5 File operation re... |
302 303 304 305 |
* * @filename: The filename to check. * * Returns true if any domain can open @filename for reading, false otherwise. |
fdb8ebb72 TOMOYO: Use RCU p... |
306 307 |
* * Caller holds tomoyo_read_lock(). |
b69a54ee5 File operation re... |
308 |
*/ |
75093152a TOMOYO: Rename sy... |
309 |
static bool tomoyo_globally_readable_file(const struct tomoyo_path_info * |
b69a54ee5 File operation re... |
310 311 |
filename) { |
e2bf69077 TOMOYO: Rename sy... |
312 |
struct tomoyo_readable_file *ptr; |
b69a54ee5 File operation re... |
313 |
bool found = false; |
fdb8ebb72 TOMOYO: Use RCU p... |
314 |
|
a230f9e71 TOMOYO: Use array... |
315 316 |
list_for_each_entry_rcu(ptr, &tomoyo_policy_list [TOMOYO_ID_GLOBALLY_READABLE], head.list) { |
82e0f001a TOMOYO: Use commo... |
317 |
if (!ptr->head.is_deleted && |
b69a54ee5 File operation re... |
318 319 320 321 322 |
tomoyo_path_matches_pattern(filename, ptr->filename)) { found = true; break; } } |
b69a54ee5 File operation re... |
323 324 325 326 |
return found; } /** |
e2bf69077 TOMOYO: Rename sy... |
327 |
* tomoyo_write_globally_readable - Write "struct tomoyo_readable_file" list. |
b69a54ee5 File operation re... |
328 329 330 331 332 |
* * @data: String to parse. * @is_delete: True if it is a delete request. * * Returns 0 on success, negative value otherwise. |
fdb8ebb72 TOMOYO: Use RCU p... |
333 334 |
* * Caller holds tomoyo_read_lock(). |
b69a54ee5 File operation re... |
335 |
*/ |
e2bf69077 TOMOYO: Rename sy... |
336 |
int tomoyo_write_globally_readable(char *data, const bool is_delete) |
b69a54ee5 File operation re... |
337 338 339 |
{ return tomoyo_update_globally_readable_entry(data, is_delete); } |
36f5e1ffb TOMOYO: Use callb... |
340 341 342 |
static bool tomoyo_same_pattern(const struct tomoyo_acl_head *a, const struct tomoyo_acl_head *b) { |
e2bf69077 TOMOYO: Rename sy... |
343 344 |
return container_of(a, struct tomoyo_no_pattern, head)->pattern == container_of(b, struct tomoyo_no_pattern, head)->pattern; |
36f5e1ffb TOMOYO: Use callb... |
345 |
} |
b69a54ee5 File operation re... |
346 |
/** |
e2bf69077 TOMOYO: Rename sy... |
347 |
* tomoyo_update_file_pattern_entry - Update "struct tomoyo_no_pattern" list. |
b69a54ee5 File operation re... |
348 349 350 351 352 |
* * @pattern: Pathname pattern. * @is_delete: True if it is a delete request. * * Returns 0 on success, negative value otherwise. |
fdb8ebb72 TOMOYO: Use RCU p... |
353 354 |
* * Caller holds tomoyo_read_lock(). |
b69a54ee5 File operation re... |
355 356 357 358 |
*/ static int tomoyo_update_file_pattern_entry(const char *pattern, const bool is_delete) { |
e2bf69077 TOMOYO: Rename sy... |
359 |
struct tomoyo_no_pattern e = { }; |
36f5e1ffb TOMOYO: Use callb... |
360 |
int error; |
b69a54ee5 File operation re... |
361 |
|
75093152a TOMOYO: Rename sy... |
362 |
if (!tomoyo_correct_word(pattern)) |
3f6296363 TOMOYO: Allow wil... |
363 364 |
return -EINVAL; e.pattern = tomoyo_get_name(pattern); |
9e4b50e93 TOMOYO: Use stack... |
365 |
if (!e.pattern) |
36f5e1ffb TOMOYO: Use callb... |
366 367 |
return -ENOMEM; error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
a230f9e71 TOMOYO: Use array... |
368 |
&tomoyo_policy_list[TOMOYO_ID_PATTERN], |
36f5e1ffb TOMOYO: Use callb... |
369 |
tomoyo_same_pattern); |
9e4b50e93 TOMOYO: Use stack... |
370 |
tomoyo_put_name(e.pattern); |
b69a54ee5 File operation re... |
371 372 373 374 |
return error; } /** |
e2bf69077 TOMOYO: Rename sy... |
375 |
* tomoyo_pattern - Get patterned pathname. |
b69a54ee5 File operation re... |
376 377 378 379 |
* * @filename: The filename to find patterned pathname. * * Returns pointer to pathname pattern if matched, @filename otherwise. |
fdb8ebb72 TOMOYO: Use RCU p... |
380 381 |
* * Caller holds tomoyo_read_lock(). |
b69a54ee5 File operation re... |
382 |
*/ |
e2bf69077 TOMOYO: Rename sy... |
383 |
const char *tomoyo_pattern(const struct tomoyo_path_info *filename) |
b69a54ee5 File operation re... |
384 |
{ |
e2bf69077 TOMOYO: Rename sy... |
385 |
struct tomoyo_no_pattern *ptr; |
b69a54ee5 File operation re... |
386 |
const struct tomoyo_path_info *pattern = NULL; |
a230f9e71 TOMOYO: Use array... |
387 388 |
list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_PATTERN], head.list) { |
82e0f001a TOMOYO: Use commo... |
389 |
if (ptr->head.is_deleted) |
b69a54ee5 File operation re... |
390 391 392 393 394 395 396 397 398 399 400 |
continue; if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) continue; pattern = ptr->pattern; if (tomoyo_strendswith(pattern->name, "/\\*")) { /* Do nothing. Try to find the better match. */ } else { /* This would be the better match. Use this. */ break; } } |
b69a54ee5 File operation re... |
401 402 |
if (pattern) filename = pattern; |
17fcfbd9d TOMOYO: Add inter... |
403 |
return filename->name; |
b69a54ee5 File operation re... |
404 405 406 |
} /** |
e2bf69077 TOMOYO: Rename sy... |
407 |
* tomoyo_write_pattern - Write "struct tomoyo_no_pattern" list. |
b69a54ee5 File operation re... |
408 409 410 411 412 |
* * @data: String to parse. * @is_delete: True if it is a delete request. * * Returns 0 on success, negative value otherwise. |
fdb8ebb72 TOMOYO: Use RCU p... |
413 414 |
* * Caller holds tomoyo_read_lock(). |
b69a54ee5 File operation re... |
415 |
*/ |
e2bf69077 TOMOYO: Rename sy... |
416 |
int tomoyo_write_pattern(char *data, const bool is_delete) |
b69a54ee5 File operation re... |
417 418 419 |
{ return tomoyo_update_file_pattern_entry(data, is_delete); } |
36f5e1ffb TOMOYO: Use callb... |
420 421 422 |
static bool tomoyo_same_no_rewrite(const struct tomoyo_acl_head *a, const struct tomoyo_acl_head *b) { |
e2bf69077 TOMOYO: Rename sy... |
423 424 |
return container_of(a, struct tomoyo_no_rewrite, head)->pattern == container_of(b, struct tomoyo_no_rewrite, head) |
36f5e1ffb TOMOYO: Use callb... |
425 426 |
->pattern; } |
b69a54ee5 File operation re... |
427 |
/** |
e2bf69077 TOMOYO: Rename sy... |
428 |
* tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite" list. |
b69a54ee5 File operation re... |
429 430 431 432 433 |
* * @pattern: Pathname pattern that are not rewritable by default. * @is_delete: True if it is a delete request. * * Returns 0 on success, negative value otherwise. |
fdb8ebb72 TOMOYO: Use RCU p... |
434 435 |
* * Caller holds tomoyo_read_lock(). |
b69a54ee5 File operation re... |
436 437 438 439 |
*/ static int tomoyo_update_no_rewrite_entry(const char *pattern, const bool is_delete) { |
e2bf69077 TOMOYO: Rename sy... |
440 |
struct tomoyo_no_rewrite e = { }; |
36f5e1ffb TOMOYO: Use callb... |
441 |
int error; |
b69a54ee5 File operation re... |
442 |
|
75093152a TOMOYO: Rename sy... |
443 |
if (!tomoyo_correct_word(pattern)) |
b69a54ee5 File operation re... |
444 |
return -EINVAL; |
9e4b50e93 TOMOYO: Use stack... |
445 446 |
e.pattern = tomoyo_get_name(pattern); if (!e.pattern) |
36f5e1ffb TOMOYO: Use callb... |
447 448 |
return -ENOMEM; error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
a230f9e71 TOMOYO: Use array... |
449 |
&tomoyo_policy_list[TOMOYO_ID_NO_REWRITE], |
36f5e1ffb TOMOYO: Use callb... |
450 |
tomoyo_same_no_rewrite); |
9e4b50e93 TOMOYO: Use stack... |
451 |
tomoyo_put_name(e.pattern); |
b69a54ee5 File operation re... |
452 453 454 455 |
return error; } /** |
75093152a TOMOYO: Rename sy... |
456 |
* tomoyo_no_rewrite_file - Check if the given pathname is not permitted to be rewrited. |
b69a54ee5 File operation re... |
457 458 459 460 461 |
* * @filename: Filename to check. * * Returns true if @filename is specified by "deny_rewrite" directive, * false otherwise. |
fdb8ebb72 TOMOYO: Use RCU p... |
462 463 |
* * Caller holds tomoyo_read_lock(). |
b69a54ee5 File operation re... |
464 |
*/ |
75093152a TOMOYO: Rename sy... |
465 |
static bool tomoyo_no_rewrite_file(const struct tomoyo_path_info *filename) |
b69a54ee5 File operation re... |
466 |
{ |
e2bf69077 TOMOYO: Rename sy... |
467 |
struct tomoyo_no_rewrite *ptr; |
b69a54ee5 File operation re... |
468 |
bool found = false; |
a230f9e71 TOMOYO: Use array... |
469 470 |
list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_NO_REWRITE], head.list) { |
82e0f001a TOMOYO: Use commo... |
471 |
if (ptr->head.is_deleted) |
b69a54ee5 File operation re... |
472 473 474 475 476 477 |
continue; if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) continue; found = true; break; } |
b69a54ee5 File operation re... |
478 479 480 481 |
return found; } /** |
e2bf69077 TOMOYO: Rename sy... |
482 |
* tomoyo_write_no_rewrite - Write "struct tomoyo_no_rewrite" list. |
b69a54ee5 File operation re... |
483 484 485 486 487 |
* * @data: String to parse. * @is_delete: True if it is a delete request. * * Returns 0 on success, negative value otherwise. |
fdb8ebb72 TOMOYO: Use RCU p... |
488 489 |
* * Caller holds tomoyo_read_lock(). |
b69a54ee5 File operation re... |
490 |
*/ |
e2bf69077 TOMOYO: Rename sy... |
491 |
int tomoyo_write_no_rewrite(char *data, const bool is_delete) |
b69a54ee5 File operation re... |
492 493 494 |
{ return tomoyo_update_no_rewrite_entry(data, is_delete); } |
484ca79c6 TOMOYO: Use pathn... |
495 |
static bool tomoyo_check_path_acl(struct tomoyo_request_info *r, |
99a852596 TOMOYO: Use callb... |
496 |
const struct tomoyo_acl_info *ptr) |
b69a54ee5 File operation re... |
497 |
{ |
99a852596 TOMOYO: Use callb... |
498 499 |
const struct tomoyo_path_acl *acl = container_of(ptr, typeof(*acl), head); |
484ca79c6 TOMOYO: Use pathn... |
500 501 502 503 504 505 506 |
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 TOMOYO: Use callb... |
507 |
} |
b69a54ee5 File operation re... |
508 |
|
484ca79c6 TOMOYO: Use pathn... |
509 |
static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r, |
99a852596 TOMOYO: Use callb... |
510 511 512 513 514 515 516 517 518 519 |
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); } |
484ca79c6 TOMOYO: Use pathn... |
520 |
static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r, |
99a852596 TOMOYO: Use callb... |
521 522 523 524 525 526 527 528 529 |
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); } |
484ca79c6 TOMOYO: Use pathn... |
530 |
static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r, |
99a852596 TOMOYO: Use callb... |
531 532 |
const struct tomoyo_acl_info *ptr) { |
75093152a TOMOYO: Rename sy... |
533 |
const struct tomoyo_mkdev_acl *acl = |
99a852596 TOMOYO: Use callb... |
534 535 536 537 538 539 540 541 542 543 |
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 File operation re... |
544 |
} |
237ab459f TOMOYO: Use callb... |
545 546 547 548 549 |
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); |
75093152a TOMOYO: Rename sy... |
550 551 |
return tomoyo_same_acl_head(&p1->head, &p2->head) && tomoyo_same_name_union(&p1->name, &p2->name); |
237ab459f TOMOYO: Use callb... |
552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 |
} 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; if (is_delete) { perm &= ~b_perm; if ((perm & TOMOYO_RW_MASK) != TOMOYO_RW_MASK) perm &= ~(1 << TOMOYO_TYPE_READ_WRITE); else if (!(perm & (1 << TOMOYO_TYPE_READ_WRITE))) perm &= ~TOMOYO_RW_MASK; } else { perm |= b_perm; if ((perm & TOMOYO_RW_MASK) == TOMOYO_RW_MASK) perm |= (1 << TOMOYO_TYPE_READ_WRITE); else if (perm & (1 << TOMOYO_TYPE_READ_WRITE)) perm |= TOMOYO_RW_MASK; } *a_perm = perm; return !perm; } |
b69a54ee5 File operation re... |
578 |
/** |
7ef612331 TOMOYO: Use short... |
579 |
* tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list. |
b69a54ee5 File operation re... |
580 581 582 583 584 585 586 |
* * @type: Type of operation. * @filename: Filename. * @domain: Pointer to "struct tomoyo_domain_info". * @is_delete: True if it is a delete request. * * Returns 0 on success, negative value otherwise. |
fdb8ebb72 TOMOYO: Use RCU p... |
587 588 |
* * Caller holds tomoyo_read_lock(). |
b69a54ee5 File operation re... |
589 |
*/ |
7ef612331 TOMOYO: Use short... |
590 |
static int tomoyo_update_path_acl(const u8 type, const char *filename, |
237ab459f TOMOYO: Use callb... |
591 |
struct tomoyo_domain_info * const domain, |
7ef612331 TOMOYO: Use short... |
592 |
const bool is_delete) |
b69a54ee5 File operation re... |
593 |
{ |
9e4b50e93 TOMOYO: Use stack... |
594 595 |
struct tomoyo_path_acl e = { .head.type = TOMOYO_TYPE_PATH_ACL, |
237ab459f TOMOYO: Use callb... |
596 |
.perm = 1 << type |
9e4b50e93 TOMOYO: Use stack... |
597 |
}; |
237ab459f TOMOYO: Use callb... |
598 599 600 |
int error; if (e.perm == (1 << TOMOYO_TYPE_READ_WRITE)) e.perm |= TOMOYO_RW_MASK; |
7762fbfff TOMOYO: Add pathn... |
601 |
if (!tomoyo_parse_name_union(filename, &e.name)) |
b69a54ee5 File operation re... |
602 |
return -EINVAL; |
237ab459f TOMOYO: Use callb... |
603 604 605 |
error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, tomoyo_same_path_acl, tomoyo_merge_path_acl); |
7762fbfff TOMOYO: Add pathn... |
606 |
tomoyo_put_name_union(&e.name); |
b69a54ee5 File operation re... |
607 608 |
return error; } |
75093152a TOMOYO: Rename sy... |
609 |
static bool tomoyo_same_mkdev_acl(const struct tomoyo_acl_info *a, |
237ab459f TOMOYO: Use callb... |
610 611 |
const struct tomoyo_acl_info *b) { |
75093152a TOMOYO: Rename sy... |
612 |
const struct tomoyo_mkdev_acl *p1 = container_of(a, typeof(*p1), |
237ab459f TOMOYO: Use callb... |
613 |
head); |
75093152a TOMOYO: Rename sy... |
614 |
const struct tomoyo_mkdev_acl *p2 = container_of(b, typeof(*p2), |
237ab459f TOMOYO: Use callb... |
615 |
head); |
75093152a TOMOYO: Rename sy... |
616 617 618 619 620 |
return tomoyo_same_acl_head(&p1->head, &p2->head) && 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 TOMOYO: Use callb... |
621 |
} |
75093152a TOMOYO: Rename sy... |
622 |
static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a, |
237ab459f TOMOYO: Use callb... |
623 624 625 |
struct tomoyo_acl_info *b, const bool is_delete) { |
75093152a TOMOYO: Rename sy... |
626 |
u8 *const a_perm = &container_of(a, struct tomoyo_mkdev_acl, |
237ab459f TOMOYO: Use callb... |
627 628 |
head)->perm; u8 perm = *a_perm; |
75093152a TOMOYO: Rename sy... |
629 |
const u8 b_perm = container_of(b, struct tomoyo_mkdev_acl, head) |
237ab459f TOMOYO: Use callb... |
630 631 632 633 634 635 636 637 |
->perm; if (is_delete) perm &= ~b_perm; else perm |= b_perm; *a_perm = perm; return !perm; } |
b69a54ee5 File operation re... |
638 |
/** |
75093152a TOMOYO: Rename sy... |
639 |
* tomoyo_update_mkdev_acl - Update "struct tomoyo_mkdev_acl" list. |
a1f9bb6a3 TOMOYO: Split fil... |
640 641 642 643 644 645 646 647 648 649 |
* * @type: Type of operation. * @filename: Filename. * @mode: Create mode. * @major: Device major number. * @minor: Device minor number. * @domain: Pointer to "struct tomoyo_domain_info". * @is_delete: True if it is a delete request. * * Returns 0 on success, negative value otherwise. |
237ab459f TOMOYO: Use callb... |
650 651 |
* * Caller holds tomoyo_read_lock(). |
a1f9bb6a3 TOMOYO: Split fil... |
652 |
*/ |
75093152a TOMOYO: Rename sy... |
653 |
static int tomoyo_update_mkdev_acl(const u8 type, const char *filename, |
237ab459f TOMOYO: Use callb... |
654 655 656 |
char *mode, char *major, char *minor, struct tomoyo_domain_info * const domain, const bool is_delete) |
a1f9bb6a3 TOMOYO: Split fil... |
657 |
{ |
75093152a TOMOYO: Rename sy... |
658 659 |
struct tomoyo_mkdev_acl e = { .head.type = TOMOYO_TYPE_MKDEV_ACL, |
237ab459f TOMOYO: Use callb... |
660 |
.perm = 1 << type |
a1f9bb6a3 TOMOYO: Split fil... |
661 662 663 664 665 666 667 |
}; int error = is_delete ? -ENOENT : -ENOMEM; if (!tomoyo_parse_name_union(filename, &e.name) || !tomoyo_parse_number_union(mode, &e.mode) || !tomoyo_parse_number_union(major, &e.major) || !tomoyo_parse_number_union(minor, &e.minor)) goto out; |
237ab459f TOMOYO: Use callb... |
668 |
error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, |
75093152a TOMOYO: Rename sy... |
669 670 |
tomoyo_same_mkdev_acl, tomoyo_merge_mkdev_acl); |
a1f9bb6a3 TOMOYO: Split fil... |
671 672 673 674 675 676 677 |
out: 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; } |
237ab459f TOMOYO: Use callb... |
678 679 680 681 682 |
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); |
75093152a TOMOYO: Rename sy... |
683 684 685 |
return tomoyo_same_acl_head(&p1->head, &p2->head) && tomoyo_same_name_union(&p1->name1, &p2->name1) && tomoyo_same_name_union(&p1->name2, &p2->name2); |
237ab459f TOMOYO: Use callb... |
686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 |
} 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 TOMOYO: Split fil... |
703 |
/** |
7ef612331 TOMOYO: Use short... |
704 |
* tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list. |
b69a54ee5 File operation re... |
705 706 707 708 709 710 711 712 |
* * @type: Type of operation. * @filename1: First filename. * @filename2: Second filename. * @domain: Pointer to "struct tomoyo_domain_info". * @is_delete: True if it is a delete request. * * Returns 0 on success, negative value otherwise. |
fdb8ebb72 TOMOYO: Use RCU p... |
713 714 |
* * Caller holds tomoyo_read_lock(). |
b69a54ee5 File operation re... |
715 |
*/ |
7ef612331 TOMOYO: Use short... |
716 717 |
static int tomoyo_update_path2_acl(const u8 type, const char *filename1, const char *filename2, |
237ab459f TOMOYO: Use callb... |
718 |
struct tomoyo_domain_info * const domain, |
7ef612331 TOMOYO: Use short... |
719 |
const bool is_delete) |
b69a54ee5 File operation re... |
720 |
{ |
9e4b50e93 TOMOYO: Use stack... |
721 722 |
struct tomoyo_path2_acl e = { .head.type = TOMOYO_TYPE_PATH2_ACL, |
237ab459f TOMOYO: Use callb... |
723 |
.perm = 1 << type |
9e4b50e93 TOMOYO: Use stack... |
724 |
}; |
ca0b7df33 TOMOYO: Reduce li... |
725 |
int error = is_delete ? -ENOENT : -ENOMEM; |
7762fbfff TOMOYO: Add pathn... |
726 727 |
if (!tomoyo_parse_name_union(filename1, &e.name1) || !tomoyo_parse_name_union(filename2, &e.name2)) |
ca0b7df33 TOMOYO: Reduce li... |
728 |
goto out; |
237ab459f TOMOYO: Use callb... |
729 730 731 |
error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, tomoyo_same_path2_acl, tomoyo_merge_path2_acl); |
ca0b7df33 TOMOYO: Reduce li... |
732 |
out: |
7762fbfff TOMOYO: Add pathn... |
733 734 |
tomoyo_put_name_union(&e.name1); tomoyo_put_name_union(&e.name2); |
b69a54ee5 File operation re... |
735 736 737 738 |
return error; } /** |
cb0abe6a5 TOMOYO: Use struc... |
739 |
* tomoyo_path_permission - Check permission for single path operation. |
b69a54ee5 File operation re... |
740 |
* |
cb0abe6a5 TOMOYO: Use struc... |
741 |
* @r: Pointer to "struct tomoyo_request_info". |
b69a54ee5 File operation re... |
742 743 |
* @operation: Type of operation. * @filename: Filename to check. |
b69a54ee5 File operation re... |
744 745 |
* * Returns 0 on success, negative value otherwise. |
fdb8ebb72 TOMOYO: Use RCU p... |
746 747 |
* * Caller holds tomoyo_read_lock(). |
b69a54ee5 File operation re... |
748 |
*/ |
05336dee9 TOMOYO: Use commo... |
749 750 |
int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation, const struct tomoyo_path_info *filename) |
b69a54ee5 File operation re... |
751 |
{ |
b69a54ee5 File operation re... |
752 |
int error; |
b69a54ee5 File operation re... |
753 |
|
b69a54ee5 File operation re... |
754 |
next: |
57c2590fb TOMOYO: Update pr... |
755 756 757 758 |
r->type = tomoyo_p2mac[operation]; r->mode = tomoyo_get_mode(r->profile, r->type); if (r->mode == TOMOYO_CONFIG_DISABLED) return 0; |
cf6e9a646 TOMOYO: Pass para... |
759 760 761 |
r->param_type = TOMOYO_TYPE_PATH_ACL; r->param.path.filename = filename; r->param.path.operation = operation; |
17fcfbd9d TOMOYO: Add inter... |
762 |
do { |
99a852596 TOMOYO: Use callb... |
763 764 |
tomoyo_check_acl(r, tomoyo_check_path_acl); if (!r->granted && operation == TOMOYO_TYPE_READ && |
05336dee9 TOMOYO: Use commo... |
765 |
!r->domain->ignore_global_allow_read && |
75093152a TOMOYO: Rename sy... |
766 |
tomoyo_globally_readable_file(filename)) |
99a852596 TOMOYO: Use callb... |
767 768 |
r->granted = true; error = tomoyo_audit_path_log(r); |
05336dee9 TOMOYO: Use commo... |
769 770 771 772 773 774 |
/* * Do not retry for execute request, for alias may have * changed. */ } while (error == TOMOYO_RETRY_REQUEST && operation != TOMOYO_TYPE_EXECUTE); |
b69a54ee5 File operation re... |
775 776 777 778 779 |
/* * Since "allow_truncate" doesn't imply "allow_rewrite" permission, * we need to check "allow_rewrite" permission if the filename is * specified by "deny_rewrite" keyword. */ |
7ef612331 TOMOYO: Use short... |
780 |
if (!error && operation == TOMOYO_TYPE_TRUNCATE && |
75093152a TOMOYO: Rename sy... |
781 |
tomoyo_no_rewrite_file(filename)) { |
7ef612331 TOMOYO: Use short... |
782 |
operation = TOMOYO_TYPE_REWRITE; |
b69a54ee5 File operation re... |
783 784 785 786 |
goto next; } return error; } |
237ab459f TOMOYO: Use callb... |
787 788 789 790 791 792 793 |
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); |
75093152a TOMOYO: Rename sy... |
794 795 796 |
return tomoyo_same_acl_head(&p1->head, &p2->head) && tomoyo_same_name_union(&p1->name, &p2->name) && tomoyo_same_number_union(&p1->number, &p2->number); |
237ab459f TOMOYO: Use callb... |
797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 |
} 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 TOMOYO: Split fil... |
815 816 817 818 819 820 821 822 823 824 825 |
/** * tomoyo_update_path_number_acl - Update ioctl/chmod/chown/chgrp ACL. * * @type: Type of operation. * @filename: Filename. * @number: Number. * @domain: Pointer to "struct tomoyo_domain_info". * @is_delete: True if it is a delete request. * * Returns 0 on success, negative value otherwise. */ |
237ab459f TOMOYO: Use callb... |
826 827 828 829 830 |
static int tomoyo_update_path_number_acl(const u8 type, const char *filename, char *number, struct tomoyo_domain_info * const domain, const bool is_delete) |
a1f9bb6a3 TOMOYO: Split fil... |
831 |
{ |
a1f9bb6a3 TOMOYO: Split fil... |
832 833 |
struct tomoyo_path_number_acl e = { .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL, |
237ab459f TOMOYO: Use callb... |
834 |
.perm = 1 << type |
a1f9bb6a3 TOMOYO: Split fil... |
835 836 |
}; int error = is_delete ? -ENOENT : -ENOMEM; |
a1f9bb6a3 TOMOYO: Split fil... |
837 838 839 840 |
if (!tomoyo_parse_name_union(filename, &e.name)) return -EINVAL; if (!tomoyo_parse_number_union(number, &e.number)) goto out; |
237ab459f TOMOYO: Use callb... |
841 842 843 |
error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, tomoyo_same_path_number_acl, tomoyo_merge_path_number_acl); |
a1f9bb6a3 TOMOYO: Split fil... |
844 845 846 847 848 849 850 |
out: tomoyo_put_name_union(&e.name); tomoyo_put_number_union(&e.number); return error; } /** |
a1f9bb6a3 TOMOYO: Split fil... |
851 852 853 854 855 856 857 858 859 860 861 862 863 |
* 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. */ int tomoyo_path_number_perm(const u8 type, struct path *path, unsigned long number) { struct tomoyo_request_info r; int error = -ENOMEM; |
c8c57e842 TOMOYO: Support l... |
864 |
struct tomoyo_path_info buf; |
a1f9bb6a3 TOMOYO: Split fil... |
865 |
int idx; |
57c2590fb TOMOYO: Update pr... |
866 867 |
if (tomoyo_init_request_info(&r, NULL, tomoyo_pn2mac[type]) == TOMOYO_CONFIG_DISABLED || !path->mnt || !path->dentry) |
a1f9bb6a3 TOMOYO: Split fil... |
868 869 |
return 0; idx = tomoyo_read_lock(); |
c8c57e842 TOMOYO: Support l... |
870 |
if (!tomoyo_get_realpath(&buf, path)) |
a1f9bb6a3 TOMOYO: Split fil... |
871 |
goto out; |
c8c57e842 TOMOYO: Support l... |
872 873 |
if (type == TOMOYO_TYPE_MKDIR) tomoyo_add_slash(&buf); |
cb917cf51 TOMOYO: Merge fun... |
874 875 876 877 878 879 880 881 |
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 TOMOYO: Support l... |
882 |
kfree(buf.name); |
cb917cf51 TOMOYO: Merge fun... |
883 |
out: |
a1f9bb6a3 TOMOYO: Split fil... |
884 885 886 887 888 889 890 |
tomoyo_read_unlock(idx); if (r.mode != TOMOYO_CONFIG_ENFORCING) error = 0; return error; } /** |
b69a54ee5 File operation re... |
891 892 893 894 895 896 897 898 899 900 901 902 |
* 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, struct path *path, const int flag) { const u8 acc_mode = ACC_MODE(flag); |
eae61f3c8 TOMOYO: Fix memor... |
903 |
int error = 0; |
c8c57e842 TOMOYO: Support l... |
904 |
struct tomoyo_path_info buf; |
cb0abe6a5 TOMOYO: Use struc... |
905 |
struct tomoyo_request_info r; |
fdb8ebb72 TOMOYO: Use RCU p... |
906 |
int idx; |
b69a54ee5 File operation re... |
907 |
|
57c2590fb TOMOYO: Update pr... |
908 909 |
if (!path->mnt || (path->dentry->d_inode && S_ISDIR(path->dentry->d_inode->i_mode))) |
b69a54ee5 File operation re... |
910 |
return 0; |
57c2590fb TOMOYO: Update pr... |
911 912 |
buf.name = NULL; r.mode = TOMOYO_CONFIG_DISABLED; |
fdb8ebb72 TOMOYO: Use RCU p... |
913 |
idx = tomoyo_read_lock(); |
b69a54ee5 File operation re... |
914 915 916 917 918 |
/* * If the filename is specified by "deny_rewrite" keyword, * we need to check "allow_rewrite" permission when the filename is not * opened for append mode or the filename is truncated at open time. */ |
57c2590fb TOMOYO: Update pr... |
919 920 921 922 923 924 925 |
if ((acc_mode & MAY_WRITE) && !(flag & O_APPEND) && tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_REWRITE) != TOMOYO_CONFIG_DISABLED) { if (!tomoyo_get_realpath(&buf, path)) { error = -ENOMEM; goto out; } |
75093152a TOMOYO: Rename sy... |
926 |
if (tomoyo_no_rewrite_file(&buf)) |
57c2590fb TOMOYO: Update pr... |
927 928 |
error = tomoyo_path_permission(&r, TOMOYO_TYPE_REWRITE, &buf); |
b69a54ee5 File operation re... |
929 |
} |
57c2590fb TOMOYO: Update pr... |
930 931 932 |
if (!error && acc_mode && tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN) != TOMOYO_CONFIG_DISABLED) { |
05336dee9 TOMOYO: Use commo... |
933 |
u8 operation; |
57c2590fb TOMOYO: Update pr... |
934 935 936 937 |
if (!buf.name && !tomoyo_get_realpath(&buf, path)) { error = -ENOMEM; goto out; } |
05336dee9 TOMOYO: Use commo... |
938 939 940 941 942 943 944 |
if (acc_mode == (MAY_READ | MAY_WRITE)) operation = TOMOYO_TYPE_READ_WRITE; else if (acc_mode == MAY_READ) operation = TOMOYO_TYPE_READ; else operation = TOMOYO_TYPE_WRITE; error = tomoyo_path_permission(&r, operation, &buf); |
57c2590fb TOMOYO: Update pr... |
945 |
} |
b69a54ee5 File operation re... |
946 |
out: |
c8c57e842 TOMOYO: Support l... |
947 |
kfree(buf.name); |
fdb8ebb72 TOMOYO: Use RCU p... |
948 |
tomoyo_read_unlock(idx); |
cb0abe6a5 TOMOYO: Use struc... |
949 |
if (r.mode != TOMOYO_CONFIG_ENFORCING) |
b69a54ee5 File operation re... |
950 951 952 953 954 |
error = 0; return error; } /** |
2106ccd97 TOMOYO: Add mount... |
955 |
* tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "rewrite", "chroot" and "unmount". |
b69a54ee5 File operation re... |
956 |
* |
b69a54ee5 File operation re... |
957 958 959 960 961 |
* @operation: Type of operation. * @path: Pointer to "struct path". * * Returns 0 on success, negative value otherwise. */ |
97d6931ea TOMOYO: Remove un... |
962 |
int tomoyo_path_perm(const u8 operation, struct path *path) |
b69a54ee5 File operation re... |
963 964 |
{ int error = -ENOMEM; |
c8c57e842 TOMOYO: Support l... |
965 |
struct tomoyo_path_info buf; |
cb0abe6a5 TOMOYO: Use struc... |
966 |
struct tomoyo_request_info r; |
fdb8ebb72 TOMOYO: Use RCU p... |
967 |
int idx; |
b69a54ee5 File operation re... |
968 |
|
57c2590fb TOMOYO: Update pr... |
969 970 971 972 |
if (!path->mnt) return 0; if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation]) == TOMOYO_CONFIG_DISABLED) |
b69a54ee5 File operation re... |
973 |
return 0; |
57c2590fb TOMOYO: Update pr... |
974 |
buf.name = NULL; |
fdb8ebb72 TOMOYO: Use RCU p... |
975 |
idx = tomoyo_read_lock(); |
c8c57e842 TOMOYO: Support l... |
976 |
if (!tomoyo_get_realpath(&buf, path)) |
b69a54ee5 File operation re... |
977 978 |
goto out; switch (operation) { |
cb0abe6a5 TOMOYO: Use struc... |
979 |
case TOMOYO_TYPE_REWRITE: |
75093152a TOMOYO: Rename sy... |
980 |
if (!tomoyo_no_rewrite_file(&buf)) { |
cb0abe6a5 TOMOYO: Use struc... |
981 982 983 984 |
error = 0; goto out; } break; |
7ef612331 TOMOYO: Use short... |
985 986 |
case TOMOYO_TYPE_RMDIR: case TOMOYO_TYPE_CHROOT: |
57c2590fb TOMOYO: Update pr... |
987 |
case TOMOYO_TYPE_UMOUNT: |
c8c57e842 TOMOYO: Support l... |
988 989 |
tomoyo_add_slash(&buf); break; |
b69a54ee5 File operation re... |
990 |
} |
c8c57e842 TOMOYO: Support l... |
991 |
error = tomoyo_path_permission(&r, operation, &buf); |
b69a54ee5 File operation re... |
992 |
out: |
c8c57e842 TOMOYO: Support l... |
993 |
kfree(buf.name); |
fdb8ebb72 TOMOYO: Use RCU p... |
994 |
tomoyo_read_unlock(idx); |
cb0abe6a5 TOMOYO: Use struc... |
995 |
if (r.mode != TOMOYO_CONFIG_ENFORCING) |
b69a54ee5 File operation re... |
996 997 998 999 1000 |
error = 0; return error; } /** |
75093152a TOMOYO: Rename sy... |
1001 |
* tomoyo_mkdev_perm - Check permission for "mkblock" and "mkchar". |
a1f9bb6a3 TOMOYO: Split fil... |
1002 1003 1004 1005 1006 1007 1008 1009 |
* * @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. */ |
75093152a TOMOYO: Rename sy... |
1010 |
int tomoyo_mkdev_perm(const u8 operation, struct path *path, |
a1f9bb6a3 TOMOYO: Split fil... |
1011 1012 1013 1014 |
const unsigned int mode, unsigned int dev) { struct tomoyo_request_info r; int error = -ENOMEM; |
c8c57e842 TOMOYO: Support l... |
1015 |
struct tomoyo_path_info buf; |
a1f9bb6a3 TOMOYO: Split fil... |
1016 |
int idx; |
57c2590fb TOMOYO: Update pr... |
1017 1018 1019 |
if (!path->mnt || tomoyo_init_request_info(&r, NULL, tomoyo_pnnn2mac[operation]) == TOMOYO_CONFIG_DISABLED) |
a1f9bb6a3 TOMOYO: Split fil... |
1020 1021 1022 |
return 0; idx = tomoyo_read_lock(); error = -ENOMEM; |
c8c57e842 TOMOYO: Support l... |
1023 |
if (tomoyo_get_realpath(&buf, path)) { |
cf6e9a646 TOMOYO: Pass para... |
1024 |
dev = new_decode_dev(dev); |
75093152a TOMOYO: Rename sy... |
1025 |
r.param_type = TOMOYO_TYPE_MKDEV_ACL; |
cf6e9a646 TOMOYO: Pass para... |
1026 1027 1028 1029 1030 |
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 TOMOYO: Use callb... |
1031 1032 |
tomoyo_check_acl(&r, tomoyo_check_mkdev_acl); error = tomoyo_audit_mkdev_log(&r); |
c8c57e842 TOMOYO: Support l... |
1033 |
kfree(buf.name); |
a1f9bb6a3 TOMOYO: Split fil... |
1034 1035 1036 1037 1038 1039 1040 1041 |
} tomoyo_read_unlock(idx); if (r.mode != TOMOYO_CONFIG_ENFORCING) error = 0; return error; } /** |
7ef612331 TOMOYO: Use short... |
1042 |
* tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root". |
b69a54ee5 File operation re... |
1043 |
* |
b69a54ee5 File operation re... |
1044 1045 1046 1047 1048 1049 |
* @operation: Type of operation. * @path1: Pointer to "struct path". * @path2: Pointer to "struct path". * * Returns 0 on success, negative value otherwise. */ |
97d6931ea TOMOYO: Remove un... |
1050 |
int tomoyo_path2_perm(const u8 operation, struct path *path1, |
7ef612331 TOMOYO: Use short... |
1051 |
struct path *path2) |
b69a54ee5 File operation re... |
1052 1053 |
{ int error = -ENOMEM; |
c8c57e842 TOMOYO: Support l... |
1054 1055 |
struct tomoyo_path_info buf1; struct tomoyo_path_info buf2; |
cb0abe6a5 TOMOYO: Use struc... |
1056 |
struct tomoyo_request_info r; |
fdb8ebb72 TOMOYO: Use RCU p... |
1057 |
int idx; |
b69a54ee5 File operation re... |
1058 |
|
57c2590fb TOMOYO: Update pr... |
1059 1060 1061 |
if (!path1->mnt || !path2->mnt || tomoyo_init_request_info(&r, NULL, tomoyo_pp2mac[operation]) == TOMOYO_CONFIG_DISABLED) |
b69a54ee5 File operation re... |
1062 |
return 0; |
c8c57e842 TOMOYO: Support l... |
1063 1064 |
buf1.name = NULL; buf2.name = NULL; |
fdb8ebb72 TOMOYO: Use RCU p... |
1065 |
idx = tomoyo_read_lock(); |
c8c57e842 TOMOYO: Support l... |
1066 1067 |
if (!tomoyo_get_realpath(&buf1, path1) || !tomoyo_get_realpath(&buf2, path2)) |
b69a54ee5 File operation re... |
1068 |
goto out; |
57c2590fb TOMOYO: Update pr... |
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 |
switch (operation) { struct dentry *dentry; case TOMOYO_TYPE_RENAME: case TOMOYO_TYPE_LINK: dentry = path1->dentry; if (!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode)) break; /* fall through */ case TOMOYO_TYPE_PIVOT_ROOT: tomoyo_add_slash(&buf1); tomoyo_add_slash(&buf2); break; } |
cf6e9a646 TOMOYO: Pass para... |
1082 1083 1084 1085 |
r.param_type = TOMOYO_TYPE_PATH2_ACL; r.param.path2.operation = operation; r.param.path2.filename1 = &buf1; r.param.path2.filename2 = &buf2; |
17fcfbd9d TOMOYO: Add inter... |
1086 |
do { |
99a852596 TOMOYO: Use callb... |
1087 1088 1089 |
tomoyo_check_acl(&r, tomoyo_check_path2_acl); error = tomoyo_audit_path2_log(&r); } while (error == TOMOYO_RETRY_REQUEST); |
b69a54ee5 File operation re... |
1090 |
out: |
c8c57e842 TOMOYO: Support l... |
1091 1092 |
kfree(buf1.name); kfree(buf2.name); |
fdb8ebb72 TOMOYO: Use RCU p... |
1093 |
tomoyo_read_unlock(idx); |
cb0abe6a5 TOMOYO: Use struc... |
1094 |
if (r.mode != TOMOYO_CONFIG_ENFORCING) |
b69a54ee5 File operation re... |
1095 1096 1097 |
error = 0; return error; } |
a1f9bb6a3 TOMOYO: Split fil... |
1098 1099 |
/** |
e2bf69077 TOMOYO: Rename sy... |
1100 |
* tomoyo_write_file - Update file related list. |
a1f9bb6a3 TOMOYO: Split fil... |
1101 1102 1103 1104 1105 1106 1107 1108 1109 |
* * @data: String to parse. * @domain: Pointer to "struct tomoyo_domain_info". * @is_delete: True if it is a delete request. * * Returns 0 on success, negative value otherwise. * * Caller holds tomoyo_read_lock(). */ |
e2bf69077 TOMOYO: Rename sy... |
1110 1111 |
int tomoyo_write_file(char *data, struct tomoyo_domain_info *domain, const bool is_delete) |
a1f9bb6a3 TOMOYO: Split fil... |
1112 1113 1114 1115 1116 |
{ char *w[5]; u8 type; if (!tomoyo_tokenize(data, w, sizeof(w)) || !w[1][0]) return -EINVAL; |
237ab459f TOMOYO: Use callb... |
1117 |
if (strncmp(w[0], "allow_", 6)) |
a1f9bb6a3 TOMOYO: Split fil... |
1118 |
goto out; |
a1f9bb6a3 TOMOYO: Split fil... |
1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 |
w[0] += 6; for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++) { if (strcmp(w[0], tomoyo_path_keyword[type])) continue; return tomoyo_update_path_acl(type, w[1], domain, is_delete); } if (!w[2][0]) goto out; for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++) { if (strcmp(w[0], tomoyo_path2_keyword[type])) continue; return tomoyo_update_path2_acl(type, w[1], w[2], domain, is_delete); } for (type = 0; type < TOMOYO_MAX_PATH_NUMBER_OPERATION; type++) { if (strcmp(w[0], tomoyo_path_number_keyword[type])) continue; return tomoyo_update_path_number_acl(type, w[1], w[2], domain, is_delete); } if (!w[3][0] || !w[4][0]) goto out; |
75093152a TOMOYO: Rename sy... |
1141 1142 |
for (type = 0; type < TOMOYO_MAX_MKDEV_OPERATION; type++) { if (strcmp(w[0], tomoyo_mkdev_keyword[type])) |
a1f9bb6a3 TOMOYO: Split fil... |
1143 |
continue; |
75093152a TOMOYO: Rename sy... |
1144 1145 |
return tomoyo_update_mkdev_acl(type, w[1], w[2], w[3], w[4], domain, is_delete); |
a1f9bb6a3 TOMOYO: Split fil... |
1146 1147 1148 1149 |
} out: return -EINVAL; } |