@@ -1980,6 +1980,114 @@ static int tomoyo_truncate(char *str)
1980
1980
return strlen (start ) + 1 ;
1981
1981
}
1982
1982
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
+
1983
2091
/**
1984
2092
* tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode.
1985
2093
*
@@ -2003,7 +2111,8 @@ static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
2003
2111
if (!cp )
2004
2112
return ;
2005
2113
* cp ++ = '\0' ;
2006
- len = strlen (cp ) + 1 ;
2114
+ /* Reserve some space for potentially using patterns. */
2115
+ len = strlen (cp ) + 16 ;
2007
2116
/* strstr() will return NULL if ordering is wrong. */
2008
2117
if (* cp == 'f' ) {
2009
2118
argv0 = strstr (header , " argv[]={ \"" );
@@ -2020,40 +2129,10 @@ static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
2020
2129
if (symlink )
2021
2130
len += tomoyo_truncate (symlink + 1 ) + 1 ;
2022
2131
}
2023
- buffer = kmalloc (len , GFP_NOFS );
2132
+ buffer = kmalloc (len , GFP_NOFS | __GFP_ZERO );
2024
2133
if (!buffer )
2025
2134
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 );
2057
2136
if (realpath )
2058
2137
tomoyo_addprintf (buffer , len , " exec.%s" , realpath );
2059
2138
if (argv0 )
0 commit comments