[PATCH] deprecate AUDIT_POSSBILE
[firefly-linux-kernel-4.4.55.git] / kernel / auditfilter.c
1 /* auditfilter.c -- filtering of audit events
2  *
3  * Copyright 2003-2004 Red Hat, Inc.
4  * Copyright 2005 Hewlett-Packard Development Company, L.P.
5  * Copyright 2005 IBM Corporation
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <linux/kernel.h>
23 #include <linux/audit.h>
24 #include <linux/kthread.h>
25 #include <linux/netlink.h>
26 #include <linux/selinux.h>
27 #include "audit.h"
28
29 /* There are three lists of rules -- one to search at task creation
30  * time, one to search at syscall entry time, and another to search at
31  * syscall exit time. */
32 struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
33         LIST_HEAD_INIT(audit_filter_list[0]),
34         LIST_HEAD_INIT(audit_filter_list[1]),
35         LIST_HEAD_INIT(audit_filter_list[2]),
36         LIST_HEAD_INIT(audit_filter_list[3]),
37         LIST_HEAD_INIT(audit_filter_list[4]),
38         LIST_HEAD_INIT(audit_filter_list[5]),
39 #if AUDIT_NR_FILTERS != 6
40 #error Fix audit_filter_list initialiser
41 #endif
42 };
43
44 static inline void audit_free_rule(struct audit_entry *e)
45 {
46         int i;
47         if (e->rule.fields)
48                 for (i = 0; i < e->rule.field_count; i++) {
49                         struct audit_field *f = &e->rule.fields[i];
50                         kfree(f->se_str);
51                         selinux_audit_rule_free(f->se_rule);
52                 }
53         kfree(e->rule.fields);
54         kfree(e);
55 }
56
57 static inline void audit_free_rule_rcu(struct rcu_head *head)
58 {
59         struct audit_entry *e = container_of(head, struct audit_entry, rcu);
60         audit_free_rule(e);
61 }
62
63 /* Initialize an audit filterlist entry. */
64 static inline struct audit_entry *audit_init_entry(u32 field_count)
65 {
66         struct audit_entry *entry;
67         struct audit_field *fields;
68
69         entry = kzalloc(sizeof(*entry), GFP_KERNEL);
70         if (unlikely(!entry))
71                 return NULL;
72
73         fields = kzalloc(sizeof(*fields) * field_count, GFP_KERNEL);
74         if (unlikely(!fields)) {
75                 kfree(entry);
76                 return NULL;
77         }
78         entry->rule.fields = fields;
79
80         return entry;
81 }
82
83 /* Unpack a filter field's string representation from user-space
84  * buffer. */
85 static char *audit_unpack_string(void **bufp, size_t *remain, size_t len)
86 {
87         char *str;
88
89         if (!*bufp || (len == 0) || (len > *remain))
90                 return ERR_PTR(-EINVAL);
91
92         /* Of the currently implemented string fields, PATH_MAX
93          * defines the longest valid length.
94          */
95         if (len > PATH_MAX)
96                 return ERR_PTR(-ENAMETOOLONG);
97
98         str = kmalloc(len + 1, GFP_KERNEL);
99         if (unlikely(!str))
100                 return ERR_PTR(-ENOMEM);
101
102         memcpy(str, *bufp, len);
103         str[len] = 0;
104         *bufp += len;
105         *remain -= len;
106
107         return str;
108 }
109
110 /* Common user-space to kernel rule translation. */
111 static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule)
112 {
113         unsigned listnr;
114         struct audit_entry *entry;
115         int i, err;
116
117         err = -EINVAL;
118         listnr = rule->flags & ~AUDIT_FILTER_PREPEND;
119         switch(listnr) {
120         default:
121                 goto exit_err;
122         case AUDIT_FILTER_USER:
123         case AUDIT_FILTER_TYPE:
124 #ifdef CONFIG_AUDITSYSCALL
125         case AUDIT_FILTER_ENTRY:
126         case AUDIT_FILTER_EXIT:
127         case AUDIT_FILTER_TASK:
128 #endif
129                 ;
130         }
131         if (unlikely(rule->action == AUDIT_POSSIBLE)) {
132                 printk(KERN_ERR "AUDIT_POSSIBLE is deprecated\n");
133                 goto exit_err;
134         }
135         if (rule->action != AUDIT_NEVER && rule->action != AUDIT_ALWAYS)
136                 goto exit_err;
137         if (rule->field_count > AUDIT_MAX_FIELDS)
138                 goto exit_err;
139
140         err = -ENOMEM;
141         entry = audit_init_entry(rule->field_count);
142         if (!entry)
143                 goto exit_err;
144
145         entry->rule.flags = rule->flags & AUDIT_FILTER_PREPEND;
146         entry->rule.listnr = listnr;
147         entry->rule.action = rule->action;
148         entry->rule.field_count = rule->field_count;
149
150         for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
151                 entry->rule.mask[i] = rule->mask[i];
152
153         return entry;
154
155 exit_err:
156         return ERR_PTR(err);
157 }
158
159 /* Translate struct audit_rule to kernel's rule respresentation.
160  * Exists for backward compatibility with userspace. */
161 static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
162 {
163         struct audit_entry *entry;
164         int err = 0;
165         int i;
166
167         entry = audit_to_entry_common(rule);
168         if (IS_ERR(entry))
169                 goto exit_nofree;
170
171         for (i = 0; i < rule->field_count; i++) {
172                 struct audit_field *f = &entry->rule.fields[i];
173
174                 f->op = rule->fields[i] & (AUDIT_NEGATE|AUDIT_OPERATORS);
175                 f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS);
176                 f->val = rule->values[i];
177
178                 if (f->type & AUDIT_UNUSED_BITS ||
179                     f->type == AUDIT_SE_USER ||
180                     f->type == AUDIT_SE_ROLE ||
181                     f->type == AUDIT_SE_TYPE ||
182                     f->type == AUDIT_SE_SEN ||
183                     f->type == AUDIT_SE_CLR) {
184                         err = -EINVAL;
185                         goto exit_free;
186                 }
187
188                 entry->rule.vers_ops = (f->op & AUDIT_OPERATORS) ? 2 : 1;
189
190                 /* Support for legacy operators where
191                  * AUDIT_NEGATE bit signifies != and otherwise assumes == */
192                 if (f->op & AUDIT_NEGATE)
193                         f->op = AUDIT_NOT_EQUAL;
194                 else if (!f->op)
195                         f->op = AUDIT_EQUAL;
196                 else if (f->op == AUDIT_OPERATORS) {
197                         err = -EINVAL;
198                         goto exit_free;
199                 }
200         }
201
202 exit_nofree:
203         return entry;
204
205 exit_free:
206         audit_free_rule(entry);
207         return ERR_PTR(err);
208 }
209
210 /* Translate struct audit_rule_data to kernel's rule respresentation. */
211 static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
212                                                size_t datasz)
213 {
214         int err = 0;
215         struct audit_entry *entry;
216         void *bufp;
217         size_t remain = datasz - sizeof(struct audit_rule_data);
218         int i;
219         char *str;
220
221         entry = audit_to_entry_common((struct audit_rule *)data);
222         if (IS_ERR(entry))
223                 goto exit_nofree;
224
225         bufp = data->buf;
226         entry->rule.vers_ops = 2;
227         for (i = 0; i < data->field_count; i++) {
228                 struct audit_field *f = &entry->rule.fields[i];
229
230                 err = -EINVAL;
231                 if (!(data->fieldflags[i] & AUDIT_OPERATORS) ||
232                     data->fieldflags[i] & ~AUDIT_OPERATORS)
233                         goto exit_free;
234
235                 f->op = data->fieldflags[i] & AUDIT_OPERATORS;
236                 f->type = data->fields[i];
237                 f->val = data->values[i];
238                 f->se_str = NULL;
239                 f->se_rule = NULL;
240                 switch(f->type) {
241                 case AUDIT_SE_USER:
242                 case AUDIT_SE_ROLE:
243                 case AUDIT_SE_TYPE:
244                 case AUDIT_SE_SEN:
245                 case AUDIT_SE_CLR:
246                         str = audit_unpack_string(&bufp, &remain, f->val);
247                         if (IS_ERR(str))
248                                 goto exit_free;
249                         entry->rule.buflen += f->val;
250
251                         err = selinux_audit_rule_init(f->type, f->op, str,
252                                                       &f->se_rule);
253                         /* Keep currently invalid fields around in case they
254                          * become valid after a policy reload. */
255                         if (err == -EINVAL) {
256                                 printk(KERN_WARNING "audit rule for selinux "
257                                        "\'%s\' is invalid\n",  str);
258                                 err = 0;
259                         }
260                         if (err) {
261                                 kfree(str);
262                                 goto exit_free;
263                         } else
264                                 f->se_str = str;
265                         break;
266                 }
267         }
268
269 exit_nofree:
270         return entry;
271
272 exit_free:
273         audit_free_rule(entry);
274         return ERR_PTR(err);
275 }
276
277 /* Pack a filter field's string representation into data block. */
278 static inline size_t audit_pack_string(void **bufp, char *str)
279 {
280         size_t len = strlen(str);
281
282         memcpy(*bufp, str, len);
283         *bufp += len;
284
285         return len;
286 }
287
288 /* Translate kernel rule respresentation to struct audit_rule.
289  * Exists for backward compatibility with userspace. */
290 static struct audit_rule *audit_krule_to_rule(struct audit_krule *krule)
291 {
292         struct audit_rule *rule;
293         int i;
294
295         rule = kmalloc(sizeof(*rule), GFP_KERNEL);
296         if (unlikely(!rule))
297                 return NULL;
298         memset(rule, 0, sizeof(*rule));
299
300         rule->flags = krule->flags | krule->listnr;
301         rule->action = krule->action;
302         rule->field_count = krule->field_count;
303         for (i = 0; i < rule->field_count; i++) {
304                 rule->values[i] = krule->fields[i].val;
305                 rule->fields[i] = krule->fields[i].type;
306
307                 if (krule->vers_ops == 1) {
308                         if (krule->fields[i].op & AUDIT_NOT_EQUAL)
309                                 rule->fields[i] |= AUDIT_NEGATE;
310                 } else {
311                         rule->fields[i] |= krule->fields[i].op;
312                 }
313         }
314         for (i = 0; i < AUDIT_BITMASK_SIZE; i++) rule->mask[i] = krule->mask[i];
315
316         return rule;
317 }
318
319 /* Translate kernel rule respresentation to struct audit_rule_data. */
320 static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
321 {
322         struct audit_rule_data *data;
323         void *bufp;
324         int i;
325
326         data = kmalloc(sizeof(*data) + krule->buflen, GFP_KERNEL);
327         if (unlikely(!data))
328                 return NULL;
329         memset(data, 0, sizeof(*data));
330
331         data->flags = krule->flags | krule->listnr;
332         data->action = krule->action;
333         data->field_count = krule->field_count;
334         bufp = data->buf;
335         for (i = 0; i < data->field_count; i++) {
336                 struct audit_field *f = &krule->fields[i];
337
338                 data->fields[i] = f->type;
339                 data->fieldflags[i] = f->op;
340                 switch(f->type) {
341                 case AUDIT_SE_USER:
342                 case AUDIT_SE_ROLE:
343                 case AUDIT_SE_TYPE:
344                 case AUDIT_SE_SEN:
345                 case AUDIT_SE_CLR:
346                         data->buflen += data->values[i] =
347                                 audit_pack_string(&bufp, f->se_str);
348                         break;
349                 default:
350                         data->values[i] = f->val;
351                 }
352         }
353         for (i = 0; i < AUDIT_BITMASK_SIZE; i++) data->mask[i] = krule->mask[i];
354
355         return data;
356 }
357
358 /* Compare two rules in kernel format.  Considered success if rules
359  * don't match. */
360 static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
361 {
362         int i;
363
364         if (a->flags != b->flags ||
365             a->listnr != b->listnr ||
366             a->action != b->action ||
367             a->field_count != b->field_count)
368                 return 1;
369
370         for (i = 0; i < a->field_count; i++) {
371                 if (a->fields[i].type != b->fields[i].type ||
372                     a->fields[i].op != b->fields[i].op)
373                         return 1;
374
375                 switch(a->fields[i].type) {
376                 case AUDIT_SE_USER:
377                 case AUDIT_SE_ROLE:
378                 case AUDIT_SE_TYPE:
379                 case AUDIT_SE_SEN:
380                 case AUDIT_SE_CLR:
381                         if (strcmp(a->fields[i].se_str, b->fields[i].se_str))
382                                 return 1;
383                         break;
384                 default:
385                         if (a->fields[i].val != b->fields[i].val)
386                                 return 1;
387                 }
388         }
389
390         for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
391                 if (a->mask[i] != b->mask[i])
392                         return 1;
393
394         return 0;
395 }
396
397 /* Duplicate selinux field information.  The se_rule is opaque, so must be
398  * re-initialized. */
399 static inline int audit_dupe_selinux_field(struct audit_field *df,
400                                            struct audit_field *sf)
401 {
402         int ret = 0;
403         char *se_str;
404
405         /* our own copy of se_str */
406         se_str = kstrdup(sf->se_str, GFP_KERNEL);
407         if (unlikely(IS_ERR(se_str)))
408             return -ENOMEM;
409         df->se_str = se_str;
410
411         /* our own (refreshed) copy of se_rule */
412         ret = selinux_audit_rule_init(df->type, df->op, df->se_str,
413                                       &df->se_rule);
414         /* Keep currently invalid fields around in case they
415          * become valid after a policy reload. */
416         if (ret == -EINVAL) {
417                 printk(KERN_WARNING "audit rule for selinux \'%s\' is "
418                        "invalid\n", df->se_str);
419                 ret = 0;
420         }
421
422         return ret;
423 }
424
425 /* Duplicate an audit rule.  This will be a deep copy with the exception
426  * of the watch - that pointer is carried over.  The selinux specific fields
427  * will be updated in the copy.  The point is to be able to replace the old
428  * rule with the new rule in the filterlist, then free the old rule. */
429 static struct audit_entry *audit_dupe_rule(struct audit_krule *old)
430 {
431         u32 fcount = old->field_count;
432         struct audit_entry *entry;
433         struct audit_krule *new;
434         int i, err = 0;
435
436         entry = audit_init_entry(fcount);
437         if (unlikely(!entry))
438                 return ERR_PTR(-ENOMEM);
439
440         new = &entry->rule;
441         new->vers_ops = old->vers_ops;
442         new->flags = old->flags;
443         new->listnr = old->listnr;
444         new->action = old->action;
445         for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
446                 new->mask[i] = old->mask[i];
447         new->buflen = old->buflen;
448         new->field_count = old->field_count;
449         memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount);
450
451         /* deep copy this information, updating the se_rule fields, because
452          * the originals will all be freed when the old rule is freed. */
453         for (i = 0; i < fcount; i++) {
454                 switch (new->fields[i].type) {
455                 case AUDIT_SE_USER:
456                 case AUDIT_SE_ROLE:
457                 case AUDIT_SE_TYPE:
458                 case AUDIT_SE_SEN:
459                 case AUDIT_SE_CLR:
460                         err = audit_dupe_selinux_field(&new->fields[i],
461                                                        &old->fields[i]);
462                 }
463                 if (err) {
464                         audit_free_rule(entry);
465                         return ERR_PTR(err);
466                 }
467         }
468
469         return entry;
470 }
471
472 /* Add rule to given filterlist if not a duplicate.  Protected by
473  * audit_netlink_mutex. */
474 static inline int audit_add_rule(struct audit_entry *entry,
475                                   struct list_head *list)
476 {
477         struct audit_entry *e;
478
479         /* Do not use the _rcu iterator here, since this is the only
480          * addition routine. */
481         list_for_each_entry(e, list, list) {
482                 if (!audit_compare_rule(&entry->rule, &e->rule))
483                         return -EEXIST;
484         }
485
486         if (entry->rule.flags & AUDIT_FILTER_PREPEND) {
487                 list_add_rcu(&entry->list, list);
488         } else {
489                 list_add_tail_rcu(&entry->list, list);
490         }
491
492         return 0;
493 }
494
495 /* Remove an existing rule from filterlist.  Protected by
496  * audit_netlink_mutex. */
497 static inline int audit_del_rule(struct audit_entry *entry,
498                                  struct list_head *list)
499 {
500         struct audit_entry  *e;
501
502         /* Do not use the _rcu iterator here, since this is the only
503          * deletion routine. */
504         list_for_each_entry(e, list, list) {
505                 if (!audit_compare_rule(&entry->rule, &e->rule)) {
506                         list_del_rcu(&e->list);
507                         call_rcu(&e->rcu, audit_free_rule_rcu);
508                         return 0;
509                 }
510         }
511         return -ENOENT;         /* No matching rule */
512 }
513
514 /* List rules using struct audit_rule.  Exists for backward
515  * compatibility with userspace. */
516 static void audit_list(int pid, int seq, struct sk_buff_head *q)
517 {
518         struct sk_buff *skb;
519         struct audit_entry *entry;
520         int i;
521
522         /* The *_rcu iterators not needed here because we are
523            always called with audit_netlink_mutex held. */
524         for (i=0; i<AUDIT_NR_FILTERS; i++) {
525                 list_for_each_entry(entry, &audit_filter_list[i], list) {
526                         struct audit_rule *rule;
527
528                         rule = audit_krule_to_rule(&entry->rule);
529                         if (unlikely(!rule))
530                                 break;
531                         skb = audit_make_reply(pid, seq, AUDIT_LIST, 0, 1,
532                                          rule, sizeof(*rule));
533                         if (skb)
534                                 skb_queue_tail(q, skb);
535                         kfree(rule);
536                 }
537         }
538         skb = audit_make_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
539         if (skb)
540                 skb_queue_tail(q, skb);
541 }
542
543 /* List rules using struct audit_rule_data. */
544 static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
545 {
546         struct sk_buff *skb;
547         struct audit_entry *e;
548         int i;
549
550         /* The *_rcu iterators not needed here because we are
551            always called with audit_netlink_mutex held. */
552         for (i=0; i<AUDIT_NR_FILTERS; i++) {
553                 list_for_each_entry(e, &audit_filter_list[i], list) {
554                         struct audit_rule_data *data;
555
556                         data = audit_krule_to_data(&e->rule);
557                         if (unlikely(!data))
558                                 break;
559                         skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1,
560                                          data, sizeof(*data));
561                         if (skb)
562                                 skb_queue_tail(q, skb);
563                         kfree(data);
564                 }
565         }
566         skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0);
567         if (skb)
568                 skb_queue_tail(q, skb);
569 }
570
571 /**
572  * audit_receive_filter - apply all rules to the specified message type
573  * @type: audit message type
574  * @pid: target pid for netlink audit messages
575  * @uid: target uid for netlink audit messages
576  * @seq: netlink audit message sequence (serial) number
577  * @data: payload data
578  * @datasz: size of payload data
579  * @loginuid: loginuid of sender
580  * @sid: SE Linux Security ID of sender
581  */
582 int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
583                          size_t datasz, uid_t loginuid, u32 sid)
584 {
585         struct task_struct *tsk;
586         struct audit_netlink_list *dest;
587         int err = 0;
588         struct audit_entry *entry;
589
590         switch (type) {
591         case AUDIT_LIST:
592         case AUDIT_LIST_RULES:
593                 /* We can't just spew out the rules here because we might fill
594                  * the available socket buffer space and deadlock waiting for
595                  * auditctl to read from it... which isn't ever going to
596                  * happen if we're actually running in the context of auditctl
597                  * trying to _send_ the stuff */
598                  
599                 dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
600                 if (!dest)
601                         return -ENOMEM;
602                 dest->pid = pid;
603                 skb_queue_head_init(&dest->q);
604
605                 if (type == AUDIT_LIST)
606                         audit_list(pid, seq, &dest->q);
607                 else
608                         audit_list_rules(pid, seq, &dest->q);
609
610                 tsk = kthread_run(audit_send_list, dest, "audit_send_list");
611                 if (IS_ERR(tsk)) {
612                         skb_queue_purge(&dest->q);
613                         kfree(dest);
614                         err = PTR_ERR(tsk);
615                 }
616                 break;
617         case AUDIT_ADD:
618         case AUDIT_ADD_RULE:
619                 if (type == AUDIT_ADD)
620                         entry = audit_rule_to_entry(data);
621                 else
622                         entry = audit_data_to_entry(data, datasz);
623                 if (IS_ERR(entry))
624                         return PTR_ERR(entry);
625
626                 err = audit_add_rule(entry,
627                                      &audit_filter_list[entry->rule.listnr]);
628                 if (sid) {
629                         char *ctx = NULL;
630                         u32 len;
631                         if (selinux_ctxid_to_string(sid, &ctx, &len)) {
632                                 /* Maybe call audit_panic? */
633                                 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
634                                  "auid=%u ssid=%u add rule to list=%d res=%d",
635                                  loginuid, sid, entry->rule.listnr, !err);
636                         } else
637                                 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
638                                  "auid=%u subj=%s add rule to list=%d res=%d",
639                                  loginuid, ctx, entry->rule.listnr, !err);
640                         kfree(ctx);
641                 } else
642                         audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
643                                 "auid=%u add rule to list=%d res=%d",
644                                 loginuid, entry->rule.listnr, !err);
645
646                 if (err)
647                         audit_free_rule(entry);
648                 break;
649         case AUDIT_DEL:
650         case AUDIT_DEL_RULE:
651                 if (type == AUDIT_DEL)
652                         entry = audit_rule_to_entry(data);
653                 else
654                         entry = audit_data_to_entry(data, datasz);
655                 if (IS_ERR(entry))
656                         return PTR_ERR(entry);
657
658                 err = audit_del_rule(entry,
659                                      &audit_filter_list[entry->rule.listnr]);
660
661                 if (sid) {
662                         char *ctx = NULL;
663                         u32 len;
664                         if (selinux_ctxid_to_string(sid, &ctx, &len)) {
665                                 /* Maybe call audit_panic? */
666                                 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
667                                         "auid=%u ssid=%u remove rule from list=%d res=%d",
668                                          loginuid, sid, entry->rule.listnr, !err);
669                         } else
670                                 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
671                                         "auid=%u subj=%s remove rule from list=%d res=%d",
672                                          loginuid, ctx, entry->rule.listnr, !err);
673                         kfree(ctx);
674                 } else
675                         audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
676                                 "auid=%u remove rule from list=%d res=%d",
677                                 loginuid, entry->rule.listnr, !err);
678
679                 audit_free_rule(entry);
680                 break;
681         default:
682                 return -EINVAL;
683         }
684
685         return err;
686 }
687
688 int audit_comparator(const u32 left, const u32 op, const u32 right)
689 {
690         switch (op) {
691         case AUDIT_EQUAL:
692                 return (left == right);
693         case AUDIT_NOT_EQUAL:
694                 return (left != right);
695         case AUDIT_LESS_THAN:
696                 return (left < right);
697         case AUDIT_LESS_THAN_OR_EQUAL:
698                 return (left <= right);
699         case AUDIT_GREATER_THAN:
700                 return (left > right);
701         case AUDIT_GREATER_THAN_OR_EQUAL:
702                 return (left >= right);
703         }
704         BUG();
705         return 0;
706 }
707
708
709
710 static int audit_filter_user_rules(struct netlink_skb_parms *cb,
711                                    struct audit_krule *rule,
712                                    enum audit_state *state)
713 {
714         int i;
715
716         for (i = 0; i < rule->field_count; i++) {
717                 struct audit_field *f = &rule->fields[i];
718                 int result = 0;
719
720                 switch (f->type) {
721                 case AUDIT_PID:
722                         result = audit_comparator(cb->creds.pid, f->op, f->val);
723                         break;
724                 case AUDIT_UID:
725                         result = audit_comparator(cb->creds.uid, f->op, f->val);
726                         break;
727                 case AUDIT_GID:
728                         result = audit_comparator(cb->creds.gid, f->op, f->val);
729                         break;
730                 case AUDIT_LOGINUID:
731                         result = audit_comparator(cb->loginuid, f->op, f->val);
732                         break;
733                 }
734
735                 if (!result)
736                         return 0;
737         }
738         switch (rule->action) {
739         case AUDIT_NEVER:    *state = AUDIT_DISABLED;       break;
740         case AUDIT_ALWAYS:   *state = AUDIT_RECORD_CONTEXT; break;
741         }
742         return 1;
743 }
744
745 int audit_filter_user(struct netlink_skb_parms *cb, int type)
746 {
747         struct audit_entry *e;
748         enum audit_state   state;
749         int ret = 1;
750
751         rcu_read_lock();
752         list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) {
753                 if (audit_filter_user_rules(cb, &e->rule, &state)) {
754                         if (state == AUDIT_DISABLED)
755                                 ret = 0;
756                         break;
757                 }
758         }
759         rcu_read_unlock();
760
761         return ret; /* Audit by default */
762 }
763
764 int audit_filter_type(int type)
765 {
766         struct audit_entry *e;
767         int result = 0;
768         
769         rcu_read_lock();
770         if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE]))
771                 goto unlock_and_return;
772
773         list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TYPE],
774                                 list) {
775                 int i;
776                 for (i = 0; i < e->rule.field_count; i++) {
777                         struct audit_field *f = &e->rule.fields[i];
778                         if (f->type == AUDIT_MSGTYPE) {
779                                 result = audit_comparator(type, f->op, f->val);
780                                 if (!result)
781                                         break;
782                         }
783                 }
784                 if (result)
785                         goto unlock_and_return;
786         }
787 unlock_and_return:
788         rcu_read_unlock();
789         return result;
790 }
791
792 /* Check to see if the rule contains any selinux fields.  Returns 1 if there
793    are selinux fields specified in the rule, 0 otherwise. */
794 static inline int audit_rule_has_selinux(struct audit_krule *rule)
795 {
796         int i;
797
798         for (i = 0; i < rule->field_count; i++) {
799                 struct audit_field *f = &rule->fields[i];
800                 switch (f->type) {
801                 case AUDIT_SE_USER:
802                 case AUDIT_SE_ROLE:
803                 case AUDIT_SE_TYPE:
804                 case AUDIT_SE_SEN:
805                 case AUDIT_SE_CLR:
806                         return 1;
807                 }
808         }
809
810         return 0;
811 }
812
813 /* This function will re-initialize the se_rule field of all applicable rules.
814  * It will traverse the filter lists serarching for rules that contain selinux
815  * specific filter fields.  When such a rule is found, it is copied, the
816  * selinux field is re-initialized, and the old rule is replaced with the
817  * updated rule. */
818 int selinux_audit_rule_update(void)
819 {
820         struct audit_entry *entry, *n, *nentry;
821         int i, err = 0;
822
823         /* audit_netlink_mutex synchronizes the writers */
824         mutex_lock(&audit_netlink_mutex);
825
826         for (i = 0; i < AUDIT_NR_FILTERS; i++) {
827                 list_for_each_entry_safe(entry, n, &audit_filter_list[i], list) {
828                         if (!audit_rule_has_selinux(&entry->rule))
829                                 continue;
830
831                         nentry = audit_dupe_rule(&entry->rule);
832                         if (unlikely(IS_ERR(nentry))) {
833                                 /* save the first error encountered for the
834                                  * return value */
835                                 if (!err)
836                                         err = PTR_ERR(nentry);
837                                 audit_panic("error updating selinux filters");
838                                 list_del_rcu(&entry->list);
839                         } else {
840                                 list_replace_rcu(&entry->list, &nentry->list);
841                         }
842                         call_rcu(&entry->rcu, audit_free_rule_rcu);
843                 }
844         }
845
846         mutex_unlock(&audit_netlink_mutex);
847
848         return err;
849 }