Pull audit updates from Paul Moore: "Add some additional audit logging to capture the openat2() syscall open_how struct info. Previous variations of the open()/openat() syscalls allowed audit admins to inspect the syscall args to get the information contained in the new open_how struct used in openat2()" * tag 'audit-pr-20211101' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit: audit: return early if the filter rule has a lower priority audit: add OPENAT2 record to list "how" info audit: add support for the openat2 syscall audit: replace magic audit syscall class numbers with macros lsm_audit: avoid overloading the "key" audit field audit: Convert to SPDX identifier audit: rename struct node to struct audit_node to prevent future name collisions
Unified · Split
| @@ -3127,6 +3127,7 @@ W: https://github.com/linux-audit · 3126 unmodified lines | |||
| 3127 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git | 3127 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git |
| 3128 | F: include/asm-generic/audit_*.h | 3128 | F: include/asm-generic/audit_*.h |
| 3129 | F: include/linux/audit.h | 3129 | F: include/linux/audit.h |
| 3130 | F: include/linux/audit_arch.h | ||
| 3130 | F: include/uapi/linux/audit.h | 3131 | F: include/uapi/linux/audit.h |
| 3131 | F: kernel/audit* | 3132 | F: kernel/audit* |
| 3132 | F: lib/*audit.c | 3133 | F: lib/*audit.c |
| @@ -37,13 +37,15 @@ int audit_classify_syscall(int abi, unsigned syscall) · 36 unmodified lines | |||
| 37 | { | 37 | { |
| 38 | switch(syscall) { | 38 | switch(syscall) { |
| 39 | case __NR_open: | 39 | case __NR_open: |
| 40 | return 2; | 40 | return AUDITSC_OPEN; |
| 41 | case __NR_openat: | 41 | case __NR_openat: |
| 42 | return 3; | 42 | return AUDITSC_OPENAT; |
| 43 | case __NR_execve: | 43 | case __NR_execve: |
| 44 | return 5; | 44 | return AUDITSC_EXECVE; |
| 45 | case __NR_openat2: | ||
| 46 | return AUDITSC_OPENAT2; | ||
| 45 | default: | 47 | default: |
| 46 | return 0; | 48 | return AUDITSC_NATIVE; |
| 47 | } | 49 | } |
| 48 | } | 50 | } |
| 49 | 51 | ||
| @@ -38,13 +38,15 @@ int audit_classify_syscall(int abi, unsigned syscall) · 37 unmodified lines | |||
| 38 | { | 38 | { |
| 39 | switch(syscall) { | 39 | switch(syscall) { |
| 40 | case __NR_open: | 40 | case __NR_open: |
| 41 | return 2; | 41 | return AUDITSC_OPEN; |
| 42 | case __NR_openat: | 42 | case __NR_openat: |
| 43 | return 3; | 43 | return AUDITSC_OPENAT; |
| 44 | case __NR_execve: | 44 | case __NR_execve: |
| 45 | return 5; | 45 | return AUDITSC_EXECVE; |
| 46 | case __NR_openat2: | ||
| 47 | return AUDITSC_OPENAT2; | ||
| 46 | default: | 48 | default: |
| 47 | return 0; | 49 | return AUDITSC_NATIVE; |
| 48 | } | 50 | } |
| 49 | } | 51 | } |
| 50 | 52 | ||
| @@ -47,13 +47,15 @@ int audit_classify_syscall(int abi, unsigned syscall) · 46 unmodified lines | |||
| 47 | #endif | 47 | #endif |
| 48 | switch (syscall) { | 48 | switch (syscall) { |
| 49 | case __NR_open: | 49 | case __NR_open: |
| 50 | return 2; | 50 | return AUDITSC_OPEN; |
| 51 | case __NR_openat: | 51 | case __NR_openat: |
| 52 | return 3; | 52 | return AUDITSC_OPENAT; |
| 53 | case __NR_execve: | 53 | case __NR_execve: |
| 54 | return 5; | 54 | return AUDITSC_EXECVE; |
| 55 | case __NR_openat2: | ||
| 56 | return AUDITSC_OPENAT2; | ||
| 55 | default: | 57 | default: |
| 56 | return 0; | 58 | return AUDITSC_NATIVE; |
| 57 | } | 59 | } |
| 58 | } | 60 | } |
| 59 | 61 | ||
| @@ -1,4 +1,5 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include <linux/audit_arch.h> | ||
| 2 | #include <asm/unistd.h> | 3 | #include <asm/unistd.h> |
| 3 | 4 | ||
| 4 | unsigned int parisc32_dir_class[] = { | 5 | unsigned int parisc32_dir_class[] = { |
| @@ -30,12 +31,14 @@ int parisc32_classify_syscall(unsigned syscall) · 25 unmodified lines | |||
| 30 | { | 31 | { |
| 31 | switch (syscall) { | 32 | switch (syscall) { |
| 32 | case __NR_open: | 33 | case __NR_open: |
| 33 | return 2; | 34 | return AUDITSC_OPEN; |
| 34 | case __NR_openat: | 35 | case __NR_openat: |
| 35 | return 3; | 36 | return AUDITSC_OPENAT; |
| 36 | case __NR_execve: | 37 | case __NR_execve: |
| 37 | return 5; | 38 | return AUDITSC_EXECVE; |
| 39 | case __NR_openat2: | ||
| 40 | return AUDITSC_OPENAT2; | ||
| 38 | default: | 41 | default: |
| 39 | return 1; | 42 | return AUDITSC_COMPAT; |
| 40 | } | 43 | } |
| 41 | } | 44 | } |
| @@ -47,15 +47,17 @@ int audit_classify_syscall(int abi, unsigned syscall) · 46 unmodified lines | |||
| 47 | #endif | 47 | #endif |
| 48 | switch(syscall) { | 48 | switch(syscall) { |
| 49 | case __NR_open: | 49 | case __NR_open: |
| 50 | return 2; | 50 | return AUDITSC_OPEN; |
| 51 | case __NR_openat: | 51 | case __NR_openat: |
| 52 | return 3; | 52 | return AUDITSC_OPENAT; |
| 53 | case __NR_socketcall: | 53 | case __NR_socketcall: |
| 54 | return 4; | 54 | return AUDITSC_SOCKETCALL; |
| 55 | case __NR_execve: | 55 | case __NR_execve: |
| 56 | return 5; | 56 | return AUDITSC_EXECVE; |
| 57 | case __NR_openat2: | ||
| 58 | return AUDITSC_OPENAT2; | ||
| 57 | default: | 59 | default: |
| 58 | return 0; | 60 | return AUDITSC_NATIVE; |
| 59 | } | 61 | } |
| 60 | } | 62 | } |
| 61 | 63 | ||
| @@ -1,5 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #undef __powerpc64__ | 2 | #undef __powerpc64__ |
| 3 | #include <linux/audit_arch.h> | ||
| 3 | #include <asm/unistd.h> | 4 | #include <asm/unistd.h> |
| 4 | 5 | ||
| 5 | unsigned ppc32_dir_class[] = { | 6 | unsigned ppc32_dir_class[] = { |
| @@ -31,14 +32,16 @@ int ppc32_classify_syscall(unsigned syscall) · 25 unmodified lines | |||
| 31 | { | 32 | { |
| 32 | switch(syscall) { | 33 | switch(syscall) { |
| 33 | case __NR_open: | 34 | case __NR_open: |
| 34 | return 2; | 35 | return AUDITSC_OPEN; |
| 35 | case __NR_openat: | 36 | case __NR_openat: |
| 36 | return 3; | 37 | return AUDITSC_OPENAT; |
| 37 | case __NR_socketcall: | 38 | case __NR_socketcall: |
| 38 | return 4; | 39 | return AUDITSC_SOCKETCALL; |
| 39 | case __NR_execve: | 40 | case __NR_execve: |
| 40 | return 5; | 41 | return AUDITSC_EXECVE; |
| 42 | case __NR_openat2: | ||
| 43 | return AUDITSC_OPENAT2; | ||
| 41 | default: | 44 | default: |
| 42 | return 1; | 45 | return AUDITSC_COMPAT; |
| 43 | } | 46 | } |
| 44 | } | 47 | } |
| @@ -47,15 +47,17 @@ int audit_classify_syscall(int abi, unsigned syscall) · 46 unmodified lines | |||
| 47 | #endif | 47 | #endif |
| 48 | switch(syscall) { | 48 | switch(syscall) { |
| 49 | case __NR_open: | 49 | case __NR_open: |
| 50 | return 2; | 50 | return AUDITSC_OPEN; |
| 51 | case __NR_openat: | 51 | case __NR_openat: |
| 52 | return 3; | 52 | return AUDITSC_OPENAT; |
| 53 | case __NR_socketcall: | 53 | case __NR_socketcall: |
| 54 | return 4; | 54 | return AUDITSC_SOCKETCALL; |
| 55 | case __NR_execve: | 55 | case __NR_execve: |
| 56 | return 5; | 56 | return AUDITSC_EXECVE; |
| 57 | case __NR_openat2: | ||
| 58 | return AUDITSC_OPENAT2; | ||
| 57 | default: | 59 | default: |
| 58 | return 0; | 60 | return AUDITSC_NATIVE; |
| 59 | } | 61 | } |
| 60 | } | 62 | } |
| 61 | 63 | ||
| @@ -1,5 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #undef __s390x__ | 2 | #undef __s390x__ |
| 3 | #include <linux/audit_arch.h> | ||
| 3 | #include <asm/unistd.h> | 4 | #include <asm/unistd.h> |
| 4 | #include "audit.h" | 5 | #include "audit.h" |
| 5 | 6 | ||
| @@ -32,14 +33,16 @@ int s390_classify_syscall(unsigned syscall) · 26 unmodified lines | |||
| 32 | { | 33 | { |
| 33 | switch(syscall) { | 34 | switch(syscall) { |
| 34 | case __NR_open: | 35 | case __NR_open: |
| 35 | return 2; | 36 | return AUDITSC_OPEN; |
| 36 | case __NR_openat: | 37 | case __NR_openat: |
| 37 | return 3; | 38 | return AUDITSC_OPENAT; |
| 38 | case __NR_socketcall: | 39 | case __NR_socketcall: |
| 39 | return 4; | 40 | return AUDITSC_SOCKETCALL; |
| 40 | case __NR_execve: | 41 | case __NR_execve: |
| 41 | return 5; | 42 | return AUDITSC_EXECVE; |
| 43 | case __NR_openat2: | ||
| 44 | return AUDITSC_OPENAT2; | ||
| 42 | default: | 45 | default: |
| 43 | return 1; | 46 | return AUDITSC_COMPAT; |
| 44 | } | 47 | } |
| 45 | } | 48 | } |
| @@ -48,15 +48,17 @@ int audit_classify_syscall(int abi, unsigned int syscall) · 47 unmodified lines | |||
| 48 | #endif | 48 | #endif |
| 49 | switch(syscall) { | 49 | switch(syscall) { |
| 50 | case __NR_open: | 50 | case __NR_open: |
| 51 | return 2; | 51 | return AUDITSC_OPEN; |
| 52 | case __NR_openat: | 52 | case __NR_openat: |
| 53 | return 3; | 53 | return AUDITSC_OPENAT; |
| 54 | case __NR_socketcall: | 54 | case __NR_socketcall: |
| 55 | return 4; | 55 | return AUDITSC_SOCKETCALL; |
| 56 | case __NR_execve: | 56 | case __NR_execve: |
| 57 | return 5; | 57 | return AUDITSC_EXECVE; |
| 58 | case __NR_openat2: | ||
| 59 | return AUDITSC_OPENAT2; | ||
| 58 | default: | 60 | default: |
| 59 | return 0; | 61 | return AUDITSC_NATIVE; |
| 60 | } | 62 | } |
| 61 | } | 63 | } |
| 62 | 64 | ||
| @@ -1,5 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #define __32bit_syscall_numbers__ | 2 | #define __32bit_syscall_numbers__ |
| 3 | #include <linux/audit_arch.h> | ||
| 3 | #include <asm/unistd.h> | 4 | #include <asm/unistd.h> |
| 4 | #include "kernel.h" | 5 | #include "kernel.h" |
| 5 | 6 | ||
| @@ -32,14 +33,16 @@ int sparc32_classify_syscall(unsigned int syscall) · 26 unmodified lines | |||
| 32 | { | 33 | { |
| 33 | switch(syscall) { | 34 | switch(syscall) { |
| 34 | case __NR_open: | 35 | case __NR_open: |
| 35 | return 2; | 36 | return AUDITSC_OPEN; |
| 36 | case __NR_openat: | 37 | case __NR_openat: |
| 37 | return 3; | 38 | return AUDITSC_OPENAT; |
| 38 | case __NR_socketcall: | 39 | case __NR_socketcall: |
| 39 | return 4; | 40 | return AUDITSC_SOCKETCALL; |
| 40 | case __NR_execve: | 41 | case __NR_execve: |
| 41 | return 5; | 42 | return AUDITSC_EXECVE; |
| 43 | case __NR_openat2: | ||
| 44 | return AUDITSC_OPENAT2; | ||
| 42 | default: | 45 | default: |
| 43 | return 1; | 46 | return AUDITSC_COMPAT; |
| 44 | } | 47 | } |
| 45 | } | 48 | } |
| @@ -1,4 +1,5 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include <linux/audit_arch.h> | ||
| 2 | #include <asm/unistd_32.h> | 3 | #include <asm/unistd_32.h> |
| 3 | #include <asm/audit.h> | 4 | #include <asm/audit.h> |
| 4 | 5 | ||
| @@ -31,15 +32,17 @@ int ia32_classify_syscall(unsigned syscall) · 26 unmodified lines | |||
| 31 | { | 32 | { |
| 32 | switch (syscall) { | 33 | switch (syscall) { |
| 33 | case __NR_open: | 34 | case __NR_open: |
| 34 | return 2; | 35 | return AUDITSC_OPEN; |
| 35 | case __NR_openat: | 36 | case __NR_openat: |
| 36 | return 3; | 37 | return AUDITSC_OPENAT; |
| 37 | case __NR_socketcall: | 38 | case __NR_socketcall: |
| 38 | return 4; | 39 | return AUDITSC_SOCKETCALL; |
| 39 | case __NR_execve: | 40 | case __NR_execve: |
| 40 | case __NR_execveat: | 41 | case __NR_execveat: |
| 41 | return 5; | 42 | return AUDITSC_EXECVE; |
| 43 | case __NR_openat2: | ||
| 44 | return AUDITSC_OPENAT2; | ||
| 42 | default: | 45 | default: |
| 43 | return 1; | 46 | return AUDITSC_COMPAT; |
| 44 | } | 47 | } |
| 45 | } | 48 | } |
| @@ -47,14 +47,16 @@ int audit_classify_syscall(int abi, unsigned syscall) · 46 unmodified lines | |||
| 47 | #endif | 47 | #endif |
| 48 | switch(syscall) { | 48 | switch(syscall) { |
| 49 | case __NR_open: | 49 | case __NR_open: |
| 50 | return 2; | 50 | return AUDITSC_OPEN; |
| 51 | case __NR_openat: | 51 | case __NR_openat: |
| 52 | return 3; | 52 | return AUDITSC_OPENAT; |
| 53 | case __NR_execve: | 53 | case __NR_execve: |
| 54 | case __NR_execveat: | 54 | case __NR_execveat: |
| 55 | return 5; | 55 | return AUDITSC_EXECVE; |
| 56 | case __NR_openat2: | ||
| 57 | return AUDITSC_OPENAT2; | ||
| 56 | default: | 58 | default: |
| 57 | return 0; | 59 | return AUDITSC_NATIVE; |
| 58 | } | 60 | } |
| 59 | } | 61 | } |
| 60 | 62 | ||
| @@ -1248,6 +1248,8 @@ SYSCALL_DEFINE4(openat2, int, dfd, const char __user *, filename, · 1247 unmodified lines | |||
| 1248 | if (err) | 1248 | if (err) |
| 1249 | return err; | 1249 | return err; |
| 1250 | 1250 | ||
| 1251 | audit_openat2_how(&tmp); | ||
| 1252 | |||
| 1251 | /* O_LARGEFILE is only allowed for non-O_PATH. */ | 1253 | /* O_LARGEFILE is only allowed for non-O_PATH. */ |
| 1252 | if (!(tmp.flags & O_PATH) && force_o_largefile()) | 1254 | if (!(tmp.flags & O_PATH) && force_o_largefile()) |
| 1253 | tmp.flags |= O_LARGEFILE; | 1255 | tmp.flags |= O_LARGEFILE; |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
| 13 | #include <linux/ptrace.h> | 13 | #include <linux/ptrace.h> |
| 14 | #include <linux/audit_arch.h> | ||
| 14 | #include <uapi/linux/audit.h> | 15 | #include <uapi/linux/audit.h> |
| 15 | #include <uapi/linux/netfilter/nf_tables.h> | 16 | #include <uapi/linux/netfilter/nf_tables.h> |
| 16 | 17 | ||
| @@ -416,6 +417,7 @@ extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm, · 399 unmodified lines | |||
| 416 | const struct cred *old); | 417 | const struct cred *old); |
| 417 | extern void __audit_log_capset(const struct cred *new, const struct cred *old); | 418 | extern void __audit_log_capset(const struct cred *new, const struct cred *old); |
| 418 | extern void __audit_mmap_fd(int fd, int flags); | 419 | extern void __audit_mmap_fd(int fd, int flags); |
| 420 | extern void __audit_openat2_how(struct open_how *how); | ||
| 419 | extern void __audit_log_kern_module(char *name); | 421 | extern void __audit_log_kern_module(char *name); |
| 420 | extern void __audit_fanotify(unsigned int response); | 422 | extern void __audit_fanotify(unsigned int response); |
| 421 | extern void __audit_tk_injoffset(struct timespec64 offset); | 423 | extern void __audit_tk_injoffset(struct timespec64 offset); |
| @@ -512,6 +514,12 @@ static inline void audit_mmap_fd(int fd, int flags) · 90 unmodified lines | |||
| 512 | __audit_mmap_fd(fd, flags); | 514 | __audit_mmap_fd(fd, flags); |
| 513 | } | 515 | } |
| 514 | 516 | ||
| 517 | static inline void audit_openat2_how(struct open_how *how) | ||
| 518 | { | ||
| 519 | if (unlikely(!audit_dummy_context())) | ||
| 520 | __audit_openat2_how(how); | ||
| 521 | } | ||
| 522 | |||
| 515 | static inline void audit_log_kern_module(char *name) | 523 | static inline void audit_log_kern_module(char *name) |
| 516 | { | 524 | { |
| 517 | if (!audit_dummy_context()) | 525 | if (!audit_dummy_context()) |
| @@ -671,6 +679,9 @@ static inline void audit_log_capset(const struct cred *new, · 153 unmodified lines | |||
| 671 | static inline void audit_mmap_fd(int fd, int flags) | 679 | static inline void audit_mmap_fd(int fd, int flags) |
| 672 | { } | 680 | { } |
| 673 | 681 | ||
| 682 | static inline void audit_openat2_how(struct open_how *how) | ||
| 683 | { } | ||
| 684 | |||
| 674 | static inline void audit_log_kern_module(char *name) | 685 | static inline void audit_log_kern_module(char *name) |
| 675 | { | 686 | { |
| 676 | } | 687 | } |
| @@ -0,0 +1,24 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||
| 2 | /* audit_arch.h -- Arch layer specific support for audit | ||
| 3 | * | ||
| 4 | * Copyright 2021 Red Hat Inc., Durham, North Carolina. | ||
| 5 | * All Rights Reserved. | ||
| 6 | * | ||
| 7 | * Author: Richard Guy Briggs <rgb@redhat.com> | ||
| 8 | */ | ||
| 9 | #ifndef _LINUX_AUDIT_ARCH_H_ | ||
| 10 | #define _LINUX_AUDIT_ARCH_H_ | ||
| 11 | |||
| 12 | enum auditsc_class_t { | ||
| 13 | AUDITSC_NATIVE = 0, | ||
| 14 | AUDITSC_COMPAT, | ||
| 15 | AUDITSC_OPEN, | ||
| 16 | AUDITSC_OPENAT, | ||
| 17 | AUDITSC_SOCKETCALL, | ||
| 18 | AUDITSC_EXECVE, | ||
| 19 | AUDITSC_OPENAT2, | ||
| 20 | |||
| 21 | AUDITSC_NVALS /* count */ | ||
| 22 | }; | ||
| 23 | |||
| 24 | #endif | ||
| @@ -119,6 +119,7 @@ · 118 unmodified lines | |||
| 119 | #define AUDIT_BPF 1334 /* BPF subsystem */ | 119 | #define AUDIT_BPF 1334 /* BPF subsystem */ |
| 120 | #define AUDIT_EVENT_LISTENER 1335 /* Task joined multicast read socket */ | 120 | #define AUDIT_EVENT_LISTENER 1335 /* Task joined multicast read socket */ |
| 121 | #define AUDIT_URINGOP 1336 /* io_uring operation */ | 121 | #define AUDIT_URINGOP 1336 /* io_uring operation */ |
| 122 | #define AUDIT_OPENAT2 1337 /* Record showing openat2 how args */ | ||
| 122 | 123 | ||
| 123 | #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ | 124 | #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ |
| 124 | #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ | 125 | #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | |||
| 14 | #include <linux/skbuff.h> | 14 | #include <linux/skbuff.h> |
| 15 | #include <uapi/linux/mqueue.h> | 15 | #include <uapi/linux/mqueue.h> |
| 16 | #include <linux/tty.h> | 16 | #include <linux/tty.h> |
| 17 | #include <uapi/linux/openat2.h> // struct open_how | ||
| 17 | 18 | ||
| 18 | /* AUDIT_NAMES is the number of slots we reserve in the audit_context | 19 | /* AUDIT_NAMES is the number of slots we reserve in the audit_context |
| 19 | * for saving names from getname(). If we get more names we will allocate | 20 | * for saving names from getname(). If we get more names we will allocate |
| @@ -193,6 +194,7 @@ struct audit_context { · 173 unmodified lines | |||
| 193 | int fd; | 194 | int fd; |
| 194 | int flags; | 195 | int flags; |
| 195 | } mmap; | 196 | } mmap; |
| 197 | struct open_how openat2; | ||
| 196 | struct { | 198 | struct { |
| 197 | int argc; | 199 | int argc; |
| 198 | } execve; | 200 | } execve; |
| @@ -30,7 +30,7 @@ struct audit_chunk { · 29 unmodified lines | |||
| 30 | int count; | 30 | int count; |
| 31 | atomic_long_t refs; | 31 | atomic_long_t refs; |
| 32 | struct rcu_head head; | 32 | struct rcu_head head; |
| 33 | struct node { | 33 | struct audit_node { |
| 34 | struct list_head list; | 34 | struct list_head list; |
| 35 | struct audit_tree *owner; | 35 | struct audit_tree *owner; |
| 36 | unsigned index; /* index; upper bit indicates 'will prune' */ | 36 | unsigned index; /* index; upper bit indicates 'will prune' */ |
| @@ -269,7 +269,7 @@ bool audit_tree_match(struct audit_chunk *chunk, struct audit_tree *tree) · 232 unmodified lines | |||
| 269 | 269 | ||
| 270 | /* tagging and untagging inodes with trees */ | 270 | /* tagging and untagging inodes with trees */ |
| 271 | 271 | ||
| 272 | static struct audit_chunk *find_chunk(struct node *p) | 272 | static struct audit_chunk *find_chunk(struct audit_node *p) |
| 273 | { | 273 | { |
| 274 | int index = p->index & ~(1U<<31); | 274 | int index = p->index & ~(1U<<31); |
| 275 | p -= index; | 275 | p -= index; |
| @@ -322,7 +322,7 @@ static void replace_chunk(struct audit_chunk *new, struct audit_chunk *old) · 46 unmodified lines | |||
| 322 | list_replace_rcu(&old->hash, &new->hash); | 322 | list_replace_rcu(&old->hash, &new->hash); |
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | static void remove_chunk_node(struct audit_chunk *chunk, struct node *p) | 325 | static void remove_chunk_node(struct audit_chunk *chunk, struct audit_node *p) |
| 326 | { | 326 | { |
| 327 | struct audit_tree *owner = p->owner; | 327 | struct audit_tree *owner = p->owner; |
| 328 | 328 | ||
| @@ -459,7 +459,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) · 130 unmodified lines | |||
| 459 | { | 459 | { |
| 460 | struct fsnotify_mark *mark; | 460 | struct fsnotify_mark *mark; |
| 461 | struct audit_chunk *chunk, *old; | 461 | struct audit_chunk *chunk, *old; |
| 462 | struct node *p; | 462 | struct audit_node *p; |
| 463 | int n; | 463 | int n; |
| 464 | 464 | ||
| 465 | mutex_lock(&audit_tree_group->mark_mutex); | 465 | mutex_lock(&audit_tree_group->mark_mutex); |
| @@ -570,11 +570,11 @@ static void prune_tree_chunks(struct audit_tree *victim, bool tagged) · 104 unmodified lines | |||
| 570 | { | 570 | { |
| 571 | spin_lock(&hash_lock); | 571 | spin_lock(&hash_lock); |
| 572 | while (!list_empty(&victim->chunks)) { | 572 | while (!list_empty(&victim->chunks)) { |
| 573 | struct node *p; | 573 | struct audit_node *p; |
| 574 | struct audit_chunk *chunk; | 574 | struct audit_chunk *chunk; |
| 575 | struct fsnotify_mark *mark; | 575 | struct fsnotify_mark *mark; |
| 576 | 576 | ||
| 577 | p = list_first_entry(&victim->chunks, struct node, list); | 577 | p = list_first_entry(&victim->chunks, struct audit_node, list); |
| 578 | /* have we run out of marked? */ | 578 | /* have we run out of marked? */ |
| 579 | if (tagged && !(p->index & (1U<<31))) | 579 | if (tagged && !(p->index & (1U<<31))) |
| 580 | break; | 580 | break; |
| @@ -616,7 +616,7 @@ static void trim_marked(struct audit_tree *tree) · 35 unmodified lines | |||
| 616 | } | 616 | } |
| 617 | /* reorder */ | 617 | /* reorder */ |
| 618 | for (p = tree->chunks.next; p != &tree->chunks; p = q) { | 618 | for (p = tree->chunks.next; p != &tree->chunks; p = q) { |
| 619 | struct node *node = list_entry(p, struct node, list); | 619 | struct audit_node *node = list_entry(p, struct audit_node, list); |
| 620 | q = p->next; | 620 | q = p->next; |
| 621 | if (node->index & (1U<<31)) { | 621 | if (node->index & (1U<<31)) { |
| 622 | list_del_init(p); | 622 | list_del_init(p); |
| @@ -684,7 +684,7 @@ void audit_trim_trees(void) · 61 unmodified lines | |||
| 684 | struct audit_tree *tree; | 684 | struct audit_tree *tree; |
| 685 | struct path path; | 685 | struct path path; |
| 686 | struct vfsmount *root_mnt; | 686 | struct vfsmount *root_mnt; |
| 687 | struct node *node; | 687 | struct audit_node *node; |
| 688 | int err; | 688 | int err; |
| 689 | 689 | ||
| 690 | tree = container_of(cursor.next, struct audit_tree, list); | 690 | tree = container_of(cursor.next, struct audit_tree, list); |
| @@ -840,7 +840,7 @@ int audit_add_tree_rule(struct audit_krule *rule) · 149 unmodified lines | |||
| 840 | drop_collected_mounts(mnt); | 840 | drop_collected_mounts(mnt); |
| 841 | 841 | ||
| 842 | if (!err) { | 842 | if (!err) { |
| 843 | struct node *node; | 843 | struct audit_node *node; |
| 844 | spin_lock(&hash_lock); | 844 | spin_lock(&hash_lock); |
| 845 | list_for_each_entry(node, &tree->chunks, list) | 845 | list_for_each_entry(node, &tree->chunks, list) |
| 846 | node->index &= ~(1U<<31); | 846 | node->index &= ~(1U<<31); |
| @@ -939,7 +939,7 @@ int audit_tag_tree(char *old, char *new) · 92 unmodified lines | |||
| 939 | mutex_unlock(&audit_filter_mutex); | 939 | mutex_unlock(&audit_filter_mutex); |
| 940 | 940 | ||
| 941 | if (!failed) { | 941 | if (!failed) { |
| 942 | struct node *node; | 942 | struct audit_node *node; |
| 943 | spin_lock(&hash_lock); | 943 | spin_lock(&hash_lock); |
| 944 | list_for_each_entry(node, &tree->chunks, list) | 944 | list_for_each_entry(node, &tree->chunks, list) |
| 945 | node->index &= ~(1U<<31); | 945 | node->index &= ~(1U<<31); |
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 1 | /* auditsc.c -- System-call auditing support | 2 | /* auditsc.c -- System-call auditing support |
| 2 | * Handles all system-call specific auditing features. | 3 | * Handles all system-call specific auditing features. |
| 3 | * | 4 | * |
| @@ -6,20 +7,6 @@ · 2 unmodified lines | |||
| 6 | * Copyright (C) 2005, 2006 IBM Corporation | 7 | * Copyright (C) 2005, 2006 IBM Corporation |
| 7 | * All Rights Reserved. | 8 | * All Rights Reserved. |
| 8 | * | 9 | * |
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 22 | * | ||
| 23 | * Written by Rickard E. (Rik) Faith <faith@redhat.com> | 10 | * Written by Rickard E. (Rik) Faith <faith@redhat.com> |
| 24 | * | 11 | * |
| 25 | * Many of the ideas implemented here are from Stephen C. Tweedie, | 12 | * Many of the ideas implemented here are from Stephen C. Tweedie, |
| @@ -76,6 +63,7 @@ · 50 unmodified lines | |||
| 76 | #include <linux/fsnotify_backend.h> | 63 | #include <linux/fsnotify_backend.h> |
| 77 | #include <uapi/linux/limits.h> | 64 | #include <uapi/linux/limits.h> |
| 78 | #include <uapi/linux/netfilter/nf_tables.h> | 65 | #include <uapi/linux/netfilter/nf_tables.h> |
| 66 | #include <uapi/linux/openat2.h> // struct open_how | ||
| 79 | 67 | ||
| 80 | #include "audit.h" | 68 | #include "audit.h" |
| 81 | 69 | ||
| @@ -166,7 +154,7 @@ static int audit_match_perm(struct audit_context *ctx, int mask) · 84 unmodified lines | |||
| 166 | n = ctx->major; | 154 | n = ctx->major; |
| 167 | 155 | ||
| 168 | switch (audit_classify_syscall(ctx->arch, n)) { | 156 | switch (audit_classify_syscall(ctx->arch, n)) { |
| 169 | case 0: /* native */ | 157 | case AUDITSC_NATIVE: |
| 170 | if ((mask & AUDIT_PERM_WRITE) && | 158 | if ((mask & AUDIT_PERM_WRITE) && |
| 171 | audit_match_class(AUDIT_CLASS_WRITE, n)) | 159 | audit_match_class(AUDIT_CLASS_WRITE, n)) |
| 172 | return 1; | 160 | return 1; |
| @@ -177,7 +165,7 @@ static int audit_match_perm(struct audit_context *ctx, int mask) · 4 unmodified lines | |||
| 177 | audit_match_class(AUDIT_CLASS_CHATTR, n)) | 165 | audit_match_class(AUDIT_CLASS_CHATTR, n)) |
| 178 | return 1; | 166 | return 1; |
| 179 | return 0; | 167 | return 0; |
| 180 | case 1: /* 32bit on biarch */ | 168 | case AUDITSC_COMPAT: /* 32bit on biarch */ |
| 181 | if ((mask & AUDIT_PERM_WRITE) && | 169 | if ((mask & AUDIT_PERM_WRITE) && |
| 182 | audit_match_class(AUDIT_CLASS_WRITE_32, n)) | 170 | audit_match_class(AUDIT_CLASS_WRITE_32, n)) |
| 183 | return 1; | 171 | return 1; |
| @@ -188,14 +176,16 @@ static int audit_match_perm(struct audit_context *ctx, int mask) · 4 unmodified lines | |||
| 188 | audit_match_class(AUDIT_CLASS_CHATTR_32, n)) | 176 | audit_match_class(AUDIT_CLASS_CHATTR_32, n)) |
| 189 | return 1; | 177 | return 1; |
| 190 | return 0; | 178 | return 0; |
| 191 | case 2: /* open */ | 179 | case AUDITSC_OPEN: |
| 192 | return mask & ACC_MODE(ctx->argv[1]); | 180 | return mask & ACC_MODE(ctx->argv[1]); |
| 193 | case 3: /* openat */ | 181 | case AUDITSC_OPENAT: |
| 194 | return mask & ACC_MODE(ctx->argv[2]); | 182 | return mask & ACC_MODE(ctx->argv[2]); |
| 195 | case 4: /* socketcall */ | 183 | case AUDITSC_SOCKETCALL: |
| 196 | return ((mask & AUDIT_PERM_WRITE) && ctx->argv[0] == SYS_BIND); | 184 | return ((mask & AUDIT_PERM_WRITE) && ctx->argv[0] == SYS_BIND); |
| 197 | case 5: /* execve */ | 185 | case AUDITSC_EXECVE: |
| 198 | return mask & AUDIT_PERM_EXEC; | 186 | return mask & AUDIT_PERM_EXEC; |
| 187 | case AUDITSC_OPENAT2: | ||
| 188 | return mask & ACC_MODE((u32)((struct open_how *)ctx->argv[2])->flags); | ||
| 199 | default: | 189 | default: |
| 200 | return 0; | 190 | return 0; |
| 201 | } | 191 | } |
| @@ -480,6 +470,9 @@ static int audit_filter_rules(struct task_struct *tsk, · 278 unmodified lines | |||
| 480 | u32 sid; | 470 | u32 sid; |
| 481 | unsigned int sessionid; | 471 | unsigned int sessionid; |
| 482 | 472 | ||
| 473 | if (ctx && rule->prio <= ctx->prio) | ||
| 474 | return 0; | ||
| 475 | |||
| 483 | cred = rcu_dereference_check(tsk->cred, tsk == current || task_creation); | 476 | cred = rcu_dereference_check(tsk->cred, tsk == current || task_creation); |
| 484 | 477 | ||
| 485 | for (i = 0; i < rule->field_count; i++) { | 478 | for (i = 0; i < rule->field_count; i++) { |
| @@ -747,8 +740,6 @@ static int audit_filter_rules(struct task_struct *tsk, · 261 unmodified lines | |||
| 747 | } | 740 | } |
| 748 | 741 | ||
| 749 | if (ctx) { | 742 | if (ctx) { |
| 750 | if (rule->prio <= ctx->prio) | ||
| 751 | return 0; | ||
| 752 | if (rule->filterkey) { | 743 | if (rule->filterkey) { |
| 753 | kfree(ctx->filterkey); | 744 | kfree(ctx->filterkey); |
| 754 | ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC); | 745 | ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC); |
| @@ -1437,6 +1428,12 @@ static void show_special(struct audit_context *context, int *call_panic) · 682 unmodified lines | |||
| 1437 | audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd, | 1428 | audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd, |
| 1438 | context->mmap.flags); | 1429 | context->mmap.flags); |
| 1439 | break; | 1430 | break; |
| 1431 | case AUDIT_OPENAT2: | ||
| 1432 | audit_log_format(ab, "oflag=0%llo mode=0%llo resolve=0x%llx", | ||
| 1433 | context->openat2.flags, | ||
| 1434 | context->openat2.mode, | ||
| 1435 | context->openat2.resolve); | ||
| 1436 | break; | ||
| 1440 | case AUDIT_EXECVE: | 1437 | case AUDIT_EXECVE: |
| 1441 | audit_log_execve_info(context, &ab); | 1438 | audit_log_execve_info(context, &ab); |
| 1442 | break; | 1439 | break; |
| @@ -2815,6 +2812,16 @@ void __audit_mmap_fd(int fd, int flags) · 1372 unmodified lines | |||
| 2815 | context->type = AUDIT_MMAP; | 2812 | context->type = AUDIT_MMAP; |
| 2816 | } | 2813 | } |
| 2817 | 2814 | ||
| 2815 | void __audit_openat2_how(struct open_how *how) | ||
| 2816 | { | ||
| 2817 | struct audit_context *context = audit_context(); | ||
| 2818 | |||
| 2819 | context->openat2.flags = how->flags; | ||
| 2820 | context->openat2.mode = how->mode; | ||
| 2821 | context->openat2.resolve = how->resolve; | ||
| 2822 | context->type = AUDIT_OPENAT2; | ||
| 2823 | } | ||
| 2824 | |||
| 2818 | void __audit_log_kern_module(char *name) | 2825 | void __audit_log_kern_module(char *name) |
| 2819 | { | 2826 | { |
| 2820 | struct audit_context *context = audit_context(); | 2827 | struct audit_context *context = audit_context(); |
| @@ -45,23 +45,27 @@ int audit_classify_syscall(int abi, unsigned syscall) · 44 unmodified lines | |||
| 45 | switch(syscall) { | 45 | switch(syscall) { |
| 46 | #ifdef __NR_open | 46 | #ifdef __NR_open |
| 47 | case __NR_open: | 47 | case __NR_open: |
| 48 | return 2; | 48 | return AUDITSC_OPEN; |
| 49 | #endif | 49 | #endif |
| 50 | #ifdef __NR_openat | 50 | #ifdef __NR_openat |
| 51 | case __NR_openat: | 51 | case __NR_openat: |
| 52 | return 3; | 52 | return AUDITSC_OPENAT; |
| 53 | #endif | 53 | #endif |
| 54 | #ifdef __NR_socketcall | 54 | #ifdef __NR_socketcall |
| 55 | case __NR_socketcall: | 55 | case __NR_socketcall: |
| 56 | return 4; | 56 | return AUDITSC_SOCKETCALL; |
| 57 | #endif | 57 | #endif |
| 58 | #ifdef __NR_execveat | 58 | #ifdef __NR_execveat |
| 59 | case __NR_execveat: | 59 | case __NR_execveat: |
| 60 | #endif | 60 | #endif |
| 61 | case __NR_execve: | 61 | case __NR_execve: |
| 62 | return 5; | 62 | return AUDITSC_EXECVE; |
| 63 | #ifdef __NR_openat2 | ||
| 64 | case __NR_openat2: | ||
| 65 | return AUDITSC_OPENAT2; | ||
| 66 | #endif | ||
| 63 | default: | 67 | default: |
| 64 | return 0; | 68 | return AUDITSC_NATIVE; |
| 65 | } | 69 | } |
| 66 | } | 70 | } |
| 67 | 71 | ||
| @@ -1,6 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include <linux/init.h> | 2 | #include <linux/init.h> |
| 3 | #include <linux/types.h> | 3 | #include <linux/types.h> |
| 4 | #include <linux/audit_arch.h> | ||
| 4 | #include <asm/unistd32.h> | 5 | #include <asm/unistd32.h> |
| 5 | 6 | ||
| 6 | unsigned compat_dir_class[] = { | 7 | unsigned compat_dir_class[] = { |
| @@ -33,19 +34,23 @@ int audit_classify_compat_syscall(int abi, unsigned syscall) · 26 unmodified lines | |||
| 33 | switch (syscall) { | 34 | switch (syscall) { |
| 34 | #ifdef __NR_open | 35 | #ifdef __NR_open |
| 35 | case __NR_open: | 36 | case __NR_open: |
| 36 | return 2; | 37 | return AUDITSC_OPEN; |
| 37 | #endif | 38 | #endif |
| 38 | #ifdef __NR_openat | 39 | #ifdef __NR_openat |
| 39 | case __NR_openat: | 40 | case __NR_openat: |
| 40 | return 3; | 41 | return AUDITSC_OPENAT; |
| 41 | #endif | 42 | #endif |
| 42 | #ifdef __NR_socketcall | 43 | #ifdef __NR_socketcall |
| 43 | case __NR_socketcall: | 44 | case __NR_socketcall: |
| 44 | return 4; | 45 | return AUDITSC_SOCKETCALL; |
| 45 | #endif | 46 | #endif |
| 46 | case __NR_execve: | 47 | case __NR_execve: |
| 47 | return 5; | 48 | return AUDITSC_EXECVE; |
| 49 | #ifdef __NR_openat2 | ||
| 50 | case __NR_openat2: | ||
| 51 | return AUDITSC_OPENAT2; | ||
| 52 | #endif | ||
| 48 | default: | 53 | default: |
| 49 | return 1; | 54 | return AUDITSC_COMPAT; |
| 50 | } | 55 | } |
| 51 | } | 56 | } |
| @@ -224,7 +224,7 @@ static void dump_common_audit_data(struct audit_buffer *ab, · 223 unmodified lines | |||
| 224 | case LSM_AUDIT_DATA_NONE: | 224 | case LSM_AUDIT_DATA_NONE: |
| 225 | return; | 225 | return; |
| 226 | case LSM_AUDIT_DATA_IPC: | 226 | case LSM_AUDIT_DATA_IPC: |
| 227 | audit_log_format(ab, " key=%d ", a->u.ipc_id); | 227 | audit_log_format(ab, " ipc_key=%d ", a->u.ipc_id); |
| 228 | break; | 228 | break; |
| 229 | case LSM_AUDIT_DATA_CAP: | 229 | case LSM_AUDIT_DATA_CAP: |
| 230 | audit_log_format(ab, " capability=%d ", a->u.cap); | 230 | audit_log_format(ab, " capability=%d ", a->u.cap); |