mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-23 07:23:12 +02:00
tomoyo: use better patterns for procfs in learning mode
Commit 08ae2487b2 ("tomoyo: automatically use patterns for several
situations in learning mode") replaced only $PID part of procfs pathname
with \$ pattern. But it turned out that we need to also replace $TID part
and $FD part to make this functionality useful for e.g. /bin/lsof .
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
This commit is contained in:
parent
691a1f3f18
commit
bdc35f164b
|
|
@ -1980,6 +1980,114 @@ static int tomoyo_truncate(char *str)
|
||||||
return strlen(start) + 1;
|
return strlen(start) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tomoyo_numscan - sscanf() which stores the length of a decimal integer value.
|
||||||
|
*
|
||||||
|
* @str: String to scan.
|
||||||
|
* @head: Leading string that must start with.
|
||||||
|
* @width: Pointer to "int" for storing length of a decimal integer value after @head.
|
||||||
|
* @tail: Optional character that must match after a decimal integer value.
|
||||||
|
*
|
||||||
|
* Returns whether @str starts with @head and a decimal value follows @head.
|
||||||
|
*/
|
||||||
|
static bool tomoyo_numscan(const char *str, const char *head, int *width, const char tail)
|
||||||
|
{
|
||||||
|
const char *cp;
|
||||||
|
const int n = strlen(head);
|
||||||
|
|
||||||
|
if (!strncmp(str, head, n)) {
|
||||||
|
cp = str + n;
|
||||||
|
while (*cp && *cp >= '0' && *cp <= '9')
|
||||||
|
cp++;
|
||||||
|
if (*cp == tail || !tail) {
|
||||||
|
*width = cp - (str + n);
|
||||||
|
return *width != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*width = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tomoyo_patternize_path - Make patterns for file path. Used by learning mode.
|
||||||
|
*
|
||||||
|
* @buffer: Destination buffer.
|
||||||
|
* @len: Size of @buffer.
|
||||||
|
* @entry: Original line.
|
||||||
|
*
|
||||||
|
* Returns nothing.
|
||||||
|
*/
|
||||||
|
static void tomoyo_patternize_path(char *buffer, const int len, char *entry)
|
||||||
|
{
|
||||||
|
int width;
|
||||||
|
char *cp = entry;
|
||||||
|
|
||||||
|
/* Nothing to do if this line is not for "file" related entry. */
|
||||||
|
if (strncmp(entry, "file ", 5))
|
||||||
|
goto flush;
|
||||||
|
/*
|
||||||
|
* Nothing to do if there is no colon in this line, for this rewriting
|
||||||
|
* applies to only filesystems where numeric values in the path are volatile.
|
||||||
|
*/
|
||||||
|
cp = strchr(entry + 5, ':');
|
||||||
|
if (!cp) {
|
||||||
|
cp = entry;
|
||||||
|
goto flush;
|
||||||
|
}
|
||||||
|
/* Flush e.g. "file ioctl" part. */
|
||||||
|
while (*cp != ' ')
|
||||||
|
cp--;
|
||||||
|
*cp++ = '\0';
|
||||||
|
tomoyo_addprintf(buffer, len, "%s ", entry);
|
||||||
|
/* e.g. file ioctl pipe:[$INO] $CMD */
|
||||||
|
if (tomoyo_numscan(cp, "pipe:[", &width, ']')) {
|
||||||
|
cp += width + 7;
|
||||||
|
tomoyo_addprintf(buffer, len, "pipe:[\\$]");
|
||||||
|
goto flush;
|
||||||
|
}
|
||||||
|
/* e.g. file ioctl socket:[$INO] $CMD */
|
||||||
|
if (tomoyo_numscan(cp, "socket:[", &width, ']')) {
|
||||||
|
cp += width + 9;
|
||||||
|
tomoyo_addprintf(buffer, len, "socket:[\\$]");
|
||||||
|
goto flush;
|
||||||
|
}
|
||||||
|
if (!strncmp(cp, "proc:/self", 10)) {
|
||||||
|
/* e.g. file read proc:/self/task/$TID/fdinfo/$FD */
|
||||||
|
cp += 10;
|
||||||
|
tomoyo_addprintf(buffer, len, "proc:/self");
|
||||||
|
} else if (tomoyo_numscan(cp, "proc:/", &width, 0)) {
|
||||||
|
/* e.g. file read proc:/$PID/task/$TID/fdinfo/$FD */
|
||||||
|
/*
|
||||||
|
* Don't patternize $PID part if $PID == 1, for several
|
||||||
|
* programs access only files in /proc/1/ directory.
|
||||||
|
*/
|
||||||
|
cp += width + 6;
|
||||||
|
if (width == 1 && *(cp - 1) == '1')
|
||||||
|
tomoyo_addprintf(buffer, len, "proc:/1");
|
||||||
|
else
|
||||||
|
tomoyo_addprintf(buffer, len, "proc:/\\$");
|
||||||
|
} else {
|
||||||
|
goto flush;
|
||||||
|
}
|
||||||
|
/* Patternize $TID part if "/task/" follows. */
|
||||||
|
if (tomoyo_numscan(cp, "/task/", &width, 0)) {
|
||||||
|
cp += width + 6;
|
||||||
|
tomoyo_addprintf(buffer, len, "/task/\\$");
|
||||||
|
}
|
||||||
|
/* Patternize $FD part if "/fd/" or "/fdinfo/" follows. */
|
||||||
|
if (tomoyo_numscan(cp, "/fd/", &width, 0)) {
|
||||||
|
cp += width + 4;
|
||||||
|
tomoyo_addprintf(buffer, len, "/fd/\\$");
|
||||||
|
} else if (tomoyo_numscan(cp, "/fdinfo/", &width, 0)) {
|
||||||
|
cp += width + 8;
|
||||||
|
tomoyo_addprintf(buffer, len, "/fdinfo/\\$");
|
||||||
|
}
|
||||||
|
flush:
|
||||||
|
/* Flush remaining part if any. */
|
||||||
|
if (*cp)
|
||||||
|
tomoyo_addprintf(buffer, len, "%s", cp);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode.
|
* tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode.
|
||||||
*
|
*
|
||||||
|
|
@ -2003,7 +2111,8 @@ static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
|
||||||
if (!cp)
|
if (!cp)
|
||||||
return;
|
return;
|
||||||
*cp++ = '\0';
|
*cp++ = '\0';
|
||||||
len = strlen(cp) + 1;
|
/* Reserve some space for potentially using patterns. */
|
||||||
|
len = strlen(cp) + 16;
|
||||||
/* strstr() will return NULL if ordering is wrong. */
|
/* strstr() will return NULL if ordering is wrong. */
|
||||||
if (*cp == 'f') {
|
if (*cp == 'f') {
|
||||||
argv0 = strstr(header, " argv[]={ \"");
|
argv0 = strstr(header, " argv[]={ \"");
|
||||||
|
|
@ -2020,40 +2129,10 @@ static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
|
||||||
if (symlink)
|
if (symlink)
|
||||||
len += tomoyo_truncate(symlink + 1) + 1;
|
len += tomoyo_truncate(symlink + 1) + 1;
|
||||||
}
|
}
|
||||||
buffer = kmalloc(len, GFP_NOFS);
|
buffer = kmalloc(len, GFP_NOFS | __GFP_ZERO);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
return;
|
return;
|
||||||
snprintf(buffer, len - 1, "%s", cp);
|
tomoyo_patternize_path(buffer, len, 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)
|
if (realpath)
|
||||||
tomoyo_addprintf(buffer, len, " exec.%s", realpath);
|
tomoyo_addprintf(buffer, len, " exec.%s", realpath);
|
||||||
if (argv0)
|
if (argv0)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user