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 | ||
