オープンソース・ソフトウェアの開発とダウンロード

Subversion リポジトリの参照

Annotation of /trunk/1.7.x/ccs-patch/security/ccsecurity/util.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3487 - (hide annotations) (download) (as text)
Tue Mar 2 05:50:36 2010 UTC (14 years, 2 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 30326 byte(s)


1 kumaneko 111 /*
2 kumaneko 2864 * security/ccsecurity/util.c
3 kumaneko 111 *
4 kumaneko 2030 * Copyright (C) 2005-2009 NTT DATA CORPORATION
5 kumaneko 111 *
6 kumaneko 3275 * Version: 1.7.1+ 2009/12/20
7 kumaneko 111 *
8     * This file is applicable to both 2.4.30 and 2.6.11 and later.
9     * See README.ccs for ChangeLog.
10     *
11     */
12    
13 kumaneko 2854 #include "internal.h"
14 kumaneko 1052
15 kumaneko 2948 /* Lock for protecting policy. */
16 kumaneko 2690 DEFINE_MUTEX(ccs_policy_lock);
17 kumaneko 2540
18 kumaneko 1052 /* Has /sbin/init started? */
19 kumaneko 2040 bool ccs_policy_loaded;
20 kumaneko 111
21 kumaneko 2948 /* Index table for searching parent category. */
22 kumaneko 2943 static const u8 ccs_index2category[CCS_MAX_MAC_INDEX +
23     CCS_MAX_CAPABILITY_INDEX] = {
24     [CCS_MAC_FILE_EXECUTE] = CCS_MAC_CATEGORY_FILE,
25     [CCS_MAC_FILE_OPEN] = CCS_MAC_CATEGORY_FILE,
26     [CCS_MAC_FILE_CREATE] = CCS_MAC_CATEGORY_FILE,
27     [CCS_MAC_FILE_UNLINK] = CCS_MAC_CATEGORY_FILE,
28     [CCS_MAC_FILE_MKDIR] = CCS_MAC_CATEGORY_FILE,
29     [CCS_MAC_FILE_RMDIR] = CCS_MAC_CATEGORY_FILE,
30     [CCS_MAC_FILE_MKFIFO] = CCS_MAC_CATEGORY_FILE,
31     [CCS_MAC_FILE_MKSOCK] = CCS_MAC_CATEGORY_FILE,
32     [CCS_MAC_FILE_TRUNCATE] = CCS_MAC_CATEGORY_FILE,
33     [CCS_MAC_FILE_SYMLINK] = CCS_MAC_CATEGORY_FILE,
34     [CCS_MAC_FILE_REWRITE] = CCS_MAC_CATEGORY_FILE,
35     [CCS_MAC_FILE_MKBLOCK] = CCS_MAC_CATEGORY_FILE,
36     [CCS_MAC_FILE_MKCHAR] = CCS_MAC_CATEGORY_FILE,
37     [CCS_MAC_FILE_LINK] = CCS_MAC_CATEGORY_FILE,
38     [CCS_MAC_FILE_RENAME] = CCS_MAC_CATEGORY_FILE,
39     [CCS_MAC_FILE_CHMOD] = CCS_MAC_CATEGORY_FILE,
40     [CCS_MAC_FILE_CHOWN] = CCS_MAC_CATEGORY_FILE,
41     [CCS_MAC_FILE_CHGRP] = CCS_MAC_CATEGORY_FILE,
42     [CCS_MAC_FILE_IOCTL] = CCS_MAC_CATEGORY_FILE,
43     [CCS_MAC_FILE_CHROOT] = CCS_MAC_CATEGORY_FILE,
44     [CCS_MAC_FILE_MOUNT] = CCS_MAC_CATEGORY_FILE,
45     [CCS_MAC_FILE_UMOUNT] = CCS_MAC_CATEGORY_FILE,
46     [CCS_MAC_FILE_PIVOT_ROOT] = CCS_MAC_CATEGORY_FILE,
47     [CCS_MAC_ENVIRON] = CCS_MAC_CATEGORY_MISC,
48     [CCS_MAC_NETWORK_UDP_BIND] = CCS_MAC_CATEGORY_NETWORK,
49     [CCS_MAC_NETWORK_UDP_CONNECT] = CCS_MAC_CATEGORY_NETWORK,
50     [CCS_MAC_NETWORK_TCP_BIND] = CCS_MAC_CATEGORY_NETWORK,
51     [CCS_MAC_NETWORK_TCP_LISTEN] = CCS_MAC_CATEGORY_NETWORK,
52     [CCS_MAC_NETWORK_TCP_CONNECT] = CCS_MAC_CATEGORY_NETWORK,
53     [CCS_MAC_NETWORK_TCP_ACCEPT] = CCS_MAC_CATEGORY_NETWORK,
54     [CCS_MAC_NETWORK_RAW_BIND] = CCS_MAC_CATEGORY_NETWORK,
55     [CCS_MAC_NETWORK_RAW_CONNECT] = CCS_MAC_CATEGORY_NETWORK,
56     [CCS_MAC_SIGNAL] = CCS_MAC_CATEGORY_IPC,
57     [CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_CREATE]
58     = CCS_MAC_CATEGORY_CAPABILITY,
59     [CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_LISTEN]
60     = CCS_MAC_CATEGORY_CAPABILITY,
61     [CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_CONNECT]
62     = CCS_MAC_CATEGORY_CAPABILITY,
63     [CCS_MAX_MAC_INDEX + CCS_USE_INET_DGRAM_SOCKET]
64     = CCS_MAC_CATEGORY_CAPABILITY,
65     [CCS_MAX_MAC_INDEX + CCS_USE_INET_RAW_SOCKET]
66     = CCS_MAC_CATEGORY_CAPABILITY,
67     [CCS_MAX_MAC_INDEX + CCS_USE_ROUTE_SOCKET]
68     = CCS_MAC_CATEGORY_CAPABILITY,
69     [CCS_MAX_MAC_INDEX + CCS_USE_PACKET_SOCKET]
70     = CCS_MAC_CATEGORY_CAPABILITY,
71     [CCS_MAX_MAC_INDEX + CCS_SYS_MOUNT]
72     = CCS_MAC_CATEGORY_CAPABILITY,
73     [CCS_MAX_MAC_INDEX + CCS_SYS_UMOUNT]
74     = CCS_MAC_CATEGORY_CAPABILITY,
75     [CCS_MAX_MAC_INDEX + CCS_SYS_REBOOT]
76     = CCS_MAC_CATEGORY_CAPABILITY,
77     [CCS_MAX_MAC_INDEX + CCS_SYS_CHROOT]
78     = CCS_MAC_CATEGORY_CAPABILITY,
79     [CCS_MAX_MAC_INDEX + CCS_SYS_KILL]
80     = CCS_MAC_CATEGORY_CAPABILITY,
81     [CCS_MAX_MAC_INDEX + CCS_SYS_VHANGUP]
82     = CCS_MAC_CATEGORY_CAPABILITY,
83     [CCS_MAX_MAC_INDEX + CCS_SYS_SETTIME]
84     = CCS_MAC_CATEGORY_CAPABILITY,
85     [CCS_MAX_MAC_INDEX + CCS_SYS_NICE]
86     = CCS_MAC_CATEGORY_CAPABILITY,
87     [CCS_MAX_MAC_INDEX + CCS_SYS_SETHOSTNAME]
88     = CCS_MAC_CATEGORY_CAPABILITY,
89     [CCS_MAX_MAC_INDEX + CCS_USE_KERNEL_MODULE]
90     = CCS_MAC_CATEGORY_CAPABILITY,
91     [CCS_MAX_MAC_INDEX + CCS_CREATE_FIFO]
92     = CCS_MAC_CATEGORY_CAPABILITY,
93     [CCS_MAX_MAC_INDEX + CCS_CREATE_BLOCK_DEV]
94     = CCS_MAC_CATEGORY_CAPABILITY,
95     [CCS_MAX_MAC_INDEX + CCS_CREATE_CHAR_DEV]
96     = CCS_MAC_CATEGORY_CAPABILITY,
97     [CCS_MAX_MAC_INDEX + CCS_CREATE_UNIX_SOCKET]
98     = CCS_MAC_CATEGORY_CAPABILITY,
99     [CCS_MAX_MAC_INDEX + CCS_SYS_LINK]
100     = CCS_MAC_CATEGORY_CAPABILITY,
101     [CCS_MAX_MAC_INDEX + CCS_SYS_SYMLINK]
102     = CCS_MAC_CATEGORY_CAPABILITY,
103     [CCS_MAX_MAC_INDEX + CCS_SYS_RENAME]
104     = CCS_MAC_CATEGORY_CAPABILITY,
105     [CCS_MAX_MAC_INDEX + CCS_SYS_UNLINK]
106     = CCS_MAC_CATEGORY_CAPABILITY,
107     [CCS_MAX_MAC_INDEX + CCS_SYS_CHMOD]
108     = CCS_MAC_CATEGORY_CAPABILITY,
109     [CCS_MAX_MAC_INDEX + CCS_SYS_CHOWN]
110     = CCS_MAC_CATEGORY_CAPABILITY,
111     [CCS_MAX_MAC_INDEX + CCS_SYS_IOCTL]
112     = CCS_MAC_CATEGORY_CAPABILITY,
113     [CCS_MAX_MAC_INDEX + CCS_SYS_KEXEC_LOAD]
114     = CCS_MAC_CATEGORY_CAPABILITY,
115     [CCS_MAX_MAC_INDEX + CCS_SYS_PIVOT_ROOT]
116     = CCS_MAC_CATEGORY_CAPABILITY,
117     [CCS_MAX_MAC_INDEX + CCS_SYS_PTRACE]
118     = CCS_MAC_CATEGORY_CAPABILITY,
119     [CCS_MAX_MAC_INDEX + CCS_CONCEAL_MOUNT]
120     = CCS_MAC_CATEGORY_CAPABILITY,
121     };
122    
123 kumaneko 1052 /* Utility functions. */
124 kumaneko 111
125 kumaneko 1052 /**
126 kumaneko 2871 * ccs_parse_ulong - Parse an "unsigned long" value.
127     *
128     * @result: Pointer to "unsigned long".
129     * @str: Pointer to string to parse.
130     *
131     * Returns value type on success, 0 otherwise.
132     *
133     * The @src is updated to point the first character after the value
134     * on success.
135     */
136     u8 ccs_parse_ulong(unsigned long *result, char **str)
137     {
138     const char *cp = *str;
139     char *ep;
140     int base = 10;
141     if (*cp == '0') {
142     char c = *(cp + 1);
143     if (c == 'x' || c == 'X') {
144     base = 16;
145     cp += 2;
146     } else if (c >= '0' && c <= '7') {
147     base = 8;
148     cp++;
149     }
150     }
151     *result = simple_strtoul(cp, &ep, base);
152     if (cp == ep)
153     return 0;
154     *str = ep;
155     switch (base) {
156     case 16:
157 kumaneko 2892 return CCS_VALUE_TYPE_HEXADECIMAL;
158 kumaneko 2871 case 8:
159 kumaneko 2892 return CCS_VALUE_TYPE_OCTAL;
160 kumaneko 2871 default:
161 kumaneko 2892 return CCS_VALUE_TYPE_DECIMAL;
162 kumaneko 2871 }
163     }
164    
165     /**
166     * ccs_print_ulong - Print an "unsigned long" value.
167     *
168     * @buffer: Pointer to buffer.
169     * @buffer_len: Size of @buffer.
170     * @value: An "unsigned long" value.
171     * @type: Type of @value.
172     *
173     * Returns nothing.
174     */
175     void ccs_print_ulong(char *buffer, const int buffer_len,
176     const unsigned long value, const u8 type)
177     {
178 kumaneko 2892 if (type == CCS_VALUE_TYPE_DECIMAL)
179 kumaneko 2871 snprintf(buffer, buffer_len, "%lu", value);
180 kumaneko 2892 else if (type == CCS_VALUE_TYPE_OCTAL)
181 kumaneko 2871 snprintf(buffer, buffer_len, "0%lo", value);
182 kumaneko 2892 else if (type == CCS_VALUE_TYPE_HEXADECIMAL)
183 kumaneko 2871 snprintf(buffer, buffer_len, "0x%lX", value);
184     else
185     snprintf(buffer, buffer_len, "type(%u)", type);
186     }
187    
188 kumaneko 2948 /**
189     * ccs_parse_name_union - Parse a ccs_name_union.
190     *
191     * @filename: Name or name group.
192     * @ptr: Pointer to "struct ccs_name_union".
193     *
194     * Returns true on success, false otherwise.
195     */
196 kumaneko 2894 bool ccs_parse_name_union(const char *filename, struct ccs_name_union *ptr)
197     {
198     if (!ccs_is_correct_path(filename, 0, 0, 0))
199     return false;
200     if (filename[0] == '@') {
201     ptr->group = ccs_get_path_group(filename + 1);
202     ptr->is_group = true;
203     return ptr->group != NULL;
204     }
205     ptr->filename = ccs_get_name(filename);
206     ptr->is_group = false;
207     return ptr->filename != NULL;
208     }
209    
210 kumaneko 2948 /**
211     * ccs_parse_number_union - Parse a ccs_number_union.
212     *
213     * @data: Number or number range or number group.
214     * @ptr: Pointer to "struct ccs_number_union".
215     *
216     * Returns true on success, false otherwise.
217     */
218 kumaneko 2888 bool ccs_parse_number_union(char *data, struct ccs_number_union *num)
219 kumaneko 2871 {
220     u8 type;
221     unsigned long v;
222     memset(num, 0, sizeof(*num));
223 kumaneko 2890 if (data[0] == '@') {
224     if (!ccs_is_correct_path(data, 0, 0, 0))
225     return false;
226     num->group = ccs_get_number_group(data + 1);
227     num->is_group = true;
228     return num->group != NULL;
229     }
230 kumaneko 2871 type = ccs_parse_ulong(&v, &data);
231     if (!type)
232     return false;
233 kumaneko 2888 num->values[0] = v;
234     num->min_type = type;
235 kumaneko 2871 if (!*data) {
236 kumaneko 2888 num->values[1] = v;
237     num->max_type = type;
238 kumaneko 2871 return true;
239     }
240     if (*data++ != '-')
241     return false;
242     type = ccs_parse_ulong(&v, &data);
243     if (!type || *data)
244     return false;
245 kumaneko 2888 num->values[1] = v;
246     num->max_type = type;
247 kumaneko 2871 return true;
248     }
249    
250     /**
251 kumaneko 2002 * ccs_is_byte_range - Check whether the string isa \ooo style octal value.
252 kumaneko 1052 *
253     * @str: Pointer to the string.
254     *
255     * Returns true if @str is a \ooo style octal value, false otherwise.
256     */
257 kumaneko 2002 static inline bool ccs_is_byte_range(const char *str)
258 kumaneko 1052 {
259     return *str >= '0' && *str++ <= '3' &&
260     *str >= '0' && *str++ <= '7' &&
261     *str >= '0' && *str <= '7';
262     }
263    
264     /**
265 kumaneko 2002 * ccs_is_decimal - Check whether the character is a decimal character.
266 kumaneko 1052 *
267     * @c: The character to check.
268     *
269     * Returns true if @c is a decimal character, false otherwise.
270     */
271 kumaneko 2002 static inline bool ccs_is_decimal(const char c)
272 kumaneko 1052 {
273 kumaneko 1468 return c >= '0' && c <= '9';
274 kumaneko 1052 }
275    
276     /**
277 kumaneko 2002 * ccs_is_hexadecimal - Check whether the character is a hexadecimal character.
278 kumaneko 1052 *
279     * @c: The character to check.
280     *
281     * Returns true if @c is a hexadecimal character, false otherwise.
282     */
283 kumaneko 2002 static inline bool ccs_is_hexadecimal(const char c)
284 kumaneko 1052 {
285 kumaneko 1468 return (c >= '0' && c <= '9') ||
286 kumaneko 1052 (c >= 'A' && c <= 'F') ||
287 kumaneko 1468 (c >= 'a' && c <= 'f');
288 kumaneko 1052 }
289    
290     /**
291 kumaneko 2002 * ccs_is_alphabet_char - Check whether the character is an alphabet.
292 kumaneko 1052 *
293     * @c: The character to check.
294     *
295     * Returns true if @c is an alphabet character, false otherwise.
296     */
297 kumaneko 2002 static inline bool ccs_is_alphabet_char(const char c)
298 kumaneko 1052 {
299 kumaneko 1794 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
300 kumaneko 1052 }
301    
302     /**
303 kumaneko 2002 * ccs_make_byte - Make byte value from three octal characters.
304 kumaneko 1064 *
305     * @c1: The first character.
306     * @c2: The second character.
307     * @c3: The third character.
308     *
309     * Returns byte value.
310     */
311 kumaneko 2002 static inline u8 ccs_make_byte(const u8 c1, const u8 c2, const u8 c3)
312 kumaneko 1064 {
313     return ((c1 - '0') << 6) + ((c2 - '0') << 3) + (c3 - '0');
314     }
315    
316     /**
317 kumaneko 2002 * ccs_str_starts - Check whether the given string starts with the given keyword.
318 kumaneko 1052 *
319     * @src: Pointer to pointer to the string.
320     * @find: Pointer to the keyword.
321     *
322     * Returns true if @src starts with @find, false otherwise.
323     *
324     * The @src is updated to point the first character after the @find
325 kumaneko 1064 * if @src starts with @find.
326 kumaneko 1052 */
327 kumaneko 2863 bool ccs_str_starts(char **src, const char *find)
328 kumaneko 1052 {
329     const int len = strlen(find);
330     char *tmp = *src;
331     if (strncmp(tmp, find, len))
332     return false;
333     tmp += len;
334     *src = tmp;
335     return true;
336     }
337    
338     /**
339 kumaneko 2002 * ccs_normalize_line - Format string.
340 kumaneko 1052 *
341     * @buffer: The line to normalize.
342     *
343 kumaneko 111 * Leading and trailing whitespaces are removed.
344     * Multiple whitespaces are packed into single space.
345 kumaneko 1052 *
346     * Returns nothing.
347 kumaneko 111 */
348 kumaneko 2308 void ccs_normalize_line(unsigned char *buffer)
349 kumaneko 111 {
350 kumaneko 1064 unsigned char *sp = buffer;
351     unsigned char *dp = buffer;
352 kumaneko 1006 bool first = true;
353 kumaneko 1052 while (*sp && (*sp <= ' ' || *sp >= 127))
354     sp++;
355 kumaneko 111 while (*sp) {
356 kumaneko 1052 if (!first)
357     *dp++ = ' ';
358 kumaneko 1006 first = false;
359 kumaneko 1052 while (*sp > ' ' && *sp < 127)
360     *dp++ = *sp++;
361     while (*sp && (*sp <= ' ' || *sp >= 127))
362     sp++;
363 kumaneko 111 }
364     *dp = '\0';
365     }
366    
367 kumaneko 1052 /**
368 kumaneko 2779 * ccs_tokenize - Tokenize string.
369     *
370     * @buffer: The line to tokenize.
371     * @w: Pointer to "char *".
372     * @size: Sizeof @w .
373     *
374     * Returns true on success, false otherwise.
375     */
376     bool ccs_tokenize(char *buffer, char *w[], size_t size)
377     {
378     int count = size / sizeof(char *);
379     int i;
380     for (i = 0; i < count; i++)
381     w[i] = "";
382     for (i = 0; i < count; i++) {
383     char *cp = strchr(buffer, ' ');
384     if (cp)
385     *cp = '\0';
386     w[i] = buffer;
387     if (!cp)
388     break;
389     buffer = cp + 1;
390     }
391     return i < count || !*buffer;
392     }
393    
394     /**
395 kumaneko 1054 * ccs_is_correct_path - Validate a pathname.
396 kumaneko 3046 *
397 kumaneko 1054 * @filename: The pathname to check.
398     * @start_type: Should the pathname start with '/'?
399     * 1 = must / -1 = must not / 0 = don't care
400     * @pattern_type: Can the pathname contain a wildcard?
401     * 1 = must / -1 = must not / 0 = don't care
402     * @end_type: Should the pathname end with '/'?
403     * 1 = must / -1 = must not / 0 = don't care
404 kumaneko 1052 *
405 kumaneko 1054 * Check whether the given filename follows the naming rules.
406 kumaneko 1052 * Returns true if @filename follows the naming rules, false otherwise.
407 kumaneko 111 */
408 kumaneko 1052 bool ccs_is_correct_path(const char *filename, const s8 start_type,
409 kumaneko 2577 const s8 pattern_type, const s8 end_type)
410 kumaneko 111 {
411 kumaneko 3012 const char *const start = filename;
412     bool in_repetition = false;
413 kumaneko 1006 bool contains_pattern = false;
414 kumaneko 1064 unsigned char c;
415     unsigned char d;
416     unsigned char e;
417 kumaneko 1052 if (!filename)
418     goto out;
419 kumaneko 111 c = *filename;
420     if (start_type == 1) { /* Must start with '/' */
421 kumaneko 1052 if (c != '/')
422     goto out;
423 kumaneko 111 } else if (start_type == -1) { /* Must not start with '/' */
424 kumaneko 1052 if (c == '/')
425     goto out;
426 kumaneko 111 }
427 kumaneko 1052 if (c)
428 kumaneko 1795 c = *(filename + strlen(filename) - 1);
429 kumaneko 111 if (end_type == 1) { /* Must end with '/' */
430 kumaneko 1052 if (c != '/')
431     goto out;
432 kumaneko 111 } else if (end_type == -1) { /* Must not end with '/' */
433 kumaneko 1052 if (c == '/')
434     goto out;
435 kumaneko 111 }
436 kumaneko 1747 while (1) {
437     c = *filename++;
438     if (!c)
439     break;
440 kumaneko 111 if (c == '\\') {
441 kumaneko 1747 c = *filename++;
442     switch (c) {
443 kumaneko 111 case '\\': /* "\\" */
444     continue;
445     case '$': /* "\$" */
446     case '+': /* "\+" */
447     case '?': /* "\?" */
448     case '*': /* "\*" */
449     case '@': /* "\@" */
450     case 'x': /* "\x" */
451     case 'X': /* "\X" */
452     case 'a': /* "\a" */
453     case 'A': /* "\A" */
454 kumaneko 206 case '-': /* "\-" */
455 kumaneko 1052 if (pattern_type == -1)
456     break; /* Must not contain pattern */
457 kumaneko 1006 contains_pattern = true;
458 kumaneko 111 continue;
459 kumaneko 3012 case '{': /* "/\{" */
460     if (filename - 3 < start ||
461     *(filename - 3) != '/')
462     break;
463     if (pattern_type == -1)
464     break; /* Must not contain pattern */
465     contains_pattern = true;
466     in_repetition = true;
467     continue;
468     case '}': /* "\}/" */
469     if (*filename != '/')
470     break;
471     if (!in_repetition)
472     break;
473     in_repetition = false;
474     continue;
475 kumaneko 111 case '0': /* "\ooo" */
476     case '1':
477     case '2':
478     case '3':
479 kumaneko 1052 d = *filename++;
480     if (d < '0' || d > '7')
481     break;
482     e = *filename++;
483     if (e < '0' || e > '7')
484     break;
485 kumaneko 2002 c = ccs_make_byte(c, d, e);
486 kumaneko 1052 if (c && (c <= ' ' || c >= 127))
487     continue; /* pattern is not \000 */
488 kumaneko 111 }
489     goto out;
490 kumaneko 3012 } else if (in_repetition && c == '/') {
491     goto out;
492 kumaneko 111 } else if (c <= ' ' || c >= 127) {
493     goto out;
494     }
495     }
496     if (pattern_type == 1) { /* Must contain pattern */
497 kumaneko 1052 if (!contains_pattern)
498     goto out;
499 kumaneko 111 }
500 kumaneko 3012 if (in_repetition)
501     goto out;
502 kumaneko 1006 return true;
503 kumaneko 111 out:
504 kumaneko 1006 return false;
505 kumaneko 111 }
506    
507 kumaneko 1052 /**
508 kumaneko 1054 * ccs_is_correct_domain - Check whether the given domainname follows the naming rules.
509 kumaneko 3046 *
510 kumaneko 1054 * @domainname: The domainname to check.
511 kumaneko 1052 *
512     * Returns true if @domainname follows the naming rules, false otherwise.
513 kumaneko 111 */
514 kumaneko 2577 bool ccs_is_correct_domain(const unsigned char *domainname)
515 kumaneko 111 {
516 kumaneko 1064 unsigned char c;
517     unsigned char d;
518     unsigned char e;
519 kumaneko 1052 if (!domainname || strncmp(domainname, ROOT_NAME, ROOT_NAME_LEN))
520     goto out;
521 kumaneko 111 domainname += ROOT_NAME_LEN;
522 kumaneko 1052 if (!*domainname)
523     return true;
524 kumaneko 111 do {
525 kumaneko 1052 if (*domainname++ != ' ')
526     goto out;
527     if (*domainname++ != '/')
528     goto out;
529 kumaneko 1747 while (1) {
530     c = *domainname;
531     if (!c || c == ' ')
532     break;
533 kumaneko 111 domainname++;
534     if (c == '\\') {
535 kumaneko 1052 c = *domainname++;
536     switch ((c)) {
537 kumaneko 111 case '\\': /* "\\" */
538     continue;
539     case '0': /* "\ooo" */
540     case '1':
541     case '2':
542     case '3':
543 kumaneko 1052 d = *domainname++;
544     if (d < '0' || d > '7')
545     break;
546     e = *domainname++;
547     if (e < '0' || e > '7')
548     break;
549 kumaneko 2002 c = ccs_make_byte(c, d, e);
550 kumaneko 1052 if (c && (c <= ' ' || c >= 127))
551     /* pattern is not \000 */
552     continue;
553 kumaneko 111 }
554     goto out;
555     } else if (c < ' ' || c >= 127) {
556     goto out;
557     }
558     }
559     } while (*domainname);
560 kumaneko 1006 return true;
561 kumaneko 111 out:
562 kumaneko 1006 return false;
563 kumaneko 111 }
564    
565 kumaneko 1052 /**
566     * ccs_is_domain_def - Check whether the given token can be a domainname.
567     *
568     * @buffer: The token to check.
569     *
570     * Returns true if @buffer possibly be a domainname, false otherwise.
571     */
572     bool ccs_is_domain_def(const unsigned char *buffer)
573 kumaneko 461 {
574 kumaneko 1052 return !strncmp(buffer, ROOT_NAME, ROOT_NAME_LEN);
575 kumaneko 461 }
576    
577 kumaneko 1052 /**
578     * ccs_find_domain - Find a domain by the given name.
579     *
580 kumaneko 1054 * @domainname: The domainname to find.
581 kumaneko 1052 *
582 kumaneko 2690 * Returns pointer to "struct ccs_domain_info" if found, NULL otherwise.
583     *
584 kumaneko 2828 * Caller holds ccs_read_lock().
585 kumaneko 1052 */
586 kumaneko 2690 struct ccs_domain_info *ccs_find_domain(const char *domainname)
587 kumaneko 461 {
588 kumaneko 2282 struct ccs_domain_info *domain;
589 kumaneko 2002 struct ccs_path_info name;
590 kumaneko 1052 name.name = domainname;
591     ccs_fill_path_info(&name);
592 kumaneko 2690 list_for_each_entry_rcu(domain, &ccs_domain_list, list) {
593 kumaneko 2692 if (!domain->is_deleted &&
594     !ccs_pathcmp(&name, domain->domainname))
595     return domain;
596 kumaneko 461 }
597 kumaneko 2692 return NULL;
598 kumaneko 461 }
599    
600 kumaneko 1052 /**
601 kumaneko 2002 * ccs_const_part_length - Evaluate the initial length without a pattern in a token.
602 kumaneko 1052 *
603     * @filename: The string to evaluate.
604     *
605 kumaneko 1064 * Returns the initial length without a pattern in @filename.
606 kumaneko 1052 */
607 kumaneko 2002 static int ccs_const_part_length(const char *filename)
608 kumaneko 111 {
609 kumaneko 1052 char c;
610 kumaneko 111 int len = 0;
611 kumaneko 1052 if (!filename)
612     return 0;
613 kumaneko 1747 while (1) {
614     c = *filename++;
615     if (!c)
616     break;
617 kumaneko 1052 if (c != '\\') {
618     len++;
619     continue;
620 kumaneko 111 }
621 kumaneko 1052 c = *filename++;
622     switch (c) {
623     case '\\': /* "\\" */
624     len += 2;
625     continue;
626     case '0': /* "\ooo" */
627     case '1':
628     case '2':
629     case '3':
630     c = *filename++;
631     if (c < '0' || c > '7')
632     break;
633     c = *filename++;
634     if (c < '0' || c > '7')
635     break;
636     len += 4;
637     continue;
638     }
639     break;
640 kumaneko 111 }
641     return len;
642     }
643    
644 kumaneko 1052 /**
645 kumaneko 2002 * ccs_fill_path_info - Fill in "struct ccs_path_info" members.
646 kumaneko 1052 *
647 kumaneko 2002 * @ptr: Pointer to "struct ccs_path_info" to fill in.
648 kumaneko 1052 *
649 kumaneko 2002 * The caller sets "struct ccs_path_info"->name.
650 kumaneko 1052 */
651 kumaneko 2002 void ccs_fill_path_info(struct ccs_path_info *ptr)
652 kumaneko 111 {
653     const char *name = ptr->name;
654     const int len = strlen(name);
655     ptr->total_len = len;
656 kumaneko 2002 ptr->const_len = ccs_const_part_length(name);
657 kumaneko 111 ptr->is_dir = len && (name[len - 1] == '/');
658     ptr->is_patterned = (ptr->const_len < len);
659     ptr->hash = full_name_hash(name, len);
660     }
661    
662 kumaneko 1052 /**
663 kumaneko 3046 * ccs_file_matches_pattern2 - Pattern matching without '/' character and "\-" pattern.
664 kumaneko 1052 *
665     * @filename: The start of string to check.
666     * @filename_end: The end of string to check.
667     * @pattern: The start of pattern to compare.
668     * @pattern_end: The end of pattern to compare.
669     *
670     * Returns true if @filename matches @pattern, false otherwise.
671     */
672 kumaneko 2039 static bool ccs_file_matches_pattern2(const char *filename,
673     const char *filename_end,
674     const char *pattern,
675     const char *pattern_end)
676 kumaneko 111 {
677     while (filename < filename_end && pattern < pattern_end) {
678 kumaneko 1052 char c;
679 kumaneko 111 if (*pattern != '\\') {
680 kumaneko 1052 if (*filename++ != *pattern++)
681     return false;
682     continue;
683     }
684     c = *filename;
685     pattern++;
686     switch (*pattern) {
687 kumaneko 1064 int i;
688     int j;
689 kumaneko 1052 case '?':
690     if (c == '/') {
691     return false;
692     } else if (c == '\\') {
693     if (filename[1] == '\\')
694     filename++;
695 kumaneko 2002 else if (ccs_is_byte_range(filename + 1))
696 kumaneko 1052 filename += 3;
697     else
698 kumaneko 1006 return false;
699 kumaneko 1052 }
700     break;
701     case '\\':
702     if (c != '\\')
703     return false;
704     if (*++filename != '\\')
705     return false;
706     break;
707     case '+':
708 kumaneko 2002 if (!ccs_is_decimal(c))
709 kumaneko 1052 return false;
710     break;
711     case 'x':
712 kumaneko 2002 if (!ccs_is_hexadecimal(c))
713 kumaneko 1052 return false;
714     break;
715     case 'a':
716 kumaneko 2002 if (!ccs_is_alphabet_char(c))
717 kumaneko 1052 return false;
718     break;
719     case '0':
720     case '1':
721     case '2':
722     case '3':
723 kumaneko 2002 if (c == '\\' && ccs_is_byte_range(filename + 1)
724 kumaneko 3030 && !strncmp(filename + 1, pattern, 3)) {
725 kumaneko 1052 filename += 3;
726     pattern += 2;
727 kumaneko 111 break;
728 kumaneko 1052 }
729     return false; /* Not matched. */
730     case '*':
731     case '@':
732     for (i = 0; i <= filename_end - filename; i++) {
733 kumaneko 2039 if (ccs_file_matches_pattern2(filename + i,
734     filename_end,
735     pattern + 1,
736     pattern_end))
737 kumaneko 1052 return true;
738     c = filename[i];
739     if (c == '.' && *pattern == '@')
740 kumaneko 111 break;
741 kumaneko 1052 if (c != '\\')
742     continue;
743     if (filename[i + 1] == '\\')
744     i++;
745 kumaneko 2002 else if (ccs_is_byte_range(filename + i + 1))
746 kumaneko 1052 i += 3;
747     else
748     break; /* Bad pattern. */
749 kumaneko 111 }
750 kumaneko 1052 return false; /* Not matched. */
751     default:
752     j = 0;
753     c = *pattern;
754     if (c == '$') {
755 kumaneko 2002 while (ccs_is_decimal(filename[j]))
756 kumaneko 1052 j++;
757     } else if (c == 'X') {
758 kumaneko 2002 while (ccs_is_hexadecimal(filename[j]))
759 kumaneko 1052 j++;
760     } else if (c == 'A') {
761 kumaneko 2002 while (ccs_is_alphabet_char(filename[j]))
762 kumaneko 1052 j++;
763     }
764     for (i = 1; i <= j; i++) {
765 kumaneko 2039 if (ccs_file_matches_pattern2(filename + i,
766     filename_end,
767     pattern + 1,
768     pattern_end))
769 kumaneko 1052 return true;
770     }
771     return false; /* Not matched or bad pattern. */
772 kumaneko 111 }
773 kumaneko 1052 filename++;
774     pattern++;
775 kumaneko 111 }
776 kumaneko 1052 while (*pattern == '\\' &&
777     (*(pattern + 1) == '*' || *(pattern + 1) == '@'))
778     pattern += 2;
779 kumaneko 1468 return filename == filename_end && pattern == pattern_end;
780 kumaneko 111 }
781    
782 kumaneko 1052 /**
783 kumaneko 2039 * ccs_file_matches_pattern - Pattern matching without without '/' character.
784 kumaneko 1052 *
785     * @filename: The start of string to check.
786     * @filename_end: The end of string to check.
787     * @pattern: The start of pattern to compare.
788     * @pattern_end: The end of pattern to compare.
789     *
790     * Returns true if @filename matches @pattern, false otherwise.
791     */
792 kumaneko 2039 static bool ccs_file_matches_pattern(const char *filename,
793     const char *filename_end,
794     const char *pattern,
795     const char *pattern_end)
796 kumaneko 206 {
797     const char *pattern_start = pattern;
798 kumaneko 1006 bool first = true;
799     bool result;
800 kumaneko 206 while (pattern < pattern_end - 1) {
801 kumaneko 1052 /* Split at "\-" pattern. */
802     if (*pattern++ != '\\' || *pattern++ != '-')
803     continue;
804 kumaneko 2039 result = ccs_file_matches_pattern2(filename, filename_end,
805 kumaneko 2040 pattern_start, pattern - 2);
806 kumaneko 1052 if (first)
807     result = !result;
808     if (result)
809     return false;
810 kumaneko 1006 first = false;
811 kumaneko 206 pattern_start = pattern;
812     }
813 kumaneko 2039 result = ccs_file_matches_pattern2(filename, filename_end,
814     pattern_start, pattern_end);
815 kumaneko 206 return first ? result : !result;
816     }
817    
818 kumaneko 1052 /**
819 kumaneko 3012 * ccs_path_matches_pattern2 - Do pathname pattern matching.
820     *
821     * @f: The start of string to check.
822     * @p: The start of pattern to compare.
823     *
824     * Returns true if @f matches @p, false otherwise.
825     */
826     static bool ccs_path_matches_pattern2(const char *f, const char *p)
827     {
828     const char *f_delimiter;
829     const char *p_delimiter;
830     while (*f && *p) {
831     f_delimiter = strchr(f, '/');
832     if (!f_delimiter)
833 kumaneko 3033 f_delimiter = f + strlen(f);
834 kumaneko 3012 p_delimiter = strchr(p, '/');
835     if (!p_delimiter)
836 kumaneko 3033 p_delimiter = p + strlen(p);
837 kumaneko 3012 if (*p == '\\' && *(p + 1) == '{')
838     goto recursive;
839     if (!ccs_file_matches_pattern(f, f_delimiter, p, p_delimiter))
840     return false;
841     f = f_delimiter;
842     if (*f)
843     f++;
844     p = p_delimiter;
845     if (*p)
846     p++;
847     }
848     /* Ignore trailing "\*" and "\@" in @pattern. */
849     while (*p == '\\' &&
850     (*(p + 1) == '*' || *(p + 1) == '@'))
851     p += 2;
852     return !*f && !*p;
853     recursive:
854     /*
855     * The "\{" pattern is permitted only after '/' character.
856     * This guarantees that below "*(p - 1)" is safe.
857     * Also, the "\}" pattern is permitted only before '/' character
858     * so that "\{" + "\}" pair will not break the "\-" operator.
859     */
860     if (*(p - 1) != '/' || p_delimiter <= p + 3 || *p_delimiter != '/' ||
861     *(p_delimiter - 1) != '}' || *(p_delimiter - 2) != '\\')
862     return false; /* Bad pattern. */
863     do {
864     /* Compare current component with pattern. */
865     if (!ccs_file_matches_pattern(f, f_delimiter, p + 2,
866     p_delimiter - 2))
867     break;
868     /* Proceed to next component. */
869     f = f_delimiter;
870 kumaneko 3032 if (!*f)
871     break;
872     f++;
873 kumaneko 3012 /* Continue comparison. */
874     if (ccs_path_matches_pattern2(f, p_delimiter + 1))
875     return true;
876     f_delimiter = strchr(f, '/');
877     } while (f_delimiter);
878     return false; /* Not matched. */
879     }
880    
881     /**
882 kumaneko 1054 * ccs_path_matches_pattern - Check whether the given filename matches the given pattern.
883 kumaneko 3046 *
884 kumaneko 1052 * @filename: The filename to check.
885     * @pattern: The pattern to compare.
886 kumaneko 111 *
887 kumaneko 1052 * Returns true if matches, false otherwise.
888     *
889     * The following patterns are available.
890     * \\ \ itself.
891     * \ooo Octal representation of a byte.
892 kumaneko 3014 * \* Zero or more repetitions of characters other than '/'.
893     * \@ Zero or more repetitions of characters other than '/' or '.'.
894 kumaneko 1052 * \? 1 byte character other than '/'.
895 kumaneko 3014 * \$ One or more repetitions of decimal digits.
896 kumaneko 1052 * \+ 1 decimal digit.
897 kumaneko 3014 * \X One or more repetitions of hexadecimal digits.
898 kumaneko 1052 * \x 1 hexadecimal digit.
899 kumaneko 3014 * \A One or more repetitions of alphabet characters.
900 kumaneko 1052 * \a 1 alphabet character.
901 kumaneko 3014 *
902 kumaneko 1052 * \- Subtraction operator.
903 kumaneko 3012 *
904 kumaneko 3046 * /\{dir\}/ '/' + 'One or more repetitions of dir/' (e.g. /dir/ /dir/dir/
905 kumaneko 3014 * /dir/dir/dir/ ).
906 kumaneko 111 */
907 kumaneko 2002 bool ccs_path_matches_pattern(const struct ccs_path_info *filename,
908     const struct ccs_path_info *pattern)
909 kumaneko 111 {
910 kumaneko 1052 const char *f = filename->name;
911     const char *p = pattern->name;
912     const int len = pattern->const_len;
913     /* If @pattern doesn't contain pattern, I can use strcmp(). */
914     if (!pattern->is_patterned)
915     return !ccs_pathcmp(filename, pattern);
916 kumaneko 3012 /* Don't compare directory and non-directory. */
917     if (filename->is_dir != pattern->is_dir)
918 kumaneko 1052 return false;
919     /* Compare the initial length without patterns. */
920     if (strncmp(f, p, len))
921     return false;
922     f += len;
923     p += len;
924 kumaneko 3012 return ccs_path_matches_pattern2(f, p);
925 kumaneko 111 }
926    
927 kumaneko 1052 /**
928     * ccs_get_exe - Get ccs_realpath() of current process.
929     *
930     * Returns the ccs_realpath() of current process on success, NULL otherwise.
931     *
932 kumaneko 2711 * This function uses kzalloc(), so the caller must kfree()
933 kumaneko 1052 * if this function didn't return NULL.
934 kumaneko 111 */
935 kumaneko 1052 const char *ccs_get_exe(void)
936 kumaneko 111 {
937 kumaneko 737 struct mm_struct *mm = current->mm;
938     struct vm_area_struct *vma;
939     const char *cp = NULL;
940 kumaneko 1052 if (!mm)
941     return NULL;
942 kumaneko 737 down_read(&mm->mmap_sem);
943     for (vma = mm->mmap; vma; vma = vma->vm_next) {
944     if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
945 kumaneko 2911 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
946     struct path path = { vma->vm_file->f_vfsmnt,
947     vma->vm_file->f_dentry };
948     cp = ccs_realpath_from_path(&path);
949     #else
950     cp = ccs_realpath_from_path(&vma->vm_file->f_path);
951     #endif
952 kumaneko 737 break;
953 kumaneko 111 }
954     }
955 kumaneko 737 up_read(&mm->mmap_sem);
956     return cp;
957 kumaneko 111 }
958    
959 kumaneko 1052 /**
960 kumaneko 2943 * ccs_get_audit - Get audit mode.
961     *
962     * @profile: Profile number.
963     * @index: Index number of functionality.
964 kumaneko 3104 * @is_granted: True if granted log, false otherwise.
965 kumaneko 2943 *
966     * Returns mode.
967     */
968     bool ccs_get_audit(const u8 profile, const u8 index, const bool is_granted)
969     {
970     u8 mode;
971     const u8 category = ccs_index2category[index] + CCS_MAX_MAC_INDEX
972     + CCS_MAX_CAPABILITY_INDEX;
973 kumaneko 2958 if (!ccs_policy_loaded)
974 kumaneko 2943 return false;
975 kumaneko 2958 mode = ccs_profile(profile)->config[index];
976     if (mode == CCS_CONFIG_USE_DEFAULT)
977     mode = ccs_profile(profile)->config[category];
978     if (mode == CCS_CONFIG_USE_DEFAULT)
979     mode = ccs_profile(profile)->default_config;
980 kumaneko 2943 if (is_granted)
981 kumaneko 2973 return mode & CCS_CONFIG_WANT_GRANT_LOG;
982     return mode & CCS_CONFIG_WANT_REJECT_LOG;
983 kumaneko 2943 }
984    
985     /**
986     * ccs_get_mode - Get MAC mode.
987     *
988     * @profile: Profile number.
989     * @index: Index number of functionality.
990     *
991     * Returns mode.
992     */
993     int ccs_get_mode(const u8 profile, const u8 index)
994     {
995     u8 mode;
996     const u8 category = ccs_index2category[index] + CCS_MAX_MAC_INDEX
997     + CCS_MAX_CAPABILITY_INDEX;
998 kumaneko 2958 if (!ccs_policy_loaded)
999     return CCS_CONFIG_DISABLED;
1000     mode = ccs_profile(profile)->config[index];
1001     if (mode == CCS_CONFIG_USE_DEFAULT)
1002     mode = ccs_profile(profile)->config[category];
1003     if (mode == CCS_CONFIG_USE_DEFAULT)
1004     mode = ccs_profile(profile)->default_config;
1005 kumaneko 2943 return mode & 3;
1006     }
1007    
1008     /**
1009 kumaneko 1657 * ccs_init_request_info - Initialize "struct ccs_request_info" members.
1010     *
1011     * @r: Pointer to "struct ccs_request_info" to initialize.
1012 kumaneko 2282 * @domain: Pointer to "struct ccs_domain_info". NULL for ccs_current_domain().
1013 kumaneko 1657 * @index: Index number of functionality.
1014 kumaneko 2911 *
1015     * Returns mode.
1016 kumaneko 1657 */
1017 kumaneko 2911 int ccs_init_request_info(struct ccs_request_info *r,
1018     struct ccs_domain_info *domain, const u8 index)
1019 kumaneko 1657 {
1020 kumaneko 2943 u8 profile;
1021 kumaneko 1657 memset(r, 0, sizeof(*r));
1022     if (!domain)
1023 kumaneko 2282 domain = ccs_current_domain();
1024 kumaneko 2690 r->domain = domain;
1025 kumaneko 2943 profile = domain->profile;
1026     r->profile = profile;
1027 kumaneko 2918 r->type = index;
1028 kumaneko 2943 r->mode = ccs_get_mode(profile, index);
1029 kumaneko 2911 return r->mode;
1030 kumaneko 1657 }
1031    
1032     /**
1033 kumaneko 2943 * ccs_last_word - Get last component of a line.
1034 kumaneko 1052 *
1035 kumaneko 2943 * @line: A line.
1036 kumaneko 1657 *
1037 kumaneko 2943 * Returns the last word of a line.
1038 kumaneko 1052 */
1039 kumaneko 2943 const char *ccs_last_word(const char *name)
1040 kumaneko 111 {
1041 kumaneko 2943 const char *cp = strrchr(name, ' ');
1042     if (cp)
1043     return cp + 1;
1044     return name;
1045 kumaneko 111 }
1046    
1047 kumaneko 2948 /**
1048     * ccs_warn_log - Print warning or error message on console.
1049     *
1050     * @r: Pointer to "struct ccs_request_info".
1051     * @fmt: The printf()'s format string, followed by parameters.
1052     */
1053 kumaneko 2943 void ccs_warn_log(struct ccs_request_info *r, const char *fmt, ...)
1054     {
1055     int len = PAGE_SIZE;
1056     va_list args;
1057     char *buffer;
1058 kumaneko 2958 const struct ccs_profile *profile =
1059     ccs_profile(r->domain->profile);
1060     switch (r->mode) {
1061     case CCS_CONFIG_ENFORCING:
1062 kumaneko 2962 if (!profile->enforcing->enforcing_verbose)
1063 kumaneko 2958 return;
1064     break;
1065     case CCS_CONFIG_PERMISSIVE:
1066 kumaneko 2962 if (!profile->permissive->permissive_verbose)
1067 kumaneko 2958 return;
1068     break;
1069     case CCS_CONFIG_LEARNING:
1070 kumaneko 2962 if (!profile->learning->learning_verbose)
1071 kumaneko 2958 return;
1072     break;
1073     }
1074 kumaneko 2943 while (1) {
1075     int len2;
1076     buffer = kmalloc(len, GFP_KERNEL);
1077     if (!buffer)
1078     return;
1079     va_start(args, fmt);
1080     len2 = vsnprintf(buffer, len - 1, fmt, args);
1081     va_end(args);
1082 kumaneko 2981 if (len2 <= len - 1) {
1083 kumaneko 2943 buffer[len2] = '\0';
1084     break;
1085     }
1086     len = len2 + 1;
1087     kfree(buffer);
1088     }
1089     printk(KERN_WARNING "%s: Access %s denied for %s\n",
1090 kumaneko 2958 r->mode == CCS_CONFIG_ENFORCING ? "ERROR" : "WARNING", buffer,
1091 kumaneko 2943 ccs_last_word(r->domain->domainname->name));
1092     kfree(buffer);
1093     }
1094    
1095 kumaneko 1052 /**
1096 kumaneko 2209 * ccs_domain_quota_ok - Check for domain's quota.
1097 kumaneko 1052 *
1098 kumaneko 2780 * @r: Pointer to "struct ccs_request_info".
1099 kumaneko 1052 *
1100     * Returns true if the domain is not exceeded quota, false otherwise.
1101 kumaneko 2690 *
1102 kumaneko 2828 * Caller holds ccs_read_lock().
1103 kumaneko 1052 */
1104 kumaneko 2780 bool ccs_domain_quota_ok(struct ccs_request_info *r)
1105 kumaneko 512 {
1106     unsigned int count = 0;
1107 kumaneko 2780 struct ccs_domain_info *domain = r->domain;
1108 kumaneko 2002 struct ccs_acl_info *ptr;
1109 kumaneko 3487 if (r->mode != TOMOYO_CONFIG_LEARNING)
1110 kumaneko 2780 return false;
1111 kumaneko 1052 if (!domain)
1112     return true;
1113 kumaneko 2690 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
1114 kumaneko 2900 if (ptr->is_deleted)
1115 kumaneko 1064 continue;
1116 kumaneko 2900 switch (ptr->type) {
1117 kumaneko 1064 u16 perm;
1118 kumaneko 2916 u8 i;
1119 kumaneko 2915 case CCS_TYPE_PATH_ACL:
1120 kumaneko 2916 perm = container_of(ptr, struct ccs_path_acl, head)->
1121     perm;
1122     for (i = 0; i < CCS_MAX_PATH_OPERATION; i++)
1123     if (perm & (1 << i))
1124     count++;
1125     if (perm & (1 << CCS_TYPE_READ_WRITE))
1126     count -= 2;
1127 kumaneko 1064 break;
1128 kumaneko 2922 case CCS_TYPE_PATH2_ACL:
1129     perm = container_of(ptr, struct ccs_path2_acl,
1130 kumaneko 2916 head)->perm;
1131 kumaneko 2922 for (i = 0; i < CCS_MAX_PATH2_OPERATION; i++)
1132 kumaneko 2916 if (perm & (1 << i))
1133     count++;
1134 kumaneko 1064 break;
1135 kumaneko 2892 case CCS_TYPE_EXECUTE_HANDLER:
1136     case CCS_TYPE_DENIED_EXECUTE_HANDLER:
1137 kumaneko 1064 break;
1138 kumaneko 2915 case CCS_TYPE_PATH_NUMBER_ACL:
1139 kumaneko 2916 perm = container_of(ptr, struct ccs_path_number_acl,
1140     head)->perm;
1141     for (i = 0; i < CCS_MAX_PATH_NUMBER_OPERATION; i++)
1142     if (perm & (1 << i))
1143     count++;
1144 kumaneko 2915 break;
1145 kumaneko 2922 case CCS_TYPE_PATH_NUMBER3_ACL:
1146 kumaneko 3106 perm = container_of(ptr, struct ccs_path_number3_acl,
1147 kumaneko 2916 head)->perm;
1148 kumaneko 3106 for (i = 0; i < CCS_MAX_PATH_NUMBER3_OPERATION; i++)
1149 kumaneko 2916 if (perm & (1 << i))
1150     count++;
1151 kumaneko 2915 break;
1152 kumaneko 2916 case CCS_TYPE_IP_NETWORK_ACL:
1153     perm = container_of(ptr, struct ccs_ip_network_acl,
1154     head)->perm;
1155     for (i = 0; i < CCS_MAX_NETWORK_OPERATION; i++)
1156     if (perm & (1 << i))
1157     count++;
1158     break;
1159 kumaneko 1064 default:
1160 kumaneko 1052 count++;
1161 kumaneko 1064 }
1162 kumaneko 512 }
1163 kumaneko 2962 if (count < ccs_profile(domain->profile)->learning->learning_max_entry)
1164 kumaneko 2692 return true;
1165     if (!domain->quota_warned) {
1166 kumaneko 1006 domain->quota_warned = true;
1167 kumaneko 3258 ccs_write_audit_log(false, r, CCS_KEYWORD_QUOTA_EXCEEDED "\n");
1168 kumaneko 2918 printk(KERN_WARNING "WARNING: "
1169 kumaneko 1052 "Domain '%s' has so many ACLs to hold. "
1170     "Stopped learning mode.\n", domain->domainname->name);
1171 kumaneko 512 }
1172 kumaneko 2692 return false;
1173 kumaneko 512 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26