^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * security/tomoyo/condition.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2005-2011 NTT DATA CORPORATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) /* List of "struct tomoyo_condition". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) LIST_HEAD(tomoyo_condition_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * tomoyo_argv - Check argv[] in "struct linux_binbrm".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * @index: Index number of @arg_ptr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * @arg_ptr: Contents of argv[@index].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * @argc: Length of @argv.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * @argv: Pointer to "struct tomoyo_argv".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * @checked: Set to true if @argv[@index] was found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Returns true on success, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static bool tomoyo_argv(const unsigned int index, const char *arg_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) const int argc, const struct tomoyo_argv *argv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) u8 *checked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct tomoyo_path_info arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) arg.name = arg_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) for (i = 0; i < argc; argv++, checked++, i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) bool result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (index != argv->index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) *checked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) tomoyo_fill_path_info(&arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) result = tomoyo_path_matches_pattern(&arg, argv->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (argv->is_not)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) result = !result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (!result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * tomoyo_envp - Check envp[] in "struct linux_binbrm".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * @env_name: The name of environment variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * @env_value: The value of environment variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * @envc: Length of @envp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * @envp: Pointer to "struct tomoyo_envp".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * @checked: Set to true if @envp[@env_name] was found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * Returns true on success, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static bool tomoyo_envp(const char *env_name, const char *env_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) const int envc, const struct tomoyo_envp *envp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u8 *checked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct tomoyo_path_info name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct tomoyo_path_info value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) name.name = env_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) tomoyo_fill_path_info(&name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) value.name = env_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) tomoyo_fill_path_info(&value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) for (i = 0; i < envc; envp++, checked++, i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) bool result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (!tomoyo_path_matches_pattern(&name, envp->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) *checked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (envp->value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) result = tomoyo_path_matches_pattern(&value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) envp->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (envp->is_not)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) result = !result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) result = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (!envp->is_not)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) result = !result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (!result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * tomoyo_scan_bprm - Scan "struct linux_binprm".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * @ee: Pointer to "struct tomoyo_execve".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * @argc: Length of @argc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * @argv: Pointer to "struct tomoyo_argv".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @envc: Length of @envp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @envp: Poiner to "struct tomoyo_envp".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * Returns true on success, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static bool tomoyo_scan_bprm(struct tomoyo_execve *ee,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) const u16 argc, const struct tomoyo_argv *argv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) const u16 envc, const struct tomoyo_envp *envp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct linux_binprm *bprm = ee->bprm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct tomoyo_page_dump *dump = &ee->dump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) char *arg_ptr = ee->tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int arg_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) unsigned long pos = bprm->p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int offset = pos % PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int argv_count = bprm->argc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int envp_count = bprm->envc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) bool result = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u8 local_checked[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u8 *checked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (argc + envc <= sizeof(local_checked)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) checked = local_checked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) memset(local_checked, 0, sizeof(local_checked));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) checked = kzalloc(argc + envc, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (!checked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) while (argv_count || envp_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (!tomoyo_dump_page(bprm, pos, dump)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) result = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) pos += PAGE_SIZE - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) while (offset < PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* Read. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) const char *kaddr = dump->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) const unsigned char c = kaddr[offset++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (c && arg_len < TOMOYO_EXEC_TMPSIZE - 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (c == '\\') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) arg_ptr[arg_len++] = '\\';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) arg_ptr[arg_len++] = '\\';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) } else if (c > ' ' && c < 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) arg_ptr[arg_len++] = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) arg_ptr[arg_len++] = '\\';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) arg_ptr[arg_len++] = (c >> 6) + '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) arg_ptr[arg_len++] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) ((c >> 3) & 7) + '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) arg_ptr[arg_len++] = (c & 7) + '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) arg_ptr[arg_len] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* Check. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (argv_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (!tomoyo_argv(bprm->argc - argv_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) arg_ptr, argc, argv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) checked)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) result = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) argv_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) } else if (envp_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) char *cp = strchr(arg_ptr, '=');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (cp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) *cp = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (!tomoyo_envp(arg_ptr, cp + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) envc, envp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) checked + argc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) result = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) envp_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) arg_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (!result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* Check not-yet-checked entries. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) for (i = 0; i < argc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (checked[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * Return true only if all unchecked indexes in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * bprm->argv[] are not matched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (argv[i].is_not)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) result = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) for (i = 0; i < envc; envp++, i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (checked[argc + i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * Return true only if all unchecked environ variables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * in bprm->envp[] are either undefined or not matched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if ((!envp->value && !envp->is_not) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) (envp->value && envp->is_not))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) result = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (checked != local_checked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) kfree(checked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * tomoyo_scan_exec_realpath - Check "exec.realpath" parameter of "struct tomoyo_condition".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * @file: Pointer to "struct file".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * @ptr: Pointer to "struct tomoyo_name_union".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * @match: True if "exec.realpath=", false if "exec.realpath!=".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * Returns true on success, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static bool tomoyo_scan_exec_realpath(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) const struct tomoyo_name_union *ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) const bool match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) bool result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct tomoyo_path_info exe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (!file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) exe.name = tomoyo_realpath_from_path(&file->f_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (!exe.name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) tomoyo_fill_path_info(&exe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) result = tomoyo_compare_name_union(&exe, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) kfree(exe.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return result == match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * tomoyo_get_dqword - tomoyo_get_name() for a quoted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * @start: String to save.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static const struct tomoyo_path_info *tomoyo_get_dqword(char *start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) char *cp = start + strlen(start) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (cp == start || *start++ != '"' || *cp != '"')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) *cp = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (*start && !tomoyo_correct_word(start))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return tomoyo_get_name(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * tomoyo_parse_name_union_quoted - Parse a quoted word.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * @param: Pointer to "struct tomoyo_acl_param".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * @ptr: Pointer to "struct tomoyo_name_union".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * Returns true on success, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static bool tomoyo_parse_name_union_quoted(struct tomoyo_acl_param *param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct tomoyo_name_union *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) char *filename = param->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (*filename == '@')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return tomoyo_parse_name_union(param, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) ptr->filename = tomoyo_get_dqword(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return ptr->filename != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * tomoyo_parse_argv - Parse an argv[] condition part.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * @left: Lefthand value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * @right: Righthand value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * @argv: Pointer to "struct tomoyo_argv".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * Returns true on success, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static bool tomoyo_parse_argv(char *left, char *right,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct tomoyo_argv *argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (tomoyo_parse_ulong(&argv->index, &left) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) TOMOYO_VALUE_TYPE_DECIMAL || *left++ != ']' || *left)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) argv->value = tomoyo_get_dqword(right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return argv->value != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * tomoyo_parse_envp - Parse an envp[] condition part.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * @left: Lefthand value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * @right: Righthand value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * @envp: Pointer to "struct tomoyo_envp".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * Returns true on success, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static bool tomoyo_parse_envp(char *left, char *right,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct tomoyo_envp *envp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) const struct tomoyo_path_info *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) const struct tomoyo_path_info *value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) char *cp = left + strlen(left) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (*cp-- != ']' || *cp != '"')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) *cp = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (!tomoyo_correct_word(left))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) name = tomoyo_get_name(left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (!strcmp(right, "NULL")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) value = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) value = tomoyo_get_dqword(right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (!value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) tomoyo_put_name(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) envp->name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) envp->value = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * tomoyo_same_condition - Check for duplicated "struct tomoyo_condition" entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * @a: Pointer to "struct tomoyo_condition".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * @b: Pointer to "struct tomoyo_condition".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * Returns true if @a == @b, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static inline bool tomoyo_same_condition(const struct tomoyo_condition *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) const struct tomoyo_condition *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return a->size == b->size && a->condc == b->condc &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) a->numbers_count == b->numbers_count &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) a->names_count == b->names_count &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) a->argc == b->argc && a->envc == b->envc &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) a->grant_log == b->grant_log && a->transit == b->transit &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) !memcmp(a + 1, b + 1, a->size - sizeof(*a));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * tomoyo_condition_type - Get condition type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * @word: Keyword string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * Returns one of values in "enum tomoyo_conditions_index" on success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * TOMOYO_MAX_CONDITION_KEYWORD otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static u8 tomoyo_condition_type(const char *word)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) for (i = 0; i < TOMOYO_MAX_CONDITION_KEYWORD; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (!strcmp(word, tomoyo_condition_keyword[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* Define this to enable debug mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* #define DEBUG_CONDITION */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) #ifdef DEBUG_CONDITION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) #define dprintk printk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) #define dprintk(...) do { } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * tomoyo_commit_condition - Commit "struct tomoyo_condition".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * @entry: Pointer to "struct tomoyo_condition".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * Returns pointer to "struct tomoyo_condition" on success, NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * This function merges duplicated entries. This function returns NULL if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * @entry is not duplicated but memory quota for policy has exceeded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static struct tomoyo_condition *tomoyo_commit_condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) (struct tomoyo_condition *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct tomoyo_condition *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (mutex_lock_interruptible(&tomoyo_policy_lock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) list_for_each_entry(ptr, &tomoyo_condition_list, head.list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (!tomoyo_same_condition(ptr, entry) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) atomic_read(&ptr->head.users) == TOMOYO_GC_IN_PROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* Same entry found. Share this entry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) atomic_inc(&ptr->head.users);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (tomoyo_memory_ok(entry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) atomic_set(&entry->head.users, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) list_add(&entry->head.list, &tomoyo_condition_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) mutex_unlock(&tomoyo_policy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) tomoyo_del_condition(&entry->head.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) kfree(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) entry = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * tomoyo_get_transit_preference - Parse domain transition preference for execve().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * @param: Pointer to "struct tomoyo_acl_param".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * @e: Pointer to "struct tomoyo_condition".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * Returns the condition string part.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static char *tomoyo_get_transit_preference(struct tomoyo_acl_param *param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) struct tomoyo_condition *e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) char * const pos = param->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) bool flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (*pos == '<') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) e->transit = tomoyo_get_domainname(param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) char *cp = strchr(pos, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) *cp = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) flag = tomoyo_correct_path(pos) || !strcmp(pos, "keep") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) !strcmp(pos, "initialize") || !strcmp(pos, "reset") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) !strcmp(pos, "child") || !strcmp(pos, "parent");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) *cp = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (!flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) e->transit = tomoyo_get_name(tomoyo_read_token(param));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (e->transit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return param->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * Return a bad read-only condition string that will let
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * tomoyo_get_condition() return NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return "/";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * tomoyo_get_condition - Parse condition part.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * @param: Pointer to "struct tomoyo_acl_param".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * Returns pointer to "struct tomoyo_condition" on success, NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) struct tomoyo_condition *tomoyo_get_condition(struct tomoyo_acl_param *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) struct tomoyo_condition *entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct tomoyo_condition_element *condp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct tomoyo_number_union *numbers_p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) struct tomoyo_name_union *names_p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct tomoyo_argv *argv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct tomoyo_envp *envp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct tomoyo_condition e = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) char * const start_of_string =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) tomoyo_get_transit_preference(param, &e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) char * const end_of_string = start_of_string + strlen(start_of_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) char *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) rerun:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) pos = start_of_string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) u8 left = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) u8 right = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) char *left_word = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) char *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) char *right_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) bool is_not;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (!*left_word)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * Since left-hand condition does not allow use of "path_group"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * or "number_group" and environment variable's names do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * accept '=', it is guaranteed that the original line consists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * of one or more repetition of $left$operator$right blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) * where "$left is free from '=' and ' '" and "$operator is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) * either '=' or '!='" and "$right is free from ' '".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * Therefore, we can reconstruct the original line at the end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * of dry run even if we overwrite $operator with '\0'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) cp = strchr(pos, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (cp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) *cp = '\0'; /* Will restore later. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) pos = cp + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) pos = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) right_word = strchr(left_word, '=');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (!right_word || right_word == left_word)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) is_not = *(right_word - 1) == '!';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if (is_not)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) *(right_word++ - 1) = '\0'; /* Will restore later. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) else if (*(right_word + 1) != '=')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) *right_word++ = '\0'; /* Will restore later. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) dprintk(KERN_WARNING "%u: <%s>%s=<%s>\n", __LINE__, left_word,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) is_not ? "!" : "", right_word);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (!strcmp(left_word, "grant_log")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (is_not ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) entry->grant_log != TOMOYO_GRANTLOG_AUTO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) else if (!strcmp(right_word, "yes"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) entry->grant_log = TOMOYO_GRANTLOG_YES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) else if (!strcmp(right_word, "no"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) entry->grant_log = TOMOYO_GRANTLOG_NO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (!strncmp(left_word, "exec.argv[", 10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (!argv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) e.argc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) e.condc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) e.argc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) e.condc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) left = TOMOYO_ARGV_ENTRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) argv->is_not = is_not;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (!tomoyo_parse_argv(left_word + 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) right_word, argv++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) goto store_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (!strncmp(left_word, "exec.envp[\"", 11)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (!envp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) e.envc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) e.condc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) e.envc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) e.condc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) left = TOMOYO_ENVP_ENTRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) envp->is_not = is_not;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (!tomoyo_parse_envp(left_word + 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) right_word, envp++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) goto store_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) left = tomoyo_condition_type(left_word);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) dprintk(KERN_WARNING "%u: <%s> left=%u\n", __LINE__, left_word,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (left == TOMOYO_MAX_CONDITION_KEYWORD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (!numbers_p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) e.numbers_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) e.numbers_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) left = TOMOYO_NUMBER_UNION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) param->data = left_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (*left_word == '@' ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) !tomoyo_parse_number_union(param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) numbers_p++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (!condp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) e.condc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) e.condc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (left == TOMOYO_EXEC_REALPATH ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) left == TOMOYO_SYMLINK_TARGET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (!names_p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) e.names_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) e.names_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) right = TOMOYO_NAME_UNION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) param->data = right_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (!tomoyo_parse_name_union_quoted(param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) names_p++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) goto store_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) right = tomoyo_condition_type(right_word);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (right == TOMOYO_MAX_CONDITION_KEYWORD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (!numbers_p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) e.numbers_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) e.numbers_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) right = TOMOYO_NUMBER_UNION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) param->data = right_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (!tomoyo_parse_number_union(param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) numbers_p++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) store_value:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (!condp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) dprintk(KERN_WARNING "%u: dry_run left=%u right=%u match=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) __LINE__, left, right, !is_not);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) condp->left = left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) condp->right = right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) condp->equals = !is_not;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) dprintk(KERN_WARNING "%u: left=%u right=%u match=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) __LINE__, condp->left, condp->right,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) condp->equals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) condp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) dprintk(KERN_INFO "%u: cond=%u numbers=%u names=%u ac=%u ec=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) __LINE__, e.condc, e.numbers_count, e.names_count, e.argc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) e.envc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) BUG_ON(e.names_count | e.numbers_count | e.argc | e.envc |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) e.condc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return tomoyo_commit_condition(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) e.size = sizeof(*entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) + e.condc * sizeof(struct tomoyo_condition_element)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) + e.numbers_count * sizeof(struct tomoyo_number_union)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) + e.names_count * sizeof(struct tomoyo_name_union)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) + e.argc * sizeof(struct tomoyo_argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) + e.envc * sizeof(struct tomoyo_envp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) entry = kzalloc(e.size, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (!entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) goto out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) *entry = e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) e.transit = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) condp = (struct tomoyo_condition_element *) (entry + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) numbers_p = (struct tomoyo_number_union *) (condp + e.condc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) names_p = (struct tomoyo_name_union *) (numbers_p + e.numbers_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) argv = (struct tomoyo_argv *) (names_p + e.names_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) envp = (struct tomoyo_envp *) (argv + e.argc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) bool flag = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) for (pos = start_of_string; pos < end_of_string; pos++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (*pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (flag) /* Restore " ". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) *pos = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) else if (*(pos + 1) == '=') /* Restore "!=". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) *pos = '!';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) else /* Restore "=". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) *pos = '=';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) flag = !flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) goto rerun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) tomoyo_del_condition(&entry->head.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) kfree(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) tomoyo_put_name(e.transit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) * tomoyo_get_attributes - Revalidate "struct inode".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * @obj: Pointer to "struct tomoyo_obj_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * Returns nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) void tomoyo_get_attributes(struct tomoyo_obj_info *obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) struct dentry *dentry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) for (i = 0; i < TOMOYO_MAX_PATH_STAT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) switch (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) case TOMOYO_PATH1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) dentry = obj->path1.dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (!dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) case TOMOYO_PATH2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) dentry = obj->path2.dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (!dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (!dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) dentry = dget_parent(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) inode = d_backing_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct tomoyo_mini_stat *stat = &obj->stat[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) stat->uid = inode->i_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) stat->gid = inode->i_gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) stat->ino = inode->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) stat->mode = inode->i_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) stat->dev = inode->i_sb->s_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) stat->rdev = inode->i_rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) obj->stat_valid[i] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (i & 1) /* TOMOYO_PATH1_PARENT or TOMOYO_PATH2_PARENT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) dput(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * tomoyo_condition - Check condition part.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) * @r: Pointer to "struct tomoyo_request_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * @cond: Pointer to "struct tomoyo_condition". Maybe NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) * Returns true on success, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * Caller holds tomoyo_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) bool tomoyo_condition(struct tomoyo_request_info *r,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) const struct tomoyo_condition *cond)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) unsigned long min_v[2] = { 0, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) unsigned long max_v[2] = { 0, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) const struct tomoyo_condition_element *condp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) const struct tomoyo_number_union *numbers_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) const struct tomoyo_name_union *names_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) const struct tomoyo_argv *argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) const struct tomoyo_envp *envp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) struct tomoyo_obj_info *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) u16 condc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) u16 argc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) u16 envc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) struct linux_binprm *bprm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (!cond)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) condc = cond->condc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) argc = cond->argc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) envc = cond->envc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) obj = r->obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (r->ee)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) bprm = r->ee->bprm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (!bprm && (argc || envc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) condp = (struct tomoyo_condition_element *) (cond + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) numbers_p = (const struct tomoyo_number_union *) (condp + condc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) names_p = (const struct tomoyo_name_union *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) (numbers_p + cond->numbers_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) argv = (const struct tomoyo_argv *) (names_p + cond->names_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) envp = (const struct tomoyo_envp *) (argv + argc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) for (i = 0; i < condc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) const bool match = condp->equals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) const u8 left = condp->left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) const u8 right = condp->right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) bool is_bitop[2] = { false, false };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) u8 j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) condp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) /* Check argv[] and envp[] later. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (left == TOMOYO_ARGV_ENTRY || left == TOMOYO_ENVP_ENTRY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /* Check string expressions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (right == TOMOYO_NAME_UNION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) const struct tomoyo_name_union *ptr = names_p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) struct tomoyo_path_info *symlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) struct tomoyo_execve *ee;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) struct file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) switch (left) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) case TOMOYO_SYMLINK_TARGET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) symlink = obj ? obj->symlink_target : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (!symlink ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) !tomoyo_compare_name_union(symlink, ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) == match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) case TOMOYO_EXEC_REALPATH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) ee = r->ee;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) file = ee ? ee->bprm->file : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (!tomoyo_scan_exec_realpath(file, ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) match))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) /* Check numeric or bit-op expressions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) for (j = 0; j < 2; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) const u8 index = j ? right : left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) unsigned long value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) switch (index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) case TOMOYO_TASK_UID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) value = from_kuid(&init_user_ns, current_uid());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) case TOMOYO_TASK_EUID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) value = from_kuid(&init_user_ns, current_euid());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) case TOMOYO_TASK_SUID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) value = from_kuid(&init_user_ns, current_suid());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) case TOMOYO_TASK_FSUID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) value = from_kuid(&init_user_ns, current_fsuid());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) case TOMOYO_TASK_GID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) value = from_kgid(&init_user_ns, current_gid());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) case TOMOYO_TASK_EGID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) value = from_kgid(&init_user_ns, current_egid());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) case TOMOYO_TASK_SGID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) value = from_kgid(&init_user_ns, current_sgid());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) case TOMOYO_TASK_FSGID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) value = from_kgid(&init_user_ns, current_fsgid());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) case TOMOYO_TASK_PID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) value = tomoyo_sys_getpid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) case TOMOYO_TASK_PPID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) value = tomoyo_sys_getppid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) case TOMOYO_TYPE_IS_SOCKET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) value = S_IFSOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) case TOMOYO_TYPE_IS_SYMLINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) value = S_IFLNK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) case TOMOYO_TYPE_IS_FILE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) value = S_IFREG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) case TOMOYO_TYPE_IS_BLOCK_DEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) value = S_IFBLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) case TOMOYO_TYPE_IS_DIRECTORY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) value = S_IFDIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) case TOMOYO_TYPE_IS_CHAR_DEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) value = S_IFCHR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) case TOMOYO_TYPE_IS_FIFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) value = S_IFIFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) case TOMOYO_MODE_SETUID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) value = S_ISUID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) case TOMOYO_MODE_SETGID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) value = S_ISGID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) case TOMOYO_MODE_STICKY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) value = S_ISVTX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) case TOMOYO_MODE_OWNER_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) value = 0400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) case TOMOYO_MODE_OWNER_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) value = 0200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) case TOMOYO_MODE_OWNER_EXECUTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) value = 0100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) case TOMOYO_MODE_GROUP_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) value = 0040;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) case TOMOYO_MODE_GROUP_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) value = 0020;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) case TOMOYO_MODE_GROUP_EXECUTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) value = 0010;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) case TOMOYO_MODE_OTHERS_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) value = 0004;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) case TOMOYO_MODE_OTHERS_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) value = 0002;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) case TOMOYO_MODE_OTHERS_EXECUTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) value = 0001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) case TOMOYO_EXEC_ARGC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (!bprm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) value = bprm->argc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) case TOMOYO_EXEC_ENVC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (!bprm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) value = bprm->envc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) case TOMOYO_NUMBER_UNION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) /* Fetch values later. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (!obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) if (!obj->validate_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) tomoyo_get_attributes(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) obj->validate_done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) u8 stat_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) struct tomoyo_mini_stat *stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) switch (index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) case TOMOYO_PATH1_UID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) case TOMOYO_PATH1_GID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) case TOMOYO_PATH1_INO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) case TOMOYO_PATH1_MAJOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) case TOMOYO_PATH1_MINOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) case TOMOYO_PATH1_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) case TOMOYO_PATH1_DEV_MAJOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) case TOMOYO_PATH1_DEV_MINOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) case TOMOYO_PATH1_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) stat_index = TOMOYO_PATH1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) case TOMOYO_PATH2_UID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) case TOMOYO_PATH2_GID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) case TOMOYO_PATH2_INO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) case TOMOYO_PATH2_MAJOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) case TOMOYO_PATH2_MINOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) case TOMOYO_PATH2_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) case TOMOYO_PATH2_DEV_MAJOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) case TOMOYO_PATH2_DEV_MINOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) case TOMOYO_PATH2_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) stat_index = TOMOYO_PATH2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) case TOMOYO_PATH1_PARENT_UID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) case TOMOYO_PATH1_PARENT_GID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) case TOMOYO_PATH1_PARENT_INO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) case TOMOYO_PATH1_PARENT_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) stat_index =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) TOMOYO_PATH1_PARENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) case TOMOYO_PATH2_PARENT_UID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) case TOMOYO_PATH2_PARENT_GID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) case TOMOYO_PATH2_PARENT_INO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) case TOMOYO_PATH2_PARENT_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) stat_index =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) TOMOYO_PATH2_PARENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (!obj->stat_valid[stat_index])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) stat = &obj->stat[stat_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) switch (index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) case TOMOYO_PATH1_UID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) case TOMOYO_PATH2_UID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) case TOMOYO_PATH1_PARENT_UID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) case TOMOYO_PATH2_PARENT_UID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) value = from_kuid(&init_user_ns, stat->uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) case TOMOYO_PATH1_GID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) case TOMOYO_PATH2_GID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) case TOMOYO_PATH1_PARENT_GID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) case TOMOYO_PATH2_PARENT_GID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) value = from_kgid(&init_user_ns, stat->gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) case TOMOYO_PATH1_INO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) case TOMOYO_PATH2_INO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) case TOMOYO_PATH1_PARENT_INO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) case TOMOYO_PATH2_PARENT_INO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) value = stat->ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) case TOMOYO_PATH1_MAJOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) case TOMOYO_PATH2_MAJOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) value = MAJOR(stat->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) case TOMOYO_PATH1_MINOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) case TOMOYO_PATH2_MINOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) value = MINOR(stat->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) case TOMOYO_PATH1_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) case TOMOYO_PATH2_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) value = stat->mode & S_IFMT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) case TOMOYO_PATH1_DEV_MAJOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) case TOMOYO_PATH2_DEV_MAJOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) value = MAJOR(stat->rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) case TOMOYO_PATH1_DEV_MINOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) case TOMOYO_PATH2_DEV_MINOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) value = MINOR(stat->rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) case TOMOYO_PATH1_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) case TOMOYO_PATH2_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) case TOMOYO_PATH1_PARENT_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) case TOMOYO_PATH2_PARENT_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) value = stat->mode & S_IALLUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) max_v[j] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) min_v[j] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) switch (index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) case TOMOYO_MODE_SETUID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) case TOMOYO_MODE_SETGID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) case TOMOYO_MODE_STICKY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) case TOMOYO_MODE_OWNER_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) case TOMOYO_MODE_OWNER_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) case TOMOYO_MODE_OWNER_EXECUTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) case TOMOYO_MODE_GROUP_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) case TOMOYO_MODE_GROUP_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) case TOMOYO_MODE_GROUP_EXECUTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) case TOMOYO_MODE_OTHERS_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) case TOMOYO_MODE_OTHERS_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) case TOMOYO_MODE_OTHERS_EXECUTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) is_bitop[j] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (left == TOMOYO_NUMBER_UNION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) /* Fetch values now. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) const struct tomoyo_number_union *ptr = numbers_p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) min_v[0] = ptr->values[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) max_v[0] = ptr->values[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) if (right == TOMOYO_NUMBER_UNION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) /* Fetch values now. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) const struct tomoyo_number_union *ptr = numbers_p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (ptr->group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (tomoyo_number_matches_group(min_v[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) max_v[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) ptr->group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) == match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) if ((min_v[0] <= ptr->values[1] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) max_v[0] >= ptr->values[0]) == match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) * Bit operation is valid only when counterpart value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) * represents permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (is_bitop[0] && is_bitop[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) } else if (is_bitop[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) switch (right) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) case TOMOYO_PATH1_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) case TOMOYO_PATH1_PARENT_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) case TOMOYO_PATH2_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) case TOMOYO_PATH2_PARENT_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (!(max_v[0] & max_v[1]) == !match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) } else if (is_bitop[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) switch (left) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) case TOMOYO_PATH1_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) case TOMOYO_PATH1_PARENT_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) case TOMOYO_PATH2_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) case TOMOYO_PATH2_PARENT_PERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (!(max_v[0] & max_v[1]) == !match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /* Normal value range comparison. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if ((min_v[0] <= max_v[1] && max_v[0] >= min_v[1]) == match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) /* Check argv[] and envp[] now. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (r->ee && (argc || envc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) return tomoyo_scan_bprm(r->ee, argc, argv, envc, envp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }