aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo/file.c')
-rw-r--r--security/tomoyo/file.c131
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
54static 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
68static 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
73static 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
79static 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
54void tomoyo_put_name_union(struct tomoyo_name_union *ptr) 90void 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 */
1279int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain, 1319int 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)