diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/auditfilter.c | 42 |
1 files changed, 17 insertions, 25 deletions
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 5d4edc6f7a32..e6e3829cadd1 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
@@ -1114,12 +1114,16 @@ static void audit_inotify_unregister(struct list_head *in_list) | |||
1114 | /* Find an existing audit rule. | 1114 | /* Find an existing audit rule. |
1115 | * Caller must hold audit_filter_mutex to prevent stale rule data. */ | 1115 | * Caller must hold audit_filter_mutex to prevent stale rule data. */ |
1116 | static struct audit_entry *audit_find_rule(struct audit_entry *entry, | 1116 | static struct audit_entry *audit_find_rule(struct audit_entry *entry, |
1117 | struct list_head *list) | 1117 | struct list_head **p) |
1118 | { | 1118 | { |
1119 | struct audit_entry *e, *found = NULL; | 1119 | struct audit_entry *e, *found = NULL; |
1120 | struct list_head *list; | ||
1120 | int h; | 1121 | int h; |
1121 | 1122 | ||
1122 | if (entry->rule.watch) { | 1123 | if (entry->rule.inode_f) { |
1124 | h = audit_hash_ino(entry->rule.inode_f->val); | ||
1125 | *p = list = &audit_inode_hash[h]; | ||
1126 | } else if (entry->rule.watch) { | ||
1123 | /* we don't know the inode number, so must walk entire hash */ | 1127 | /* we don't know the inode number, so must walk entire hash */ |
1124 | for (h = 0; h < AUDIT_INODE_BUCKETS; h++) { | 1128 | for (h = 0; h < AUDIT_INODE_BUCKETS; h++) { |
1125 | list = &audit_inode_hash[h]; | 1129 | list = &audit_inode_hash[h]; |
@@ -1130,6 +1134,8 @@ static struct audit_entry *audit_find_rule(struct audit_entry *entry, | |||
1130 | } | 1134 | } |
1131 | } | 1135 | } |
1132 | goto out; | 1136 | goto out; |
1137 | } else { | ||
1138 | *p = list = &audit_filter_list[entry->rule.listnr]; | ||
1133 | } | 1139 | } |
1134 | 1140 | ||
1135 | list_for_each_entry(e, list, list) | 1141 | list_for_each_entry(e, list, list) |
@@ -1274,14 +1280,13 @@ static u64 prio_low = ~0ULL/2; | |||
1274 | static u64 prio_high = ~0ULL/2 - 1; | 1280 | static u64 prio_high = ~0ULL/2 - 1; |
1275 | 1281 | ||
1276 | /* Add rule to given filterlist if not a duplicate. */ | 1282 | /* Add rule to given filterlist if not a duplicate. */ |
1277 | static inline int audit_add_rule(struct audit_entry *entry, | 1283 | static inline int audit_add_rule(struct audit_entry *entry) |
1278 | struct list_head *list) | ||
1279 | { | 1284 | { |
1280 | struct audit_entry *e; | 1285 | struct audit_entry *e; |
1281 | struct audit_field *inode_f = entry->rule.inode_f; | ||
1282 | struct audit_watch *watch = entry->rule.watch; | 1286 | struct audit_watch *watch = entry->rule.watch; |
1283 | struct audit_tree *tree = entry->rule.tree; | 1287 | struct audit_tree *tree = entry->rule.tree; |
1284 | struct nameidata *ndp = NULL, *ndw = NULL; | 1288 | struct nameidata *ndp = NULL, *ndw = NULL; |
1289 | struct list_head *list; | ||
1285 | int h, err; | 1290 | int h, err; |
1286 | #ifdef CONFIG_AUDITSYSCALL | 1291 | #ifdef CONFIG_AUDITSYSCALL |
1287 | int dont_count = 0; | 1292 | int dont_count = 0; |
@@ -1292,13 +1297,8 @@ static inline int audit_add_rule(struct audit_entry *entry, | |||
1292 | dont_count = 1; | 1297 | dont_count = 1; |
1293 | #endif | 1298 | #endif |
1294 | 1299 | ||
1295 | if (inode_f) { | ||
1296 | h = audit_hash_ino(inode_f->val); | ||
1297 | list = &audit_inode_hash[h]; | ||
1298 | } | ||
1299 | |||
1300 | mutex_lock(&audit_filter_mutex); | 1300 | mutex_lock(&audit_filter_mutex); |
1301 | e = audit_find_rule(entry, list); | 1301 | e = audit_find_rule(entry, &list); |
1302 | mutex_unlock(&audit_filter_mutex); | 1302 | mutex_unlock(&audit_filter_mutex); |
1303 | if (e) { | 1303 | if (e) { |
1304 | err = -EEXIST; | 1304 | err = -EEXIST; |
@@ -1372,15 +1372,14 @@ error: | |||
1372 | } | 1372 | } |
1373 | 1373 | ||
1374 | /* Remove an existing rule from filterlist. */ | 1374 | /* Remove an existing rule from filterlist. */ |
1375 | static inline int audit_del_rule(struct audit_entry *entry, | 1375 | static inline int audit_del_rule(struct audit_entry *entry) |
1376 | struct list_head *list) | ||
1377 | { | 1376 | { |
1378 | struct audit_entry *e; | 1377 | struct audit_entry *e; |
1379 | struct audit_field *inode_f = entry->rule.inode_f; | ||
1380 | struct audit_watch *watch, *tmp_watch = entry->rule.watch; | 1378 | struct audit_watch *watch, *tmp_watch = entry->rule.watch; |
1381 | struct audit_tree *tree = entry->rule.tree; | 1379 | struct audit_tree *tree = entry->rule.tree; |
1380 | struct list_head *list; | ||
1382 | LIST_HEAD(inotify_list); | 1381 | LIST_HEAD(inotify_list); |
1383 | int h, ret = 0; | 1382 | int ret = 0; |
1384 | #ifdef CONFIG_AUDITSYSCALL | 1383 | #ifdef CONFIG_AUDITSYSCALL |
1385 | int dont_count = 0; | 1384 | int dont_count = 0; |
1386 | 1385 | ||
@@ -1390,13 +1389,8 @@ static inline int audit_del_rule(struct audit_entry *entry, | |||
1390 | dont_count = 1; | 1389 | dont_count = 1; |
1391 | #endif | 1390 | #endif |
1392 | 1391 | ||
1393 | if (inode_f) { | ||
1394 | h = audit_hash_ino(inode_f->val); | ||
1395 | list = &audit_inode_hash[h]; | ||
1396 | } | ||
1397 | |||
1398 | mutex_lock(&audit_filter_mutex); | 1392 | mutex_lock(&audit_filter_mutex); |
1399 | e = audit_find_rule(entry, list); | 1393 | e = audit_find_rule(entry, &list); |
1400 | if (!e) { | 1394 | if (!e) { |
1401 | mutex_unlock(&audit_filter_mutex); | 1395 | mutex_unlock(&audit_filter_mutex); |
1402 | ret = -ENOENT; | 1396 | ret = -ENOENT; |
@@ -1603,8 +1597,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
1603 | if (IS_ERR(entry)) | 1597 | if (IS_ERR(entry)) |
1604 | return PTR_ERR(entry); | 1598 | return PTR_ERR(entry); |
1605 | 1599 | ||
1606 | err = audit_add_rule(entry, | 1600 | err = audit_add_rule(entry); |
1607 | &audit_filter_list[entry->rule.listnr]); | ||
1608 | audit_log_rule_change(loginuid, sessionid, sid, "add", | 1601 | audit_log_rule_change(loginuid, sessionid, sid, "add", |
1609 | &entry->rule, !err); | 1602 | &entry->rule, !err); |
1610 | 1603 | ||
@@ -1620,8 +1613,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
1620 | if (IS_ERR(entry)) | 1613 | if (IS_ERR(entry)) |
1621 | return PTR_ERR(entry); | 1614 | return PTR_ERR(entry); |
1622 | 1615 | ||
1623 | err = audit_del_rule(entry, | 1616 | err = audit_del_rule(entry); |
1624 | &audit_filter_list[entry->rule.listnr]); | ||
1625 | audit_log_rule_change(loginuid, sessionid, sid, "remove", | 1617 | audit_log_rule_change(loginuid, sessionid, sid, "remove", |
1626 | &entry->rule, !err); | 1618 | &entry->rule, !err); |
1627 | 1619 | ||