Commit b22b8b9fd90eecfb7133e56b4e113595f09f4492

Authored by Tetsuo Handa
Committed by James Morris
1 parent 2c47ab9353

TOMOYO: Rename meminfo to stat and show more statistics.

Show statistics such as last policy update time and last policy violation time
in addition to memory usage.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>

Showing 6 changed files with 206 additions and 143 deletions Side-by-side Diff

security/tomoyo/audit.c
... ... @@ -10,47 +10,6 @@
10 10 #include <linux/slab.h>
11 11  
12 12 /**
13   - * tomoyo_convert_time - Convert time_t to YYYY/MM/DD hh/mm/ss.
14   - *
15   - * @time: Seconds since 1970/01/01 00:00:00.
16   - * @stamp: Pointer to "struct tomoyo_time".
17   - *
18   - * Returns nothing.
19   - *
20   - * This function does not handle Y2038 problem.
21   - */
22   -static void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp)
23   -{
24   - static const u16 tomoyo_eom[2][12] = {
25   - { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
26   - { 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
27   - };
28   - u16 y;
29   - u8 m;
30   - bool r;
31   - stamp->sec = time % 60;
32   - time /= 60;
33   - stamp->min = time % 60;
34   - time /= 60;
35   - stamp->hour = time % 24;
36   - time /= 24;
37   - for (y = 1970; ; y++) {
38   - const unsigned short days = (y & 3) ? 365 : 366;
39   - if (time < days)
40   - break;
41   - time -= days;
42   - }
43   - r = (y & 3) == 0;
44   - for (m = 0; m < 11 && time >= tomoyo_eom[r][m]; m++)
45   - ;
46   - if (m)
47   - time -= tomoyo_eom[r][m - 1];
48   - stamp->year = y;
49   - stamp->month = ++m;
50   - stamp->day = ++time;
51   -}
52   -
53   -/**
54 13 * tomoyo_print_header - Get header line of audit log.
55 14 *
56 15 * @r: Pointer to "struct tomoyo_request_info".
security/tomoyo/common.c
... ... @@ -1584,8 +1584,9 @@
1584 1584 return;
1585 1585 snprintf(buffer, len - 1, "%s", cp);
1586 1586 tomoyo_normalize_line(buffer);
1587   - tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer,
1588   - false);
  1587 + if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer,
  1588 + false))
  1589 + tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
1589 1590 kfree(buffer);
1590 1591 }
1591 1592  
... ... @@ -1618,6 +1619,8 @@
1618 1619 /* Nothing more to do if granted. */
1619 1620 if (r->granted)
1620 1621 return 0;
  1622 + if (r->mode)
  1623 + tomoyo_update_stat(r->mode);
1621 1624 switch (r->mode) {
1622 1625 case TOMOYO_CONFIG_ENFORCING:
1623 1626 error = -EPERM;
1624 1627  
... ... @@ -1857,7 +1860,105 @@
1857 1860 }
1858 1861 }
1859 1862  
  1863 +/* String table for /sys/kernel/security/tomoyo/stat interface. */
  1864 +static const char * const tomoyo_policy_headers[TOMOYO_MAX_POLICY_STAT] = {
  1865 + [TOMOYO_STAT_POLICY_UPDATES] = "update:",
  1866 + [TOMOYO_STAT_POLICY_LEARNING] = "violation in learning mode:",
  1867 + [TOMOYO_STAT_POLICY_PERMISSIVE] = "violation in permissive mode:",
  1868 + [TOMOYO_STAT_POLICY_ENFORCING] = "violation in enforcing mode:",
  1869 +};
  1870 +
  1871 +/* String table for /sys/kernel/security/tomoyo/stat interface. */
  1872 +static const char * const tomoyo_memory_headers[TOMOYO_MAX_MEMORY_STAT] = {
  1873 + [TOMOYO_MEMORY_POLICY] = "policy:",
  1874 + [TOMOYO_MEMORY_AUDIT] = "audit log:",
  1875 + [TOMOYO_MEMORY_QUERY] = "query message:",
  1876 +};
  1877 +
  1878 +/* Timestamp counter for last updated. */
  1879 +static unsigned int tomoyo_stat_updated[TOMOYO_MAX_POLICY_STAT];
  1880 +/* Counter for number of updates. */
  1881 +static unsigned int tomoyo_stat_modified[TOMOYO_MAX_POLICY_STAT];
  1882 +
1860 1883 /**
  1884 + * tomoyo_update_stat - Update statistic counters.
  1885 + *
  1886 + * @index: Index for policy type.
  1887 + *
  1888 + * Returns nothing.
  1889 + */
  1890 +void tomoyo_update_stat(const u8 index)
  1891 +{
  1892 + struct timeval tv;
  1893 + do_gettimeofday(&tv);
  1894 + /*
  1895 + * I don't use atomic operations because race condition is not fatal.
  1896 + */
  1897 + tomoyo_stat_updated[index]++;
  1898 + tomoyo_stat_modified[index] = tv.tv_sec;
  1899 +}
  1900 +
  1901 +/**
  1902 + * tomoyo_read_stat - Read statistic data.
  1903 + *
  1904 + * @head: Pointer to "struct tomoyo_io_buffer".
  1905 + *
  1906 + * Returns nothing.
  1907 + */
  1908 +static void tomoyo_read_stat(struct tomoyo_io_buffer *head)
  1909 +{
  1910 + u8 i;
  1911 + unsigned int total = 0;
  1912 + if (head->r.eof)
  1913 + return;
  1914 + for (i = 0; i < TOMOYO_MAX_POLICY_STAT; i++) {
  1915 + tomoyo_io_printf(head, "Policy %-30s %10u",
  1916 + tomoyo_policy_headers[i],
  1917 + tomoyo_stat_updated[i]);
  1918 + if (tomoyo_stat_modified[i]) {
  1919 + struct tomoyo_time stamp;
  1920 + tomoyo_convert_time(tomoyo_stat_modified[i], &stamp);
  1921 + tomoyo_io_printf(head, " (Last: %04u/%02u/%02u "
  1922 + "%02u:%02u:%02u)",
  1923 + stamp.year, stamp.month, stamp.day,
  1924 + stamp.hour, stamp.min, stamp.sec);
  1925 + }
  1926 + tomoyo_set_lf(head);
  1927 + }
  1928 + for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) {
  1929 + unsigned int used = tomoyo_memory_used[i];
  1930 + total += used;
  1931 + tomoyo_io_printf(head, "Memory used by %-22s %10u",
  1932 + tomoyo_memory_headers[i], used);
  1933 + used = tomoyo_memory_quota[i];
  1934 + if (used)
  1935 + tomoyo_io_printf(head, " (Quota: %10u)", used);
  1936 + tomoyo_set_lf(head);
  1937 + }
  1938 + tomoyo_io_printf(head, "Total memory used: %10u\n",
  1939 + total);
  1940 + head->r.eof = true;
  1941 +}
  1942 +
  1943 +/**
  1944 + * tomoyo_write_stat - Set memory quota.
  1945 + *
  1946 + * @head: Pointer to "struct tomoyo_io_buffer".
  1947 + *
  1948 + * Returns 0.
  1949 + */
  1950 +static int tomoyo_write_stat(struct tomoyo_io_buffer *head)
  1951 +{
  1952 + char *data = head->write_buf;
  1953 + u8 i;
  1954 + if (tomoyo_str_starts(&data, "Memory used by "))
  1955 + for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++)
  1956 + if (tomoyo_str_starts(&data, tomoyo_memory_headers[i]))
  1957 + sscanf(data, "%u", &tomoyo_memory_quota[i]);
  1958 + return 0;
  1959 +}
  1960 +
  1961 +/**
1861 1962 * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface.
1862 1963 *
1863 1964 * @type: Type of interface.
... ... @@ -1908,11 +2009,11 @@
1908 2009 head->read = tomoyo_read_version;
1909 2010 head->readbuf_size = 128;
1910 2011 break;
1911   - case TOMOYO_MEMINFO:
1912   - /* /sys/kernel/security/tomoyo/meminfo */
1913   - head->write = tomoyo_write_memory_quota;
1914   - head->read = tomoyo_read_memory_counter;
1915   - head->readbuf_size = 512;
  2012 + case TOMOYO_STAT:
  2013 + /* /sys/kernel/security/tomoyo/stat */
  2014 + head->write = tomoyo_write_stat;
  2015 + head->read = tomoyo_read_stat;
  2016 + head->readbuf_size = 1024;
1916 2017 break;
1917 2018 case TOMOYO_PROFILE:
1918 2019 /* /sys/kernel/security/tomoyo/profile */
... ... @@ -2186,6 +2287,20 @@
2186 2287 case -EPERM:
2187 2288 error = -EPERM;
2188 2289 goto out;
  2290 + case 0:
  2291 + switch (head->type) {
  2292 + case TOMOYO_DOMAINPOLICY:
  2293 + case TOMOYO_EXCEPTIONPOLICY:
  2294 + case TOMOYO_DOMAIN_STATUS:
  2295 + case TOMOYO_STAT:
  2296 + case TOMOYO_PROFILE:
  2297 + case TOMOYO_MANAGER:
  2298 + tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
  2299 + break;
  2300 + default:
  2301 + break;
  2302 + }
  2303 + break;
2189 2304 }
2190 2305 }
2191 2306 out:
security/tomoyo/common.h
... ... @@ -133,6 +133,7 @@
133 133 TOMOYO_MAX_PATH_OPERATION
134 134 };
135 135  
  136 +/* Index numbers for /sys/kernel/security/tomoyo/stat interface. */
136 137 enum tomoyo_memory_stat_type {
137 138 TOMOYO_MEMORY_POLICY,
138 139 TOMOYO_MEMORY_AUDIT,
... ... @@ -173,7 +174,7 @@
173 174 TOMOYO_EXCEPTIONPOLICY,
174 175 TOMOYO_DOMAIN_STATUS,
175 176 TOMOYO_PROCESS_STATUS,
176   - TOMOYO_MEMINFO,
  177 + TOMOYO_STAT,
177 178 TOMOYO_SELFDOMAIN,
178 179 TOMOYO_AUDIT,
179 180 TOMOYO_VERSION,
... ... @@ -237,6 +238,16 @@
237 238 */
238 239 #define TOMOYO_RETRY_REQUEST 1
239 240  
  241 +/* Index numbers for /sys/kernel/security/tomoyo/stat interface. */
  242 +enum tomoyo_policy_stat_type {
  243 + /* Do not change this order. */
  244 + TOMOYO_STAT_POLICY_UPDATES,
  245 + TOMOYO_STAT_POLICY_LEARNING, /* == TOMOYO_CONFIG_LEARNING */
  246 + TOMOYO_STAT_POLICY_PERMISSIVE, /* == TOMOYO_CONFIG_PERMISSIVE */
  247 + TOMOYO_STAT_POLICY_ENFORCING, /* == TOMOYO_CONFIG_ENFORCING */
  248 + TOMOYO_MAX_POLICY_STAT
  249 +};
  250 +
240 251 /* Index numbers for profile's PREFERENCE values. */
241 252 enum tomoyo_pref_index {
242 253 TOMOYO_PREF_MAX_AUDIT_LOG,
... ... @@ -648,8 +659,8 @@
648 659 bool tomoyo_memory_ok(void *ptr);
649 660 void *tomoyo_commit_ok(void *data, const unsigned int size);
650 661 const struct tomoyo_path_info *tomoyo_get_name(const char *name);
651   -void tomoyo_read_memory_counter(struct tomoyo_io_buffer *head);
652   -int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head);
  662 +void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp);
  663 +void tomoyo_update_stat(const u8 index);
653 664 void __init tomoyo_mm_init(void);
654 665 int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
655 666 const struct tomoyo_path_info *filename);
security/tomoyo/memory.c
... ... @@ -29,16 +29,13 @@
29 29 panic("MAC Initialization failed.\n");
30 30 }
31 31  
  32 +/* Lock for protecting tomoyo_memory_used. */
  33 +static DEFINE_SPINLOCK(tomoyo_policy_memory_lock);
32 34 /* Memoy currently used by policy/audit log/query. */
33 35 unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT];
34 36 /* Memory quota for "policy"/"audit log"/"query". */
35 37 unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT];
36 38  
37   -/* Memory allocated for policy. */
38   -static atomic_t tomoyo_policy_memory_size;
39   -/* Quota for holding policy. */
40   -static unsigned int tomoyo_quota_for_policy;
41   -
42 39 /**
43 40 * tomoyo_memory_ok - Check memory quota.
44 41 *
45 42  
... ... @@ -50,15 +47,20 @@
50 47 */
51 48 bool tomoyo_memory_ok(void *ptr)
52 49 {
53   - size_t s = ptr ? ksize(ptr) : 0;
54   - atomic_add(s, &tomoyo_policy_memory_size);
55   - if (ptr && (!tomoyo_quota_for_policy ||
56   - atomic_read(&tomoyo_policy_memory_size)
57   - <= tomoyo_quota_for_policy)) {
58   - memset(ptr, 0, s);
59   - return true;
  50 + if (ptr) {
  51 + const size_t s = ksize(ptr);
  52 + bool result;
  53 + spin_lock(&tomoyo_policy_memory_lock);
  54 + tomoyo_memory_used[TOMOYO_MEMORY_POLICY] += s;
  55 + result = !tomoyo_memory_quota[TOMOYO_MEMORY_POLICY] ||
  56 + tomoyo_memory_used[TOMOYO_MEMORY_POLICY] <=
  57 + tomoyo_memory_quota[TOMOYO_MEMORY_POLICY];
  58 + if (!result)
  59 + tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s;
  60 + spin_unlock(&tomoyo_policy_memory_lock);
  61 + if (result)
  62 + return true;
60 63 }
61   - atomic_sub(s, &tomoyo_policy_memory_size);
62 64 tomoyo_warn_oom(__func__);
63 65 return false;
64 66 }
... ... @@ -91,7 +93,10 @@
91 93 */
92 94 void tomoyo_memory_free(void *ptr)
93 95 {
94   - atomic_sub(ksize(ptr), &tomoyo_policy_memory_size);
  96 + size_t s = ksize(ptr);
  97 + spin_lock(&tomoyo_policy_memory_lock);
  98 + tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s;
  99 + spin_unlock(&tomoyo_policy_memory_lock);
95 100 kfree(ptr);
96 101 }
97 102  
... ... @@ -162,7 +167,6 @@
162 167 struct tomoyo_name *ptr;
163 168 unsigned int hash;
164 169 int len;
165   - int allocated_len;
166 170 struct list_head *head;
167 171  
168 172 if (!name)
169 173  
170 174  
... ... @@ -179,22 +183,17 @@
179 183 goto out;
180 184 }
181 185 ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS);
182   - allocated_len = ptr ? ksize(ptr) : 0;
183   - if (!ptr || (tomoyo_quota_for_policy &&
184   - atomic_read(&tomoyo_policy_memory_size) + allocated_len
185   - > tomoyo_quota_for_policy)) {
  186 + if (tomoyo_memory_ok(ptr)) {
  187 + ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
  188 + memmove((char *) ptr->entry.name, name, len);
  189 + atomic_set(&ptr->head.users, 1);
  190 + tomoyo_fill_path_info(&ptr->entry);
  191 + list_add_tail(&ptr->head.list, head);
  192 + } else {
186 193 kfree(ptr);
187 194 ptr = NULL;
188   - tomoyo_warn_oom(__func__);
189   - goto out;
190 195 }
191   - atomic_add(allocated_len, &tomoyo_policy_memory_size);
192   - ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
193   - memmove((char *) ptr->entry.name, name, len);
194   - atomic_set(&ptr->head.users, 1);
195   - tomoyo_fill_path_info(&ptr->entry);
196   - list_add_tail(&ptr->head.list, head);
197   - out:
  196 +out:
198 197 mutex_unlock(&tomoyo_policy_lock);
199 198 return ptr ? &ptr->entry : NULL;
200 199 }
... ... @@ -226,67 +225,5 @@
226 225 TOMOYO_TRANSITION_CONTROL_INITIALIZE);
227 226 }
228 227 #endif
229   -}
230   -
231   -
232   -/* Memory allocated for query lists. */
233   -unsigned int tomoyo_query_memory_size;
234   -/* Quota for holding query lists. */
235   -unsigned int tomoyo_quota_for_query;
236   -
237   -/**
238   - * tomoyo_read_memory_counter - Check for memory usage in bytes.
239   - *
240   - * @head: Pointer to "struct tomoyo_io_buffer".
241   - *
242   - * Returns memory usage.
243   - */
244   -void tomoyo_read_memory_counter(struct tomoyo_io_buffer *head)
245   -{
246   - if (!head->r.eof) {
247   - const unsigned int policy
248   - = atomic_read(&tomoyo_policy_memory_size);
249   - const unsigned int query = tomoyo_query_memory_size;
250   - char buffer[64];
251   -
252   - memset(buffer, 0, sizeof(buffer));
253   - if (tomoyo_quota_for_policy)
254   - snprintf(buffer, sizeof(buffer) - 1,
255   - " (Quota: %10u)",
256   - tomoyo_quota_for_policy);
257   - else
258   - buffer[0] = '\0';
259   - tomoyo_io_printf(head, "Policy: %10u%s\n", policy,
260   - buffer);
261   - if (tomoyo_quota_for_query)
262   - snprintf(buffer, sizeof(buffer) - 1,
263   - " (Quota: %10u)",
264   - tomoyo_quota_for_query);
265   - else
266   - buffer[0] = '\0';
267   - tomoyo_io_printf(head, "Query lists: %10u%s\n", query,
268   - buffer);
269   - tomoyo_io_printf(head, "Total: %10u\n", policy + query);
270   - head->r.eof = true;
271   - }
272   -}
273   -
274   -/**
275   - * tomoyo_write_memory_quota - Set memory quota.
276   - *
277   - * @head: Pointer to "struct tomoyo_io_buffer".
278   - *
279   - * Returns 0.
280   - */
281   -int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head)
282   -{
283   - char *data = head->write_buf;
284   - unsigned int size;
285   -
286   - if (sscanf(data, "Policy: %u", &size) == 1)
287   - tomoyo_quota_for_policy = size;
288   - else if (sscanf(data, "Query lists: %u", &size) == 1)
289   - tomoyo_quota_for_query = size;
290   - return 0;
291 228 }
security/tomoyo/securityfs_if.c
... ... @@ -143,8 +143,8 @@
143 143 TOMOYO_DOMAIN_STATUS);
144 144 tomoyo_create_entry(".process_status", 0600, tomoyo_dir,
145 145 TOMOYO_PROCESS_STATUS);
146   - tomoyo_create_entry("meminfo", 0600, tomoyo_dir,
147   - TOMOYO_MEMINFO);
  146 + tomoyo_create_entry("stat", 0644, tomoyo_dir,
  147 + TOMOYO_STAT);
148 148 tomoyo_create_entry("profile", 0600, tomoyo_dir,
149 149 TOMOYO_PROFILE);
150 150 tomoyo_create_entry("manager", 0600, tomoyo_dir,
security/tomoyo/util.c
... ... @@ -47,6 +47,47 @@
47 47 };
48 48  
49 49 /**
  50 + * tomoyo_convert_time - Convert time_t to YYYY/MM/DD hh/mm/ss.
  51 + *
  52 + * @time: Seconds since 1970/01/01 00:00:00.
  53 + * @stamp: Pointer to "struct tomoyo_time".
  54 + *
  55 + * Returns nothing.
  56 + *
  57 + * This function does not handle Y2038 problem.
  58 + */
  59 +void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp)
  60 +{
  61 + static const u16 tomoyo_eom[2][12] = {
  62 + { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
  63 + { 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
  64 + };
  65 + u16 y;
  66 + u8 m;
  67 + bool r;
  68 + stamp->sec = time % 60;
  69 + time /= 60;
  70 + stamp->min = time % 60;
  71 + time /= 60;
  72 + stamp->hour = time % 24;
  73 + time /= 24;
  74 + for (y = 1970; ; y++) {
  75 + const unsigned short days = (y & 3) ? 365 : 366;
  76 + if (time < days)
  77 + break;
  78 + time -= days;
  79 + }
  80 + r = (y & 3) == 0;
  81 + for (m = 0; m < 11 && time >= tomoyo_eom[r][m]; m++)
  82 + ;
  83 + if (m)
  84 + time -= tomoyo_eom[r][m - 1];
  85 + stamp->year = y;
  86 + stamp->month = ++m;
  87 + stamp->day = ++time;
  88 +}
  89 +
  90 +/**
50 91 * tomoyo_permstr - Find permission keywords.
51 92 *
52 93 * @string: String representation for permissions in foo/bar/buz format.