aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorRichard Guy Briggs <rgb@redhat.com>2016-06-24 16:35:46 -0400
committerPaul Moore <paul@paul-moore.com>2016-06-27 11:01:00 -0400
commit86b2efbe3a390e07dbba725ef700b0d143e9a385 (patch)
tree6f29eca2803a82292ca3fd0f282b37764445d547 /kernel
parentda7f750c1ef570c0a22e5a3fc1fdfd8d308d9a1a (diff)
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>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/audit.c4
-rw-r--r--kernel/audit.h2
-rw-r--r--kernel/auditfilter.c151
3 files changed, 57 insertions, 100 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index 678c3f000191..994588ef9489 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -934,7 +934,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
934 if (!audit_enabled && msg_type != AUDIT_USER_AVC) 934 if (!audit_enabled && msg_type != AUDIT_USER_AVC)
935 return 0; 935 return 0;
936 936
937 err = audit_filter_user(msg_type); 937 err = audit_filter(msg_type, AUDIT_FILTER_USER);
938 if (err == 1) { /* match or error */ 938 if (err == 1) { /* match or error */
939 err = 0; 939 err = 0;
940 if (msg_type == AUDIT_USER_TTY) { 940 if (msg_type == AUDIT_USER_TTY) {
@@ -1382,7 +1382,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
1382 if (audit_initialized != AUDIT_INITIALIZED) 1382 if (audit_initialized != AUDIT_INITIALIZED)
1383 return NULL; 1383 return NULL;
1384 1384
1385 if (unlikely(audit_filter_type(type))) 1385 if (unlikely(!audit_filter(type, AUDIT_FILTER_TYPE)))
1386 return NULL; 1386 return NULL;
1387 1387
1388 if (gfp_mask & __GFP_DIRECT_RECLAIM) { 1388 if (gfp_mask & __GFP_DIRECT_RECLAIM) {
diff --git a/kernel/audit.h b/kernel/audit.h
index cbbe6bb6496e..1879f02cb2c3 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -327,6 +327,8 @@ extern pid_t audit_sig_pid;
327extern kuid_t audit_sig_uid; 327extern kuid_t audit_sig_uid;
328extern u32 audit_sig_sid; 328extern u32 audit_sig_sid;
329 329
330extern int audit_filter(int msgtype, unsigned int listtype);
331
330#ifdef CONFIG_AUDITSYSCALL 332#ifdef CONFIG_AUDITSYSCALL
331extern int __audit_signal_info(int sig, struct task_struct *t); 333extern int __audit_signal_info(int sig, struct task_struct *t);
332static inline int audit_signal_info(int sig, struct task_struct *t) 334static inline int audit_signal_info(int sig, struct task_struct *t)
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index ff59a5eed691..85d9cac497e4 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -1290,117 +1290,72 @@ int audit_compare_dname_path(const char *dname, const char *path, int parentlen)
1290 return strncmp(p, dname, dlen); 1290 return strncmp(p, dname, dlen);
1291} 1291}
1292 1292
1293static int audit_filter_user_rules(struct audit_krule *rule, int type, 1293int audit_filter(int msgtype, unsigned int listtype)
1294 enum audit_state *state)
1295{
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
1356int audit_filter_user(int type)
1357{
1358 enum audit_state state = AUDIT_DISABLED;
1359 struct audit_entry *e;
1360 int rc, ret;
1361
1362 ret = 1; /* Audit by default */
1363
1364 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
1378int audit_filter_type(int type)
1379{ 1294{
1380 struct audit_entry *e; 1295 struct audit_entry *e;
1381 int result = 0; 1296 int ret = 1; /* Audit by default */
1382 1297
1383 rcu_read_lock(); 1298 rcu_read_lock();
1384 if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE])) 1299 if (list_empty(&audit_filter_list[listtype]))
1385 goto unlock_and_return; 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 for (i = 0; i < e->rule.field_count; i++) { 1304 for (i = 0; i < e->rule.field_count; i++) {
1391 struct audit_field *f = &e->rule.fields[i]; 1305 struct audit_field *f = &e->rule.fields[i];
1392 if (f->type == AUDIT_MSGTYPE) { 1306 pid_t pid;
1393 result = audit_comparator(type, f->op, f->val); 1307 u32 sid;
1394 if (!result) 1308
1395 break; 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;
1349 }
1350 if (result > 0) {
1351 if (e->rule.action == AUDIT_NEVER || listtype == AUDIT_FILTER_TYPE)
1352 ret = 0;
1353 break;
1397 } 1354 }
1398 if (result)
1399 goto unlock_and_return;
1400 } 1355 }
1401unlock_and_return: 1356unlock_and_return:
1402 rcu_read_unlock(); 1357 rcu_read_unlock();
1403 return result; 1358 return ret;
1404} 1359}
1405 1360
1406static int update_lsm_rule(struct audit_krule *r) 1361static int update_lsm_rule(struct audit_krule *r)