Skip to content

Commit

Permalink
TOMOYO: Allow using executable's realpath and symlink's target as con…
Browse files Browse the repository at this point in the history
…ditions.

This patch adds support for permission checks using executable file's realpath
upon execve() and symlink's target upon symlink(). Hooks are in the last patch
of this pathset.

Signed-off-by: Tetsuo Handa <[email protected]>
Signed-off-by: James Morris <[email protected]>
  • Loading branch information
Tetsuo Handa authored and James Morris committed Jul 11, 2011
1 parent 8761afd commit 2ca9bf4
Show file tree
Hide file tree
Showing 5 changed files with 228 additions and 4 deletions.
21 changes: 21 additions & 0 deletions security/tomoyo/audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,22 +140,43 @@ char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt,
{
char *buf = NULL;
const char *header = NULL;
char *realpath = NULL;
const char *symlink = NULL;
int pos;
const char *domainname = r->domain->domainname->name;
header = tomoyo_print_header(r);
if (!header)
return NULL;
/* +10 is for '\n' etc. and '\0'. */
len += strlen(domainname) + strlen(header) + 10;
if (r->ee) {
struct file *file = r->ee->bprm->file;
realpath = tomoyo_realpath_from_path(&file->f_path);
if (!realpath)
goto out;
/* +80 is for " exec={ realpath=\"%s\" }" */
len += strlen(realpath) + 80;
} else if (r->obj && r->obj->symlink_target) {
symlink = r->obj->symlink_target->name;
/* +18 is for " symlink.target=\"%s\"" */
len += 18 + strlen(symlink);
}
len = tomoyo_round2(len);
buf = kzalloc(len, GFP_NOFS);
if (!buf)
goto out;
len--;
pos = snprintf(buf, len, "%s", header);
if (realpath) {
pos += snprintf(buf + pos, len - pos,
" exec={ realpath=\"%s\" }", realpath);
} else if (symlink)
pos += snprintf(buf + pos, len - pos, " symlink.target=\"%s\"",
symlink);
pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname);
vsnprintf(buf + pos, len - pos, fmt, args);
out:
kfree(realpath);
kfree(header);
return buf;
}
Expand Down
66 changes: 66 additions & 0 deletions security/tomoyo/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ const char * const tomoyo_condition_keyword[TOMOYO_MAX_CONDITION_KEYWORD] = {
[TOMOYO_MODE_OTHERS_READ] = "others_read",
[TOMOYO_MODE_OTHERS_WRITE] = "others_write",
[TOMOYO_MODE_OTHERS_EXECUTE] = "others_execute",
[TOMOYO_EXEC_REALPATH] = "exec.realpath",
[TOMOYO_SYMLINK_TARGET] = "symlink.target",
[TOMOYO_PATH1_UID] = "path1.uid",
[TOMOYO_PATH1_GID] = "path1.gid",
[TOMOYO_PATH1_INO] = "path1.ino",
Expand Down Expand Up @@ -352,6 +354,27 @@ static void tomoyo_print_name_union(struct tomoyo_io_buffer *head,
}
}

/**
* tomoyo_print_name_union_quoted - Print a tomoyo_name_union with a quote.
*
* @head: Pointer to "struct tomoyo_io_buffer".
* @ptr: Pointer to "struct tomoyo_name_union".
*
* Returns nothing.
*/
static void tomoyo_print_name_union_quoted(struct tomoyo_io_buffer *head,
const struct tomoyo_name_union *ptr)
{
if (ptr->group) {
tomoyo_set_string(head, "@");
tomoyo_set_string(head, ptr->group->group_name->name);
} else {
tomoyo_set_string(head, "\"");
tomoyo_set_string(head, ptr->filename->name);
tomoyo_set_string(head, "\"");
}
}

/**
* tomoyo_print_number_union_nospace - Print a tomoyo_number_union without a space.
*
Expand Down Expand Up @@ -1101,6 +1124,9 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
(typeof(condp)) (cond + 1);
const struct tomoyo_number_union *numbers_p =
(typeof(numbers_p)) (condp + condc);
const struct tomoyo_name_union *names_p =
(typeof(names_p))
(numbers_p + cond->numbers_count);
u16 skip;
for (skip = 0; skip < head->r.cond_index; skip++) {
const u8 left = condp->left;
Expand All @@ -1112,6 +1138,9 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
break;
}
switch (right) {
case TOMOYO_NAME_UNION:
names_p++;
break;
case TOMOYO_NUMBER_UNION:
numbers_p++;
break;
Expand All @@ -1138,6 +1167,10 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
}
tomoyo_set_string(head, match ? "=" : "!=");
switch (right) {
case TOMOYO_NAME_UNION:
tomoyo_print_name_union_quoted
(head, names_p++);
break;
case TOMOYO_NUMBER_UNION:
tomoyo_print_number_union_nospace
(head, numbers_p++);
Expand Down Expand Up @@ -1665,6 +1698,22 @@ static DEFINE_SPINLOCK(tomoyo_query_list_lock);
*/
static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);

/**
* tomoyo_truncate - Truncate a line.
*
* @str: String to truncate.
*
* Returns length of truncated @str.
*/
static int tomoyo_truncate(char *str)
{
char *start = str;
while (*(unsigned char *) str > (unsigned char) ' ')
str++;
*str = '\0';
return strlen(start) + 1;
}

/**
* tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode.
*
Expand All @@ -1676,6 +1725,8 @@ static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);
static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
{
char *buffer;
char *realpath = NULL;
char *symlink = NULL;
char *cp = strchr(header, '\n');
int len;
if (!cp)
Expand All @@ -1685,10 +1736,25 @@ static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
return;
*cp++ = '\0';
len = strlen(cp) + 1;
/* strstr() will return NULL if ordering is wrong. */
if (*cp == 'f') {
realpath = strstr(header, " exec={ realpath=\"");
if (realpath) {
realpath += 8;
len += tomoyo_truncate(realpath) + 6;
}
symlink = strstr(header, " symlink.target=\"");
if (symlink)
len += tomoyo_truncate(symlink + 1) + 1;
}
buffer = kmalloc(len, GFP_NOFS);
if (!buffer)
return;
snprintf(buffer, len - 1, "%s", cp);
if (realpath)
tomoyo_addprintf(buffer, len, " exec.%s", realpath);
if (symlink)
tomoyo_addprintf(buffer, len, "%s", symlink);
tomoyo_normalize_line(buffer);
if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer,
false))
Expand Down
24 changes: 24 additions & 0 deletions security/tomoyo/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ enum tomoyo_conditions_index {
TOMOYO_MODE_OTHERS_READ, /* S_IROTH */
TOMOYO_MODE_OTHERS_WRITE, /* S_IWOTH */
TOMOYO_MODE_OTHERS_EXECUTE, /* S_IXOTH */
TOMOYO_EXEC_REALPATH,
TOMOYO_SYMLINK_TARGET,
TOMOYO_PATH1_UID,
TOMOYO_PATH1_GID,
TOMOYO_PATH1_INO,
Expand Down Expand Up @@ -101,6 +103,7 @@ enum tomoyo_conditions_index {
TOMOYO_PATH2_PARENT_PERM,
TOMOYO_MAX_CONDITION_KEYWORD,
TOMOYO_NUMBER_UNION,
TOMOYO_NAME_UNION,
};


Expand Down Expand Up @@ -351,6 +354,11 @@ struct tomoyo_request_info {
* NULL if not dealing files.
*/
struct tomoyo_obj_info *obj;
/*
* For holding parameters specific to execve() request.
* NULL if not dealing do_execve().
*/
struct tomoyo_execve *ee;
struct tomoyo_domain_info *domain;
/* For holding parameters. */
union {
Expand Down Expand Up @@ -476,6 +484,20 @@ struct tomoyo_obj_info {
* parent directory.
*/
struct tomoyo_mini_stat stat[TOMOYO_MAX_PATH_STAT];
/*
* Content of symbolic link to be created. NULL for operations other
* than symlink().
*/
struct tomoyo_path_info *symlink_target;
};

/* Structure for execve() operation. */
struct tomoyo_execve {
struct tomoyo_request_info r;
struct tomoyo_obj_info obj;
struct linux_binprm *bprm;
/* For temporary use. */
char *tmp; /* Size is TOMOYO_EXEC_TMPSIZE bytes */
};

/* Structure for entries which follows "struct tomoyo_condition". */
Expand All @@ -494,9 +516,11 @@ struct tomoyo_condition {
u32 size; /* Memory size allocated for this entry. */
u16 condc; /* Number of conditions in this struct. */
u16 numbers_count; /* Number of "struct tomoyo_number_union values". */
u16 names_count; /* Number of "struct tomoyo_name_union names". */
/*
* struct tomoyo_condition_element condition[condc];
* struct tomoyo_number_union values[numbers_count];
* struct tomoyo_name_union names[names_count];
*/
};

Expand Down
Loading

0 comments on commit 2ca9bf4

Please sign in to comment.