diff options
Diffstat (limited to 'security/tomoyo/file.c')
-rw-r--r-- | security/tomoyo/file.c | 131 |
1 files changed, 93 insertions, 38 deletions
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c index 83fa17a1113a..8e51348d022e 100644 --- a/security/tomoyo/file.c +++ b/security/tomoyo/file.c | |||
@@ -51,6 +51,42 @@ static const char *tomoyo_path_number_keyword | |||
51 | [TOMOYO_TYPE_CHGRP] = "chgrp", | 51 | [TOMOYO_TYPE_CHGRP] = "chgrp", |
52 | }; | 52 | }; |
53 | 53 | ||
54 | static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = { | ||
55 | [TOMOYO_TYPE_READ_WRITE] = TOMOYO_MAC_FILE_OPEN, | ||
56 | [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE, | ||
57 | [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN, | ||
58 | [TOMOYO_TYPE_WRITE] = TOMOYO_MAC_FILE_OPEN, | ||
59 | [TOMOYO_TYPE_UNLINK] = TOMOYO_MAC_FILE_UNLINK, | ||
60 | [TOMOYO_TYPE_RMDIR] = TOMOYO_MAC_FILE_RMDIR, | ||
61 | [TOMOYO_TYPE_TRUNCATE] = TOMOYO_MAC_FILE_TRUNCATE, | ||
62 | [TOMOYO_TYPE_SYMLINK] = TOMOYO_MAC_FILE_SYMLINK, | ||
63 | [TOMOYO_TYPE_REWRITE] = TOMOYO_MAC_FILE_REWRITE, | ||
64 | [TOMOYO_TYPE_CHROOT] = TOMOYO_MAC_FILE_CHROOT, | ||
65 | [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT, | ||
66 | }; | ||
67 | |||
68 | static const u8 tomoyo_pnnn2mac[TOMOYO_MAX_PATH_NUMBER3_OPERATION] = { | ||
69 | [TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK, | ||
70 | [TOMOYO_TYPE_MKCHAR] = TOMOYO_MAC_FILE_MKCHAR, | ||
71 | }; | ||
72 | |||
73 | static const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = { | ||
74 | [TOMOYO_TYPE_LINK] = TOMOYO_MAC_FILE_LINK, | ||
75 | [TOMOYO_TYPE_RENAME] = TOMOYO_MAC_FILE_RENAME, | ||
76 | [TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT, | ||
77 | }; | ||
78 | |||
79 | static const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = { | ||
80 | [TOMOYO_TYPE_CREATE] = TOMOYO_MAC_FILE_CREATE, | ||
81 | [TOMOYO_TYPE_MKDIR] = TOMOYO_MAC_FILE_MKDIR, | ||
82 | [TOMOYO_TYPE_MKFIFO] = TOMOYO_MAC_FILE_MKFIFO, | ||
83 | [TOMOYO_TYPE_MKSOCK] = TOMOYO_MAC_FILE_MKSOCK, | ||
84 | [TOMOYO_TYPE_IOCTL] = TOMOYO_MAC_FILE_IOCTL, | ||
85 | [TOMOYO_TYPE_CHMOD] = TOMOYO_MAC_FILE_CHMOD, | ||
86 | [TOMOYO_TYPE_CHOWN] = TOMOYO_MAC_FILE_CHOWN, | ||
87 | [TOMOYO_TYPE_CHGRP] = TOMOYO_MAC_FILE_CHGRP, | ||
88 | }; | ||
89 | |||
54 | void tomoyo_put_name_union(struct tomoyo_name_union *ptr) | 90 | void tomoyo_put_name_union(struct tomoyo_name_union *ptr) |
55 | { | 91 | { |
56 | if (!ptr) | 92 | if (!ptr) |
@@ -1057,6 +1093,10 @@ static int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation, | |||
1057 | int error; | 1093 | int error; |
1058 | 1094 | ||
1059 | next: | 1095 | next: |
1096 | r->type = tomoyo_p2mac[operation]; | ||
1097 | r->mode = tomoyo_get_mode(r->profile, r->type); | ||
1098 | if (r->mode == TOMOYO_CONFIG_DISABLED) | ||
1099 | return 0; | ||
1060 | do { | 1100 | do { |
1061 | error = tomoyo_path_acl(r, filename, 1 << operation); | 1101 | error = tomoyo_path_acl(r, filename, 1 << operation); |
1062 | if (!error) | 1102 | if (!error) |
@@ -1249,8 +1289,8 @@ int tomoyo_path_number_perm(const u8 type, struct path *path, | |||
1249 | struct tomoyo_path_info buf; | 1289 | struct tomoyo_path_info buf; |
1250 | int idx; | 1290 | int idx; |
1251 | 1291 | ||
1252 | if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED || | 1292 | if (tomoyo_init_request_info(&r, NULL, tomoyo_pn2mac[type]) |
1253 | !path->mnt || !path->dentry) | 1293 | == TOMOYO_CONFIG_DISABLED || !path->mnt || !path->dentry) |
1254 | return 0; | 1294 | return 0; |
1255 | idx = tomoyo_read_lock(); | 1295 | idx = tomoyo_read_lock(); |
1256 | if (!tomoyo_get_realpath(&buf, path)) | 1296 | if (!tomoyo_get_realpath(&buf, path)) |
@@ -1269,21 +1309,19 @@ int tomoyo_path_number_perm(const u8 type, struct path *path, | |||
1269 | /** | 1309 | /** |
1270 | * tomoyo_check_exec_perm - Check permission for "execute". | 1310 | * tomoyo_check_exec_perm - Check permission for "execute". |
1271 | * | 1311 | * |
1272 | * @domain: Pointer to "struct tomoyo_domain_info". | 1312 | * @r: Pointer to "struct tomoyo_request_info". |
1273 | * @filename: Check permission for "execute". | 1313 | * @filename: Check permission for "execute". |
1274 | * | 1314 | * |
1275 | * Returns 0 on success, negativevalue otherwise. | 1315 | * Returns 0 on success, negativevalue otherwise. |
1276 | * | 1316 | * |
1277 | * Caller holds tomoyo_read_lock(). | 1317 | * Caller holds tomoyo_read_lock(). |
1278 | */ | 1318 | */ |
1279 | int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain, | 1319 | int tomoyo_check_exec_perm(struct tomoyo_request_info *r, |
1280 | const struct tomoyo_path_info *filename) | 1320 | const struct tomoyo_path_info *filename) |
1281 | { | 1321 | { |
1282 | struct tomoyo_request_info r; | 1322 | if (r->mode == TOMOYO_CONFIG_DISABLED) |
1283 | |||
1284 | if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED) | ||
1285 | return 0; | 1323 | return 0; |
1286 | return tomoyo_file_perm(&r, filename, 1); | 1324 | return tomoyo_file_perm(r, filename, 1); |
1287 | } | 1325 | } |
1288 | 1326 | ||
1289 | /** | 1327 | /** |
@@ -1304,17 +1342,11 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, | |||
1304 | struct tomoyo_request_info r; | 1342 | struct tomoyo_request_info r; |
1305 | int idx; | 1343 | int idx; |
1306 | 1344 | ||
1307 | if (tomoyo_init_request_info(&r, domain) == TOMOYO_CONFIG_DISABLED || | 1345 | if (!path->mnt || |
1308 | !path->mnt) | 1346 | (path->dentry->d_inode && S_ISDIR(path->dentry->d_inode->i_mode))) |
1309 | return 0; | ||
1310 | if (acc_mode == 0) | ||
1311 | return 0; | ||
1312 | if (path->dentry->d_inode && S_ISDIR(path->dentry->d_inode->i_mode)) | ||
1313 | /* | ||
1314 | * I don't check directories here because mkdir() and rmdir() | ||
1315 | * don't call me. | ||
1316 | */ | ||
1317 | return 0; | 1347 | return 0; |
1348 | buf.name = NULL; | ||
1349 | r.mode = TOMOYO_CONFIG_DISABLED; | ||
1318 | idx = tomoyo_read_lock(); | 1350 | idx = tomoyo_read_lock(); |
1319 | if (!tomoyo_get_realpath(&buf, path)) | 1351 | if (!tomoyo_get_realpath(&buf, path)) |
1320 | goto out; | 1352 | goto out; |
@@ -1324,15 +1356,26 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, | |||
1324 | * we need to check "allow_rewrite" permission when the filename is not | 1356 | * we need to check "allow_rewrite" permission when the filename is not |
1325 | * opened for append mode or the filename is truncated at open time. | 1357 | * opened for append mode or the filename is truncated at open time. |
1326 | */ | 1358 | */ |
1327 | if ((acc_mode & MAY_WRITE) && | 1359 | if ((acc_mode & MAY_WRITE) && !(flag & O_APPEND) |
1328 | ((flag & O_TRUNC) || !(flag & O_APPEND)) && | 1360 | && tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_REWRITE) |
1329 | (tomoyo_is_no_rewrite_file(&buf))) { | 1361 | != TOMOYO_CONFIG_DISABLED) { |
1330 | error = tomoyo_path_permission(&r, TOMOYO_TYPE_REWRITE, &buf); | 1362 | if (!tomoyo_get_realpath(&buf, path)) { |
1363 | error = -ENOMEM; | ||
1364 | goto out; | ||
1365 | } | ||
1366 | if (tomoyo_is_no_rewrite_file(&buf)) | ||
1367 | error = tomoyo_path_permission(&r, TOMOYO_TYPE_REWRITE, | ||
1368 | &buf); | ||
1331 | } | 1369 | } |
1332 | if (!error) | 1370 | if (!error && acc_mode && |
1371 | tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN) | ||
1372 | != TOMOYO_CONFIG_DISABLED) { | ||
1373 | if (!buf.name && !tomoyo_get_realpath(&buf, path)) { | ||
1374 | error = -ENOMEM; | ||
1375 | goto out; | ||
1376 | } | ||
1333 | error = tomoyo_file_perm(&r, &buf, acc_mode); | 1377 | error = tomoyo_file_perm(&r, &buf, acc_mode); |
1334 | if (!error && (flag & O_TRUNC)) | 1378 | } |
1335 | error = tomoyo_path_permission(&r, TOMOYO_TYPE_TRUNCATE, &buf); | ||
1336 | out: | 1379 | out: |
1337 | kfree(buf.name); | 1380 | kfree(buf.name); |
1338 | tomoyo_read_unlock(idx); | 1381 | tomoyo_read_unlock(idx); |
@@ -1356,9 +1399,12 @@ int tomoyo_path_perm(const u8 operation, struct path *path) | |||
1356 | struct tomoyo_request_info r; | 1399 | struct tomoyo_request_info r; |
1357 | int idx; | 1400 | int idx; |
1358 | 1401 | ||
1359 | if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED || | 1402 | if (!path->mnt) |
1360 | !path->mnt) | 1403 | return 0; |
1404 | if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation]) | ||
1405 | == TOMOYO_CONFIG_DISABLED) | ||
1361 | return 0; | 1406 | return 0; |
1407 | buf.name = NULL; | ||
1362 | idx = tomoyo_read_lock(); | 1408 | idx = tomoyo_read_lock(); |
1363 | if (!tomoyo_get_realpath(&buf, path)) | 1409 | if (!tomoyo_get_realpath(&buf, path)) |
1364 | goto out; | 1410 | goto out; |
@@ -1371,6 +1417,7 @@ int tomoyo_path_perm(const u8 operation, struct path *path) | |||
1371 | break; | 1417 | break; |
1372 | case TOMOYO_TYPE_RMDIR: | 1418 | case TOMOYO_TYPE_RMDIR: |
1373 | case TOMOYO_TYPE_CHROOT: | 1419 | case TOMOYO_TYPE_CHROOT: |
1420 | case TOMOYO_TYPE_UMOUNT: | ||
1374 | tomoyo_add_slash(&buf); | 1421 | tomoyo_add_slash(&buf); |
1375 | break; | 1422 | break; |
1376 | } | 1423 | } |
@@ -1442,8 +1489,9 @@ int tomoyo_path_number3_perm(const u8 operation, struct path *path, | |||
1442 | struct tomoyo_path_info buf; | 1489 | struct tomoyo_path_info buf; |
1443 | int idx; | 1490 | int idx; |
1444 | 1491 | ||
1445 | if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED || | 1492 | if (!path->mnt || |
1446 | !path->mnt) | 1493 | tomoyo_init_request_info(&r, NULL, tomoyo_pnnn2mac[operation]) |
1494 | == TOMOYO_CONFIG_DISABLED) | ||
1447 | return 0; | 1495 | return 0; |
1448 | idx = tomoyo_read_lock(); | 1496 | idx = tomoyo_read_lock(); |
1449 | error = -ENOMEM; | 1497 | error = -ENOMEM; |
@@ -1477,8 +1525,9 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1, | |||
1477 | struct tomoyo_request_info r; | 1525 | struct tomoyo_request_info r; |
1478 | int idx; | 1526 | int idx; |
1479 | 1527 | ||
1480 | if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED || | 1528 | if (!path1->mnt || !path2->mnt || |
1481 | !path1->mnt || !path2->mnt) | 1529 | tomoyo_init_request_info(&r, NULL, tomoyo_pp2mac[operation]) |
1530 | == TOMOYO_CONFIG_DISABLED) | ||
1482 | return 0; | 1531 | return 0; |
1483 | buf1.name = NULL; | 1532 | buf1.name = NULL; |
1484 | buf2.name = NULL; | 1533 | buf2.name = NULL; |
@@ -1486,13 +1535,19 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1, | |||
1486 | if (!tomoyo_get_realpath(&buf1, path1) || | 1535 | if (!tomoyo_get_realpath(&buf1, path1) || |
1487 | !tomoyo_get_realpath(&buf2, path2)) | 1536 | !tomoyo_get_realpath(&buf2, path2)) |
1488 | goto out; | 1537 | goto out; |
1489 | { | 1538 | switch (operation) { |
1490 | struct dentry *dentry = path1->dentry; | 1539 | struct dentry *dentry; |
1491 | if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) { | 1540 | case TOMOYO_TYPE_RENAME: |
1492 | tomoyo_add_slash(&buf1); | 1541 | case TOMOYO_TYPE_LINK: |
1493 | tomoyo_add_slash(&buf2); | 1542 | dentry = path1->dentry; |
1494 | } | 1543 | if (!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode)) |
1495 | } | 1544 | break; |
1545 | /* fall through */ | ||
1546 | case TOMOYO_TYPE_PIVOT_ROOT: | ||
1547 | tomoyo_add_slash(&buf1); | ||
1548 | tomoyo_add_slash(&buf2); | ||
1549 | break; | ||
1550 | } | ||
1496 | do { | 1551 | do { |
1497 | error = tomoyo_path2_acl(&r, operation, &buf1, &buf2); | 1552 | error = tomoyo_path2_acl(&r, operation, &buf1, &buf2); |
1498 | if (!error) | 1553 | if (!error) |