Skip to content

Commit

Permalink
TOMOYO: Simplify profile structure.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: James Morris <[email protected]>
  • Loading branch information
Tetsuo Handa authored and James Morris committed Jun 28, 2011
1 parent 0d2171d commit d5ca172
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 168 deletions.
205 changes: 69 additions & 136 deletions security/tomoyo/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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)
{
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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:
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}
}
Expand Down
7 changes: 7 additions & 0 deletions security/tomoyo/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,12 @@ enum tomoyo_mac_category_index {
*/
#define TOMOYO_RETRY_REQUEST 1

/* Index numbers for profile's PREFERENCE values. */
enum tomoyo_pref_index {
TOMOYO_PREF_MAX_LEARNING_ENTRY,
TOMOYO_MAX_PREF
};

/********** Structure definitions. **********/

/* Common header for holding ACL entries. */
Expand Down Expand Up @@ -497,6 +503,7 @@ struct tomoyo_profile {
struct tomoyo_preference preference;
u8 default_config;
u8 config[TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX];
unsigned int pref[TOMOYO_MAX_PREF];
};

/********** Function prototypes. **********/
Expand Down
Loading

0 comments on commit d5ca172

Please sign in to comment.