summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/tomoyo/common.c195
1 files changed, 121 insertions, 74 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 7cb6c0459d9..30e4b08905e 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -302,6 +302,124 @@ struct tomoyo_profile *tomoyo_profile(const u8 profile)
return ptr;
}
+static s8 tomoyo_find_yesno(const char *string, const char *find)
+{
+ const char *cp = strstr(string, find);
+ if (cp) {
+ cp += strlen(find);
+ if (!strncmp(cp, "=yes", 4))
+ return 1;
+ else if (!strncmp(cp, "=no", 3))
+ return 0;
+ }
+ return -1;
+}
+
+static void tomoyo_set_bool(bool *b, const char *string, const char *find)
+{
+ switch (tomoyo_find_yesno(string, find)) {
+ case 1:
+ *b = true;
+ break;
+ case 0:
+ *b = false;
+ break;
+ }
+}
+
+static void tomoyo_set_uint(unsigned int *i, const char *string,
+ const char *find)
+{
+ const char *cp = strstr(string, find);
+ if (cp)
+ sscanf(cp + strlen(find), "=%u", i);
+}
+
+static void tomoyo_set_pref(const char *name, const char *value,
+ const bool use_default,
+ struct tomoyo_profile *profile)
+{
+ struct tomoyo_preference **pref;
+ bool *verbose;
+ if (!strcmp(name, "enforcing")) {
+ if (use_default) {
+ pref = &profile->enforcing;
+ goto set_default;
+ }
+ profile->enforcing = &profile->preference;
+ verbose = &profile->preference.enforcing_verbose;
+ goto set_verbose;
+ }
+ if (!strcmp(name, "permissive")) {
+ if (use_default) {
+ pref = &profile->permissive;
+ goto set_default;
+ }
+ profile->permissive = &profile->preference;
+ verbose = &profile->preference.permissive_verbose;
+ goto set_verbose;
+ }
+ if (!strcmp(name, "learning")) {
+ if (use_default) {
+ pref = &profile->learning;
+ goto set_default;
+ }
+ profile->learning = &profile->preference;
+ tomoyo_set_uint(&profile->preference.learning_max_entry, value,
+ "max_entry");
+ verbose = &profile->preference.learning_verbose;
+ goto set_verbose;
+ }
+ return;
+ set_default:
+ *pref = &tomoyo_default_profile.preference;
+ return;
+ set_verbose:
+ tomoyo_set_bool(verbose, value, "verbose");
+}
+
+static int tomoyo_set_mode(char *name, const char *value,
+ const bool use_default,
+ struct tomoyo_profile *profile)
+{
+ u8 i;
+ u8 config;
+ if (!strcmp(name, "CONFIG")) {
+ i = TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX;
+ config = profile->default_config;
+ } else if (tomoyo_str_starts(&name, "CONFIG::")) {
+ config = 0;
+ for (i = 0; i < TOMOYO_MAX_MAC_INDEX
+ + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) {
+ if (strcmp(name, tomoyo_mac_keywords[i]))
+ continue;
+ config = profile->config[i];
+ break;
+ }
+ if (i == TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX)
+ return -EINVAL;
+ } else {
+ return -EINVAL;
+ }
+ if (use_default) {
+ config = TOMOYO_CONFIG_USE_DEFAULT;
+ } else {
+ u8 mode;
+ for (mode = 0; mode < 4; mode++)
+ if (strstr(value, tomoyo_mode[mode]))
+ /*
+ * Update lower 3 bits in order to distinguish
+ * 'config' from 'TOMOYO_CONFIG_USE_DEAFULT'.
+ */
+ config = (config & ~7) | mode;
+ }
+ if (i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX)
+ profile->config[i] = config;
+ else if (config != TOMOYO_CONFIG_USE_DEFAULT)
+ profile->default_config = config;
+ return 0;
+}
+
/**
* tomoyo_write_profile - Write profile table.
*
@@ -313,9 +431,6 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
{
char *data = head->write_buf;
unsigned int i;
- int value;
- int mode;
- u8 config;
bool use_default = false;
char *cp;
struct tomoyo_profile *profile;
@@ -338,45 +453,8 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
*cp++ = '\0';
if (profile != &tomoyo_default_profile)
use_default = strstr(cp, "use_default") != NULL;
- if (strstr(cp, "verbose=yes"))
- value = 1;
- else if (strstr(cp, "verbose=no"))
- value = 0;
- else
- value = -1;
- if (!strcmp(data, "PREFERENCE::enforcing")) {
- if (use_default) {
- profile->enforcing = &tomoyo_default_profile.preference;
- return 0;
- }
- profile->enforcing = &profile->preference;
- if (value >= 0)
- profile->preference.enforcing_verbose = value;
- return 0;
- }
- if (!strcmp(data, "PREFERENCE::permissive")) {
- if (use_default) {
- profile->permissive = &tomoyo_default_profile.preference;
- return 0;
- }
- profile->permissive = &profile->preference;
- if (value >= 0)
- profile->preference.permissive_verbose = value;
- return 0;
- }
- if (!strcmp(data, "PREFERENCE::learning")) {
- char *cp2;
- if (use_default) {
- profile->learning = &tomoyo_default_profile.preference;
- return 0;
- }
- profile->learning = &profile->preference;
- if (value >= 0)
- profile->preference.learning_verbose = value;
- cp2 = strstr(cp, "max_entry=");
- if (cp2)
- sscanf(cp2 + 10, "%u",
- &profile->preference.learning_max_entry);
+ if (tomoyo_str_starts(&data, "PREFERENCE::")) {
+ tomoyo_set_pref(data, cp, use_default, profile);
return 0;
}
if (profile == &tomoyo_default_profile)
@@ -387,38 +465,7 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
tomoyo_put_name(old_comment);
return 0;
}
- if (!strcmp(data, "CONFIG")) {
- i = TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX;
- config = profile->default_config;
- } else if (tomoyo_str_starts(&data, "CONFIG::")) {
- config = 0;
- for (i = 0; i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) {
- if (strcmp(data, tomoyo_mac_keywords[i]))
- continue;
- config = profile->config[i];
- break;
- }
- if (i == TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX)
- return -EINVAL;
- } else {
- return -EINVAL;
- }
- if (use_default) {
- config = TOMOYO_CONFIG_USE_DEFAULT;
- } else {
- for (mode = 3; mode >= 0; mode--)
- if (strstr(cp, tomoyo_mode[mode]))
- /*
- * Update lower 3 bits in order to distinguish
- * 'config' from 'TOMOYO_CONFIG_USE_DEAFULT'.
- */
- config = (config & ~7) | mode;
- }
- if (i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX)
- profile->config[i] = config;
- else if (config != TOMOYO_CONFIG_USE_DEFAULT)
- profile->default_config = config;
- return 0;
+ return tomoyo_set_mode(data, cp, use_default, profile);
}
static void tomoyo_print_preference(struct tomoyo_io_buffer *head,