diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/tomoyo/common.c | 32 | ||||
-rw-r--r-- | security/tomoyo/domain.c | 11 |
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; |