summaryrefslogtreecommitdiff
path: root/security/tomoyo/common.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2011-06-26 23:18:21 +0900
committerJames Morris <jmorris@namei.org>2011-06-29 09:31:20 +1000
commitd5ca1725ac9ba876c2dd614bb9826d0c4e13d818 (patch)
treefbff7fe1e39597c5bac981f63a2be659f4ec84e7 /security/tomoyo/common.c
parent0d2171d711cbfca84cc0001121be8a6cc8e4d148 (diff)
downloadlwn-d5ca1725ac9ba876c2dd614bb9826d0c4e13d818.tar.gz
lwn-d5ca1725ac9ba876c2dd614bb9826d0c4e13d818.zip
TOMOYO: Simplify profile structure.
Remove global preference from profile structure in order to make code simpler. Due to this structure change, printk() warnings upon policy violation are temporarily disabled. They will be replaced by /sys/kernel/security/tomoyo/audit by next patch. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r--security/tomoyo/common.c205
1 files changed, 69 insertions, 136 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 465df022c211..2b280350708f 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -11,16 +11,6 @@
#include <linux/security.h>
#include "common.h"
-static struct tomoyo_profile tomoyo_default_profile = {
- .learning = &tomoyo_default_profile.preference,
- .permissive = &tomoyo_default_profile.preference,
- .enforcing = &tomoyo_default_profile.preference,
- .preference.enforcing_verbose = true,
- .preference.learning_max_entry = 2048,
- .preference.learning_verbose = false,
- .preference.permissive_verbose = true
-};
-
/* Profile version. Currently only 20090903 is defined. */
static unsigned int tomoyo_profile_version;
@@ -61,6 +51,11 @@ static const char *tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
[TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file",
};
+/* String table for PREFERENCE keyword. */
+static const char * const tomoyo_pref_keywords[TOMOYO_MAX_PREF] = {
+ [TOMOYO_PREF_MAX_LEARNING_ENTRY] = "max_learning_entry",
+};
+
/* Permit policy management by non-root user? */
static bool tomoyo_manage_by_non_root;
@@ -71,11 +66,22 @@ static bool tomoyo_manage_by_non_root;
*
* @value: Bool value.
*/
+/*
static const char *tomoyo_yesno(const unsigned int value)
{
return value ? "yes" : "no";
}
+*/
+/**
+ * tomoyo_addprintf - strncat()-like-snprintf().
+ *
+ * @buffer: Buffer to write to. Must be '\0'-terminated.
+ * @len: Size of @buffer.
+ * @fmt: The printf()'s format string, followed by parameters.
+ *
+ * Returns nothing.
+ */
static void tomoyo_addprintf(char *buffer, int len, const char *fmt, ...)
{
va_list args;
@@ -294,12 +300,10 @@ static struct tomoyo_profile *tomoyo_assign_profile(const unsigned int profile)
ptr = tomoyo_profile_ptr[profile];
if (!ptr && tomoyo_memory_ok(entry)) {
ptr = entry;
- ptr->learning = &tomoyo_default_profile.preference;
- ptr->permissive = &tomoyo_default_profile.preference;
- ptr->enforcing = &tomoyo_default_profile.preference;
ptr->default_config = TOMOYO_CONFIG_DISABLED;
memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT,
sizeof(ptr->config));
+ ptr->pref[TOMOYO_PREF_MAX_LEARNING_ENTRY] = 2048;
mb(); /* Avoid out-of-order execution. */
tomoyo_profile_ptr[profile] = ptr;
entry = NULL;
@@ -319,13 +323,22 @@ static struct tomoyo_profile *tomoyo_assign_profile(const unsigned int profile)
*/
struct tomoyo_profile *tomoyo_profile(const u8 profile)
{
+ static struct tomoyo_profile tomoyo_null_profile;
struct tomoyo_profile *ptr = tomoyo_profile_ptr[profile];
- if (!tomoyo_policy_loaded)
- return &tomoyo_default_profile;
- BUG_ON(!ptr);
+ if (!ptr)
+ ptr = &tomoyo_null_profile;
return ptr;
}
+/**
+ * tomoyo_find_yesno - Find values for specified keyword.
+ *
+ * @string: String to check.
+ * @find: Name of keyword.
+ *
+ * Returns 1 if "@find=yes" was found, 0 if "@find=no" was found, -1 otherwise.
+ */
+/*
static s8 tomoyo_find_yesno(const char *string, const char *find)
{
const char *cp = strstr(string, find);
@@ -338,19 +351,17 @@ static s8 tomoyo_find_yesno(const char *string, const char *find)
}
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;
- }
-}
-
+/**
+ * tomoyo_set_uint - Set value for specified preference.
+ *
+ * @i: Pointer to "unsigned int".
+ * @string: String to check.
+ * @find: Name of keyword.
+ *
+ * Returns nothing.
+ */
static void tomoyo_set_uint(unsigned int *i, const char *string,
const char *find)
{
@@ -359,51 +370,16 @@ static void tomoyo_set_uint(unsigned int *i, const char *string,
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");
-}
-
+/**
+ * tomoyo_set_mode - Set mode for specified profile.
+ *
+ * @name: Name of functionality.
+ * @value: Mode for @name.
+ * @profile: Pointer to "struct tomoyo_profile".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
static int tomoyo_set_mode(char *name, const char *value,
- const bool use_default,
struct tomoyo_profile *profile)
{
u8 i;
@@ -425,7 +401,7 @@ static int tomoyo_set_mode(char *name, const char *value,
} else {
return -EINVAL;
}
- if (use_default) {
+ if (strstr(value, "use_default")) {
config = TOMOYO_CONFIG_USE_DEFAULT;
} else {
u8 mode;
@@ -455,34 +431,21 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
{
char *data = head->write_buf;
unsigned int i;
- bool use_default = false;
char *cp;
struct tomoyo_profile *profile;
if (sscanf(data, "PROFILE_VERSION=%u", &tomoyo_profile_version) == 1)
return 0;
i = simple_strtoul(data, &cp, 10);
- if (data == cp) {
- profile = &tomoyo_default_profile;
- } else {
- if (*cp != '-')
- return -EINVAL;
- data = cp + 1;
- profile = tomoyo_assign_profile(i);
- if (!profile)
- return -EINVAL;
- }
+ if (*cp != '-')
+ return -EINVAL;
+ data = cp + 1;
+ profile = tomoyo_assign_profile(i);
+ if (!profile)
+ return -EINVAL;
cp = strchr(data, '=');
if (!cp)
return -EINVAL;
*cp++ = '\0';
- if (profile != &tomoyo_default_profile)
- use_default = strstr(cp, "use_default") != NULL;
- if (tomoyo_str_starts(&data, "PREFERENCE::")) {
- tomoyo_set_pref(data, cp, use_default, profile);
- return 0;
- }
- if (profile == &tomoyo_default_profile)
- return -EINVAL;
if (!strcmp(data, "COMMENT")) {
static DEFINE_SPINLOCK(lock);
const struct tomoyo_path_info *new_comment
@@ -497,48 +460,13 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
tomoyo_put_name(old_comment);
return 0;
}
- return tomoyo_set_mode(data, cp, use_default, profile);
-}
-
-static void tomoyo_print_preference(struct tomoyo_io_buffer *head,
- const int idx)
-{
- struct tomoyo_preference *pref = &tomoyo_default_profile.preference;
- const struct tomoyo_profile *profile = idx >= 0 ?
- tomoyo_profile_ptr[idx] : NULL;
- char buffer[16] = "";
- if (profile) {
- buffer[sizeof(buffer) - 1] = '\0';
- snprintf(buffer, sizeof(buffer) - 1, "%u-", idx);
- }
- if (profile) {
- pref = profile->learning;
- if (pref == &tomoyo_default_profile.preference)
- goto skip1;
- }
- tomoyo_io_printf(head, "%sPREFERENCE::%s={ "
- "verbose=%s max_entry=%u }\n",
- buffer, "learning",
- tomoyo_yesno(pref->learning_verbose),
- pref->learning_max_entry);
- skip1:
- if (profile) {
- pref = profile->permissive;
- if (pref == &tomoyo_default_profile.preference)
- goto skip2;
- }
- tomoyo_io_printf(head, "%sPREFERENCE::%s={ verbose=%s }\n",
- buffer, "permissive",
- tomoyo_yesno(pref->permissive_verbose));
- skip2:
- if (profile) {
- pref = profile->enforcing;
- if (pref == &tomoyo_default_profile.preference)
- return;
+ if (!strcmp(data, "PREFERENCE")) {
+ for (i = 0; i < TOMOYO_MAX_PREF; i++)
+ tomoyo_set_uint(&profile->pref[i], cp,
+ tomoyo_pref_keywords[i]);
+ return 0;
}
- tomoyo_io_printf(head, "%sPREFERENCE::%s={ verbose=%s }\n",
- buffer, "enforcing",
- tomoyo_yesno(pref->enforcing_verbose));
+ return tomoyo_set_mode(data, cp, profile);
}
static void tomoyo_print_config(struct tomoyo_io_buffer *head, const u8 config)
@@ -561,7 +489,6 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
switch (head->r.step) {
case 0:
tomoyo_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");
- tomoyo_print_preference(head, -1);
head->r.step++;
break;
case 1:
@@ -575,11 +502,18 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
break;
case 2:
{
+ u8 i;
const struct tomoyo_path_info *comment =
profile->comment;
tomoyo_io_printf(head, "%u-COMMENT=", index);
tomoyo_set_string(head, comment ? comment->name : "");
tomoyo_set_lf(head);
+ tomoyo_io_printf(head, "%u-PREFERENCE={ ", index);
+ for (i = 0; i < TOMOYO_MAX_PREF; i++)
+ tomoyo_io_printf(head, "%s=%u ",
+ tomoyo_pref_keywords[i],
+ profile->pref[i]);
+ tomoyo_set_string(head, "}\n");
head->r.step++;
}
break;
@@ -606,7 +540,6 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
}
if (head->r.bit == TOMOYO_MAX_MAC_INDEX
+ TOMOYO_MAX_MAC_CATEGORY_INDEX) {
- tomoyo_print_preference(head, index);
head->r.index++;
head->r.step = 1;
}
@@ -1777,7 +1710,7 @@ static int tomoyo_write_answer(struct tomoyo_io_buffer *head)
static void tomoyo_read_version(struct tomoyo_io_buffer *head)
{
if (!head->r.eof) {
- tomoyo_io_printf(head, "2.3.0");
+ tomoyo_io_printf(head, "2.4.0");
head->r.eof = true;
}
}