Commit d2fac0af authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'audit-pr-20211101' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit

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
parents cdab10bf d9516f34
...@@ -3127,6 +3127,7 @@ W: https://github.com/linux-audit ...@@ -3127,6 +3127,7 @@ W: https://github.com/linux-audit
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git
F: include/asm-generic/audit_*.h F: include/asm-generic/audit_*.h
F: include/linux/audit.h F: include/linux/audit.h
F: include/linux/audit_arch.h
F: include/uapi/linux/audit.h F: include/uapi/linux/audit.h
F: kernel/audit* F: kernel/audit*
F: lib/*audit.c F: lib/*audit.c
......
...@@ -37,13 +37,15 @@ int audit_classify_syscall(int abi, unsigned syscall) ...@@ -37,13 +37,15 @@ int audit_classify_syscall(int abi, unsigned syscall)
{ {
switch(syscall) { switch(syscall) {
case __NR_open: case __NR_open:
return 2; return AUDITSC_OPEN;
case __NR_openat: case __NR_openat:
return 3; return AUDITSC_OPENAT;
case __NR_execve: case __NR_execve:
return 5; return AUDITSC_EXECVE;
case __NR_openat2:
return AUDITSC_OPENAT2;
default: default:
return 0; return AUDITSC_NATIVE;
} }
} }
......
...@@ -38,13 +38,15 @@ int audit_classify_syscall(int abi, unsigned syscall) ...@@ -38,13 +38,15 @@ int audit_classify_syscall(int abi, unsigned syscall)
{ {
switch(syscall) { switch(syscall) {
case __NR_open: case __NR_open:
return 2; return AUDITSC_OPEN;
case __NR_openat: case __NR_openat:
return 3; return AUDITSC_OPENAT;
case __NR_execve: case __NR_execve:
return 5; return AUDITSC_EXECVE;
case __NR_openat2:
return AUDITSC_OPENAT2;
default: default:
return 0; return AUDITSC_NATIVE;
} }
} }
......
...@@ -47,13 +47,15 @@ int audit_classify_syscall(int abi, unsigned syscall) ...@@ -47,13 +47,15 @@ int audit_classify_syscall(int abi, unsigned syscall)
#endif #endif
switch (syscall) { switch (syscall) {
case __NR_open: case __NR_open:
return 2; return AUDITSC_OPEN;
case __NR_openat: case __NR_openat:
return 3; return AUDITSC_OPENAT;
case __NR_execve: case __NR_execve:
return 5; return AUDITSC_EXECVE;
case __NR_openat2:
return AUDITSC_OPENAT2;
default: default:
return 0; return AUDITSC_NATIVE;
} }
} }
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include <linux/audit_arch.h>
#include <asm/unistd.h> #include <asm/unistd.h>
unsigned int parisc32_dir_class[] = { unsigned int parisc32_dir_class[] = {
...@@ -30,12 +31,14 @@ int parisc32_classify_syscall(unsigned syscall) ...@@ -30,12 +31,14 @@ int parisc32_classify_syscall(unsigned syscall)
{ {
switch (syscall) { switch (syscall) {
case __NR_open: case __NR_open:
return 2; return AUDITSC_OPEN;
case __NR_openat: case __NR_openat:
return 3; return AUDITSC_OPENAT;
case __NR_execve: case __NR_execve:
return 5; return AUDITSC_EXECVE;
case __NR_openat2:
return AUDITSC_OPENAT2;
default: default:
return 1; return AUDITSC_COMPAT;
} }
} }
...@@ -47,15 +47,17 @@ int audit_classify_syscall(int abi, unsigned syscall) ...@@ -47,15 +47,17 @@ int audit_classify_syscall(int abi, unsigned syscall)
#endif #endif
switch(syscall) { switch(syscall) {
case __NR_open: case __NR_open:
return 2; return AUDITSC_OPEN;
case __NR_openat: case __NR_openat:
return 3; return AUDITSC_OPENAT;
case __NR_socketcall: case __NR_socketcall:
return 4; return AUDITSC_SOCKETCALL;
case __NR_execve: case __NR_execve:
return 5; return AUDITSC_EXECVE;
case __NR_openat2:
return AUDITSC_OPENAT2;
default: default:
return 0; return AUDITSC_NATIVE;
} }
} }
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#undef __powerpc64__ #undef __powerpc64__
#include <linux/audit_arch.h>
#include <asm/unistd.h> #include <asm/unistd.h>
unsigned ppc32_dir_class[] = { unsigned ppc32_dir_class[] = {
...@@ -31,14 +32,16 @@ int ppc32_classify_syscall(unsigned syscall) ...@@ -31,14 +32,16 @@ int ppc32_classify_syscall(unsigned syscall)
{ {
switch(syscall) { switch(syscall) {
case __NR_open: case __NR_open:
return 2; return AUDITSC_OPEN;
case __NR_openat: case __NR_openat:
return 3; return AUDITSC_OPENAT;
case __NR_socketcall: case __NR_socketcall:
return 4; return AUDITSC_SOCKETCALL;
case __NR_execve: case __NR_execve:
return 5; return AUDITSC_EXECVE;
case __NR_openat2:
return AUDITSC_OPENAT2;
default: default:
return 1; return AUDITSC_COMPAT;
} }
} }
...@@ -47,15 +47,17 @@ int audit_classify_syscall(int abi, unsigned syscall) ...@@ -47,15 +47,17 @@ int audit_classify_syscall(int abi, unsigned syscall)
#endif #endif
switch(syscall) { switch(syscall) {
case __NR_open: case __NR_open:
return 2; return AUDITSC_OPEN;
case __NR_openat: case __NR_openat:
return 3; return AUDITSC_OPENAT;
case __NR_socketcall: case __NR_socketcall:
return 4; return AUDITSC_SOCKETCALL;
case __NR_execve: case __NR_execve:
return 5; return AUDITSC_EXECVE;
case __NR_openat2:
return AUDITSC_OPENAT2;
default: default:
return 0; return AUDITSC_NATIVE;
} }
} }
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#undef __s390x__ #undef __s390x__
#include <linux/audit_arch.h>
#include <asm/unistd.h> #include <asm/unistd.h>
#include "audit.h" #include "audit.h"
...@@ -32,14 +33,16 @@ int s390_classify_syscall(unsigned syscall) ...@@ -32,14 +33,16 @@ int s390_classify_syscall(unsigned syscall)
{ {
switch(syscall) { switch(syscall) {
case __NR_open: case __NR_open:
return 2; return AUDITSC_OPEN;
case __NR_openat: case __NR_openat:
return 3; return AUDITSC_OPENAT;
case __NR_socketcall: case __NR_socketcall:
return 4; return AUDITSC_SOCKETCALL;
case __NR_execve: case __NR_execve:
return 5; return AUDITSC_EXECVE;
case __NR_openat2:
return AUDITSC_OPENAT2;
default: default:
return 1; return AUDITSC_COMPAT;
} }
} }
...@@ -48,15 +48,17 @@ int audit_classify_syscall(int abi, unsigned int syscall) ...@@ -48,15 +48,17 @@ int audit_classify_syscall(int abi, unsigned int syscall)
#endif #endif
switch(syscall) { switch(syscall) {
case __NR_open: case __NR_open:
return 2; return AUDITSC_OPEN;
case __NR_openat: case __NR_openat:
return 3; return AUDITSC_OPENAT;
case __NR_socketcall: case __NR_socketcall:
return 4; return AUDITSC_SOCKETCALL;
case __NR_execve: case __NR_execve:
return 5; return AUDITSC_EXECVE;
case __NR_openat2:
return AUDITSC_OPENAT2;
default: default:
return 0; return AUDITSC_NATIVE;
} }
} }
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#define __32bit_syscall_numbers__ #define __32bit_syscall_numbers__
#include <linux/audit_arch.h>
#include <asm/unistd.h> #include <asm/unistd.h>
#include "kernel.h" #include "kernel.h"
...@@ -32,14 +33,16 @@ int sparc32_classify_syscall(unsigned int syscall) ...@@ -32,14 +33,16 @@ int sparc32_classify_syscall(unsigned int syscall)
{ {
switch(syscall) { switch(syscall) {
case __NR_open: case __NR_open:
return 2; return AUDITSC_OPEN;
case __NR_openat: case __NR_openat:
return 3; return AUDITSC_OPENAT;
case __NR_socketcall: case __NR_socketcall:
return 4; return AUDITSC_SOCKETCALL;
case __NR_execve: case __NR_execve:
return 5; return AUDITSC_EXECVE;
case __NR_openat2:
return AUDITSC_OPENAT2;
default: default:
return 1; return AUDITSC_COMPAT;
} }
} }
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include <linux/audit_arch.h>
#include <asm/unistd_32.h> #include <asm/unistd_32.h>
#include <asm/audit.h> #include <asm/audit.h>
...@@ -31,15 +32,17 @@ int ia32_classify_syscall(unsigned syscall) ...@@ -31,15 +32,17 @@ int ia32_classify_syscall(unsigned syscall)
{ {
switch (syscall) { switch (syscall) {
case __NR_open: case __NR_open:
return 2; return AUDITSC_OPEN;
case __NR_openat: case __NR_openat:
return 3; return AUDITSC_OPENAT;
case __NR_socketcall: case __NR_socketcall:
return 4; return AUDITSC_SOCKETCALL;
case __NR_execve: case __NR_execve:
case __NR_execveat: case __NR_execveat:
return 5; return AUDITSC_EXECVE;
case __NR_openat2:
return AUDITSC_OPENAT2;
default: default:
return 1; return AUDITSC_COMPAT;
} }
} }
...@@ -47,14 +47,16 @@ int audit_classify_syscall(int abi, unsigned syscall) ...@@ -47,14 +47,16 @@ int audit_classify_syscall(int abi, unsigned syscall)
#endif #endif
switch(syscall) { switch(syscall) {
case __NR_open: case __NR_open:
return 2; return AUDITSC_OPEN;
case __NR_openat: case __NR_openat:
return 3; return AUDITSC_OPENAT;
case __NR_execve: case __NR_execve:
case __NR_execveat: case __NR_execveat:
return 5; return AUDITSC_EXECVE;
case __NR_openat2:
return AUDITSC_OPENAT2;
default: default:
return 0; return AUDITSC_NATIVE;
} }
} }
......
...@@ -1248,6 +1248,8 @@ SYSCALL_DEFINE4(openat2, int, dfd, const char __user *, filename, ...@@ -1248,6 +1248,8 @@ SYSCALL_DEFINE4(openat2, int, dfd, const char __user *, filename,
if (err) if (err)
return err; return err;
audit_openat2_how(&tmp);
/* O_LARGEFILE is only allowed for non-O_PATH. */ /* O_LARGEFILE is only allowed for non-O_PATH. */
if (!(tmp.flags & O_PATH) && force_o_largefile()) if (!(tmp.flags & O_PATH) && force_o_largefile())
tmp.flags |= O_LARGEFILE; tmp.flags |= O_LARGEFILE;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/audit_arch.h>
#include <uapi/linux/audit.h> #include <uapi/linux/audit.h>
#include <uapi/linux/netfilter/nf_tables.h> #include <uapi/linux/netfilter/nf_tables.h>
...@@ -416,6 +417,7 @@ extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm, ...@@ -416,6 +417,7 @@ extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
const struct cred *old); const struct cred *old);
extern void __audit_log_capset(const struct cred *new, const struct cred *old); extern void __audit_log_capset(const struct cred *new, const struct cred *old);
extern void __audit_mmap_fd(int fd, int flags); extern void __audit_mmap_fd(int fd, int flags);
extern void __audit_openat2_how(struct open_how *how);
extern void __audit_log_kern_module(char *name); extern void __audit_log_kern_module(char *name);
extern void __audit_fanotify(unsigned int response); extern void __audit_fanotify(unsigned int response);
extern void __audit_tk_injoffset(struct timespec64 offset); extern void __audit_tk_injoffset(struct timespec64 offset);
...@@ -512,6 +514,12 @@ static inline void audit_mmap_fd(int fd, int flags) ...@@ -512,6 +514,12 @@ static inline void audit_mmap_fd(int fd, int flags)
__audit_mmap_fd(fd, flags); __audit_mmap_fd(fd, flags);
} }
static inline void audit_openat2_how(struct open_how *how)
{
if (unlikely(!audit_dummy_context()))
__audit_openat2_how(how);
}
static inline void audit_log_kern_module(char *name) static inline void audit_log_kern_module(char *name)
{ {
if (!audit_dummy_context()) if (!audit_dummy_context())
...@@ -671,6 +679,9 @@ static inline void audit_log_capset(const struct cred *new, ...@@ -671,6 +679,9 @@ static inline void audit_log_capset(const struct cred *new,
static inline void audit_mmap_fd(int fd, int flags) static inline void audit_mmap_fd(int fd, int flags)
{ } { }
static inline void audit_openat2_how(struct open_how *how)
{ }
static inline void audit_log_kern_module(char *name) static inline void audit_log_kern_module(char *name)
{ {
} }
......
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* audit_arch.h -- Arch layer specific support for audit
*
* Copyright 2021 Red Hat Inc., Durham, North Carolina.
* All Rights Reserved.
*
* Author: Richard Guy Briggs <rgb@redhat.com>
*/
#ifndef _LINUX_AUDIT_ARCH_H_
#define _LINUX_AUDIT_ARCH_H_
enum auditsc_class_t {
AUDITSC_NATIVE = 0,
AUDITSC_COMPAT,
AUDITSC_OPEN,
AUDITSC_OPENAT,
AUDITSC_SOCKETCALL,
AUDITSC_EXECVE,
AUDITSC_OPENAT2,
AUDITSC_NVALS /* count */
};
#endif
...@@ -119,6 +119,7 @@ ...@@ -119,6 +119,7 @@
#define AUDIT_BPF 1334 /* BPF subsystem */ #define AUDIT_BPF 1334 /* BPF subsystem */
#define AUDIT_EVENT_LISTENER 1335 /* Task joined multicast read socket */ #define AUDIT_EVENT_LISTENER 1335 /* Task joined multicast read socket */
#define AUDIT_URINGOP 1336 /* io_uring operation */ #define AUDIT_URINGOP 1336 /* io_uring operation */
#define AUDIT_OPENAT2 1337 /* Record showing openat2 how args */
#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <uapi/linux/mqueue.h> #include <uapi/linux/mqueue.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <uapi/linux/openat2.h> // struct open_how
/* AUDIT_NAMES is the number of slots we reserve in the audit_context /* AUDIT_NAMES is the number of slots we reserve in the audit_context
* for saving names from getname(). If we get more names we will allocate * for saving names from getname(). If we get more names we will allocate
...@@ -193,6 +194,7 @@ struct audit_context { ...@@ -193,6 +194,7 @@ struct audit_context {
int fd; int fd;
int flags; int flags;
} mmap; } mmap;
struct open_how openat2;
struct { struct {
int argc; int argc;
} execve; } execve;
......
...@@ -30,7 +30,7 @@ struct audit_chunk { ...@@ -30,7 +30,7 @@ struct audit_chunk {
int count; int count;
atomic_long_t refs; atomic_long_t refs;
struct rcu_head head; struct rcu_head head;
struct node { struct audit_node {
struct list_head list; struct list_head list;
struct audit_tree *owner; struct audit_tree *owner;
unsigned index; /* index; upper bit indicates 'will prune' */ unsigned index; /* index; upper bit indicates 'will prune' */
...@@ -269,7 +269,7 @@ bool audit_tree_match(struct audit_chunk *chunk, struct audit_tree *tree) ...@@ -269,7 +269,7 @@ bool audit_tree_match(struct audit_chunk *chunk, struct audit_tree *tree)
/* tagging and untagging inodes with trees */ /* tagging and untagging inodes with trees */
static struct audit_chunk *find_chunk(struct node *p) static struct audit_chunk *find_chunk(struct audit_node *p)
{ {
int index = p->index & ~(1U<<31); int index = p->index & ~(1U<<31);
p -= index; p -= index;
...@@ -322,7 +322,7 @@ static void replace_chunk(struct audit_chunk *new, struct audit_chunk *old) ...@@ -322,7 +322,7 @@ static void replace_chunk(struct audit_chunk *new, struct audit_chunk *old)
list_replace_rcu(&old->hash, &new->hash); list_replace_rcu(&old->hash, &new->hash);
} }
static void remove_chunk_node(struct audit_chunk *chunk, struct node *p) static void remove_chunk_node(struct audit_chunk *chunk, struct audit_node *p)
{ {
struct audit_tree *owner = p->owner; struct audit_tree *owner = p->owner;
...@@ -459,7 +459,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) ...@@ -459,7 +459,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
{ {
struct fsnotify_mark *mark; struct fsnotify_mark *mark;
struct audit_chunk *chunk, *old; struct audit_chunk *chunk, *old;
struct node *p; struct audit_node *p;
int n; int n;
mutex_lock(&audit_tree_group->mark_mutex); mutex_lock(&audit_tree_group->mark_mutex);
...@@ -570,11 +570,11 @@ static void prune_tree_chunks(struct audit_tree *victim, bool tagged) ...@@ -570,11 +570,11 @@ static void prune_tree_chunks(struct audit_tree *victim, bool tagged)
{ {
spin_lock(&hash_lock); spin_lock(&hash_lock);
while (!list_empty(&victim->chunks)) { while (!list_empty(&victim->chunks)) {
struct node *p; struct audit_node *p;
struct audit_chunk *chunk; struct audit_chunk *chunk;
struct fsnotify_mark *mark; struct fsnotify_mark *mark;
p = list_first_entry(&victim->chunks, struct node, list); p = list_first_entry(&victim->chunks, struct audit_node, list);
/* have we run out of marked? */ /* have we run out of marked? */
if (tagged && !(p->index & (1U<<31))) if (tagged && !(p->index & (1U<<31)))
break; break;
...@@ -616,7 +616,7 @@ static void trim_marked(struct audit_tree *tree) ...@@ -616,7 +616,7 @@ static void trim_marked(struct audit_tree *tree)
} }
/* reorder */ /* reorder */
for (p = tree->chunks.next; p != &tree->chunks; p = q) { for (p = tree->chunks.next; p != &tree->chunks; p = q) {
struct node *node = list_entry(p, struct node, list); struct audit_node *node = list_entry(p, struct audit_node, list);
q = p->next; q = p->next;
if (node->index & (1U<<31)) { if (node->index & (1U<<31)) {
list_del_init(p); list_del_init(p);
...@@ -684,7 +684,7 @@ void audit_trim_trees(void) ...@@ -684,7 +684,7 @@ void audit_trim_trees(void)
struct audit_tree *tree; struct audit_tree *tree;
struct path path; struct path path;
struct vfsmount *root_mnt; struct vfsmount *root_mnt;
struct node *node; struct audit_node *node;
int err; int err;
tree = container_of(cursor.next, struct audit_tree, list); tree = container_of(cursor.next, struct audit_tree, list);
...@@ -840,7 +840,7 @@ int audit_add_tree_rule(struct audit_krule *rule) ...@@ -840,7 +840,7 @@ int audit_add_tree_rule(struct audit_krule *rule)
drop_collected_mounts(mnt); drop_collected_mounts(mnt);
if (!err) { if (!err) {
struct node *node; struct audit_node *node;
spin_lock(&hash_lock); spin_lock(&hash_lock);
list_for_each_entry(node, &tree->chunks, list) list_for_each_entry(node, &tree->chunks, list)
node->index &= ~(1U<<31); node->index &= ~(1U<<31);
...@@ -939,7 +939,7 @@ int audit_tag_tree(char *old, char *new) ...@@ -939,7 +939,7 @@ int audit_tag_tree(char *old, char *new)
mutex_unlock(&audit_filter_mutex); mutex_unlock(&audit_filter_mutex);
if (!failed) { if (!failed) {
struct node *node; struct audit_node *node;
spin_lock(&hash_lock); spin_lock(&hash_lock);
list_for_each_entry(node, &tree->chunks, list) list_for_each_entry(node, &tree->chunks, list)
node->index &= ~(1U<<31); node->index &= ~(1U<<31);
......
// SPDX-License-Identifier: GPL-2.0-or-later
/* auditsc.c -- System-call auditing support /* auditsc.c -- System-call auditing support
* Handles all system-call specific auditing features. * Handles all system-call specific auditing features.
* *
...@@ -6,20 +7,6 @@ ...@@ -6,20 +7,6 @@
* Copyright (C) 2005, 2006 IBM Corporation * Copyright (C) 2005, 2006 IBM Corporation
* All Rights Reserved. * All Rights Reserved.
* *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Written by Rickard E. (Rik) Faith <faith@redhat.com> * Written by Rickard E. (Rik) Faith <faith@redhat.com>
* *
* Many of the ideas implemented here are from Stephen C. Tweedie, * Many of the ideas implemented here are from Stephen C. Tweedie,
...@@ -76,6 +63,7 @@ ...@@ -76,6 +63,7 @@
#include <linux/fsnotify_backend.h> #include <linux/fsnotify_backend.h>
#include <uapi/linux/limits.h> #include <uapi/linux/limits.h>
#include <uapi/linux/netfilter/nf_tables.h> #include <uapi/linux/netfilter/nf_tables.h>
#include <uapi/linux/openat2.h> // struct open_how
#include "audit.h" #include "audit.h"
...@@ -166,7 +154,7 @@ static int audit_match_perm(struct audit_context *ctx, int mask) ...@@ -166,7 +154,7 @@ static int audit_match_perm(struct audit_context *ctx, int mask)
n = ctx->major; n = ctx->major;
switch (audit_classify_syscall(ctx->arch, n)) { switch (audit_classify_syscall(ctx->arch, n)) {
case 0: /* native */ case AUDITSC_NATIVE:
if ((mask & AUDIT_PERM_WRITE) && if ((mask & AUDIT_PERM_WRITE) &&
audit_match_class(AUDIT_CLASS_WRITE, n)) audit_match_class(AUDIT_CLASS_WRITE, n))
return 1; return 1;
...@@ -177,7 +165,7 @@ static int audit_match_perm(struct audit_context *ctx, int mask) ...@@ -177,7 +165,7 @@ static int audit_match_perm(struct audit_context *ctx, int mask)
audit_match_class(AUDIT_CLASS_CHATTR, n)) audit_match_class(AUDIT_CLASS_CHATTR, n))
return 1; return 1;
return 0; return 0;
case 1: /* 32bit on biarch */ case AUDITSC_COMPAT: /* 32bit on biarch */
if ((mask & AUDIT_PERM_WRITE) && if ((mask & AUDIT_PERM_WRITE) &&
audit_match_class(AUDIT_CLASS_WRITE_32, n)) audit_match_class(AUDIT_CLASS_WRITE_32, n))
return 1; return 1;
...@@ -188,14 +176,16 @@ static int audit_match_perm(struct audit_context *ctx, int mask) ...@@ -188,14 +176,16 @@ static int audit_match_perm(struct audit_context *ctx, int mask)
audit_match_class(AUDIT_CLASS_CHATTR_32, n)) audit_match_class(AUDIT_CLASS_CHATTR_32, n))
return 1; return 1;
return 0; return 0;
case 2: /* open */ case AUDITSC_OPEN:
return mask & ACC_MODE(ctx->argv[1]); return mask & ACC_MODE(ctx->argv[1]);
case 3: /* openat */ case AUDITSC_OPENAT:
return mask & ACC_MODE(ctx->argv[2]); return mask & ACC_MODE(ctx->argv[2]);
case 4: /* socketcall */ case AUDITSC_SOCKETCALL:
return ((mask & AUDIT_PERM_WRITE) && ctx->argv[0] == SYS_BIND); return ((mask & AUDIT_PERM_WRITE) && ctx->argv[0] == SYS_BIND);
case 5: /* execve */ case AUDITSC_EXECVE:
return mask & AUDIT_PERM_EXEC; return mask & AUDIT_PERM_EXEC;
case AUDITSC_OPENAT2:
return mask & ACC_MODE((u32)((struct open_how *)ctx->argv[2])->flags);
default: default:
return 0; return 0;
} }
...@@ -480,6 +470,9 @@ static int audit_filter_rules(struct task_struct *tsk, ...@@ -480,6 +470,9 @@ static int audit_filter_rules(struct task_struct *tsk,
u32 sid; u32 sid;
unsigned int sessionid; unsigned int sessionid;
if (ctx && rule->prio <= ctx->prio)
return 0;
cred = rcu_dereference_check(tsk->cred, tsk == current || task_creation); cred = rcu_dereference_check(tsk->cred, tsk == current || task_creation);
for (i = 0; i < rule->field_count; i++) { for (i = 0; i < rule->field_count; i++) {
...@@ -747,8 +740,6 @@ static int audit_filter_rules(struct task_struct *tsk, ...@@ -747,8 +740,6 @@ static int audit_filter_rules(struct task_struct *tsk,
} }
if (ctx) { if (ctx) {
if (rule->prio <= ctx->prio)
return 0;
if (rule->filterkey) { if (rule->filterkey) {
kfree(ctx->filterkey); kfree(ctx->filterkey);
ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC); ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC);
...@@ -1437,6 +1428,12 @@ static void show_special(struct audit_context *context, int *call_panic) ...@@ -1437,6 +1428,12 @@ static void show_special(struct audit_context *context, int *call_panic)
audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd, audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd,
context->mmap.flags); context->mmap.flags);
break; break;
case AUDIT_OPENAT2:
audit_log_format(ab, "oflag=0%llo mode=0%llo resolve=0x%llx",
context->openat2.flags,
context->openat2.mode,
context->openat2.resolve);
break;
case AUDIT_EXECVE: case AUDIT_EXECVE:
audit_log_execve_info(context, &ab); audit_log_execve_info(context, &ab);
break; break;
...@@ -2815,6 +2812,16 @@ void __audit_mmap_fd(int fd, int flags) ...@@ -2815,6 +2812,16 @@ void __audit_mmap_fd(int fd, int flags)
context->type = AUDIT_MMAP; context->type = AUDIT_MMAP;
} }
void __audit_openat2_how(struct open_how *how)
{
struct audit_context *context = audit_context();
context->openat2.flags = how->flags;
context->openat2.mode = how->mode;
context->openat2.resolve = how->resolve;
context->type = AUDIT_OPENAT2;
}
void __audit_log_kern_module(char *name) void __audit_log_kern_module(char *name)
{ {
struct audit_context *context = audit_context(); struct audit_context *context = audit_context();
......
...@@ -45,23 +45,27 @@ int audit_classify_syscall(int abi, unsigned syscall) ...@@ -45,23 +45,27 @@ int audit_classify_syscall(int abi, unsigned syscall)
switch(syscall) { switch(syscall) {
#ifdef __NR_open #ifdef __NR_open
case __NR_open: case __NR_open:
return 2; return AUDITSC_OPEN;
#endif #endif
#ifdef __NR_openat #ifdef __NR_openat
case __NR_openat: case __NR_openat:
return 3; return AUDITSC_OPENAT;
#endif #endif
#ifdef __NR_socketcall #ifdef __NR_socketcall
case __NR_socketcall: case __NR_socketcall:
return 4; return AUDITSC_SOCKETCALL;
#endif #endif
#ifdef __NR_execveat #ifdef __NR_execveat
case __NR_execveat: case __NR_execveat:
#endif #endif
case __NR_execve: case __NR_execve:
return 5; return AUDITSC_EXECVE;
#ifdef __NR_openat2
case __NR_openat2:
return AUDITSC_OPENAT2;
#endif
default: default:
return 0; return AUDITSC_NATIVE;
} }
} }
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include <linux/init.h> #include <linux/init.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/audit_arch.h>
#include <asm/unistd32.h> #include <asm/unistd32.h>
unsigned compat_dir_class[] = { unsigned compat_dir_class[] = {
...@@ -33,19 +34,23 @@ int audit_classify_compat_syscall(int abi, unsigned syscall) ...@@ -33,19 +34,23 @@ int audit_classify_compat_syscall(int abi, unsigned syscall)
switch (syscall) { switch (syscall) {
#ifdef __NR_open #ifdef __NR_open
case __NR_open: case __NR_open:
return 2; return AUDITSC_OPEN;
#endif #endif
#ifdef __NR_openat #ifdef __NR_openat
case __NR_openat: case __NR_openat:
return 3; return AUDITSC_OPENAT;
#endif #endif
#ifdef __NR_socketcall #ifdef __NR_socketcall
case __NR_socketcall: case __NR_socketcall:
return 4; return AUDITSC_SOCKETCALL;
#endif #endif
case __NR_execve: case __NR_execve:
return 5; return AUDITSC_EXECVE;
#ifdef __NR_openat2
case __NR_openat2:
return AUDITSC_OPENAT2;
#endif
default: default:
return 1; return AUDITSC_COMPAT;
} }
} }
...@@ -224,7 +224,7 @@ static void dump_common_audit_data(struct audit_buffer *ab, ...@@ -224,7 +224,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
case LSM_AUDIT_DATA_NONE: case LSM_AUDIT_DATA_NONE:
return; return;
case LSM_AUDIT_DATA_IPC: case LSM_AUDIT_DATA_IPC:
audit_log_format(ab, " key=%d ", a->u.ipc_id); audit_log_format(ab, " ipc_key=%d ", a->u.ipc_id);
break; break;
case LSM_AUDIT_DATA_CAP: case LSM_AUDIT_DATA_CAP:
audit_log_format(ab, " capability=%d ", a->u.cap); audit_log_format(ab, " capability=%d ", a->u.cap);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment