summaryrefslogtreecommitdiffstats
path: root/security/tomoyo/common.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2011-07-08 00:23:44 -0400
committerJames Morris <jmorris@namei.org>2011-07-10 21:05:33 -0400
commit2ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563 (patch)
treeb9f6051059a2a90547a4501bf296b0cf3c9dbc76 /security/tomoyo/common.c
parent8761afd49ebff8ae04c1a7888af090177441d07d (diff)
TOMOYO: Allow using executable's realpath and symlink's target as conditions.
This patch adds support for permission checks using executable file's realpath upon execve() and symlink's target upon symlink(). Hooks are in the last patch of this pathset. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r--security/tomoyo/common.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index ec02d2ab08c3..69d6b59f5937 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -79,6 +79,8 @@ const char * const tomoyo_condition_keyword[TOMOYO_MAX_CONDITION_KEYWORD] = {
79 [TOMOYO_MODE_OTHERS_READ] = "others_read", 79 [TOMOYO_MODE_OTHERS_READ] = "others_read",
80 [TOMOYO_MODE_OTHERS_WRITE] = "others_write", 80 [TOMOYO_MODE_OTHERS_WRITE] = "others_write",
81 [TOMOYO_MODE_OTHERS_EXECUTE] = "others_execute", 81 [TOMOYO_MODE_OTHERS_EXECUTE] = "others_execute",
82 [TOMOYO_EXEC_REALPATH] = "exec.realpath",
83 [TOMOYO_SYMLINK_TARGET] = "symlink.target",
82 [TOMOYO_PATH1_UID] = "path1.uid", 84 [TOMOYO_PATH1_UID] = "path1.uid",
83 [TOMOYO_PATH1_GID] = "path1.gid", 85 [TOMOYO_PATH1_GID] = "path1.gid",
84 [TOMOYO_PATH1_INO] = "path1.ino", 86 [TOMOYO_PATH1_INO] = "path1.ino",
@@ -353,6 +355,27 @@ static void tomoyo_print_name_union(struct tomoyo_io_buffer *head,
353} 355}
354 356
355/** 357/**
358 * tomoyo_print_name_union_quoted - Print a tomoyo_name_union with a quote.
359 *
360 * @head: Pointer to "struct tomoyo_io_buffer".
361 * @ptr: Pointer to "struct tomoyo_name_union".
362 *
363 * Returns nothing.
364 */
365static void tomoyo_print_name_union_quoted(struct tomoyo_io_buffer *head,
366 const struct tomoyo_name_union *ptr)
367{
368 if (ptr->group) {
369 tomoyo_set_string(head, "@");
370 tomoyo_set_string(head, ptr->group->group_name->name);
371 } else {
372 tomoyo_set_string(head, "\"");
373 tomoyo_set_string(head, ptr->filename->name);
374 tomoyo_set_string(head, "\"");
375 }
376}
377
378/**
356 * tomoyo_print_number_union_nospace - Print a tomoyo_number_union without a space. 379 * tomoyo_print_number_union_nospace - Print a tomoyo_number_union without a space.
357 * 380 *
358 * @head: Pointer to "struct tomoyo_io_buffer". 381 * @head: Pointer to "struct tomoyo_io_buffer".
@@ -1101,6 +1124,9 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
1101 (typeof(condp)) (cond + 1); 1124 (typeof(condp)) (cond + 1);
1102 const struct tomoyo_number_union *numbers_p = 1125 const struct tomoyo_number_union *numbers_p =
1103 (typeof(numbers_p)) (condp + condc); 1126 (typeof(numbers_p)) (condp + condc);
1127 const struct tomoyo_name_union *names_p =
1128 (typeof(names_p))
1129 (numbers_p + cond->numbers_count);
1104 u16 skip; 1130 u16 skip;
1105 for (skip = 0; skip < head->r.cond_index; skip++) { 1131 for (skip = 0; skip < head->r.cond_index; skip++) {
1106 const u8 left = condp->left; 1132 const u8 left = condp->left;
@@ -1112,6 +1138,9 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
1112 break; 1138 break;
1113 } 1139 }
1114 switch (right) { 1140 switch (right) {
1141 case TOMOYO_NAME_UNION:
1142 names_p++;
1143 break;
1115 case TOMOYO_NUMBER_UNION: 1144 case TOMOYO_NUMBER_UNION:
1116 numbers_p++; 1145 numbers_p++;
1117 break; 1146 break;
@@ -1138,6 +1167,10 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
1138 } 1167 }
1139 tomoyo_set_string(head, match ? "=" : "!="); 1168 tomoyo_set_string(head, match ? "=" : "!=");
1140 switch (right) { 1169 switch (right) {
1170 case TOMOYO_NAME_UNION:
1171 tomoyo_print_name_union_quoted
1172 (head, names_p++);
1173 break;
1141 case TOMOYO_NUMBER_UNION: 1174 case TOMOYO_NUMBER_UNION:
1142 tomoyo_print_number_union_nospace 1175 tomoyo_print_number_union_nospace
1143 (head, numbers_p++); 1176 (head, numbers_p++);
@@ -1666,6 +1699,22 @@ static DEFINE_SPINLOCK(tomoyo_query_list_lock);
1666static atomic_t tomoyo_query_observers = ATOMIC_INIT(0); 1699static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);
1667 1700
1668/** 1701/**
1702 * tomoyo_truncate - Truncate a line.
1703 *
1704 * @str: String to truncate.
1705 *
1706 * Returns length of truncated @str.
1707 */
1708static int tomoyo_truncate(char *str)
1709{
1710 char *start = str;
1711 while (*(unsigned char *) str > (unsigned char) ' ')
1712 str++;
1713 *str = '\0';
1714 return strlen(start) + 1;
1715}
1716
1717/**
1669 * tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode. 1718 * tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode.
1670 * 1719 *
1671 * @domain: Pointer to "struct tomoyo_domain_info". 1720 * @domain: Pointer to "struct tomoyo_domain_info".
@@ -1676,6 +1725,8 @@ static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);
1676static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header) 1725static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
1677{ 1726{
1678 char *buffer; 1727 char *buffer;
1728 char *realpath = NULL;
1729 char *symlink = NULL;
1679 char *cp = strchr(header, '\n'); 1730 char *cp = strchr(header, '\n');
1680 int len; 1731 int len;
1681 if (!cp) 1732 if (!cp)
@@ -1685,10 +1736,25 @@ static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
1685 return; 1736 return;
1686 *cp++ = '\0'; 1737 *cp++ = '\0';
1687 len = strlen(cp) + 1; 1738 len = strlen(cp) + 1;
1739 /* strstr() will return NULL if ordering is wrong. */
1740 if (*cp == 'f') {
1741 realpath = strstr(header, " exec={ realpath=\"");
1742 if (realpath) {
1743 realpath += 8;
1744 len += tomoyo_truncate(realpath) + 6;
1745 }
1746 symlink = strstr(header, " symlink.target=\"");
1747 if (symlink)
1748 len += tomoyo_truncate(symlink + 1) + 1;
1749 }
1688 buffer = kmalloc(len, GFP_NOFS); 1750 buffer = kmalloc(len, GFP_NOFS);
1689 if (!buffer) 1751 if (!buffer)
1690 return; 1752 return;
1691 snprintf(buffer, len - 1, "%s", cp); 1753 snprintf(buffer, len - 1, "%s", cp);
1754 if (realpath)
1755 tomoyo_addprintf(buffer, len, " exec.%s", realpath);
1756 if (symlink)
1757 tomoyo_addprintf(buffer, len, "%s", symlink);
1692 tomoyo_normalize_line(buffer); 1758 tomoyo_normalize_line(buffer);
1693 if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer, 1759 if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer,
1694 false)) 1760 false))