aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r--security/tomoyo/common.c259
1 files changed, 200 insertions, 59 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index cb1aaf148ad4..044115d49033 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -1192,75 +1192,216 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head)
1192 return -EINVAL; 1192 return -EINVAL;
1193} 1193}
1194 1194
1195static void tomoyo_print_number(char *buffer, int buffer_len,
1196 const struct tomoyo_number_union *ptr)
1197{
1198 int i;
1199 unsigned long min = ptr->values[0];
1200 const unsigned long max = ptr->values[1];
1201 u8 min_type = ptr->min_type;
1202 const u8 max_type = ptr->max_type;
1203 memset(buffer, 0, buffer_len);
1204 buffer_len -= 2;
1205 for (i = 0; i < 2; i++) {
1206 int len;
1207 switch (min_type) {
1208 case TOMOYO_VALUE_TYPE_HEXADECIMAL:
1209 snprintf(buffer, buffer_len, "0x%lX", min);
1210 break;
1211 case TOMOYO_VALUE_TYPE_OCTAL:
1212 snprintf(buffer, buffer_len, "0%lo", min);
1213 break;
1214 default:
1215 snprintf(buffer, buffer_len, "%lu", min);
1216 break;
1217 }
1218 if (min == max && min_type == max_type)
1219 break;
1220 len = strlen(buffer);
1221 buffer[len++] = '-';
1222 buffer += len;
1223 buffer_len -= len;
1224 min_type = max_type;
1225 min = max;
1226 }
1227}
1228
1229static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
1230 [TOMOYO_PATH_GROUP] = TOMOYO_KEYWORD_PATH_GROUP,
1231 [TOMOYO_NUMBER_GROUP] = TOMOYO_KEYWORD_NUMBER_GROUP
1232};
1233
1195/** 1234/**
1196 * tomoyo_read_exception_policy - Read exception policy. 1235 * tomoyo_read_group - Read "struct tomoyo_path_group"/"struct tomoyo_number_group" list.
1197 * 1236 *
1198 * @head: Pointer to "struct tomoyo_io_buffer". 1237 * @head: Pointer to "struct tomoyo_io_buffer".
1238 * @idx: Index number.
1239 *
1240 * Returns true on success, false otherwise.
1199 * 1241 *
1200 * Caller holds tomoyo_read_lock(). 1242 * Caller holds tomoyo_read_lock().
1201 */ 1243 */
1202static void tomoyo_read_exception_policy(struct tomoyo_io_buffer *head) 1244static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
1203{ 1245{
1204 if (!head->read_eof) { 1246 struct list_head *gpos;
1205 switch (head->read_step) { 1247 struct list_head *mpos;
1206 case 0: 1248 const char *w[3] = { "", "", "" };
1207 head->read_var2 = NULL; 1249 w[0] = tomoyo_group_name[idx];
1208 head->read_step = 1; 1250 list_for_each_cookie(gpos, head->read_var1, &tomoyo_group_list[idx]) {
1209 case 1: 1251 struct tomoyo_group *group =
1210 if (!tomoyo_read_domain_keeper_policy(head)) 1252 list_entry(gpos, struct tomoyo_group, list);
1211 break; 1253 w[1] = group->group_name->name;
1212 head->read_var2 = NULL; 1254 list_for_each_cookie(mpos, head->read_var2,
1213 head->read_step = 2; 1255 &group->member_list) {
1214 case 2: 1256 char buffer[128];
1215 if (!tomoyo_read_globally_readable_policy(head)) 1257 struct tomoyo_acl_head *ptr =
1216 break; 1258 list_entry(mpos, struct tomoyo_acl_head, list);
1217 head->read_var2 = NULL; 1259 if (ptr->is_deleted)
1218 head->read_step = 3; 1260 continue;
1219 case 3: 1261 if (idx == TOMOYO_PATH_GROUP) {
1220 head->read_var2 = NULL; 1262 w[2] = container_of(ptr,
1221 head->read_step = 4; 1263 struct tomoyo_path_group,
1222 case 4: 1264 head)->member_name->name;
1223 if (!tomoyo_read_domain_initializer_policy(head)) 1265 } else if (idx == TOMOYO_NUMBER_GROUP) {
1224 break; 1266 tomoyo_print_number(buffer, sizeof(buffer),
1225 head->read_var2 = NULL; 1267 &container_of
1226 head->read_step = 5; 1268 (ptr, struct
1227 case 5: 1269 tomoyo_number_group,
1228 if (!tomoyo_read_alias_policy(head)) 1270 head)->number);
1229 break; 1271 w[2] = buffer;
1230 head->read_var2 = NULL; 1272 }
1231 head->read_step = 6; 1273 if (!tomoyo_io_printf(head, "%s%s %s\n", w[0], w[1],
1232 case 6: 1274 w[2]))
1233 if (!tomoyo_read_aggregator_policy(head)) 1275 return false;
1234 break; 1276 }
1235 head->read_var2 = NULL; 1277 }
1236 head->read_step = 7; 1278 return true;
1237 case 7: 1279}
1238 if (!tomoyo_read_file_pattern(head)) 1280
1239 break; 1281/**
1240 head->read_var2 = NULL; 1282 * tomoyo_read_policy - Read "struct tomoyo_..._entry" list.
1241 head->read_step = 8; 1283 *
1242 case 8: 1284 * @head: Pointer to "struct tomoyo_io_buffer".
1243 if (!tomoyo_read_no_rewrite_policy(head)) 1285 * @idx: Index number.
1244 break; 1286 *
1245 head->read_var2 = NULL; 1287 * Returns true on success, false otherwise.
1246 head->read_step = 9; 1288 *
1247 case 9: 1289 * Caller holds tomoyo_read_lock().
1248 if (!tomoyo_read_path_group_policy(head)) 1290 */
1249 break; 1291static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1250 head->read_var1 = NULL; 1292{
1251 head->read_var2 = NULL; 1293 struct list_head *pos;
1252 head->read_step = 10; 1294 list_for_each_cookie(pos, head->read_var2, &tomoyo_policy_list[idx]) {
1253 case 10: 1295 const char *w[4] = { "", "", "", "" };
1254 if (!tomoyo_read_number_group_policy(head)) 1296 struct tomoyo_acl_head *acl = container_of(pos, typeof(*acl),
1255 break; 1297 list);
1256 head->read_var1 = NULL; 1298 if (acl->is_deleted)
1257 head->read_var2 = NULL; 1299 continue;
1258 head->read_step = 11; 1300 switch (idx) {
1259 case 11: 1301 case TOMOYO_ID_DOMAIN_KEEPER:
1260 head->read_eof = true; 1302 {
1303 struct tomoyo_domain_keeper_entry *ptr =
1304 container_of(acl, typeof(*ptr), head);
1305 w[0] = ptr->is_not ?
1306 TOMOYO_KEYWORD_NO_KEEP_DOMAIN :
1307 TOMOYO_KEYWORD_KEEP_DOMAIN;
1308 if (ptr->program) {
1309 w[1] = ptr->program->name;
1310 w[2] = " from ";
1311 }
1312 w[3] = ptr->domainname->name;
1313 }
1314 break;
1315 case TOMOYO_ID_DOMAIN_INITIALIZER:
1316 {
1317 struct tomoyo_domain_initializer_entry *ptr =
1318 container_of(acl, typeof(*ptr), head);
1319 w[0] = ptr->is_not ?
1320 TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN :
1321 TOMOYO_KEYWORD_INITIALIZE_DOMAIN;
1322 w[1] = ptr->program->name;
1323 if (ptr->domainname) {
1324 w[2] = " from ";
1325 w[3] = ptr->domainname->name;
1326 }
1327 }
1261 break; 1328 break;
1329 case TOMOYO_ID_GLOBALLY_READABLE:
1330 {
1331 struct tomoyo_globally_readable_file_entry *ptr
1332 = container_of(acl, typeof(*ptr), head);
1333 w[0] = TOMOYO_KEYWORD_ALLOW_READ;
1334 w[1] = ptr->filename->name;
1335 }
1336 break;
1337 case TOMOYO_ID_ALIAS:
1338 {
1339 struct tomoyo_alias_entry *ptr =
1340 container_of(acl, typeof(*ptr), head);
1341 w[0] = TOMOYO_KEYWORD_ALIAS;
1342 w[1] = ptr->original_name->name;
1343 w[2] = " ";
1344 w[3] = ptr->aliased_name->name;
1345 }
1346 break;
1347 case TOMOYO_ID_AGGREGATOR:
1348 {
1349 struct tomoyo_aggregator_entry *ptr =
1350 container_of(acl, typeof(*ptr), head);
1351 w[0] = TOMOYO_KEYWORD_AGGREGATOR;
1352 w[1] = ptr->original_name->name;
1353 w[2] = " ";
1354 w[3] = ptr->aggregated_name->name;
1355 }
1356 break;
1357 case TOMOYO_ID_PATTERN:
1358 {
1359 struct tomoyo_pattern_entry *ptr =
1360 container_of(acl, typeof(*ptr), head);
1361 w[0] = TOMOYO_KEYWORD_FILE_PATTERN;
1362 w[1] = ptr->pattern->name;
1363 }
1364 break;
1365 case TOMOYO_ID_NO_REWRITE:
1366 {
1367 struct tomoyo_no_rewrite_entry *ptr =
1368 container_of(acl, typeof(*ptr), head);
1369 w[0] = TOMOYO_KEYWORD_DENY_REWRITE;
1370 w[1] = ptr->pattern->name;
1371 }
1372 break;
1373 default:
1374 continue;
1262 } 1375 }
1376 if (!tomoyo_io_printf(head, "%s%s%s%s\n", w[0], w[1], w[2],
1377 w[3]))
1378 return false;
1263 } 1379 }
1380 return true;
1381}
1382
1383/**
1384 * tomoyo_read_exception_policy - Read exception policy.
1385 *
1386 * @head: Pointer to "struct tomoyo_io_buffer".
1387 *
1388 * Caller holds tomoyo_read_lock().
1389 */
1390static void tomoyo_read_exception_policy(struct tomoyo_io_buffer *head)
1391{
1392 if (head->read_eof)
1393 return;
1394 while (head->read_step < TOMOYO_MAX_POLICY &&
1395 tomoyo_read_policy(head, head->read_step))
1396 head->read_step++;
1397 if (head->read_step < TOMOYO_MAX_POLICY)
1398 return;
1399 while (head->read_step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP &&
1400 tomoyo_read_group(head, head->read_step - TOMOYO_MAX_POLICY))
1401 head->read_step++;
1402 if (head->read_step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP)
1403 return;
1404 head->read_eof = true;
1264} 1405}
1265 1406
1266/** 1407/**