diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2011-07-08 00:21:37 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2011-07-10 21:05:32 -0400 |
commit | 2066a36125fcbf5220990173b9d8e8bc49ad7538 (patch) | |
tree | c8ea3a6d92a8b4b68cda986601336e8e8f58553e /security/tomoyo/common.c | |
parent | 5c4274f13819b40e726f6ee4ef13b4952cff5010 (diff) |
TOMOYO: Allow using UID/GID etc. of current thread as conditions.
This patch adds support for permission checks using current thread's UID/GID
etc. in addition to pathnames.
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.c | 146 |
1 files changed, 137 insertions, 9 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index b340137a9216..32ce1705b85a 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -48,6 +48,20 @@ const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX | |||
48 | [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file", | 48 | [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file", |
49 | }; | 49 | }; |
50 | 50 | ||
51 | /* String table for conditions. */ | ||
52 | const char * const tomoyo_condition_keyword[TOMOYO_MAX_CONDITION_KEYWORD] = { | ||
53 | [TOMOYO_TASK_UID] = "task.uid", | ||
54 | [TOMOYO_TASK_EUID] = "task.euid", | ||
55 | [TOMOYO_TASK_SUID] = "task.suid", | ||
56 | [TOMOYO_TASK_FSUID] = "task.fsuid", | ||
57 | [TOMOYO_TASK_GID] = "task.gid", | ||
58 | [TOMOYO_TASK_EGID] = "task.egid", | ||
59 | [TOMOYO_TASK_SGID] = "task.sgid", | ||
60 | [TOMOYO_TASK_FSGID] = "task.fsgid", | ||
61 | [TOMOYO_TASK_PID] = "task.pid", | ||
62 | [TOMOYO_TASK_PPID] = "task.ppid", | ||
63 | }; | ||
64 | |||
51 | /* String table for PREFERENCE keyword. */ | 65 | /* String table for PREFERENCE keyword. */ |
52 | static const char * const tomoyo_pref_keywords[TOMOYO_MAX_PREF] = { | 66 | static const char * const tomoyo_pref_keywords[TOMOYO_MAX_PREF] = { |
53 | [TOMOYO_PREF_MAX_AUDIT_LOG] = "max_audit_log", | 67 | [TOMOYO_PREF_MAX_AUDIT_LOG] = "max_audit_log", |
@@ -294,15 +308,16 @@ static void tomoyo_print_name_union(struct tomoyo_io_buffer *head, | |||
294 | } | 308 | } |
295 | 309 | ||
296 | /** | 310 | /** |
297 | * tomoyo_print_number_union - Print a tomoyo_number_union. | 311 | * tomoyo_print_number_union_nospace - Print a tomoyo_number_union without a space. |
298 | * | 312 | * |
299 | * @head: Pointer to "struct tomoyo_io_buffer". | 313 | * @head: Pointer to "struct tomoyo_io_buffer". |
300 | * @ptr: Pointer to "struct tomoyo_number_union". | 314 | * @ptr: Pointer to "struct tomoyo_number_union". |
315 | * | ||
316 | * Returns nothing. | ||
301 | */ | 317 | */ |
302 | static void tomoyo_print_number_union(struct tomoyo_io_buffer *head, | 318 | static void tomoyo_print_number_union_nospace |
303 | const struct tomoyo_number_union *ptr) | 319 | (struct tomoyo_io_buffer *head, const struct tomoyo_number_union *ptr) |
304 | { | 320 | { |
305 | tomoyo_set_space(head); | ||
306 | if (ptr->group) { | 321 | if (ptr->group) { |
307 | tomoyo_set_string(head, "@"); | 322 | tomoyo_set_string(head, "@"); |
308 | tomoyo_set_string(head, ptr->group->group_name->name); | 323 | tomoyo_set_string(head, ptr->group->group_name->name); |
@@ -325,8 +340,8 @@ static void tomoyo_print_number_union(struct tomoyo_io_buffer *head, | |||
325 | "0%lo", min); | 340 | "0%lo", min); |
326 | break; | 341 | break; |
327 | default: | 342 | default: |
328 | tomoyo_addprintf(buffer, sizeof(buffer), | 343 | tomoyo_addprintf(buffer, sizeof(buffer), "%lu", |
329 | "%lu", min); | 344 | min); |
330 | break; | 345 | break; |
331 | } | 346 | } |
332 | if (min == max && min_type == max_type) | 347 | if (min == max && min_type == max_type) |
@@ -340,6 +355,21 @@ static void tomoyo_print_number_union(struct tomoyo_io_buffer *head, | |||
340 | } | 355 | } |
341 | 356 | ||
342 | /** | 357 | /** |
358 | * tomoyo_print_number_union - Print a tomoyo_number_union. | ||
359 | * | ||
360 | * @head: Pointer to "struct tomoyo_io_buffer". | ||
361 | * @ptr: Pointer to "struct tomoyo_number_union". | ||
362 | * | ||
363 | * Returns nothing. | ||
364 | */ | ||
365 | static void tomoyo_print_number_union(struct tomoyo_io_buffer *head, | ||
366 | const struct tomoyo_number_union *ptr) | ||
367 | { | ||
368 | tomoyo_set_space(head); | ||
369 | tomoyo_print_number_union_nospace(head, ptr); | ||
370 | } | ||
371 | |||
372 | /** | ||
343 | * tomoyo_assign_profile - Create a new profile. | 373 | * tomoyo_assign_profile - Create a new profile. |
344 | * | 374 | * |
345 | * @ns: Pointer to "struct tomoyo_policy_namespace". | 375 | * @ns: Pointer to "struct tomoyo_policy_namespace". |
@@ -1004,6 +1034,91 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head) | |||
1004 | } | 1034 | } |
1005 | 1035 | ||
1006 | /** | 1036 | /** |
1037 | * tomoyo_print_condition - Print condition part. | ||
1038 | * | ||
1039 | * @head: Pointer to "struct tomoyo_io_buffer". | ||
1040 | * @cond: Pointer to "struct tomoyo_condition". | ||
1041 | * | ||
1042 | * Returns true on success, false otherwise. | ||
1043 | */ | ||
1044 | static bool tomoyo_print_condition(struct tomoyo_io_buffer *head, | ||
1045 | const struct tomoyo_condition *cond) | ||
1046 | { | ||
1047 | switch (head->r.cond_step) { | ||
1048 | case 0: | ||
1049 | head->r.cond_index = 0; | ||
1050 | head->r.cond_step++; | ||
1051 | /* fall through */ | ||
1052 | case 1: | ||
1053 | { | ||
1054 | const u16 condc = cond->condc; | ||
1055 | const struct tomoyo_condition_element *condp = | ||
1056 | (typeof(condp)) (cond + 1); | ||
1057 | const struct tomoyo_number_union *numbers_p = | ||
1058 | (typeof(numbers_p)) (condp + condc); | ||
1059 | u16 skip; | ||
1060 | for (skip = 0; skip < head->r.cond_index; skip++) { | ||
1061 | const u8 left = condp->left; | ||
1062 | const u8 right = condp->right; | ||
1063 | condp++; | ||
1064 | switch (left) { | ||
1065 | case TOMOYO_NUMBER_UNION: | ||
1066 | numbers_p++; | ||
1067 | break; | ||
1068 | } | ||
1069 | switch (right) { | ||
1070 | case TOMOYO_NUMBER_UNION: | ||
1071 | numbers_p++; | ||
1072 | break; | ||
1073 | } | ||
1074 | } | ||
1075 | while (head->r.cond_index < condc) { | ||
1076 | const u8 match = condp->equals; | ||
1077 | const u8 left = condp->left; | ||
1078 | const u8 right = condp->right; | ||
1079 | if (!tomoyo_flush(head)) | ||
1080 | return false; | ||
1081 | condp++; | ||
1082 | head->r.cond_index++; | ||
1083 | tomoyo_set_space(head); | ||
1084 | switch (left) { | ||
1085 | case TOMOYO_NUMBER_UNION: | ||
1086 | tomoyo_print_number_union_nospace | ||
1087 | (head, numbers_p++); | ||
1088 | break; | ||
1089 | default: | ||
1090 | tomoyo_set_string(head, | ||
1091 | tomoyo_condition_keyword[left]); | ||
1092 | break; | ||
1093 | } | ||
1094 | tomoyo_set_string(head, match ? "=" : "!="); | ||
1095 | switch (right) { | ||
1096 | case TOMOYO_NUMBER_UNION: | ||
1097 | tomoyo_print_number_union_nospace | ||
1098 | (head, numbers_p++); | ||
1099 | break; | ||
1100 | default: | ||
1101 | tomoyo_set_string(head, | ||
1102 | tomoyo_condition_keyword[right]); | ||
1103 | break; | ||
1104 | } | ||
1105 | } | ||
1106 | } | ||
1107 | head->r.cond_step++; | ||
1108 | /* fall through */ | ||
1109 | case 2: | ||
1110 | if (!tomoyo_flush(head)) | ||
1111 | break; | ||
1112 | head->r.cond_step++; | ||
1113 | /* fall through */ | ||
1114 | case 3: | ||
1115 | tomoyo_set_lf(head); | ||
1116 | return true; | ||
1117 | } | ||
1118 | return false; | ||
1119 | } | ||
1120 | |||
1121 | /** | ||
1007 | * tomoyo_set_group - Print "acl_group " header keyword and category name. | 1122 | * tomoyo_set_group - Print "acl_group " header keyword and category name. |
1008 | * | 1123 | * |
1009 | * @head: Pointer to "struct tomoyo_io_buffer". | 1124 | * @head: Pointer to "struct tomoyo_io_buffer". |
@@ -1037,6 +1152,8 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
1037 | bool first = true; | 1152 | bool first = true; |
1038 | u8 bit; | 1153 | u8 bit; |
1039 | 1154 | ||
1155 | if (head->r.print_cond_part) | ||
1156 | goto print_cond_part; | ||
1040 | if (acl->is_deleted) | 1157 | if (acl->is_deleted) |
1041 | return true; | 1158 | return true; |
1042 | if (!tomoyo_flush(head)) | 1159 | if (!tomoyo_flush(head)) |
@@ -1135,7 +1252,18 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
1135 | tomoyo_print_name_union(head, &ptr->fs_type); | 1252 | tomoyo_print_name_union(head, &ptr->fs_type); |
1136 | tomoyo_print_number_union(head, &ptr->flags); | 1253 | tomoyo_print_number_union(head, &ptr->flags); |
1137 | } | 1254 | } |
1138 | tomoyo_set_lf(head); | 1255 | if (acl->cond) { |
1256 | head->r.print_cond_part = true; | ||
1257 | head->r.cond_step = 0; | ||
1258 | if (!tomoyo_flush(head)) | ||
1259 | return false; | ||
1260 | print_cond_part: | ||
1261 | if (!tomoyo_print_condition(head, acl->cond)) | ||
1262 | return false; | ||
1263 | head->r.print_cond_part = false; | ||
1264 | } else { | ||
1265 | tomoyo_set_lf(head); | ||
1266 | } | ||
1139 | return true; | 1267 | return true; |
1140 | } | 1268 | } |
1141 | 1269 | ||