[PATCH] audit: always enable syscall auditing when supported and audit is enabled
by Paul Moore
To the best of our knowledge, everyone who enables audit at compile
time also enables syscall auditing; this patch simplifies the Kconfig
menus by removing the option to disable syscall auditing when audit
is selected and the target arch supports it.
Signed-off-by: Paul Moore <pmoore(a)redhat.com>
---
init/Kconfig | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/init/Kconfig b/init/Kconfig
index c24b6f7..d4663b1 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -299,20 +299,15 @@ config AUDIT
help
Enable auditing infrastructure that can be used with another
kernel subsystem, such as SELinux (which requires this for
- logging of avc messages output). Does not do system-call
- auditing without CONFIG_AUDITSYSCALL.
+ logging of avc messages output). System call auditing is included
+ on architectures which support it.
config HAVE_ARCH_AUDITSYSCALL
bool
config AUDITSYSCALL
- bool "Enable system-call auditing support"
+ def_bool y
depends on AUDIT && HAVE_ARCH_AUDITSYSCALL
- default y if SECURITY_SELINUX
- help
- Enable low-overhead system-call auditing infrastructure that
- can be used independently or with another kernel subsystem,
- such as SELinux.
config AUDIT_WATCH
def_bool y
5 years, 10 months
[PATCH V3] filter: add filesystem filter with fstype
by Richard Guy Briggs
Tracefs or debugfs were causing hundreds to thousands of PATH records to
be associated with the init_module and finit_module SYSCALL records on a
few modules when the following rule was in place for startup:
-a always,exit -F arch=x86_64 -S init_module -F key=mod-load
Add the new "filesystem" filter list anchored in __audit_inode_child() to
filter out PATH records from uninteresting filesystem types, "fstype",
keying on their kernel hexadecimal 4-octet magic identifier.
An example rule would look like:
-a never,filesystem -F fstype=0x74726163 -F key=ignore_tracefs
-a never,filesystem -F fstype=0x64626720 -F key=ignore_debugfs
Note: "always,filesystem" will log the PATH record anyways and add latency.
See: https://github.com/linux-audit/audit-kernel/issues/8
See: https://github.com/linux-audit/audit-userspace/issues/15
Test case: https://github.com/linux-audit/audit-testsuite/issues/42
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
v3:
Update feature bitmap macros to reflect filter name change.
v2:
Change filter name from "path" to "filesystem".
Rebase onto other patches accepted upstream.
docs/audit_add_rule_data.3 | 3 +++
lib/errormsg.h | 5 +++++
lib/fieldtab.h | 2 ++
lib/flagtab.h | 10 ++++++----
lib/libaudit.c | 26 ++++++++++++++++++++++++--
lib/libaudit.h | 10 ++++++++++
lib/private.h | 1 +
src/auditctl-listing.c | 6 ++++--
src/auditctl.c | 16 ++++++++++++++--
9 files changed, 69 insertions(+), 10 deletions(-)
diff --git a/docs/audit_add_rule_data.3 b/docs/audit_add_rule_data.3
index a0802c0..1e7540c 100644
--- a/docs/audit_add_rule_data.3
+++ b/docs/audit_add_rule_data.3
@@ -22,6 +22,9 @@ AUDIT_FILTER_EXIT - Apply rule at syscall exit. This is the main filter that is
.TP
\(bu
AUDIT_FILTER_TYPE - Apply rule at audit_log_start. This is the exclude filter which discards any records that match.
+.TP
+\(bu
+AUDIT_FILTER_FS - Apply rule when adding PATH auxiliary records to SYSCALL events. This is the filesystem filter. This is used to ignore PATH records that are not of interest.
.LP
.PP
diff --git a/lib/errormsg.h b/lib/errormsg.h
index 91d8252..ef54589 100644
--- a/lib/errormsg.h
+++ b/lib/errormsg.h
@@ -20,6 +20,7 @@
* Authors:
* Zhang Xiliang <zhangxiliang(a)cn.fujitsu.com>
* Steve Grubb <sgrubb(a)redhat.com>
+ * Richard Guy Briggs <rgb(a)redhat.com>
*/
struct msg_tab {
@@ -66,6 +67,8 @@ struct msg_tab {
#define EAU_FIELDNOFILTER 31
#define EAU_FILTERMISSING 32
#define EAU_COMPINCOMPAT 33
+#define EAU_FIELDUNAVAIL 34
+#define EAU_FILTERNOSUPPORT 35
static const struct msg_tab err_msgtab[] = {
{ -EAU_OPMISSING, 2, "-F missing operation for" },
{ -EAU_FIELDUNKNOWN, 2, "-F unknown field:" },
@@ -100,5 +103,7 @@ static const struct msg_tab err_msgtab[] = {
{ -EAU_FIELDNOFILTER, 1, "must be used with exclude, user, or exit filter" },
{ -EAU_FILTERMISSING, 0, "filter is missing from rule" },
{ -EAU_COMPINCOMPAT, 2, "-C incompatible comparison" },
+ { -EAU_FIELDUNAVAIL, 1, "field is not valid for the filter" },
+ { -EAU_FILTERNOSUPPORT, 1, "filter is not supported ty kernel" },
};
#endif
diff --git a/lib/fieldtab.h b/lib/fieldtab.h
index 0c5e39d..c425d5b 100644
--- a/lib/fieldtab.h
+++ b/lib/fieldtab.h
@@ -18,6 +18,7 @@
*
* Authors:
* Steve Grubb <sgrubb(a)redhat.com>
+ * Richard Guy Briggs <rgb(a)redhat.com>
*/
_S(AUDIT_PID, "pid" )
@@ -56,6 +57,7 @@ _S(AUDIT_WATCH, "path" )
_S(AUDIT_PERM, "perm" )
_S(AUDIT_DIR, "dir" )
_S(AUDIT_FILETYPE, "filetype" )
+_S(AUDIT_FSTYPE, "fstype" )
_S(AUDIT_OBJ_UID, "obj_uid" )
_S(AUDIT_OBJ_GID, "obj_gid" )
_S(AUDIT_FIELD_COMPARE, "field_compare" )
diff --git a/lib/flagtab.h b/lib/flagtab.h
index 4b04692..7a618e0 100644
--- a/lib/flagtab.h
+++ b/lib/flagtab.h
@@ -18,8 +18,10 @@
*
* Authors:
* Steve Grubb <sgrubb(a)redhat.com>
+ * Richard Guy Briggs <rgb(a)redhat.com>
*/
-_S(AUDIT_FILTER_TASK, "task" )
-_S(AUDIT_FILTER_EXIT, "exit" )
-_S(AUDIT_FILTER_USER, "user" )
-_S(AUDIT_FILTER_EXCLUDE, "exclude" )
+_S(AUDIT_FILTER_TASK, "task" )
+_S(AUDIT_FILTER_EXIT, "exit" )
+_S(AUDIT_FILTER_USER, "user" )
+_S(AUDIT_FILTER_EXCLUDE, "exclude" )
+_S(AUDIT_FILTER_FS, "filesystem")
diff --git a/lib/libaudit.c b/lib/libaudit.c
index 18cd384..58134a2 100644
--- a/lib/libaudit.c
+++ b/lib/libaudit.c
@@ -19,6 +19,7 @@
* Authors:
* Steve Grubb <sgrubb(a)redhat.com>
* Rickard E. (Rik) Faith <faith(a)redhat.com>
+ * Richard Guy Briggs <rgb(a)redhat.com>
*/
#include "config.h"
@@ -85,6 +86,7 @@ int _audit_permadded = 0;
int _audit_archadded = 0;
int _audit_syscalladded = 0;
int _audit_exeadded = 0;
+int _audit_filterfsadded = 0;
unsigned int _audit_elf = 0U;
static struct libaudit_conf config;
@@ -1466,6 +1468,23 @@ int audit_rule_fieldpair_data(struct audit_rule_data **rulep, const char *pair,
}
}
+ /* FS filter can be used only with FSTYPE field */
+ if (flags == AUDIT_FILTER_FS) {
+ uint32_t features = audit_get_features();
+ if ((features & AUDIT_FEATURE_BITMAP_FILTER_FS) == 0) {
+ return -EAU_FILTERNOSUPPORT;
+ } else {
+ switch(field) {
+ case AUDIT_FSTYPE:
+ _audit_filterfsadded = 1;
+ case AUDIT_FILTERKEY:
+ break;
+ default:
+ return -EAU_FIELDUNAVAIL;
+ }
+ }
+ }
+
rule->fields[rule->field_count] = field;
rule->fieldflags[rule->field_count] = op;
switch (field)
@@ -1580,7 +1599,8 @@ int audit_rule_fieldpair_data(struct audit_rule_data **rulep, const char *pair,
}
if (field == AUDIT_FILTERKEY &&
!(_audit_syscalladded || _audit_permadded ||
- _audit_exeadded))
+ _audit_exeadded ||
+ _audit_filterfsadded))
return -EAU_KEYDEP;
vlen = strlen(v);
if (field == AUDIT_FILTERKEY &&
@@ -1715,7 +1735,7 @@ int audit_rule_fieldpair_data(struct audit_rule_data **rulep, const char *pair,
return -EAU_EXITONLY;
/* fallthrough */
default:
- if (field == AUDIT_INODE) {
+ if (field == AUDIT_INODE || field == AUDIT_FSTYPE) {
if (!(op == AUDIT_NOT_EQUAL ||
op == AUDIT_EQUAL))
return -EAU_OPEQNOTEQ;
@@ -1727,6 +1747,8 @@ int audit_rule_fieldpair_data(struct audit_rule_data **rulep, const char *pair,
if (!isdigit((char)*(v)))
return -EAU_FIELDVALNUM;
+ if (field == AUDIT_FSTYPE && flags != AUDIT_FILTER_FS)
+ return -EAU_FIELDUNAVAIL;
if (field == AUDIT_INODE)
rule->values[rule->field_count] =
strtoul(v, NULL, 0);
diff --git a/lib/libaudit.h b/lib/libaudit.h
index e5c7a4d..70646cd 100644
--- a/lib/libaudit.h
+++ b/lib/libaudit.h
@@ -277,6 +277,9 @@ extern "C" {
#define AUDIT_KEY_SEPARATOR 0x01
/* These are used in filter control */
+#ifndef AUDIT_FILTER_FS
+#define AUDIT_FILTER_FS 0x06 /* FS record filter in __audit_inode_child */
+#endif
#define AUDIT_FILTER_EXCLUDE AUDIT_FILTER_TYPE
#define AUDIT_FILTER_MASK 0x07 /* Mask to get actual filter */
#define AUDIT_FILTER_UNSET 0x80 /* This value means filter is unset */
@@ -305,6 +308,9 @@ extern "C" {
#ifndef AUDIT_FEATURE_BITMAP_LOST_RESET
#define AUDIT_FEATURE_BITMAP_LOST_RESET 0x00000020
#endif
+#ifndef AUDIT_FEATURE_BITMAP_FILTER_FS
+#define AUDIT_FEATURE_BITMAP_FILTER_FS 0x00000040
+#endif
/* Defines for interfield comparison update */
#ifndef AUDIT_OBJ_UID
@@ -324,6 +330,10 @@ extern "C" {
#define AUDIT_SESSIONID 25
#endif
+#ifndef AUDIT_FSTYPE
+#define AUDIT_FSTYPE 26
+#endif
+
#ifndef AUDIT_COMPARE_UID_TO_OBJ_UID
#define AUDIT_COMPARE_UID_TO_OBJ_UID 1
#endif
diff --git a/lib/private.h b/lib/private.h
index cde1906..bd5e8b3 100644
--- a/lib/private.h
+++ b/lib/private.h
@@ -139,6 +139,7 @@ extern int _audit_permadded;
extern int _audit_archadded;
extern int _audit_syscalladded;
extern int _audit_exeadded;
+extern int _audit_filterfsadded;
extern unsigned int _audit_elf;
#ifdef __cplusplus
diff --git a/src/auditctl-listing.c b/src/auditctl-listing.c
index 3bc8e71..50bc0b8 100644
--- a/src/auditctl-listing.c
+++ b/src/auditctl-listing.c
@@ -91,7 +91,8 @@ static int is_watch(const struct audit_rule_data *r)
if (((r->flags & AUDIT_FILTER_MASK) != AUDIT_FILTER_USER) &&
((r->flags & AUDIT_FILTER_MASK) != AUDIT_FILTER_TASK) &&
- ((r->flags & AUDIT_FILTER_MASK) != AUDIT_FILTER_EXCLUDE)) {
+ ((r->flags & AUDIT_FILTER_MASK) != AUDIT_FILTER_EXCLUDE) &&
+ ((r->flags & AUDIT_FILTER_MASK) != AUDIT_FILTER_FS)) {
for (i = 0; i < (AUDIT_BITMASK_SIZE-1); i++) {
if (r->mask[i] != (uint32_t)~0) {
all = 0;
@@ -139,7 +140,8 @@ static int print_syscall(const struct audit_rule_data *r, unsigned int *sc)
/* Rules on the following filters do not take a syscall */
if (((r->flags & AUDIT_FILTER_MASK) == AUDIT_FILTER_USER) ||
((r->flags & AUDIT_FILTER_MASK) == AUDIT_FILTER_TASK) ||
- ((r->flags &AUDIT_FILTER_MASK) == AUDIT_FILTER_EXCLUDE))
+ ((r->flags &AUDIT_FILTER_MASK) == AUDIT_FILTER_EXCLUDE) ||
+ ((r->flags &AUDIT_FILTER_MASK) == AUDIT_FILTER_FS))
return 0;
/* See if its all or specific syscalls */
diff --git a/src/auditctl.c b/src/auditctl.c
index 04765f4..b99c957 100644
--- a/src/auditctl.c
+++ b/src/auditctl.c
@@ -19,6 +19,7 @@
* Authors:
* Steve Grubb <sgrubb(a)redhat.com>
* Rickard E. (Rik) Faith <faith(a)redhat.com>
+ * Richard Guy Briggs <rgb(a)redhat.com>
*/
#include "config.h"
@@ -74,6 +75,7 @@ static int reset_vars(void)
_audit_permadded = 0;
_audit_archadded = 0;
_audit_exeadded = 0;
+ _audit_filterfsadded = 0;
_audit_elf = 0;
add = AUDIT_FILTER_UNSET;
del = AUDIT_FILTER_UNSET;
@@ -151,6 +153,8 @@ static int lookup_filter(const char *str, int *filter)
*filter = AUDIT_FILTER_EXIT;
else if (strcmp(str, "user") == 0)
*filter = AUDIT_FILTER_USER;
+ else if (strcmp(str, "filesystem") == 0)
+ *filter = AUDIT_FILTER_FS;
else if (strcmp(str, "exclude") == 0) {
*filter = AUDIT_FILTER_EXCLUDE;
exclude = 1;
@@ -760,6 +764,13 @@ static int setopt(int count, int lineno, char *vars[])
audit_msg(LOG_ERR,
"Error: syscall auditing being added to user list");
return -1;
+ } else if (((add & (AUDIT_FILTER_MASK|AUDIT_FILTER_UNSET)) ==
+ AUDIT_FILTER_FS || (del &
+ (AUDIT_FILTER_MASK|AUDIT_FILTER_UNSET)) ==
+ AUDIT_FILTER_FS)) {
+ audit_msg(LOG_ERR,
+ "Error: syscall auditing being added to filesystem list");
+ return -1;
} else if (exclude) {
audit_msg(LOG_ERR,
"Error: syscall auditing cannot be put on exclude list");
@@ -936,8 +947,9 @@ static int setopt(int count, int lineno, char *vars[])
break;
case 'k':
if (!(_audit_syscalladded || _audit_permadded ||
- _audit_exeadded) || (add==AUDIT_FILTER_UNSET &&
- del==AUDIT_FILTER_UNSET)) {
+ _audit_exeadded ||
+ _audit_filterfsadded) ||
+ (add==AUDIT_FILTER_UNSET && del==AUDIT_FILTER_UNSET)) {
audit_msg(LOG_ERR,
"key option needs a watch or syscall given prior to it");
retval = -1;
--
1.7.1
7 years, 2 months
[PATCH] capabilities: add field names for ambient capabilities
by Richard Guy Briggs
Linux kernel capabilities were augmented to include ambient capabilities in
v4.3 commit 58319057b784 ("capabilities: ambient capabilities").
Add interpretation types for cap_pa, old_pa, pa.
The record contains fields "old_pp", "old_pi", "old_pe", "new_pp",
"new_pi", "new_pe" so in keeping with the previous record
normalizations, change the "new_p*" variants to simply drop the "new_"
prefix.
A sample of the replaced BPRM_FCAPS record:
RAW: type=BPRM_FCAPS msg=audit(1491468034.252:237): fver=2 fp=0000000000200000 fi=0000000000000000 fe=1 old_pp=0000000000000000 old_pi=0000000000000000 old_pe=0000000000000000 old_pa=0000000000000000 pp=0000000000200000 pi=0000000000000000 pe=0000000000200000 pa=0000000000000000
INTERPRET: type=BPRM_FCAPS msg=audit(04/06/2017 04:40:34.252:237) : fver=2 fp=sys_admin fi=none fe=chown old_pp=none old_pi=none old_pe=none old_pa=none pp=sys_admin pi=none pe=sys_admin pa=none
A sample of the replaced CAPSET record:
RAW: type=CAPSET msg=audit(1491469502.371:242): pid=833 cap_pi=0000003fffffffff cap_pp=0000003fffffffff cap_pe=0000003fffffffff cap_pa=0000000000000000
INTERPRET: type=CAPSET msg=audit(04/06/2017 05:05:02.371:242) : pid=833 \
cap_pi=chown,dac_override,dac_read_search,fowner,fsetid,kill,setgid,setuid,setpcap,linux_immutable,net_bind_service,net_broadcast,net_admin,net_raw,ipc_lock,ipc_owner,sys_module,sys_rawio,sys_chroot,sys_ptrace,sys_pacct,sys_admin,sys_boot,sys_nice,sys_resource,sys_time,sys_tty_config,mknod,lease,audit_write,audit_control,setfcap,mac_override,mac_admin,syslog,wake_alarm,block_suspend,audit_read \
cap_pp=chown,dac_override,dac_read_search,fowner,fsetid,kill,setgid,setuid,setpcap,linux_immutable,net_bind_service,net_broadcast,net_admin,net_raw,ipc_lock,ipc_owner,sys_module,sys_rawio,sys_chroot,sys_ptrace,sys_pacct,sys_admin,sys_boot,sys_nice,sys_resource,sys_time,sys_tty_config,mknod,lease,audit_write,audit_control,setfcap,mac_override,mac_admin,syslog,wake_alarm,block_suspend,audit_read \
cap_pe=chown,dac_override,dac_read_search,fowner,fsetid,kill,setgid,setuid,setpcap,linux_immutable,net_bind_service,net_broadcast,net_admin,net_raw,ipc_lock,ipc_owner,sys_module,sys_rawio,sys_chroot,sys_ptrace,sys_pacct,sys_admin,sys_boot,sys_nice,sys_resource,sys_time,sys_tty_config,mknod,lease,audit_write,audit_control,setfcap,mac_override,mac_admin,syslog,wake_alarm,block_suspend,audit_read \
cap_pa=none
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
auparse/typetab.h | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/auparse/typetab.h b/auparse/typetab.h
index be82796..42f3e82 100644
--- a/auparse/typetab.h
+++ b/auparse/typetab.h
@@ -89,6 +89,7 @@ _S(AUPARSE_TYPE_SESSION, "ses" )
_S(AUPARSE_TYPE_CAP_BITMAP, "cap_pi" )
_S(AUPARSE_TYPE_CAP_BITMAP, "cap_pe" )
_S(AUPARSE_TYPE_CAP_BITMAP, "cap_pp" )
+_S(AUPARSE_TYPE_CAP_BITMAP, "cap_pa" )
_S(AUPARSE_TYPE_CAP_BITMAP, "cap_fi" )
_S(AUPARSE_TYPE_CAP_BITMAP, "cap_fp" )
_S(AUPARSE_TYPE_CAP_BITMAP, "fp" )
@@ -97,9 +98,14 @@ _S(AUPARSE_TYPE_CAP_BITMAP, "fe" )
_S(AUPARSE_TYPE_CAP_BITMAP, "old_pp" )
_S(AUPARSE_TYPE_CAP_BITMAP, "old_pi" )
_S(AUPARSE_TYPE_CAP_BITMAP, "old_pe" )
+_S(AUPARSE_TYPE_CAP_BITMAP, "old_pa" )
_S(AUPARSE_TYPE_CAP_BITMAP, "new_pp" )
_S(AUPARSE_TYPE_CAP_BITMAP, "new_pi" )
_S(AUPARSE_TYPE_CAP_BITMAP, "new_pe" )
+_S(AUPARSE_TYPE_CAP_BITMAP, "pp" )
+_S(AUPARSE_TYPE_CAP_BITMAP, "pi" )
+_S(AUPARSE_TYPE_CAP_BITMAP, "pe" )
+_S(AUPARSE_TYPE_CAP_BITMAP, "pa" )
_S(AUPARSE_TYPE_NFPROTO, "family" )
_S(AUPARSE_TYPE_ICMPTYPE, "icmptype" )
_S(AUPARSE_TYPE_PROTOCOL, "proto" )
--
1.7.1
7 years, 2 months
[PATCH] selinux: remove AVC init audit log message
by Richard Guy Briggs
In the process of normalizing audit log messages, it was noticed that the AVC
initialization code registered an audit log KERNEL record that didn't fit the
standard format. In the process of attempting to normalize it it was
determined that this record was not even necessary. Remove it.
Ref: http://marc.info/?l=selinux&m=149614868525826&w=2
See: https://github.com/linux-audit/audit-kernel/issues/48
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
security/selinux/avc.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index e60c79d..4b42931 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -197,8 +197,6 @@ void __init avc_init(void)
avc_xperms_data_cachep = kmem_cache_create("avc_xperms_data",
sizeof(struct extended_perms_data),
0, SLAB_PANIC, NULL);
-
- audit_log(current->audit_context, GFP_KERNEL, AUDIT_KERNEL, "AVC INITIALIZED\n");
}
int avc_get_hash_stats(char *page)
--
1.7.1
7 years, 3 months
[PATCH ALT4 V2 1/2] audit: show fstype:pathname for entries with anonymous parents
by Richard Guy Briggs
Tracefs or debugfs were causing hundreds to thousands of null PATH
records to be associated with the init_module and finit_module SYSCALL
records on a few modules when the following rule was in place for
startup:
-a always,exit -F arch=x86_64 -S init_module -F key=mod-load
This happens because the parent inode is not found in the task's
audit_names list and hence treats it as anonymous. This gives us no
information other than a numerical device number that may no longer be
visible upon log inspeciton, and an inode number.
Fill in the filesystem type, filesystem magic number and full pathname
from the filesystem mount point on previously null PATH records from
entries that have an anonymous parent from the child dentry using
dentry_path_raw().
Make the dentry argument of __audit_inode_child() non-const so that we
can take a reference to it in the case of an anonymous parent with
dget() and dget_parent() to be able to later print a partial path from
the host filesystem rather than null.
Since all we are given is an inode of the parent and the dentry of the
child, finding the path from the mount point to the root of the
filesystem is more challenging that would involve searching all
vfsmounts from "/" until a matching dentry is found for that
filesystem's root dentry. Even if one is found, there may be more than
one mount point. At this point the gain seems marginal since
knowing the filesystem type and path are a significant help in tracking
down the source of the PATH records and being to address them.
Sample output:
type=PROCTITLE msg=audit(1488317694.446:143): proctitle=2F7362696E2F6D6F6470726F6265002D71002D2D006E66737634
type=PATH msg=audit(1488317694.446:143): item=797 name=tracefs(74726163):/events/nfs4/nfs4_setclientid/format inode=15969 dev=00:09 mode=0100444 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:tracefs_t:s0 nametype=CREATE
type=PATH msg=audit(1488317694.446:143): item=796 name=tracefs(74726163):/events/nfs4/nfs4_setclientid inode=15964 dev=00:09 mode=040755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:tracefs_t:s0 nametype=PARENT
...
type=PATH msg=audit(1488317694.446:143): item=1 name=tracefs(74726163):/events/nfs4 inode=15571 dev=00:09 mode=040755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:tracefs_t:s0 nametype=CREATE
type=PATH msg=audit(1488317694.446:143): item=0 name=tracefs(74726163):/events inode=119 dev=00:09 mode=040755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:tracefs_t:s0 nametype=PARENT
type=UNKNOWN[1330] msg=audit(1488317694.446:143): name="nfsv4"
type=SYSCALL msg=audit(1488317694.446:143): arch=c000003e syscall=313 success=yes exit=0 a0=1 a1=55d5a35ce106 a2=0 a3=1 items=798 ppid=6 pid=528 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="modprobe" exe="/usr/bin/kmod" subj=system_u:system_r:insmod_t:s0 key="mod-load"
See: https://github.com/linux-audit/audit-kernel/issues/8
Test case: https://github.com/linux-audit/audit-testsuite/issues/42
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
include/linux/audit.h | 8 ++++----
kernel/audit.c | 16 ++++++++++++++++
kernel/audit.h | 1 +
kernel/auditsc.c | 8 +++++++-
4 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index aba3a26..367a03a 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -241,7 +241,7 @@ extern void __audit_inode(struct filename *name, const struct dentry *dentry,
unsigned int flags);
extern void __audit_file(const struct file *);
extern void __audit_inode_child(struct inode *parent,
- const struct dentry *dentry,
+ struct dentry *dentry,
const unsigned char type);
extern void __audit_seccomp(unsigned long syscall, long signr, int code);
extern void __audit_ptrace(struct task_struct *t);
@@ -306,7 +306,7 @@ static inline void audit_inode_parent_hidden(struct filename *name,
AUDIT_INODE_PARENT | AUDIT_INODE_HIDDEN);
}
static inline void audit_inode_child(struct inode *parent,
- const struct dentry *dentry,
+ struct dentry *dentry,
const unsigned char type) {
if (unlikely(!audit_dummy_context()))
__audit_inode_child(parent, dentry, type);
@@ -487,7 +487,7 @@ static inline void __audit_inode(struct filename *name,
unsigned int flags)
{ }
static inline void __audit_inode_child(struct inode *parent,
- const struct dentry *dentry,
+ struct dentry *dentry,
const unsigned char type)
{ }
static inline void audit_inode(struct filename *name,
@@ -501,7 +501,7 @@ static inline void audit_inode_parent_hidden(struct filename *name,
const struct dentry *dentry)
{ }
static inline void audit_inode_child(struct inode *parent,
- const struct dentry *dentry,
+ struct dentry *dentry,
const unsigned char type)
{ }
static inline void audit_core_dumps(long signr)
diff --git a/kernel/audit.c b/kernel/audit.c
index 25dd70a..7d83c5a 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -66,6 +66,7 @@
#include <linux/freezer.h>
#include <linux/pid_namespace.h>
#include <net/netns/generic.h>
+#include <linux/dcache.h>
#include "audit.h"
@@ -1884,6 +1885,10 @@ void audit_copy_inode(struct audit_names *name, const struct dentry *dentry,
name->gid = inode->i_gid;
name->rdev = inode->i_rdev;
security_inode_getsecid(inode, &name->osid);
+ if (name->dentry) {
+ dput(name->dentry);
+ name->dentry = NULL;
+ }
audit_copy_fcaps(name, dentry);
}
@@ -1925,6 +1930,17 @@ void audit_log_name(struct audit_context *context, struct audit_names *n,
audit_log_n_untrustedstring(ab, n->name->name,
n->name_len);
}
+ } else if (n->dentry) {
+ char *fullpath;
+ const char *fullpathp;
+
+ fullpath = kmalloc(PATH_MAX, GFP_KERNEL);
+ if (!fullpath)
+ return;
+ fullpathp = dentry_path_raw(n->dentry, fullpath, PATH_MAX);
+ audit_log_format(ab, " name=%s(0x%lx):%s",
+ n->dentry->d_sb->s_type->name?:"?",
+ n->dentry->d_sb->s_magic, fullpathp?:"?");
} else
audit_log_format(ab, " name=(null)");
diff --git a/kernel/audit.h b/kernel/audit.h
index 144b7eb..2a11583 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -84,6 +84,7 @@ struct audit_names {
unsigned long ino;
dev_t dev;
+ struct dentry *dentry;
umode_t mode;
kuid_t uid;
kgid_t gid;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 4db32e8..b3797c7 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -74,6 +74,7 @@
#include <linux/string.h>
#include <linux/uaccess.h>
#include <uapi/linux/limits.h>
+#include <linux/dcache.h>
#include "audit.h"
@@ -881,6 +882,8 @@ static inline void audit_free_names(struct audit_context *context)
list_del(&n->list);
if (n->name)
putname(n->name);
+ if (n->dentry)
+ dput(n->dentry);
if (n->should_free)
kfree(n);
}
@@ -1858,7 +1861,7 @@ void __audit_file(const struct file *file)
* unsuccessful attempts.
*/
void __audit_inode_child(struct inode *parent,
- const struct dentry *dentry,
+ struct dentry *dentry,
const unsigned char type)
{
struct audit_context *context = current->audit_context;
@@ -1914,6 +1917,7 @@ void __audit_inode_child(struct inode *parent,
if (!n)
return;
audit_copy_inode(n, NULL, parent);
+ n->dentry = dget_parent(dentry);
}
if (!found_child) {
@@ -1935,6 +1939,8 @@ void __audit_inode_child(struct inode *parent,
audit_copy_inode(found_child, dentry, inode);
else
found_child->ino = AUDIT_INO_UNSET;
+ if (!found_parent)
+ found_child->dentry = dget(dentry);
}
EXPORT_SYMBOL_GPL(__audit_inode_child);
--
1.7.1
7 years, 4 months
[PATCH v5 0/6] Improved seccomp logging
by Tyler Hicks
This is an update to the previous seccomp logging patch sets. The main
difference in this revision compared to the last is that the application now
has the ability to request that all actions in a filter, except for RET_ALLOW,
should be logged. This is done with a new filter flag. In support of that
change, the log_max_action sysctl was renamed to actions_logged as it now lists
the actions that an admin has allowed to be logged. The admin has the final say
in what actions get logged.
Please see the individual patches for summaries of changes since the last
revision.
Thanks!
Tyler
7 years, 4 months
Re: [RESEND PATCH 2/6] ipc: mqueue: Replace timespec with timespec64
by Richard Guy Briggs
On 2017-07-28 11:52, Deepa Dinamani wrote:
> struct timespec is not y2038 safe. Replace
> all uses of timespec by y2038 safe struct timespec64.
>
> Even though timespec is used here to represent timeouts,
> replace these with timespec64 so that it facilitates
> in verification by creating a y2038 safe kernel image
> that is free of timespec.
>
> The syscall interfaces themselves are not changed as part
> of the patch. They will be part of a different series.
>
> Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
> Cc: Paul Moore <paul(a)paul-moore.com>
> Cc: Richard Guy Briggs <rgb(a)redhat.com>
Looks reasonable to me.
Reviewed-by: Richard Guy Briggs <rgb(a)redhat.com>
> ---
> include/linux/audit.h | 6 +++---
> ipc/mqueue.c | 28 ++++++++++++++--------------
> kernel/audit.h | 2 +-
> kernel/auditsc.c | 12 ++++++------
> 4 files changed, 24 insertions(+), 24 deletions(-)
>
> diff --git a/include/linux/audit.h b/include/linux/audit.h
> index 2150bdccfbab..74d4d4e8e3db 100644
> --- a/include/linux/audit.h
> +++ b/include/linux/audit.h
> @@ -351,7 +351,7 @@ extern int __audit_socketcall(int nargs, unsigned long *args);
> extern int __audit_sockaddr(int len, void *addr);
> extern void __audit_fd_pair(int fd1, int fd2);
> extern void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr);
> -extern void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout);
> +extern void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec64 *abs_timeout);
> extern void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification);
> extern void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
> extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
> @@ -412,7 +412,7 @@ static inline void audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
> if (unlikely(!audit_dummy_context()))
> __audit_mq_open(oflag, mode, attr);
> }
> -static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout)
> +static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec64 *abs_timeout)
> {
> if (unlikely(!audit_dummy_context()))
> __audit_mq_sendrecv(mqdes, msg_len, msg_prio, abs_timeout);
> @@ -549,7 +549,7 @@ static inline void audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
> { }
> static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len,
> unsigned int msg_prio,
> - const struct timespec *abs_timeout)
> + const struct timespec64 *abs_timeout)
> { }
> static inline void audit_mq_notify(mqd_t mqdes,
> const struct sigevent *notification)
> diff --git a/ipc/mqueue.c b/ipc/mqueue.c
> index c9ff943f19ab..5be1346a9167 100644
> --- a/ipc/mqueue.c
> +++ b/ipc/mqueue.c
> @@ -668,11 +668,11 @@ static void __do_notify(struct mqueue_inode_info *info)
> }
>
> static int prepare_timeout(const struct timespec __user *u_abs_timeout,
> - struct timespec *ts)
> + struct timespec64 *ts)
> {
> - if (copy_from_user(ts, u_abs_timeout, sizeof(struct timespec)))
> + if (get_timespec64(ts, u_abs_timeout))
> return -EFAULT;
> - if (!timespec_valid(ts))
> + if (!timespec64_valid(ts))
> return -EINVAL;
> return 0;
> }
> @@ -962,7 +962,7 @@ static inline void pipelined_receive(struct wake_q_head *wake_q,
>
> static int do_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
> size_t msg_len, unsigned int msg_prio,
> - struct timespec *ts)
> + struct timespec64 *ts)
> {
> struct fd f;
> struct inode *inode;
> @@ -979,7 +979,7 @@ static int do_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
> return -EINVAL;
>
> if (ts) {
> - expires = timespec_to_ktime(*ts);
> + expires = timespec64_to_ktime(*ts);
> timeout = &expires;
> }
>
> @@ -1080,7 +1080,7 @@ static int do_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
>
> static int do_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
> size_t msg_len, unsigned int __user *u_msg_prio,
> - struct timespec *ts)
> + struct timespec64 *ts)
> {
> ssize_t ret;
> struct msg_msg *msg_ptr;
> @@ -1092,7 +1092,7 @@ static int do_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
> struct posix_msg_tree_node *new_leaf = NULL;
>
> if (ts) {
> - expires = timespec_to_ktime(*ts);
> + expires = timespec64_to_ktime(*ts);
> timeout = &expires;
> }
>
> @@ -1184,7 +1184,7 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr,
> size_t, msg_len, unsigned int, msg_prio,
> const struct timespec __user *, u_abs_timeout)
> {
> - struct timespec ts, *p = NULL;
> + struct timespec64 ts, *p = NULL;
> if (u_abs_timeout) {
> int res = prepare_timeout(u_abs_timeout, &ts);
> if (res)
> @@ -1198,7 +1198,7 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr,
> size_t, msg_len, unsigned int __user *, u_msg_prio,
> const struct timespec __user *, u_abs_timeout)
> {
> - struct timespec ts, *p = NULL;
> + struct timespec64 ts, *p = NULL;
> if (u_abs_timeout) {
> int res = prepare_timeout(u_abs_timeout, &ts);
> if (res)
> @@ -1473,11 +1473,11 @@ COMPAT_SYSCALL_DEFINE4(mq_open, const char __user *, u_name,
> }
>
> static int compat_prepare_timeout(const struct compat_timespec __user *p,
> - struct timespec *ts)
> + struct timespec64 *ts)
> {
> - if (compat_get_timespec(ts, p))
> + if (compat_get_timespec64(ts, p))
> return -EFAULT;
> - if (!timespec_valid(ts))
> + if (!timespec64_valid(ts))
> return -EINVAL;
> return 0;
> }
> @@ -1487,7 +1487,7 @@ COMPAT_SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes,
> compat_size_t, msg_len, unsigned int, msg_prio,
> const struct compat_timespec __user *, u_abs_timeout)
> {
> - struct timespec ts, *p = NULL;
> + struct timespec64 ts, *p = NULL;
> if (u_abs_timeout) {
> int res = compat_prepare_timeout(u_abs_timeout, &ts);
> if (res)
> @@ -1502,7 +1502,7 @@ COMPAT_SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes,
> compat_size_t, msg_len, unsigned int __user *, u_msg_prio,
> const struct compat_timespec __user *, u_abs_timeout)
> {
> - struct timespec ts, *p = NULL;
> + struct timespec64 ts, *p = NULL;
> if (u_abs_timeout) {
> int res = compat_prepare_timeout(u_abs_timeout, &ts);
> if (res)
> diff --git a/kernel/audit.h b/kernel/audit.h
> index b331d9b83f63..9b110ae17ee3 100644
> --- a/kernel/audit.h
> +++ b/kernel/audit.h
> @@ -182,7 +182,7 @@ struct audit_context {
> mqd_t mqdes;
> size_t msg_len;
> unsigned int msg_prio;
> - struct timespec abs_timeout;
> + struct timespec64 abs_timeout;
> } mq_sendrecv;
> struct {
> int oflag;
> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> index 3260ba2312a9..d0870f8e3656 100644
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -1235,11 +1235,11 @@ static void show_special(struct audit_context *context, int *call_panic)
> case AUDIT_MQ_SENDRECV:
> audit_log_format(ab,
> "mqdes=%d msg_len=%zd msg_prio=%u "
> - "abs_timeout_sec=%ld abs_timeout_nsec=%ld",
> + "abs_timeout_sec=%lld abs_timeout_nsec=%ld",
> context->mq_sendrecv.mqdes,
> context->mq_sendrecv.msg_len,
> context->mq_sendrecv.msg_prio,
> - context->mq_sendrecv.abs_timeout.tv_sec,
> + (long long) context->mq_sendrecv.abs_timeout.tv_sec,
> context->mq_sendrecv.abs_timeout.tv_nsec);
> break;
> case AUDIT_MQ_NOTIFY:
> @@ -2083,15 +2083,15 @@ void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
> *
> */
> void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,
> - const struct timespec *abs_timeout)
> + const struct timespec64 *abs_timeout)
> {
> struct audit_context *context = current->audit_context;
> - struct timespec *p = &context->mq_sendrecv.abs_timeout;
> + struct timespec64 *p = &context->mq_sendrecv.abs_timeout;
>
> if (abs_timeout)
> - memcpy(p, abs_timeout, sizeof(struct timespec));
> + memcpy(p, abs_timeout, sizeof(struct timespec64));
> else
> - memset(p, 0, sizeof(struct timespec));
> + memset(p, 0, sizeof(struct timespec64));
>
> context->mq_sendrecv.mqdes = mqdes;
> context->mq_sendrecv.msg_len = msg_len;
> --
> 2.11.0
>
- RGB
--
Richard Guy Briggs <rgb(a)redhat.com>
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635
7 years, 4 months