Commit 86b2efbe3a390e07dbba725ef700b0d143e9a385

Authored by Richard Guy Briggs
Committed by Paul Moore
1 parent da7f750c1e

audit: add fields to exclude filter by reusing user filter

RFE: add additional fields for use in audit filter exclude rules
https://github.com/linux-audit/audit-kernel/issues/5

Re-factor and combine audit_filter_type() with audit_filter_user() to
use audit_filter_user_rules() to enable the exclude filter to
additionally filter on PID, UID, GID, AUID, LOGINUID_SET, SUBJ_*.

The process of combining the similar audit_filter_user() and
audit_filter_type() functions, required inverting the meaning and
including the ALWAYS action of the latter.

Include audit_filter_user_rules() into audit_filter(), removing
unneeded logic in the process.

Keep the check to quit early if the list is empty.

Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
[PM: checkpatch.pl fixes - whitespace damage, wrapped description]
Signed-off-by: Paul Moore <paul@paul-moore.com>

Showing 4 changed files with 57 additions and 102 deletions Side-by-side Diff

include/linux/audit.h
... ... @@ -163,8 +163,6 @@
163 163 extern int audit_update_lsm_rules(void);
164 164  
165 165 /* Private API (for audit.c only) */
166   -extern int audit_filter_user(int type);
167   -extern int audit_filter_type(int type);
168 166 extern int audit_rule_change(int type, __u32 portid, int seq,
169 167 void *data, size_t datasz);
170 168 extern int audit_list_rules_send(struct sk_buff *request_skb, int seq);
... ... @@ -934,7 +934,7 @@
934 934 if (!audit_enabled && msg_type != AUDIT_USER_AVC)
935 935 return 0;
936 936  
937   - err = audit_filter_user(msg_type);
  937 + err = audit_filter(msg_type, AUDIT_FILTER_USER);
938 938 if (err == 1) { /* match or error */
939 939 err = 0;
940 940 if (msg_type == AUDIT_USER_TTY) {
... ... @@ -1382,7 +1382,7 @@
1382 1382 if (audit_initialized != AUDIT_INITIALIZED)
1383 1383 return NULL;
1384 1384  
1385   - if (unlikely(audit_filter_type(type)))
  1385 + if (unlikely(!audit_filter(type, AUDIT_FILTER_TYPE)))
1386 1386 return NULL;
1387 1387  
1388 1388 if (gfp_mask & __GFP_DIRECT_RECLAIM) {
... ... @@ -327,6 +327,8 @@
327 327 extern kuid_t audit_sig_uid;
328 328 extern u32 audit_sig_sid;
329 329  
  330 +extern int audit_filter(int msgtype, unsigned int listtype);
  331 +
330 332 #ifdef CONFIG_AUDITSYSCALL
331 333 extern int __audit_signal_info(int sig, struct task_struct *t);
332 334 static inline int audit_signal_info(int sig, struct task_struct *t)
kernel/auditfilter.c
... ... @@ -1290,117 +1290,72 @@
1290 1290 return strncmp(p, dname, dlen);
1291 1291 }
1292 1292  
1293   -static int audit_filter_user_rules(struct audit_krule *rule, int type,
1294   - enum audit_state *state)
  1293 +int audit_filter(int msgtype, unsigned int listtype)
1295 1294 {
1296   - int i;
1297   -
1298   - for (i = 0; i < rule->field_count; i++) {
1299   - struct audit_field *f = &rule->fields[i];
1300   - pid_t pid;
1301   - int result = 0;
1302   - u32 sid;
1303   -
1304   - switch (f->type) {
1305   - case AUDIT_PID:
1306   - pid = task_pid_nr(current);
1307   - result = audit_comparator(pid, f->op, f->val);
1308   - break;
1309   - case AUDIT_UID:
1310   - result = audit_uid_comparator(current_uid(), f->op, f->uid);
1311   - break;
1312   - case AUDIT_GID:
1313   - result = audit_gid_comparator(current_gid(), f->op, f->gid);
1314   - break;
1315   - case AUDIT_LOGINUID:
1316   - result = audit_uid_comparator(audit_get_loginuid(current),
1317   - f->op, f->uid);
1318   - break;
1319   - case AUDIT_LOGINUID_SET:
1320   - result = audit_comparator(audit_loginuid_set(current),
1321   - f->op, f->val);
1322   - break;
1323   - case AUDIT_MSGTYPE:
1324   - result = audit_comparator(type, f->op, f->val);
1325   - break;
1326   - case AUDIT_SUBJ_USER:
1327   - case AUDIT_SUBJ_ROLE:
1328   - case AUDIT_SUBJ_TYPE:
1329   - case AUDIT_SUBJ_SEN:
1330   - case AUDIT_SUBJ_CLR:
1331   - if (f->lsm_rule) {
1332   - security_task_getsecid(current, &sid);
1333   - result = security_audit_rule_match(sid,
1334   - f->type,
1335   - f->op,
1336   - f->lsm_rule,
1337   - NULL);
1338   - }
1339   - break;
1340   - }
1341   -
1342   - if (result <= 0)
1343   - return result;
1344   - }
1345   - switch (rule->action) {
1346   - case AUDIT_NEVER:
1347   - *state = AUDIT_DISABLED;
1348   - break;
1349   - case AUDIT_ALWAYS:
1350   - *state = AUDIT_RECORD_CONTEXT;
1351   - break;
1352   - }
1353   - return 1;
1354   -}
1355   -
1356   -int audit_filter_user(int type)
1357   -{
1358   - enum audit_state state = AUDIT_DISABLED;
1359 1295 struct audit_entry *e;
1360   - int rc, ret;
  1296 + int ret = 1; /* Audit by default */
1361 1297  
1362   - ret = 1; /* Audit by default */
1363   -
1364 1298 rcu_read_lock();
1365   - list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) {
1366   - rc = audit_filter_user_rules(&e->rule, type, &state);
1367   - if (rc) {
1368   - if (rc > 0 && state == AUDIT_DISABLED)
1369   - ret = 0;
1370   - break;
1371   - }
1372   - }
1373   - rcu_read_unlock();
1374   -
1375   - return ret;
1376   -}
1377   -
1378   -int audit_filter_type(int type)
1379   -{
1380   - struct audit_entry *e;
1381   - int result = 0;
1382   -
1383   - rcu_read_lock();
1384   - if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE]))
  1299 + if (list_empty(&audit_filter_list[listtype]))
1385 1300 goto unlock_and_return;
  1301 + list_for_each_entry_rcu(e, &audit_filter_list[listtype], list) {
  1302 + int i, result = 0;
1386 1303  
1387   - list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TYPE],
1388   - list) {
1389   - int i;
1390 1304 for (i = 0; i < e->rule.field_count; i++) {
1391 1305 struct audit_field *f = &e->rule.fields[i];
1392   - if (f->type == AUDIT_MSGTYPE) {
1393   - result = audit_comparator(type, f->op, f->val);
1394   - if (!result)
1395   - break;
  1306 + pid_t pid;
  1307 + u32 sid;
  1308 +
  1309 + switch (f->type) {
  1310 + case AUDIT_PID:
  1311 + pid = task_pid_nr(current);
  1312 + result = audit_comparator(pid, f->op, f->val);
  1313 + break;
  1314 + case AUDIT_UID:
  1315 + result = audit_uid_comparator(current_uid(), f->op, f->uid);
  1316 + break;
  1317 + case AUDIT_GID:
  1318 + result = audit_gid_comparator(current_gid(), f->op, f->gid);
  1319 + break;
  1320 + case AUDIT_LOGINUID:
  1321 + result = audit_uid_comparator(audit_get_loginuid(current),
  1322 + f->op, f->uid);
  1323 + break;
  1324 + case AUDIT_LOGINUID_SET:
  1325 + result = audit_comparator(audit_loginuid_set(current),
  1326 + f->op, f->val);
  1327 + break;
  1328 + case AUDIT_MSGTYPE:
  1329 + result = audit_comparator(msgtype, f->op, f->val);
  1330 + break;
  1331 + case AUDIT_SUBJ_USER:
  1332 + case AUDIT_SUBJ_ROLE:
  1333 + case AUDIT_SUBJ_TYPE:
  1334 + case AUDIT_SUBJ_SEN:
  1335 + case AUDIT_SUBJ_CLR:
  1336 + if (f->lsm_rule) {
  1337 + security_task_getsecid(current, &sid);
  1338 + result = security_audit_rule_match(sid,
  1339 + f->type, f->op, f->lsm_rule, NULL);
  1340 + }
  1341 + break;
  1342 + default:
  1343 + goto unlock_and_return;
1396 1344 }
  1345 + if (result < 0) /* error */
  1346 + goto unlock_and_return;
  1347 + if (!result)
  1348 + break;
1397 1349 }
1398   - if (result)
1399   - goto unlock_and_return;
  1350 + if (result > 0) {
  1351 + if (e->rule.action == AUDIT_NEVER || listtype == AUDIT_FILTER_TYPE)
  1352 + ret = 0;
  1353 + break;
  1354 + }
1400 1355 }
1401 1356 unlock_and_return:
1402 1357 rcu_read_unlock();
1403   - return result;
  1358 + return ret;
1404 1359 }
1405 1360  
1406 1361 static int update_lsm_rule(struct audit_krule *r)