22 #include <linux/kernel.h>
23 #include <linux/audit.h>
28 #include <linux/netlink.h>
29 #include <linux/sched.h>
30 #include <linux/slab.h>
55 #if AUDIT_NR_FILTERS != 6
56 #error Fix audit_filter_list initialiser
70 static inline void audit_free_rule(
struct audit_entry *
e)
82 security_audit_rule_free(f->
lsm_rule);
96 static inline struct audit_entry *audit_init_entry(
u32 field_count)
105 fields = kzalloc(
sizeof(*fields) * field_count,
GFP_KERNEL);
121 if (!*bufp || (len == 0) || (len > *remain))
143 static inline int audit_to_inode(
struct audit_krule *krule,
162 while (*list != ~0
U) {
163 unsigned n = *list++;
187 #ifdef CONFIG_AUDITSYSCALL
188 static inline int audit_match_class_bits(
int class,
u32 *
mask)
192 if (classes[
class]) {
194 if (mask[i] & classes[
class][i])
200 static int audit_match_signal(
struct audit_entry *entry)
238 #ifdef CONFIG_AUDITSYSCALL
264 entry->
rule.listnr = listnr;
269 entry->
rule.mask[i] = rule->
mask[i];
272 int bit = AUDIT_BITMASK_SIZE * 32 - i - 1;
283 entry->
rule.mask[j] |=
class[j];
293 static u32 audit_ops[] =
322 entry = audit_to_entry_common(rule);
339 f->
op = audit_to_op(n);
365 if (!uid_valid(f->
uid))
377 if (!gid_valid(f->
gid))
401 entry->
rule.arch_f =
f;
412 err = audit_to_inode(&entry->
rule, f);
426 audit_free_rule(entry);
441 entry = audit_to_entry_common((
struct audit_rule *)data);
446 entry->
rule.vers_ops = 2;
474 if (!uid_valid(f->
uid))
487 if (!gid_valid(f->
gid))
504 entry->
rule.arch_f =
f;
521 err = security_audit_rule_init(f->
type, f->
op, str,
527 "\'%s\' is invalid\n", str);
560 err = audit_to_inode(&entry->
rule, f);
597 audit_free_rule(entry);
602 static inline size_t audit_pack_string(
void **bufp,
const char *str)
652 memset(data, 0,
sizeof(*data));
675 audit_pack_string(&bufp, f->
lsm_str);
679 audit_pack_string(&bufp,
684 audit_pack_string(&bufp,
689 audit_pack_string(&bufp, krule->
filterkey);
717 switch(a->
fields[i].type) {
778 static inline int audit_dupe_lsm_field(
struct audit_field *
df,
791 ret = security_audit_rule_init(df->
type, df->
op, df->
lsm_str,
818 entry = audit_init_entry(fcount);
824 new->flags = old->
flags;
825 new->listnr = old->
listnr;
826 new->action = old->
action;
828 new->mask[i] = old->
mask[i];
829 new->prio = old->
prio;
830 new->buflen = old->
buflen;
841 new->tree = old->
tree;
846 for (i = 0; i < fcount; i++) {
847 switch (new->fields[i].type) {
858 err = audit_dupe_lsm_field(&new->fields[i],
869 audit_free_rule(entry);
876 new->watch = old->
watch;
891 if (entry->
rule.inode_f) {
892 h = audit_hash_ino(entry->
rule.inode_f->val);
894 }
else if (entry->
rule.watch) {
899 if (!audit_compare_rule(&entry->rule, &e->rule)) {
906 *p = list = &audit_filter_list[entry->
rule.listnr];
910 if (!audit_compare_rule(&entry->rule, &e->rule)) {
919 static u64 prio_low = ~0ULL/2;
920 static u64 prio_high = ~0ULL/2 - 1;
923 static inline int audit_add_rule(
struct audit_entry *entry)
930 #ifdef CONFIG_AUDITSYSCALL
940 e = audit_find_rule(entry, &list);
966 entry->
rule.prio = ~0ULL;
969 entry->
rule.prio = ++prio_high;
971 entry->
rule.prio = --prio_low;
975 list_add(&entry->
rule.list,
976 &audit_rules_list[entry->
rule.listnr]);
977 list_add_rcu(&entry->
list, list);
981 &audit_rules_list[entry->
rule.listnr]);
982 list_add_tail_rcu(&entry->
list, list);
984 #ifdef CONFIG_AUDITSYSCALL
988 if (!audit_match_signal(entry))
1002 static inline int audit_del_rule(
struct audit_entry *entry)
1009 #ifdef CONFIG_AUDITSYSCALL
1019 e = audit_find_rule(entry, &list);
1032 list_del_rcu(&e->
list);
1036 #ifdef CONFIG_AUDITSYSCALL
1040 if (!audit_match_signal(entry))
1068 rule = audit_krule_to_rule(r);
1072 rule,
sizeof(*rule));
1084 static void audit_list_rules(
int pid,
int seq,
struct sk_buff_head *q)
1096 data = audit_krule_to_data(r);
1100 data,
sizeof(*data) + data->
buflen);
1112 static void audit_log_rule_change(
kuid_t loginuid,
u32 sessionid,
u32 sid,
1137 audit_log_string(ab, action);
1156 size_t datasz,
kuid_t loginuid,
u32 sessionid,
u32 sid)
1176 skb_queue_head_init(&dest->
q);
1180 audit_list(pid, seq, &dest->
q);
1182 audit_list_rules(pid, seq, &dest->
q);
1195 entry = audit_rule_to_entry(data);
1197 entry = audit_data_to_entry(data, datasz);
1199 return PTR_ERR(entry);
1201 err = audit_add_rule(entry);
1202 audit_log_rule_change(loginuid, sessionid, sid,
"add rule",
1203 &entry->
rule, !err);
1206 audit_free_rule(entry);
1211 entry = audit_rule_to_entry(data);
1213 entry = audit_data_to_entry(data, datasz);
1215 return PTR_ERR(entry);
1217 err = audit_del_rule(entry);
1218 audit_log_rule_change(loginuid, sessionid, sid,
"remove rule",
1219 &entry->
rule, !err);
1221 audit_free_rule(entry);
1234 return (left == right);
1236 return (left != right);
1238 return (left < right);
1240 return (left <= right);
1242 return (left > right);
1244 return (left >= right);
1246 return (left & right);
1248 return ((left & right) == right);
1259 return uid_eq(left, right);
1261 return !uid_eq(left, right);
1263 return uid_lt(left, right);
1265 return uid_lte(left, right);
1267 return uid_gt(left, right);
1269 return uid_gte(left, right);
1282 return gid_eq(left, right);
1284 return !gid_eq(left, right);
1286 return gid_lt(left, right);
1288 return gid_lte(left, right);
1290 return gid_gt(left, right);
1292 return gid_gte(left, right);
1316 p = path + plen - 1;
1317 while ((*p ==
'/') && (p > path))
1321 while ((*p !=
'/') && (p > path))
1350 if (pathlen - parentlen != dlen)
1353 p = path + parentlen;
1355 return strncmp(p, dname, dlen);
1358 static int audit_filter_user_rules(
struct audit_krule *rule,
1389 result = security_audit_rule_match(sid,
1416 if (audit_filter_user_rules(&e->
rule, &state)) {
1434 goto unlock_and_return;
1436 list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TYPE],
1439 for (i = 0; i < e->
rule.field_count; i++) {
1448 goto unlock_and_return;
1461 if (!security_audit_rule_known(r))
1465 if (IS_ERR(nentry)) {
1468 err = PTR_ERR(nentry);
1472 list_del_rcu(&entry->
list);
1476 list_replace_init(&r->
rlist, &nentry->
rule.rlist);
1477 list_replace_rcu(&entry->
list, &nentry->
list);
1478 list_replace(&r->
list, &nentry->
rule.list);
1500 int res = update_lsm_rule(r);