summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/tomoyo/common.c32
-rw-r--r--security/tomoyo/domain.c11
2 files changed, 40 insertions, 3 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 5c7b059a332a..d9fa69632147 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -2024,6 +2024,36 @@ static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
if (!buffer)
return;
snprintf(buffer, len - 1, "%s", cp);
+ if (*cp == 'f' && strchr(buffer, ':')) {
+ /* Automatically replace 2 or more digits with \$ pattern. */
+ char *cp2;
+
+ /* e.g. file read proc:/$PID/stat */
+ cp = strstr(buffer, " proc:/");
+ if (cp && simple_strtoul(cp + 7, &cp2, 10) >= 10 && *cp2 == '/') {
+ *(cp + 7) = '\\';
+ *(cp + 8) = '$';
+ memmove(cp + 9, cp2, strlen(cp2) + 1);
+ goto ok;
+ }
+ /* e.g. file ioctl pipe:[$INO] $CMD */
+ cp = strstr(buffer, " pipe:[");
+ if (cp && simple_strtoul(cp + 7, &cp2, 10) >= 10 && *cp2 == ']') {
+ *(cp + 7) = '\\';
+ *(cp + 8) = '$';
+ memmove(cp + 9, cp2, strlen(cp2) + 1);
+ goto ok;
+ }
+ /* e.g. file ioctl socket:[$INO] $CMD */
+ cp = strstr(buffer, " socket:[");
+ if (cp && simple_strtoul(cp + 9, &cp2, 10) >= 10 && *cp2 == ']') {
+ *(cp + 9) = '\\';
+ *(cp + 10) = '$';
+ memmove(cp + 11, cp2, strlen(cp2) + 1);
+ goto ok;
+ }
+ }
+ok:
if (realpath)
tomoyo_addprintf(buffer, len, " exec.%s", realpath);
if (argv0)
@@ -2665,7 +2695,7 @@ ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head,
if (head->w.avail >= head->writebuf_size - 1) {
const int len = head->writebuf_size * 2;
- char *cp = kzalloc(len, GFP_NOFS);
+ char *cp = kzalloc(len, GFP_NOFS | __GFP_NOWARN);
if (!cp) {
error = -ENOMEM;
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index aed9e3ef2c9e..3a7b0874cf44 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -722,10 +722,17 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
ee->bprm = bprm;
ee->r.obj = &ee->obj;
ee->obj.path1 = bprm->file->f_path;
- /* Get symlink's pathname of program. */
+ /*
+ * Get symlink's pathname of program, but fallback to realpath if
+ * symlink's pathname does not exist or symlink's pathname refers
+ * to proc filesystem (e.g. /dev/fd/<num> or /proc/self/fd/<num> ).
+ */
exename.name = tomoyo_realpath_nofollow(original_name);
+ if (exename.name && !strncmp(exename.name, "proc:/", 6)) {
+ kfree(exename.name);
+ exename.name = NULL;
+ }
if (!exename.name) {
- /* Fallback to realpath if symlink's pathname does not exist. */
exename.name = tomoyo_realpath_from_path(&bprm->file->f_path);
if (!exename.name)
goto out;