/* List of "struct tomoyo_condition". */
LIST_HEAD(tomoyo_condition_list);
/** * tomoyo_argv - Check argv[] in "struct linux_binbrm". * * @index: Index number of @arg_ptr. * @arg_ptr: Contents of argv[@index]. * @argc: Length of @argv. * @argv: Pointer to "struct tomoyo_argv". * @checked: Set to true if @argv[@index] was found. * * Returns true on success, false otherwise.
*/ staticbool tomoyo_argv(constunsignedint index, constchar *arg_ptr, constint argc, conststruct tomoyo_argv *argv,
u8 *checked)
{ int i; struct tomoyo_path_info arg;
arg.name = arg_ptr; for (i = 0; i < argc; argv++, checked++, i++) { bool result;
if (index != argv->index) continue;
*checked = 1;
tomoyo_fill_path_info(&arg);
result = tomoyo_path_matches_pattern(&arg, argv->value); if (argv->is_not)
result = !result; if (!result) returnfalse;
} returntrue;
}
/** * tomoyo_envp - Check envp[] in "struct linux_binbrm". * * @env_name: The name of environment variable. * @env_value: The value of environment variable. * @envc: Length of @envp. * @envp: Pointer to "struct tomoyo_envp". * @checked: Set to true if @envp[@env_name] was found. * * Returns true on success, false otherwise.
*/ staticbool tomoyo_envp(constchar *env_name, constchar *env_value, constint envc, conststruct tomoyo_envp *envp,
u8 *checked)
{ int i; struct tomoyo_path_info name; struct tomoyo_path_info value;
name.name = env_name;
tomoyo_fill_path_info(&name);
value.name = env_value;
tomoyo_fill_path_info(&value); for (i = 0; i < envc; envp++, checked++, i++) { bool result;
if (!tomoyo_path_matches_pattern(&name, envp->name)) continue;
*checked = 1; if (envp->value) {
result = tomoyo_path_matches_pattern(&value,
envp->value); if (envp->is_not)
result = !result;
} else {
result = true; if (!envp->is_not)
result = !result;
} if (!result) returnfalse;
} returntrue;
}
/** * tomoyo_scan_bprm - Scan "struct linux_binprm". * * @ee: Pointer to "struct tomoyo_execve". * @argc: Length of @argc. * @argv: Pointer to "struct tomoyo_argv". * @envc: Length of @envp. * @envp: Pointer to "struct tomoyo_envp". * * Returns true on success, false otherwise.
*/ staticbool tomoyo_scan_bprm(struct tomoyo_execve *ee, const u16 argc, conststruct tomoyo_argv *argv, const u16 envc, conststruct tomoyo_envp *envp)
{ struct linux_binprm *bprm = ee->bprm; struct tomoyo_page_dump *dump = &ee->dump; char *arg_ptr = ee->tmp; int arg_len = 0; unsignedlong pos = bprm->p; int offset = pos % PAGE_SIZE; int argv_count = bprm->argc; int envp_count = bprm->envc; bool result = true;
u8 local_checked[32];
u8 *checked;
if (argc + envc <= sizeof(local_checked)) {
checked = local_checked;
memset(local_checked, 0, sizeof(local_checked));
} else {
checked = kzalloc(argc + envc, GFP_NOFS); if (!checked) returnfalse;
} while (argv_count || envp_count) { if (!tomoyo_dump_page(bprm, pos, dump)) {
result = false; goto out;
}
pos += PAGE_SIZE - offset; while (offset < PAGE_SIZE) { /* Read. */ constchar *kaddr = dump->data; constunsignedchar c = kaddr[offset++];
if (cp) {
*cp = '\0'; if (!tomoyo_envp(arg_ptr, cp + 1,
envc, envp,
checked + argc)) {
result = false; break;
}
}
envp_count--;
} else { break;
}
arg_len = 0;
}
offset = 0; if (!result) break;
}
out: if (result) { int i;
/* Check not-yet-checked entries. */ for (i = 0; i < argc; i++) { if (checked[i]) continue; /* * Return true only if all unchecked indexes in * bprm->argv[] are not matched.
*/ if (argv[i].is_not) continue;
result = false; break;
} for (i = 0; i < envc; envp++, i++) { if (checked[argc + i]) continue; /* * Return true only if all unchecked environ variables * in bprm->envp[] are either undefined or not matched.
*/ if ((!envp->value && !envp->is_not) ||
(envp->value && envp->is_not)) continue;
result = false; break;
}
} if (checked != local_checked)
kfree(checked); return result;
}
/** * tomoyo_scan_exec_realpath - Check "exec.realpath" parameter of "struct tomoyo_condition". * * @file: Pointer to "struct file". * @ptr: Pointer to "struct tomoyo_name_union". * @match: True if "exec.realpath=", false if "exec.realpath!=". * * Returns true on success, false otherwise.
*/ staticbool tomoyo_scan_exec_realpath(struct file *file, conststruct tomoyo_name_union *ptr, constbool match)
{ bool result; struct tomoyo_path_info exe;
if (!file) returnfalse;
exe.name = tomoyo_realpath_from_path(&file->f_path); if (!exe.name) returnfalse;
tomoyo_fill_path_info(&exe);
result = tomoyo_compare_name_union(&exe, ptr);
kfree(exe.name); return result == match;
}
/** * tomoyo_get_dqword - tomoyo_get_name() for a quoted string. * * @start: String to save. * * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
*/ staticconststruct tomoyo_path_info *tomoyo_get_dqword(char *start)
{ char *cp = start + strlen(start) - 1;
/** * tomoyo_condition_type - Get condition type. * * @word: Keyword string. * * Returns one of values in "enum tomoyo_conditions_index" on success, * TOMOYO_MAX_CONDITION_KEYWORD otherwise.
*/ static u8 tomoyo_condition_type(constchar *word)
{
u8 i;
for (i = 0; i < TOMOYO_MAX_CONDITION_KEYWORD; i++) { if (!strcmp(word, tomoyo_condition_keyword[i])) break;
} return i;
}
/* Define this to enable debug mode. */ /* #define DEBUG_CONDITION */
#ifdef DEBUG_CONDITION #define dprintk printk #else #define dprintk(...) do { } while (0) #endif
/** * tomoyo_commit_condition - Commit "struct tomoyo_condition". * * @entry: Pointer to "struct tomoyo_condition". * * Returns pointer to "struct tomoyo_condition" on success, NULL otherwise. * * This function merges duplicated entries. This function returns NULL if * @entry is not duplicated but memory quota for policy has exceeded.
*/ staticstruct tomoyo_condition *tomoyo_commit_condition
(struct tomoyo_condition *entry)
{ struct tomoyo_condition *ptr; bool found = false;
if (mutex_lock_interruptible(&tomoyo_policy_lock)) {
dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
ptr = NULL;
found = true; goto out;
}
list_for_each_entry(ptr, &tomoyo_condition_list, head.list) { if (!tomoyo_same_condition(ptr, entry) ||
atomic_read(&ptr->head.users) == TOMOYO_GC_IN_PROGRESS) continue; /* Same entry found. Share this entry. */
atomic_inc(&ptr->head.users);
found = true; break;
} if (!found) { if (tomoyo_memory_ok(entry)) {
atomic_set(&entry->head.users, 1);
list_add(&entry->head.list, &tomoyo_condition_list);
} else {
found = true;
ptr = NULL;
}
}
mutex_unlock(&tomoyo_policy_lock);
out: if (found) {
tomoyo_del_condition(&entry->head.list);
kfree(entry);
entry = ptr;
} return entry;
}
switch (left) { case TOMOYO_SYMLINK_TARGET:
symlink = obj ? obj->symlink_target : NULL; if (!symlink ||
!tomoyo_compare_name_union(symlink, ptr)
== match) goto out; break; case TOMOYO_EXEC_REALPATH:
ee = r->ee;
file = ee ? ee->bprm->file : NULL; if (!tomoyo_scan_exec_realpath(file, ptr,
match)) goto out; break;
} continue;
} /* Check numeric or bit-op expressions. */ for (j = 0; j < 2; j++) { const u8 index = j ? right : left; unsignedlong value = 0;
switch (index) { case TOMOYO_TASK_UID:
value = from_kuid(&init_user_ns, current_uid()); break; case TOMOYO_TASK_EUID:
value = from_kuid(&init_user_ns, current_euid()); break; case TOMOYO_TASK_SUID:
value = from_kuid(&init_user_ns, current_suid()); break; case TOMOYO_TASK_FSUID:
value = from_kuid(&init_user_ns, current_fsuid()); break; case TOMOYO_TASK_GID:
value = from_kgid(&init_user_ns, current_gid()); break; case TOMOYO_TASK_EGID:
value = from_kgid(&init_user_ns, current_egid()); break; case TOMOYO_TASK_SGID:
value = from_kgid(&init_user_ns, current_sgid()); break; case TOMOYO_TASK_FSGID:
value = from_kgid(&init_user_ns, current_fsgid()); break; case TOMOYO_TASK_PID:
value = tomoyo_sys_getpid(); break; case TOMOYO_TASK_PPID:
value = tomoyo_sys_getppid(); break; case TOMOYO_TYPE_IS_SOCKET:
value = S_IFSOCK; break; case TOMOYO_TYPE_IS_SYMLINK:
value = S_IFLNK; break; case TOMOYO_TYPE_IS_FILE:
value = S_IFREG; break; case TOMOYO_TYPE_IS_BLOCK_DEV:
value = S_IFBLK; break; case TOMOYO_TYPE_IS_DIRECTORY:
value = S_IFDIR; break; case TOMOYO_TYPE_IS_CHAR_DEV:
value = S_IFCHR; break; case TOMOYO_TYPE_IS_FIFO:
value = S_IFIFO; break; case TOMOYO_MODE_SETUID:
value = S_ISUID; break; case TOMOYO_MODE_SETGID:
value = S_ISGID; break; case TOMOYO_MODE_STICKY:
value = S_ISVTX; break; case TOMOYO_MODE_OWNER_READ:
value = 0400; break; case TOMOYO_MODE_OWNER_WRITE:
value = 0200; break; case TOMOYO_MODE_OWNER_EXECUTE:
value = 0100; break; case TOMOYO_MODE_GROUP_READ:
value = 0040; break; case TOMOYO_MODE_GROUP_WRITE:
value = 0020; break; case TOMOYO_MODE_GROUP_EXECUTE:
value = 0010; break; case TOMOYO_MODE_OTHERS_READ:
value = 0004; break; case TOMOYO_MODE_OTHERS_WRITE:
value = 0002; break; case TOMOYO_MODE_OTHERS_EXECUTE:
value = 0001; break; case TOMOYO_EXEC_ARGC: if (!bprm) goto out;
value = bprm->argc; break; case TOMOYO_EXEC_ENVC: if (!bprm) goto out;
value = bprm->envc; break; case TOMOYO_NUMBER_UNION: /* Fetch values later. */ break; default: if (!obj) goto out; if (!obj->validate_done) {
tomoyo_get_attributes(obj);
obj->validate_done = true;
}
{
u8 stat_index; struct tomoyo_mini_stat *stat;
switch (index) { case TOMOYO_PATH1_UID: case TOMOYO_PATH1_GID: case TOMOYO_PATH1_INO: case TOMOYO_PATH1_MAJOR: case TOMOYO_PATH1_MINOR: case TOMOYO_PATH1_TYPE: case TOMOYO_PATH1_DEV_MAJOR: case TOMOYO_PATH1_DEV_MINOR: case TOMOYO_PATH1_PERM:
stat_index = TOMOYO_PATH1; break; case TOMOYO_PATH2_UID: case TOMOYO_PATH2_GID: case TOMOYO_PATH2_INO: case TOMOYO_PATH2_MAJOR: case TOMOYO_PATH2_MINOR: case TOMOYO_PATH2_TYPE: case TOMOYO_PATH2_DEV_MAJOR: case TOMOYO_PATH2_DEV_MINOR: case TOMOYO_PATH2_PERM:
stat_index = TOMOYO_PATH2; break; case TOMOYO_PATH1_PARENT_UID: case TOMOYO_PATH1_PARENT_GID: case TOMOYO_PATH1_PARENT_INO: case TOMOYO_PATH1_PARENT_PERM:
stat_index =
TOMOYO_PATH1_PARENT; break; case TOMOYO_PATH2_PARENT_UID: case TOMOYO_PATH2_PARENT_GID: case TOMOYO_PATH2_PARENT_INO: case TOMOYO_PATH2_PARENT_PERM:
stat_index =
TOMOYO_PATH2_PARENT; break; default: goto out;
} if (!obj->stat_valid[stat_index]) goto out;
stat = &obj->stat[stat_index]; switch (index) { case TOMOYO_PATH1_UID: case TOMOYO_PATH2_UID: case TOMOYO_PATH1_PARENT_UID: case TOMOYO_PATH2_PARENT_UID:
value = from_kuid(&init_user_ns, stat->uid); break; case TOMOYO_PATH1_GID: case TOMOYO_PATH2_GID: case TOMOYO_PATH1_PARENT_GID: case TOMOYO_PATH2_PARENT_GID:
value = from_kgid(&init_user_ns, stat->gid); break; case TOMOYO_PATH1_INO: case TOMOYO_PATH2_INO: case TOMOYO_PATH1_PARENT_INO: case TOMOYO_PATH2_PARENT_INO:
value = stat->ino; break; case TOMOYO_PATH1_MAJOR: case TOMOYO_PATH2_MAJOR:
value = MAJOR(stat->dev); break; case TOMOYO_PATH1_MINOR: case TOMOYO_PATH2_MINOR:
value = MINOR(stat->dev); break; case TOMOYO_PATH1_TYPE: case TOMOYO_PATH2_TYPE:
value = stat->mode & S_IFMT; break; case TOMOYO_PATH1_DEV_MAJOR: case TOMOYO_PATH2_DEV_MAJOR:
value = MAJOR(stat->rdev); break; case TOMOYO_PATH1_DEV_MINOR: case TOMOYO_PATH2_DEV_MINOR:
value = MINOR(stat->rdev); break; case TOMOYO_PATH1_PERM: case TOMOYO_PATH2_PERM: case TOMOYO_PATH1_PARENT_PERM: case TOMOYO_PATH2_PARENT_PERM:
value = stat->mode & S_IALLUGO; break;
}
} break;
}
max_v[j] = value;
min_v[j] = value; switch (index) { case TOMOYO_MODE_SETUID: case TOMOYO_MODE_SETGID: case TOMOYO_MODE_STICKY: case TOMOYO_MODE_OWNER_READ: case TOMOYO_MODE_OWNER_WRITE: case TOMOYO_MODE_OWNER_EXECUTE: case TOMOYO_MODE_GROUP_READ: case TOMOYO_MODE_GROUP_WRITE: case TOMOYO_MODE_GROUP_EXECUTE: case TOMOYO_MODE_OTHERS_READ: case TOMOYO_MODE_OTHERS_WRITE: case TOMOYO_MODE_OTHERS_EXECUTE:
is_bitop[j] = true;
}
} if (left == TOMOYO_NUMBER_UNION) { /* Fetch values now. */ conststruct tomoyo_number_union *ptr = numbers_p++;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.