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.c136
1 files changed, 58 insertions, 78 deletions
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index c13806937dc6..cef685415df1 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -148,6 +148,17 @@ const char *tomoyo_path_number2keyword(const u8 operation)
148 ? tomoyo_path_number_keyword[operation] : NULL; 148 ? tomoyo_path_number_keyword[operation] : NULL;
149} 149}
150 150
151static void tomoyo_add_slash(struct tomoyo_path_info *buf)
152{
153 if (buf->is_dir)
154 return;
155 /*
156 * This is OK because tomoyo_encode() reserves space for appending "/".
157 */
158 strcat((char *) buf->name, "/");
159 tomoyo_fill_path_info(buf);
160}
161
151/** 162/**
152 * tomoyo_strendswith - Check whether the token ends with the given token. 163 * tomoyo_strendswith - Check whether the token ends with the given token.
153 * 164 *
@@ -167,30 +178,21 @@ static bool tomoyo_strendswith(const char *name, const char *tail)
167} 178}
168 179
169/** 180/**
170 * tomoyo_get_path - Get realpath. 181 * tomoyo_get_realpath - Get realpath.
171 * 182 *
183 * @buf: Pointer to "struct tomoyo_path_info".
172 * @path: Pointer to "struct path". 184 * @path: Pointer to "struct path".
173 * 185 *
174 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. 186 * Returns true on success, false otherwise.
175 */ 187 */
176static struct tomoyo_path_info *tomoyo_get_path(struct path *path) 188static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, struct path *path)
177{ 189{
178 int error; 190 buf->name = tomoyo_realpath_from_path(path);
179 struct tomoyo_path_info_with_data *buf = kzalloc(sizeof(*buf), 191 if (buf->name) {
180 GFP_NOFS); 192 tomoyo_fill_path_info(buf);
181 193 return true;
182 if (!buf)
183 return NULL;
184 /* Reserve one byte for appending "/". */
185 error = tomoyo_realpath_from_path2(path, buf->body,
186 sizeof(buf->body) - 2);
187 if (!error) {
188 buf->head.name = buf->body;
189 tomoyo_fill_path_info(&buf->head);
190 return &buf->head;
191 } 194 }
192 kfree(buf); 195 return false;
193 return NULL;
194} 196}
195 197
196static int tomoyo_update_path2_acl(const u8 type, const char *filename1, 198static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
@@ -1259,26 +1261,20 @@ int tomoyo_path_number_perm(const u8 type, struct path *path,
1259{ 1261{
1260 struct tomoyo_request_info r; 1262 struct tomoyo_request_info r;
1261 int error = -ENOMEM; 1263 int error = -ENOMEM;
1262 struct tomoyo_path_info *buf; 1264 struct tomoyo_path_info buf;
1263 int idx; 1265 int idx;
1264 1266
1265 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED || 1267 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED ||
1266 !path->mnt || !path->dentry) 1268 !path->mnt || !path->dentry)
1267 return 0; 1269 return 0;
1268 idx = tomoyo_read_lock(); 1270 idx = tomoyo_read_lock();
1269 buf = tomoyo_get_path(path); 1271 if (!tomoyo_get_realpath(&buf, path))
1270 if (!buf)
1271 goto out; 1272 goto out;
1272 if (type == TOMOYO_TYPE_MKDIR && !buf->is_dir) { 1273 if (type == TOMOYO_TYPE_MKDIR)
1273 /* 1274 tomoyo_add_slash(&buf);
1274 * tomoyo_get_path() reserves space for appending "/." 1275 error = tomoyo_path_number_perm2(&r, type, &buf, number);
1275 */
1276 strcat((char *) buf->name, "/");
1277 tomoyo_fill_path_info(buf);
1278 }
1279 error = tomoyo_path_number_perm2(&r, type, buf, number);
1280 out: 1276 out:
1281 kfree(buf); 1277 kfree(buf.name);
1282 tomoyo_read_unlock(idx); 1278 tomoyo_read_unlock(idx);
1283 if (r.mode != TOMOYO_CONFIG_ENFORCING) 1279 if (r.mode != TOMOYO_CONFIG_ENFORCING)
1284 error = 0; 1280 error = 0;
@@ -1319,7 +1315,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1319{ 1315{
1320 const u8 acc_mode = ACC_MODE(flag); 1316 const u8 acc_mode = ACC_MODE(flag);
1321 int error = -ENOMEM; 1317 int error = -ENOMEM;
1322 struct tomoyo_path_info *buf; 1318 struct tomoyo_path_info buf;
1323 struct tomoyo_request_info r; 1319 struct tomoyo_request_info r;
1324 int idx; 1320 int idx;
1325 1321
@@ -1335,8 +1331,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1335 */ 1331 */
1336 return 0; 1332 return 0;
1337 idx = tomoyo_read_lock(); 1333 idx = tomoyo_read_lock();
1338 buf = tomoyo_get_path(path); 1334 if (!tomoyo_get_realpath(&buf, path))
1339 if (!buf)
1340 goto out; 1335 goto out;
1341 error = 0; 1336 error = 0;
1342 /* 1337 /*
@@ -1346,15 +1341,15 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1346 */ 1341 */
1347 if ((acc_mode & MAY_WRITE) && 1342 if ((acc_mode & MAY_WRITE) &&
1348 ((flag & O_TRUNC) || !(flag & O_APPEND)) && 1343 ((flag & O_TRUNC) || !(flag & O_APPEND)) &&
1349 (tomoyo_is_no_rewrite_file(buf))) { 1344 (tomoyo_is_no_rewrite_file(&buf))) {
1350 error = tomoyo_path_permission(&r, TOMOYO_TYPE_REWRITE, buf); 1345 error = tomoyo_path_permission(&r, TOMOYO_TYPE_REWRITE, &buf);
1351 } 1346 }
1352 if (!error) 1347 if (!error)
1353 error = tomoyo_file_perm(&r, buf, acc_mode); 1348 error = tomoyo_file_perm(&r, &buf, acc_mode);
1354 if (!error && (flag & O_TRUNC)) 1349 if (!error && (flag & O_TRUNC))
1355 error = tomoyo_path_permission(&r, TOMOYO_TYPE_TRUNCATE, buf); 1350 error = tomoyo_path_permission(&r, TOMOYO_TYPE_TRUNCATE, &buf);
1356 out: 1351 out:
1357 kfree(buf); 1352 kfree(buf.name);
1358 tomoyo_read_unlock(idx); 1353 tomoyo_read_unlock(idx);
1359 if (r.mode != TOMOYO_CONFIG_ENFORCING) 1354 if (r.mode != TOMOYO_CONFIG_ENFORCING)
1360 error = 0; 1355 error = 0;
@@ -1372,7 +1367,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1372int tomoyo_path_perm(const u8 operation, struct path *path) 1367int tomoyo_path_perm(const u8 operation, struct path *path)
1373{ 1368{
1374 int error = -ENOMEM; 1369 int error = -ENOMEM;
1375 struct tomoyo_path_info *buf; 1370 struct tomoyo_path_info buf;
1376 struct tomoyo_request_info r; 1371 struct tomoyo_request_info r;
1377 int idx; 1372 int idx;
1378 1373
@@ -1380,29 +1375,23 @@ int tomoyo_path_perm(const u8 operation, struct path *path)
1380 !path->mnt) 1375 !path->mnt)
1381 return 0; 1376 return 0;
1382 idx = tomoyo_read_lock(); 1377 idx = tomoyo_read_lock();
1383 buf = tomoyo_get_path(path); 1378 if (!tomoyo_get_realpath(&buf, path))
1384 if (!buf)
1385 goto out; 1379 goto out;
1386 switch (operation) { 1380 switch (operation) {
1387 case TOMOYO_TYPE_REWRITE: 1381 case TOMOYO_TYPE_REWRITE:
1388 if (!tomoyo_is_no_rewrite_file(buf)) { 1382 if (!tomoyo_is_no_rewrite_file(&buf)) {
1389 error = 0; 1383 error = 0;
1390 goto out; 1384 goto out;
1391 } 1385 }
1392 break; 1386 break;
1393 case TOMOYO_TYPE_RMDIR: 1387 case TOMOYO_TYPE_RMDIR:
1394 case TOMOYO_TYPE_CHROOT: 1388 case TOMOYO_TYPE_CHROOT:
1395 if (!buf->is_dir) { 1389 tomoyo_add_slash(&buf);
1396 /* 1390 break;
1397 * tomoyo_get_path() reserves space for appending "/."
1398 */
1399 strcat((char *) buf->name, "/");
1400 tomoyo_fill_path_info(buf);
1401 }
1402 } 1391 }
1403 error = tomoyo_path_permission(&r, operation, buf); 1392 error = tomoyo_path_permission(&r, operation, &buf);
1404 out: 1393 out:
1405 kfree(buf); 1394 kfree(buf.name);
1406 tomoyo_read_unlock(idx); 1395 tomoyo_read_unlock(idx);
1407 if (r.mode != TOMOYO_CONFIG_ENFORCING) 1396 if (r.mode != TOMOYO_CONFIG_ENFORCING)
1408 error = 0; 1397 error = 0;
@@ -1465,7 +1454,7 @@ int tomoyo_path_number3_perm(const u8 operation, struct path *path,
1465{ 1454{
1466 struct tomoyo_request_info r; 1455 struct tomoyo_request_info r;
1467 int error = -ENOMEM; 1456 int error = -ENOMEM;
1468 struct tomoyo_path_info *buf; 1457 struct tomoyo_path_info buf;
1469 int idx; 1458 int idx;
1470 1459
1471 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED || 1460 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED ||
@@ -1473,11 +1462,10 @@ int tomoyo_path_number3_perm(const u8 operation, struct path *path,
1473 return 0; 1462 return 0;
1474 idx = tomoyo_read_lock(); 1463 idx = tomoyo_read_lock();
1475 error = -ENOMEM; 1464 error = -ENOMEM;
1476 buf = tomoyo_get_path(path); 1465 if (tomoyo_get_realpath(&buf, path)) {
1477 if (buf) { 1466 error = tomoyo_path_number3_perm2(&r, operation, &buf, mode,
1478 error = tomoyo_path_number3_perm2(&r, operation, buf, mode,
1479 new_decode_dev(dev)); 1467 new_decode_dev(dev));
1480 kfree(buf); 1468 kfree(buf.name);
1481 } 1469 }
1482 tomoyo_read_unlock(idx); 1470 tomoyo_read_unlock(idx);
1483 if (r.mode != TOMOYO_CONFIG_ENFORCING) 1471 if (r.mode != TOMOYO_CONFIG_ENFORCING)
@@ -1499,48 +1487,40 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
1499{ 1487{
1500 int error = -ENOMEM; 1488 int error = -ENOMEM;
1501 const char *msg; 1489 const char *msg;
1502 struct tomoyo_path_info *buf1; 1490 struct tomoyo_path_info buf1;
1503 struct tomoyo_path_info *buf2; 1491 struct tomoyo_path_info buf2;
1504 struct tomoyo_request_info r; 1492 struct tomoyo_request_info r;
1505 int idx; 1493 int idx;
1506 1494
1507 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED || 1495 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED ||
1508 !path1->mnt || !path2->mnt) 1496 !path1->mnt || !path2->mnt)
1509 return 0; 1497 return 0;
1498 buf1.name = NULL;
1499 buf2.name = NULL;
1510 idx = tomoyo_read_lock(); 1500 idx = tomoyo_read_lock();
1511 buf1 = tomoyo_get_path(path1); 1501 if (!tomoyo_get_realpath(&buf1, path1) ||
1512 buf2 = tomoyo_get_path(path2); 1502 !tomoyo_get_realpath(&buf2, path2))
1513 if (!buf1 || !buf2)
1514 goto out; 1503 goto out;
1515 { 1504 {
1516 struct dentry *dentry = path1->dentry; 1505 struct dentry *dentry = path1->dentry;
1517 if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) { 1506 if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) {
1518 /* 1507 tomoyo_add_slash(&buf1);
1519 * tomoyo_get_path() reserves space for appending "/." 1508 tomoyo_add_slash(&buf2);
1520 */
1521 if (!buf1->is_dir) {
1522 strcat((char *) buf1->name, "/");
1523 tomoyo_fill_path_info(buf1);
1524 }
1525 if (!buf2->is_dir) {
1526 strcat((char *) buf2->name, "/");
1527 tomoyo_fill_path_info(buf2);
1528 }
1529 } 1509 }
1530 } 1510 }
1531 do { 1511 do {
1532 error = tomoyo_path2_acl(&r, operation, buf1, buf2); 1512 error = tomoyo_path2_acl(&r, operation, &buf1, &buf2);
1533 if (!error) 1513 if (!error)
1534 break; 1514 break;
1535 msg = tomoyo_path22keyword(operation); 1515 msg = tomoyo_path22keyword(operation);
1536 tomoyo_warn_log(&r, "%s %s %s", msg, buf1->name, buf2->name); 1516 tomoyo_warn_log(&r, "%s %s %s", msg, buf1.name, buf2.name);
1537 error = tomoyo_supervisor(&r, "allow_%s %s %s\n", msg, 1517 error = tomoyo_supervisor(&r, "allow_%s %s %s\n", msg,
1538 tomoyo_file_pattern(buf1), 1518 tomoyo_file_pattern(&buf1),
1539 tomoyo_file_pattern(buf2)); 1519 tomoyo_file_pattern(&buf2));
1540 } while (error == TOMOYO_RETRY_REQUEST); 1520 } while (error == TOMOYO_RETRY_REQUEST);
1541 out: 1521 out:
1542 kfree(buf1); 1522 kfree(buf1.name);
1543 kfree(buf2); 1523 kfree(buf2.name);
1544 tomoyo_read_unlock(idx); 1524 tomoyo_read_unlock(idx);
1545 if (r.mode != TOMOYO_CONFIG_ENFORCING) 1525 if (r.mode != TOMOYO_CONFIG_ENFORCING)
1546 error = 0; 1526 error = 0;