@@ -1980,6 +1980,114 @@ static int tomoyo_truncate(char *str)
19801980 return strlen (start ) + 1 ;
19811981}
19821982
1983+ /**
1984+ * tomoyo_numscan - sscanf() which stores the length of a decimal integer value.
1985+ *
1986+ * @str: String to scan.
1987+ * @head: Leading string that must start with.
1988+ * @width: Pointer to "int" for storing length of a decimal integer value after @head.
1989+ * @tail: Optional character that must match after a decimal integer value.
1990+ *
1991+ * Returns whether @str starts with @head and a decimal value follows @head.
1992+ */
1993+ static bool tomoyo_numscan (const char * str , const char * head , int * width , const char tail )
1994+ {
1995+ const char * cp ;
1996+ const int n = strlen (head );
1997+
1998+ if (!strncmp (str , head , n )) {
1999+ cp = str + n ;
2000+ while (* cp && * cp >= '0' && * cp <= '9' )
2001+ cp ++ ;
2002+ if (* cp == tail || !tail ) {
2003+ * width = cp - (str + n );
2004+ return * width != 0 ;
2005+ }
2006+ }
2007+ * width = 0 ;
2008+ return 0 ;
2009+ }
2010+
2011+ /**
2012+ * tomoyo_patternize_path - Make patterns for file path. Used by learning mode.
2013+ *
2014+ * @buffer: Destination buffer.
2015+ * @len: Size of @buffer.
2016+ * @entry: Original line.
2017+ *
2018+ * Returns nothing.
2019+ */
2020+ static void tomoyo_patternize_path (char * buffer , const int len , char * entry )
2021+ {
2022+ int width ;
2023+ char * cp = entry ;
2024+
2025+ /* Nothing to do if this line is not for "file" related entry. */
2026+ if (strncmp (entry , "file " , 5 ))
2027+ goto flush ;
2028+ /*
2029+ * Nothing to do if there is no colon in this line, for this rewriting
2030+ * applies to only filesystems where numeric values in the path are volatile.
2031+ */
2032+ cp = strchr (entry + 5 , ':' );
2033+ if (!cp ) {
2034+ cp = entry ;
2035+ goto flush ;
2036+ }
2037+ /* Flush e.g. "file ioctl" part. */
2038+ while (* cp != ' ' )
2039+ cp -- ;
2040+ * cp ++ = '\0' ;
2041+ tomoyo_addprintf (buffer , len , "%s " , entry );
2042+ /* e.g. file ioctl pipe:[$INO] $CMD */
2043+ if (tomoyo_numscan (cp , "pipe:[" , & width , ']' )) {
2044+ cp += width + 7 ;
2045+ tomoyo_addprintf (buffer , len , "pipe:[\\$]" );
2046+ goto flush ;
2047+ }
2048+ /* e.g. file ioctl socket:[$INO] $CMD */
2049+ if (tomoyo_numscan (cp , "socket:[" , & width , ']' )) {
2050+ cp += width + 9 ;
2051+ tomoyo_addprintf (buffer , len , "socket:[\\$]" );
2052+ goto flush ;
2053+ }
2054+ if (!strncmp (cp , "proc:/self" , 10 )) {
2055+ /* e.g. file read proc:/self/task/$TID/fdinfo/$FD */
2056+ cp += 10 ;
2057+ tomoyo_addprintf (buffer , len , "proc:/self" );
2058+ } else if (tomoyo_numscan (cp , "proc:/" , & width , 0 )) {
2059+ /* e.g. file read proc:/$PID/task/$TID/fdinfo/$FD */
2060+ /*
2061+ * Don't patternize $PID part if $PID == 1, for several
2062+ * programs access only files in /proc/1/ directory.
2063+ */
2064+ cp += width + 6 ;
2065+ if (width == 1 && * (cp - 1 ) == '1' )
2066+ tomoyo_addprintf (buffer , len , "proc:/1" );
2067+ else
2068+ tomoyo_addprintf (buffer , len , "proc:/\\$" );
2069+ } else {
2070+ goto flush ;
2071+ }
2072+ /* Patternize $TID part if "/task/" follows. */
2073+ if (tomoyo_numscan (cp , "/task/" , & width , 0 )) {
2074+ cp += width + 6 ;
2075+ tomoyo_addprintf (buffer , len , "/task/\\$" );
2076+ }
2077+ /* Patternize $FD part if "/fd/" or "/fdinfo/" follows. */
2078+ if (tomoyo_numscan (cp , "/fd/" , & width , 0 )) {
2079+ cp += width + 4 ;
2080+ tomoyo_addprintf (buffer , len , "/fd/\\$" );
2081+ } else if (tomoyo_numscan (cp , "/fdinfo/" , & width , 0 )) {
2082+ cp += width + 8 ;
2083+ tomoyo_addprintf (buffer , len , "/fdinfo/\\$" );
2084+ }
2085+ flush :
2086+ /* Flush remaining part if any. */
2087+ if (* cp )
2088+ tomoyo_addprintf (buffer , len , "%s" , cp );
2089+ }
2090+
19832091/**
19842092 * tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode.
19852093 *
@@ -2003,7 +2111,8 @@ static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
20032111 if (!cp )
20042112 return ;
20052113 * cp ++ = '\0' ;
2006- len = strlen (cp ) + 1 ;
2114+ /* Reserve some space for potentially using patterns. */
2115+ len = strlen (cp ) + 16 ;
20072116 /* strstr() will return NULL if ordering is wrong. */
20082117 if (* cp == 'f' ) {
20092118 argv0 = strstr (header , " argv[]={ \"" );
@@ -2020,40 +2129,10 @@ static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
20202129 if (symlink )
20212130 len += tomoyo_truncate (symlink + 1 ) + 1 ;
20222131 }
2023- buffer = kmalloc (len , GFP_NOFS );
2132+ buffer = kmalloc (len , GFP_NOFS | __GFP_ZERO );
20242133 if (!buffer )
20252134 return ;
2026- snprintf (buffer , len - 1 , "%s" , cp );
2027- if (* cp == 'f' && strchr (buffer , ':' )) {
2028- /* Automatically replace 2 or more digits with \$ pattern. */
2029- char * cp2 ;
2030-
2031- /* e.g. file read proc:/$PID/stat */
2032- cp = strstr (buffer , " proc:/" );
2033- if (cp && simple_strtoul (cp + 7 , & cp2 , 10 ) >= 10 && * cp2 == '/' ) {
2034- * (cp + 7 ) = '\\' ;
2035- * (cp + 8 ) = '$' ;
2036- memmove (cp + 9 , cp2 , strlen (cp2 ) + 1 );
2037- goto ok ;
2038- }
2039- /* e.g. file ioctl pipe:[$INO] $CMD */
2040- cp = strstr (buffer , " pipe:[" );
2041- if (cp && simple_strtoul (cp + 7 , & cp2 , 10 ) >= 10 && * cp2 == ']' ) {
2042- * (cp + 7 ) = '\\' ;
2043- * (cp + 8 ) = '$' ;
2044- memmove (cp + 9 , cp2 , strlen (cp2 ) + 1 );
2045- goto ok ;
2046- }
2047- /* e.g. file ioctl socket:[$INO] $CMD */
2048- cp = strstr (buffer , " socket:[" );
2049- if (cp && simple_strtoul (cp + 9 , & cp2 , 10 ) >= 10 && * cp2 == ']' ) {
2050- * (cp + 9 ) = '\\' ;
2051- * (cp + 10 ) = '$' ;
2052- memmove (cp + 11 , cp2 , strlen (cp2 ) + 1 );
2053- goto ok ;
2054- }
2055- }
2056- ok :
2135+ tomoyo_patternize_path (buffer , len , cp );
20572136 if (realpath )
20582137 tomoyo_addprintf (buffer , len , " exec.%s" , realpath );
20592138 if (argv0 )
0 commit comments