aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/tomoyo/audit.c41
-rw-r--r--security/tomoyo/common.c129
-rw-r--r--security/tomoyo/common.h17
-rw-r--r--security/tomoyo/memory.c117
-rw-r--r--security/tomoyo/securityfs_if.c4
-rw-r--r--security/tomoyo/util.c41
6 files changed, 206 insertions, 143 deletions
diff --git a/security/tomoyo/audit.c b/security/tomoyo/audit.c
index 45e0a9f3c384..f2c869767d79 100644
--- a/security/tomoyo/audit.c
+++ b/security/tomoyo/audit.c
@@ -10,47 +10,6 @@
10#include <linux/slab.h> 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 */
22static 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 * tomoyo_print_header - Get header line of audit log. 13 * tomoyo_print_header - Get header line of audit log.
55 * 14 *
56 * @r: Pointer to "struct tomoyo_request_info". 15 * @r: Pointer to "struct tomoyo_request_info".
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 6402183e2a6b..7bc0d1d95867 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -1584,8 +1584,9 @@ static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
1584 return; 1584 return;
1585 snprintf(buffer, len - 1, "%s", cp); 1585 snprintf(buffer, len - 1, "%s", cp);
1586 tomoyo_normalize_line(buffer); 1586 tomoyo_normalize_line(buffer);
1587 tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer, 1587 if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer,
1588 false); 1588 false))
1589 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
1589 kfree(buffer); 1590 kfree(buffer);
1590} 1591}
1591 1592
@@ -1618,6 +1619,8 @@ int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
1618 /* Nothing more to do if granted. */ 1619 /* Nothing more to do if granted. */
1619 if (r->granted) 1620 if (r->granted)
1620 return 0; 1621 return 0;
1622 if (r->mode)
1623 tomoyo_update_stat(r->mode);
1621 switch (r->mode) { 1624 switch (r->mode) {
1622 case TOMOYO_CONFIG_ENFORCING: 1625 case TOMOYO_CONFIG_ENFORCING:
1623 error = -EPERM; 1626 error = -EPERM;
@@ -1857,6 +1860,104 @@ static void tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
1857 } 1860 }
1858} 1861}
1859 1862
1863/* String table for /sys/kernel/security/tomoyo/stat interface. */
1864static 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. */
1872static 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. */
1879static unsigned int tomoyo_stat_updated[TOMOYO_MAX_POLICY_STAT];
1880/* Counter for number of updates. */
1881static unsigned int tomoyo_stat_modified[TOMOYO_MAX_POLICY_STAT];
1882
1883/**
1884 * tomoyo_update_stat - Update statistic counters.
1885 *
1886 * @index: Index for policy type.
1887 *
1888 * Returns nothing.
1889 */
1890void 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 */
1908static 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 */
1950static 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
1860/** 1961/**
1861 * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface. 1962 * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface.
1862 * 1963 *
@@ -1908,11 +2009,11 @@ int tomoyo_open_control(const u8 type, struct file *file)
1908 head->read = tomoyo_read_version; 2009 head->read = tomoyo_read_version;
1909 head->readbuf_size = 128; 2010 head->readbuf_size = 128;
1910 break; 2011 break;
1911 case TOMOYO_MEMINFO: 2012 case TOMOYO_STAT:
1912 /* /sys/kernel/security/tomoyo/meminfo */ 2013 /* /sys/kernel/security/tomoyo/stat */
1913 head->write = tomoyo_write_memory_quota; 2014 head->write = tomoyo_write_stat;
1914 head->read = tomoyo_read_memory_counter; 2015 head->read = tomoyo_read_stat;
1915 head->readbuf_size = 512; 2016 head->readbuf_size = 1024;
1916 break; 2017 break;
1917 case TOMOYO_PROFILE: 2018 case TOMOYO_PROFILE:
1918 /* /sys/kernel/security/tomoyo/profile */ 2019 /* /sys/kernel/security/tomoyo/profile */
@@ -2186,6 +2287,20 @@ ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head,
2186 case -EPERM: 2287 case -EPERM:
2187 error = -EPERM; 2288 error = -EPERM;
2188 goto out; 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 }
2191out: 2306out:
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index b54455dfe0ca..7984a0ed548b 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -133,6 +133,7 @@ enum tomoyo_path_acl_index {
133 TOMOYO_MAX_PATH_OPERATION 133 TOMOYO_MAX_PATH_OPERATION
134}; 134};
135 135
136/* Index numbers for /sys/kernel/security/tomoyo/stat interface. */
136enum tomoyo_memory_stat_type { 137enum tomoyo_memory_stat_type {
137 TOMOYO_MEMORY_POLICY, 138 TOMOYO_MEMORY_POLICY,
138 TOMOYO_MEMORY_AUDIT, 139 TOMOYO_MEMORY_AUDIT,
@@ -173,7 +174,7 @@ enum tomoyo_securityfs_interface_index {
173 TOMOYO_EXCEPTIONPOLICY, 174 TOMOYO_EXCEPTIONPOLICY,
174 TOMOYO_DOMAIN_STATUS, 175 TOMOYO_DOMAIN_STATUS,
175 TOMOYO_PROCESS_STATUS, 176 TOMOYO_PROCESS_STATUS,
176 TOMOYO_MEMINFO, 177 TOMOYO_STAT,
177 TOMOYO_SELFDOMAIN, 178 TOMOYO_SELFDOMAIN,
178 TOMOYO_AUDIT, 179 TOMOYO_AUDIT,
179 TOMOYO_VERSION, 180 TOMOYO_VERSION,
@@ -237,6 +238,16 @@ enum tomoyo_mac_category_index {
237 */ 238 */
238#define TOMOYO_RETRY_REQUEST 1 239#define TOMOYO_RETRY_REQUEST 1
239 240
241/* Index numbers for /sys/kernel/security/tomoyo/stat interface. */
242enum 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/* Index numbers for profile's PREFERENCE values. */ 251/* Index numbers for profile's PREFERENCE values. */
241enum tomoyo_pref_index { 252enum tomoyo_pref_index {
242 TOMOYO_PREF_MAX_AUDIT_LOG, 253 TOMOYO_PREF_MAX_AUDIT_LOG,
@@ -648,8 +659,8 @@ char *tomoyo_realpath_from_path(struct path *path);
648bool tomoyo_memory_ok(void *ptr); 659bool tomoyo_memory_ok(void *ptr);
649void *tomoyo_commit_ok(void *data, const unsigned int size); 660void *tomoyo_commit_ok(void *data, const unsigned int size);
650const struct tomoyo_path_info *tomoyo_get_name(const char *name); 661const struct tomoyo_path_info *tomoyo_get_name(const char *name);
651void tomoyo_read_memory_counter(struct tomoyo_io_buffer *head); 662void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp);
652int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head); 663void tomoyo_update_stat(const u8 index);
653void __init tomoyo_mm_init(void); 664void __init tomoyo_mm_init(void);
654int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation, 665int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
655 const struct tomoyo_path_info *filename); 666 const struct tomoyo_path_info *filename);
diff --git a/security/tomoyo/memory.c b/security/tomoyo/memory.c
index 39d012823f84..78b6143068de 100644
--- a/security/tomoyo/memory.c
+++ b/security/tomoyo/memory.c
@@ -29,16 +29,13 @@ void tomoyo_warn_oom(const char *function)
29 panic("MAC Initialization failed.\n"); 29 panic("MAC Initialization failed.\n");
30} 30}
31 31
32/* Lock for protecting tomoyo_memory_used. */
33static DEFINE_SPINLOCK(tomoyo_policy_memory_lock);
32/* Memoy currently used by policy/audit log/query. */ 34/* Memoy currently used by policy/audit log/query. */
33unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT]; 35unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT];
34/* Memory quota for "policy"/"audit log"/"query". */ 36/* Memory quota for "policy"/"audit log"/"query". */
35unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT]; 37unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT];
36 38
37/* Memory allocated for policy. */
38static atomic_t tomoyo_policy_memory_size;
39/* Quota for holding policy. */
40static unsigned int tomoyo_quota_for_policy;
41
42/** 39/**
43 * tomoyo_memory_ok - Check memory quota. 40 * tomoyo_memory_ok - Check memory quota.
44 * 41 *
@@ -50,15 +47,20 @@ static unsigned int tomoyo_quota_for_policy;
50 */ 47 */
51bool tomoyo_memory_ok(void *ptr) 48bool tomoyo_memory_ok(void *ptr)
52{ 49{
53 size_t s = ptr ? ksize(ptr) : 0; 50 if (ptr) {
54 atomic_add(s, &tomoyo_policy_memory_size); 51 const size_t s = ksize(ptr);
55 if (ptr && (!tomoyo_quota_for_policy || 52 bool result;
56 atomic_read(&tomoyo_policy_memory_size) 53 spin_lock(&tomoyo_policy_memory_lock);
57 <= tomoyo_quota_for_policy)) { 54 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] += s;
58 memset(ptr, 0, s); 55 result = !tomoyo_memory_quota[TOMOYO_MEMORY_POLICY] ||
59 return true; 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 tomoyo_warn_oom(__func__); 64 tomoyo_warn_oom(__func__);
63 return false; 65 return false;
64} 66}
@@ -91,7 +93,10 @@ void *tomoyo_commit_ok(void *data, const unsigned int size)
91 */ 93 */
92void tomoyo_memory_free(void *ptr) 94void 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 kfree(ptr); 100 kfree(ptr);
96} 101}
97 102
@@ -162,7 +167,6 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
162 struct tomoyo_name *ptr; 167 struct tomoyo_name *ptr;
163 unsigned int hash; 168 unsigned int hash;
164 int len; 169 int len;
165 int allocated_len;
166 struct list_head *head; 170 struct list_head *head;
167 171
168 if (!name) 172 if (!name)
@@ -179,22 +183,17 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
179 goto out; 183 goto out;
180 } 184 }
181 ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS); 185 ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS);
182 allocated_len = ptr ? ksize(ptr) : 0; 186 if (tomoyo_memory_ok(ptr)) {
183 if (!ptr || (tomoyo_quota_for_policy && 187 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
184 atomic_read(&tomoyo_policy_memory_size) + allocated_len 188 memmove((char *) ptr->entry.name, name, len);
185 > tomoyo_quota_for_policy)) { 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 kfree(ptr); 193 kfree(ptr);
187 ptr = NULL; 194 ptr = NULL;
188 tomoyo_warn_oom(__func__);
189 goto out;
190 } 195 }
191 atomic_add(allocated_len, &tomoyo_policy_memory_size); 196out:
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:
198 mutex_unlock(&tomoyo_policy_lock); 197 mutex_unlock(&tomoyo_policy_lock);
199 return ptr ? &ptr->entry : NULL; 198 return ptr ? &ptr->entry : NULL;
200} 199}
@@ -227,65 +226,3 @@ void __init tomoyo_mm_init(void)
227 } 226 }
228#endif 227#endif
229} 228}
230
231
232/* Memory allocated for query lists. */
233unsigned int tomoyo_query_memory_size;
234/* Quota for holding query lists. */
235unsigned 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 */
244void 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 */
281int 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}
diff --git a/security/tomoyo/securityfs_if.c b/security/tomoyo/securityfs_if.c
index e056609b422b..b509e2cd2ab1 100644
--- a/security/tomoyo/securityfs_if.c
+++ b/security/tomoyo/securityfs_if.c
@@ -143,8 +143,8 @@ static int __init tomoyo_initerface_init(void)
143 TOMOYO_DOMAIN_STATUS); 143 TOMOYO_DOMAIN_STATUS);
144 tomoyo_create_entry(".process_status", 0600, tomoyo_dir, 144 tomoyo_create_entry(".process_status", 0600, tomoyo_dir,
145 TOMOYO_PROCESS_STATUS); 145 TOMOYO_PROCESS_STATUS);
146 tomoyo_create_entry("meminfo", 0600, tomoyo_dir, 146 tomoyo_create_entry("stat", 0644, tomoyo_dir,
147 TOMOYO_MEMINFO); 147 TOMOYO_STAT);
148 tomoyo_create_entry("profile", 0600, tomoyo_dir, 148 tomoyo_create_entry("profile", 0600, tomoyo_dir,
149 TOMOYO_PROFILE); 149 TOMOYO_PROFILE);
150 tomoyo_create_entry("manager", 0600, tomoyo_dir, 150 tomoyo_create_entry("manager", 0600, tomoyo_dir,
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index daf7a45f70f1..7ff54c95e1f2 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -47,6 +47,47 @@ const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX] = {
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 */
59void 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 * tomoyo_permstr - Find permission keywords. 91 * tomoyo_permstr - Find permission keywords.
51 * 92 *
52 * @string: String representation for permissions in foo/bar/buz format. 93 * @string: String representation for permissions in foo/bar/buz format.