.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* auditfilter.c -- filtering of audit events |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright 2003-2004 Red Hat, Inc. |
---|
4 | 5 | * Copyright 2005 Hewlett-Packard Development Company, L.P. |
---|
5 | 6 | * Copyright 2005 IBM Corporation |
---|
6 | | - * |
---|
7 | | - * This program is free software; you can redistribute it and/or modify |
---|
8 | | - * it under the terms of the GNU General Public License as published by |
---|
9 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
10 | | - * (at your option) any later version. |
---|
11 | | - * |
---|
12 | | - * This program is distributed in the hope that it will be useful, |
---|
13 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
15 | | - * GNU General Public License for more details. |
---|
16 | | - * |
---|
17 | | - * You should have received a copy of the GNU General Public License |
---|
18 | | - * along with this program; if not, write to the Free Software |
---|
19 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
20 | 7 | */ |
---|
21 | 8 | |
---|
22 | 9 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
.. | .. |
---|
335 | 322 | /* check if an audit field is valid */ |
---|
336 | 323 | static int audit_field_valid(struct audit_entry *entry, struct audit_field *f) |
---|
337 | 324 | { |
---|
338 | | - switch(f->type) { |
---|
| 325 | + switch (f->type) { |
---|
339 | 326 | case AUDIT_MSGTYPE: |
---|
340 | 327 | if (entry->rule.listnr != AUDIT_FILTER_EXCLUDE && |
---|
341 | 328 | entry->rule.listnr != AUDIT_FILTER_USER) |
---|
.. | .. |
---|
347 | 334 | break; |
---|
348 | 335 | } |
---|
349 | 336 | |
---|
350 | | - switch(entry->rule.listnr) { |
---|
| 337 | + switch (entry->rule.listnr) { |
---|
351 | 338 | case AUDIT_FILTER_FS: |
---|
352 | 339 | switch(f->type) { |
---|
353 | 340 | case AUDIT_FSTYPE: |
---|
.. | .. |
---|
358 | 345 | } |
---|
359 | 346 | } |
---|
360 | 347 | |
---|
361 | | - switch(f->type) { |
---|
362 | | - default: |
---|
363 | | - return -EINVAL; |
---|
| 348 | + /* Check for valid field type and op */ |
---|
| 349 | + switch (f->type) { |
---|
| 350 | + case AUDIT_ARG0: |
---|
| 351 | + case AUDIT_ARG1: |
---|
| 352 | + case AUDIT_ARG2: |
---|
| 353 | + case AUDIT_ARG3: |
---|
| 354 | + case AUDIT_PERS: /* <uapi/linux/personality.h> */ |
---|
| 355 | + case AUDIT_DEVMINOR: |
---|
| 356 | + /* all ops are valid */ |
---|
| 357 | + break; |
---|
364 | 358 | case AUDIT_UID: |
---|
365 | 359 | case AUDIT_EUID: |
---|
366 | 360 | case AUDIT_SUID: |
---|
.. | .. |
---|
373 | 367 | case AUDIT_FSGID: |
---|
374 | 368 | case AUDIT_OBJ_GID: |
---|
375 | 369 | case AUDIT_PID: |
---|
376 | | - case AUDIT_PERS: |
---|
377 | 370 | case AUDIT_MSGTYPE: |
---|
378 | 371 | case AUDIT_PPID: |
---|
379 | 372 | case AUDIT_DEVMAJOR: |
---|
380 | | - case AUDIT_DEVMINOR: |
---|
381 | 373 | case AUDIT_EXIT: |
---|
382 | 374 | case AUDIT_SUCCESS: |
---|
383 | 375 | case AUDIT_INODE: |
---|
384 | 376 | case AUDIT_SESSIONID: |
---|
| 377 | + case AUDIT_SUBJ_SEN: |
---|
| 378 | + case AUDIT_SUBJ_CLR: |
---|
| 379 | + case AUDIT_OBJ_LEV_LOW: |
---|
| 380 | + case AUDIT_OBJ_LEV_HIGH: |
---|
| 381 | + case AUDIT_SADDR_FAM: |
---|
385 | 382 | /* bit ops are only useful on syscall args */ |
---|
386 | 383 | if (f->op == Audit_bitmask || f->op == Audit_bittest) |
---|
387 | 384 | return -EINVAL; |
---|
388 | 385 | break; |
---|
389 | | - case AUDIT_ARG0: |
---|
390 | | - case AUDIT_ARG1: |
---|
391 | | - case AUDIT_ARG2: |
---|
392 | | - case AUDIT_ARG3: |
---|
393 | 386 | case AUDIT_SUBJ_USER: |
---|
394 | 387 | case AUDIT_SUBJ_ROLE: |
---|
395 | 388 | case AUDIT_SUBJ_TYPE: |
---|
396 | | - case AUDIT_SUBJ_SEN: |
---|
397 | | - case AUDIT_SUBJ_CLR: |
---|
398 | 389 | case AUDIT_OBJ_USER: |
---|
399 | 390 | case AUDIT_OBJ_ROLE: |
---|
400 | 391 | case AUDIT_OBJ_TYPE: |
---|
401 | | - case AUDIT_OBJ_LEV_LOW: |
---|
402 | | - case AUDIT_OBJ_LEV_HIGH: |
---|
403 | 392 | case AUDIT_WATCH: |
---|
404 | 393 | case AUDIT_DIR: |
---|
405 | 394 | case AUDIT_FILTERKEY: |
---|
406 | | - break; |
---|
407 | 395 | case AUDIT_LOGINUID_SET: |
---|
408 | | - if ((f->val != 0) && (f->val != 1)) |
---|
409 | | - return -EINVAL; |
---|
410 | | - /* FALL THROUGH */ |
---|
411 | 396 | case AUDIT_ARCH: |
---|
412 | 397 | case AUDIT_FSTYPE: |
---|
| 398 | + case AUDIT_PERM: |
---|
| 399 | + case AUDIT_FILETYPE: |
---|
| 400 | + case AUDIT_FIELD_COMPARE: |
---|
| 401 | + case AUDIT_EXE: |
---|
| 402 | + /* only equal and not equal valid ops */ |
---|
413 | 403 | if (f->op != Audit_not_equal && f->op != Audit_equal) |
---|
| 404 | + return -EINVAL; |
---|
| 405 | + break; |
---|
| 406 | + default: |
---|
| 407 | + /* field not recognized */ |
---|
| 408 | + return -EINVAL; |
---|
| 409 | + } |
---|
| 410 | + |
---|
| 411 | + /* Check for select valid field values */ |
---|
| 412 | + switch (f->type) { |
---|
| 413 | + case AUDIT_LOGINUID_SET: |
---|
| 414 | + if ((f->val != 0) && (f->val != 1)) |
---|
414 | 415 | return -EINVAL; |
---|
415 | 416 | break; |
---|
416 | 417 | case AUDIT_PERM: |
---|
.. | .. |
---|
425 | 426 | if (f->val > AUDIT_MAX_FIELD_COMPARE) |
---|
426 | 427 | return -EINVAL; |
---|
427 | 428 | break; |
---|
428 | | - case AUDIT_EXE: |
---|
429 | | - if (f->op != Audit_not_equal && f->op != Audit_equal) |
---|
| 429 | + case AUDIT_SADDR_FAM: |
---|
| 430 | + if (f->val >= AF_MAX) |
---|
430 | 431 | return -EINVAL; |
---|
431 | 432 | break; |
---|
| 433 | + default: |
---|
| 434 | + break; |
---|
432 | 435 | } |
---|
| 436 | + |
---|
433 | 437 | return 0; |
---|
434 | 438 | } |
---|
435 | 439 | |
---|
.. | .. |
---|
677 | 681 | data->values[i] = AUDIT_UID_UNSET; |
---|
678 | 682 | break; |
---|
679 | 683 | } |
---|
680 | | - /* fallthrough if set */ |
---|
| 684 | + fallthrough; /* if set */ |
---|
681 | 685 | default: |
---|
682 | 686 | data->values[i] = f->val; |
---|
683 | 687 | } |
---|
.. | .. |
---|
1098 | 1102 | if (!audit_enabled) |
---|
1099 | 1103 | return; |
---|
1100 | 1104 | |
---|
1101 | | - ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
---|
| 1105 | + ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
---|
1102 | 1106 | if (!ab) |
---|
1103 | 1107 | return; |
---|
1104 | 1108 | audit_log_session_info(ab); |
---|
.. | .. |
---|
1208 | 1212 | case Audit_bittest: |
---|
1209 | 1213 | return ((left & right) == right); |
---|
1210 | 1214 | default: |
---|
1211 | | - BUG(); |
---|
1212 | 1215 | return 0; |
---|
1213 | 1216 | } |
---|
1214 | 1217 | } |
---|
.. | .. |
---|
1231 | 1234 | case Audit_bitmask: |
---|
1232 | 1235 | case Audit_bittest: |
---|
1233 | 1236 | default: |
---|
1234 | | - BUG(); |
---|
1235 | 1237 | return 0; |
---|
1236 | 1238 | } |
---|
1237 | 1239 | } |
---|
.. | .. |
---|
1254 | 1256 | case Audit_bitmask: |
---|
1255 | 1257 | case Audit_bittest: |
---|
1256 | 1258 | default: |
---|
1257 | | - BUG(); |
---|
1258 | 1259 | return 0; |
---|
1259 | 1260 | } |
---|
1260 | 1261 | } |
---|
.. | .. |
---|
1297 | 1298 | * @parentlen: length of the parent if known. Passing in AUDIT_NAME_FULL |
---|
1298 | 1299 | * here indicates that we must compute this value. |
---|
1299 | 1300 | */ |
---|
1300 | | -int audit_compare_dname_path(const char *dname, const char *path, int parentlen) |
---|
| 1301 | +int audit_compare_dname_path(const struct qstr *dname, const char *path, int parentlen) |
---|
1301 | 1302 | { |
---|
1302 | 1303 | int dlen, pathlen; |
---|
1303 | 1304 | const char *p; |
---|
1304 | 1305 | |
---|
1305 | | - dlen = strlen(dname); |
---|
| 1306 | + dlen = dname->len; |
---|
1306 | 1307 | pathlen = strlen(path); |
---|
1307 | 1308 | if (pathlen < dlen) |
---|
1308 | 1309 | return 1; |
---|
.. | .. |
---|
1313 | 1314 | |
---|
1314 | 1315 | p = path + parentlen; |
---|
1315 | 1316 | |
---|
1316 | | - return strncmp(p, dname, dlen); |
---|
| 1317 | + return strncmp(p, dname->name, dlen); |
---|
1317 | 1318 | } |
---|
1318 | 1319 | |
---|
1319 | 1320 | int audit_filter(int msgtype, unsigned int listtype) |
---|
.. | .. |
---|
1322 | 1323 | int ret = 1; /* Audit by default */ |
---|
1323 | 1324 | |
---|
1324 | 1325 | rcu_read_lock(); |
---|
1325 | | - if (list_empty(&audit_filter_list[listtype])) |
---|
1326 | | - goto unlock_and_return; |
---|
1327 | 1326 | list_for_each_entry_rcu(e, &audit_filter_list[listtype], list) { |
---|
1328 | 1327 | int i, result = 0; |
---|
1329 | 1328 | |
---|
.. | .. |
---|
1362 | 1361 | if (f->lsm_rule) { |
---|
1363 | 1362 | security_task_getsecid(current, &sid); |
---|
1364 | 1363 | result = security_audit_rule_match(sid, |
---|
1365 | | - f->type, f->op, f->lsm_rule, NULL); |
---|
| 1364 | + f->type, f->op, f->lsm_rule); |
---|
1366 | 1365 | } |
---|
1367 | 1366 | break; |
---|
1368 | 1367 | case AUDIT_EXE: |
---|