[PATCH v2] selinux: log invalid contexts in AVCs
by Ondrej Mosnacek
In case a file has an invalid context set, in an AVC record generated
upon access to such file, the target context is always reported as
unlabeled. This patch adds new optional fields to the AVC record
(srawcon and trawcon) that report the actual context string if it
differs from the one reported in scontext/tcontext. This is useful for
diagnosing SELinux denials involving invalid contexts.
To trigger an AVC that illustrates this situation:
# setenforce 0
# touch /tmp/testfile
# setfattr -n security.selinux -v system_u:object_r:banana_t:s0 /tmp/testfile
# runcon system_u:system_r:sshd_t:s0 cat /tmp/testfile
AVC before:
type=AVC msg=audit(1547801083.248:11): avc: denied { open } for pid=1149 comm="cat" path="/tmp/testfile" dev="tmpfs" ino=6608 scontext=system_u:system_r:sshd_t:s0 tcontext=system_u:object_r:unlabeled_t:s15:c0.c1023 tclass=file permissive=1
AVC after:
type=AVC msg=audit(1547801083.248:11): avc: denied { open } for pid=1149 comm="cat" path="/tmp/testfile" dev="tmpfs" ino=6608 scontext=system_u:system_r:sshd_t:s0 tcontext=system_u:object_r:unlabeled_t:s15:c0.c1023 trawcon=system_u:object_r:banana_t:s0 tclass=file permissive=1
Cc: Daniel Walsh <dwalsh(a)redhat.com>
Link: https://bugzilla.redhat.com/show_bug.cgi?id=1135683
Signed-off-by: Ondrej Mosnacek <omosnace(a)redhat.com>
---
v2: Rename fields to "(s|t)rawcon".
security/selinux/avc.c | 49 +++++++++++++++++++++++++-----------------
1 file changed, 29 insertions(+), 20 deletions(-)
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 9b63d8ee1687..df5490db575b 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -165,6 +165,32 @@ static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av)
audit_log_format(ab, " }");
}
+static void avc_dump_sid(struct audit_buffer *ab, struct selinux_state *state,
+ u32 sid, char type)
+{
+ int rc;
+ char *context, *rcontext;
+ u32 context_len, rcontext_len;
+
+ rc = security_sid_to_context(state, sid, &context, &context_len);
+ if (rc) {
+ audit_log_format(ab, "%csid=%d ", type, sid);
+ return;
+ }
+
+ audit_log_format(ab, "%ccontext=%s ", type, context);
+
+ /* in case of invalid context report also the actual context string */
+ rc = security_sid_to_context_force(state, sid, &rcontext,
+ &rcontext_len);
+ if (!rc) {
+ if (strcmp(context, rcontext))
+ audit_log_format(ab, "%crawcon=%s ", type, rcontext);
+ kfree(rcontext);
+ }
+ kfree(context);
+}
+
/**
* avc_dump_query - Display a SID pair and a class in human-readable form.
* @ssid: source security identifier
@@ -174,28 +200,11 @@ static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av)
static void avc_dump_query(struct audit_buffer *ab, struct selinux_state *state,
u32 ssid, u32 tsid, u16 tclass)
{
- int rc;
- char *scontext;
- u32 scontext_len;
-
- rc = security_sid_to_context(state, ssid, &scontext, &scontext_len);
- if (rc)
- audit_log_format(ab, "ssid=%d", ssid);
- else {
- audit_log_format(ab, "scontext=%s", scontext);
- kfree(scontext);
- }
-
- rc = security_sid_to_context(state, tsid, &scontext, &scontext_len);
- if (rc)
- audit_log_format(ab, " tsid=%d", tsid);
- else {
- audit_log_format(ab, " tcontext=%s", scontext);
- kfree(scontext);
- }
+ avc_dump_sid(ab, state, ssid, 's');
+ avc_dump_sid(ab, state, tsid, 't');
BUG_ON(!tclass || tclass >= ARRAY_SIZE(secclass_map));
- audit_log_format(ab, " tclass=%s", secclass_map[tclass-1].name);
+ audit_log_format(ab, "tclass=%s", secclass_map[tclass-1].name);
}
/**
--
2.20.1
5 years, 9 months
[PATCH ghak90 (was ghak32) V4 00/10] audit: implement container identifier
by Richard Guy Briggs
Implement kernel audit container identifier.
This patchset is a fourth based on the proposal document (V3)
posted:
https://www.redhat.com/archives/linux-audit/2018-January/msg00014.html
The first patch is the last patch from ghak81 that is included here as a
convenience.
The second patch implements the proc fs write to set the audit container
identifier of a process, emitting an AUDIT_CONTAINER_OP record to announce the
registration of that audit container identifier on that process. This patch
requires userspace support for record acceptance and proper type
display.
The third implements the auxiliary record AUDIT_CONTAINER if an
audit container identifier is identifiable with an event. This patch
requires userspace support for proper type display.
The 4th adds signal and ptrace support.
The 5th creates a local audit context to be able to bind a standalone
record with a locally created auxiliary record.
The 6th patch adds audit container identifier records to the tty
standalone record.
The 7th adds audit container identifier filtering to the exit,
exclude and user lists. This patch adds the AUDIT_CONTID field and
requires auditctl userspace support for the --contid option.
The 8th adds network namespace audit container identifier labelling
based on member tasks' audit container identifier labels.
The 9th adds audit container identifier support to standalone netfilter
records that don't have a task context and lists each container to which
that net namespace belongs.
The 10th implements reading the audit container identifier from the proc
filesystem for debugging. This patch isn't planned for upstream
inclusion.
Example: Set an audit container identifier of 123456 to the "sleep" task:
sleep 2&
child=$!
echo 123456 > /proc/$child/audit_containerid; echo $?
ausearch -ts recent -m container
echo child:$child contid:$( cat /proc/$child/audit_containerid)
This should produce a record such as:
type=CONTAINER_OP msg=audit(2018-06-06 12:39:29.636:26949) : op=set opid=2209 old-contid=18446744073709551615 contid=123456 pid=628 auid=root uid=root tty=ttyS0 ses=1 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 comm=bash exe=/usr/bin/bash res=yes
Example: Set a filter on an audit container identifier 123459 on /tmp/tmpcontainerid:
contid=123459
key=tmpcontainerid
auditctl -a exit,always -F dir=/tmp -F perm=wa -F contid=$contid -F key=$key
perl -e "sleep 1; open(my \$tmpfile, '>', \"/tmp/$key\"); close(\$tmpfile);" &
child=$!
echo $contid > /proc/$child/audit_containerid
sleep 2
ausearch -i -ts recent -k $key
auditctl -d exit,always -F dir=/tmp -F perm=wa -F contid=$contid -F key=$key
rm -f /tmp/$key
This should produce an event such as:
type=CONTAINER msg=audit(2018-06-06 12:46:31.707:26953) : op=task contid=123459
type=PROCTITLE msg=audit(2018-06-06 12:46:31.707:26953) : proctitle=perl -e sleep 1; open(my $tmpfile, '>', "/tmp/tmpcontainerid"); close($tmpfile);
type=PATH msg=audit(2018-06-06 12:46:31.707:26953) : item=1 name=/tmp/tmpcontainerid inode=25656 dev=00:26 mode=file,644 ouid=root ogid=root rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0 nametype=CREATE cap_fp=none cap_fi=none cap_fe=0 cap_fver=0
type=PATH msg=audit(2018-06-06 12:46:31.707:26953) : item=0 name=/tmp/ inode=8985 dev=00:26 mode=dir,sticky,777 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:tmp_t:s0 nametype=PARENT cap_fp=none cap_fi=none cap_fe=0 cap_fver=0
type=CWD msg=audit(2018-06-06 12:46:31.707:26953) : cwd=/root
type=SYSCALL msg=audit(2018-06-06 12:46:31.707:26953) : arch=x86_64 syscall=openat success=yes exit=3 a0=0xffffffffffffff9c a1=0x5621f2b81900 a2=O_WRONLY|O_CREAT|O_TRUNC a3=0x1b6 items=2 ppid=628 pid=2232 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=ttyS0 ses=1 comm=perl exe=/usr/bin/perl subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=tmpcontainerid
Includes: https://github.com/linux-audit/audit-kernel/issues/81
See: https://github.com/linux-audit/audit-kernel/issues/90
See: https://github.com/linux-audit/audit-userspace/issues/40
See: https://github.com/linux-audit/audit-testsuite/issues/64
See: https://github.com/linux-audit/audit-kernel/wiki/RFE-Audit-Container-ID
Changelog:
v4
- preface set with ghak81:"collect audit task parameters"
- add shallyn and sgrubb acks
- rename feature bitmap macro
- rename cid_valid() to audit_contid_valid()
- rename AUDIT_CONTAINER_ID to AUDIT_CONTAINER_OP
- delete audit_get_contid_list() from headers
- move work into inner if, delete "found"
- change netns contid list function names
- move exports for audit_log_contid audit_alloc_local audit_free_context to non-syscall patch
- list contids CSV
- pass in gfp flags to audit_alloc_local() (fix audit_alloc_context callers)
- use "local" in lieu of abusing in_syscall for auditsc_get_stamp()
- read_lock(&tasklist_lock) around children and thread check
- task_lock(tsk) should be taken before first check of tsk->audit
- add spin lock to contid list in aunet
- restrict /proc read to CAP_AUDIT_CONTROL
- remove set again prohibition and inherited flag
- delete contidion spelling fix from patchset, send to netdev/linux-wireless
v3
- switched from containerid in task_struct to audit_task_info (depends on ghak81)
- drop INVALID_CID in favour of only AUDIT_CID_UNSET
- check for !audit_task_info, throw -ENOPROTOOPT on set
- changed -EPERM to -EEXIST for parent check
- return AUDIT_CID_UNSET if !audit_enabled
- squash child/thread check patch into AUDIT_CONTAINER_ID patch
- changed -EPERM to -EBUSY for child check
- separate child and thread checks, use -EALREADY for latter
- move addition of op= from ptrace/signal patch to AUDIT_CONTAINER patch
- fix && to || bashism in ptrace/signal patch
- uninline and export function for audit_free_context()
- drop CONFIG_CHANGE, FEATURE_CHANGE, ANOM_ABEND, ANOM_SECCOMP patches
- move audit_enabled check (xt_AUDIT)
- switched from containerid list in struct net to net_generic's struct audit_net
- move containerid list iteration into audit (xt_AUDIT)
- create function to move namespace switch into audit
- switched /proc/PID/ entry from containerid to audit_containerid
- call kzalloc with GFP_ATOMIC on in_atomic() in audit_alloc_context()
- call kzalloc with GFP_ATOMIC on in_atomic() in audit_log_container_info()
- use xt_net(par) instead of sock_net(skb->sk) to get net
- switched record and field names: initial CONTAINER_ID, aux CONTAINER, field CONTID
- allow to set own contid
- open code audit_set_containerid
- add contid inherited flag
- ccontainerid and pcontainerid eliminated due to inherited flag
- change name of container list funcitons
- rename containerid to contid
- convert initial container record to syscall aux
- fix spelling mistake of contidion in net/rfkill/core.c to avoid contid name collision
v2
- add check for children and threads
- add network namespace container identifier list
- add NETFILTER_PKT audit container identifier logging
- patch description and documentation clean-up and example
- reap unused ppid
Richard Guy Briggs (10):
audit: collect audit task parameters
audit: add container id
audit: log container info of syscalls
audit: add containerid support for ptrace and signals
audit: add support for non-syscall auxiliary records
audit: add containerid support for tty_audit
audit: add containerid filtering
audit: add support for containerid to network namespaces
audit: NETFILTER_PKT: record each container ID associated with a netNS
debug audit: read container ID of a process
drivers/tty/tty_audit.c | 5 +-
fs/proc/base.c | 56 ++++++++++++++
include/linux/audit.h | 95 ++++++++++++++++++++---
include/linux/sched.h | 5 +-
include/uapi/linux/audit.h | 8 +-
init/init_task.c | 3 +-
init/main.c | 2 +
kernel/audit.c | 137 +++++++++++++++++++++++++++++++++
kernel/audit.h | 4 +
kernel/auditfilter.c | 47 ++++++++++++
kernel/auditsc.c | 183 ++++++++++++++++++++++++++++++++++++++++-----
kernel/fork.c | 4 +-
kernel/nsproxy.c | 4 +
net/netfilter/xt_AUDIT.c | 12 ++-
14 files changed, 526 insertions(+), 39 deletions(-)
--
1.8.3.1
5 years, 9 months
[RFC PATCH] selinux: log invalid contexts in AVCs
by Ondrej Mosnacek
In case a file has an invalid context set, in an AVC record generated
upon access to such file, the target context is always reported as
unlabeled. This patch adds new optional fields to the AVC record (slcon
and tlcon) that report the actual context string if it differs from the
one reported in scontext/tcontext. This is useful for diagnosing SELinux
denials.
To trigger an AVC that illustrates this situation:
# setenforce 0
# touch /tmp/testfile
# setfattr -n security.selinux -v system_u:object_r:banana_t:s0 /tmp/testfile
# runcon system_u:system_r:sshd_t:s0 cat /tmp/testfile
AVC before:
type=AVC msg=audit(1547801083.248:11): avc: denied { open } for pid=1149 comm="cat" path="/tmp/testfile" dev="tmpfs" ino=6608 scontext=system_u:system_r:sshd_t:s0 tcontext=system_u:object_r:unlabeled_t:s15:c0.c1023 tclass=file permissive=1
AVC after:
type=AVC msg=audit(1547801083.248:11): avc: denied { open } for pid=1149 comm="cat" path="/tmp/testfile" dev="tmpfs" ino=6608 scontext=system_u:system_r:sshd_t:s0 tcontext=system_u:object_r:unlabeled_t:s15:c0.c1023 tlcon=system_u:object_r:banana_t:s0 tclass=file permissive=1
Cc: Daniel Walsh <dwalsh(a)redhat.com>
Link: https://bugzilla.redhat.com/show_bug.cgi?id=1135683
Signed-off-by: Ondrej Mosnacek <omosnace(a)redhat.com>
---
security/selinux/avc.c | 49 +++++++++++++++++++++++++-----------------
1 file changed, 29 insertions(+), 20 deletions(-)
I'm not entirely sure about the record format here, so I'm Cc'ing
linux-audit and Steve for feedback. I went for optional fields to
minimize the size of the record, but maybe a different format is
preferred. If so, let me know and I'll do a respin.
Also, I accept suggestions for better field names than "slcon"/"tlcon"
("lcon" is meant as an acronym for "literal context", but I'm not sure
if that's a good name...).
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 9b63d8ee1687..4a181ed56e37 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -165,6 +165,32 @@ static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av)
audit_log_format(ab, " }");
}
+static void avc_dump_sid(struct audit_buffer *ab, struct selinux_state *state,
+ u32 sid, char type)
+{
+ int rc;
+ char *context, *lcontext;
+ u32 context_len, lcontext_len;
+
+ rc = security_sid_to_context(state, sid, &context, &context_len);
+ if (rc) {
+ audit_log_format(ab, "%csid=%d ", type, sid);
+ return;
+ }
+
+ audit_log_format(ab, "%ccontext=%s ", type, context);
+
+ /* in case of invalid context report also the actual context string */
+ rc = security_sid_to_context_force(state, sid, &lcontext,
+ &lcontext_len);
+ if (!rc) {
+ if (strcmp(context, lcontext))
+ audit_log_format(ab, "%clcon=%s ", type, lcontext);
+ kfree(lcontext);
+ }
+ kfree(context);
+}
+
/**
* avc_dump_query - Display a SID pair and a class in human-readable form.
* @ssid: source security identifier
@@ -174,28 +200,11 @@ static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av)
static void avc_dump_query(struct audit_buffer *ab, struct selinux_state *state,
u32 ssid, u32 tsid, u16 tclass)
{
- int rc;
- char *scontext;
- u32 scontext_len;
-
- rc = security_sid_to_context(state, ssid, &scontext, &scontext_len);
- if (rc)
- audit_log_format(ab, "ssid=%d", ssid);
- else {
- audit_log_format(ab, "scontext=%s", scontext);
- kfree(scontext);
- }
-
- rc = security_sid_to_context(state, tsid, &scontext, &scontext_len);
- if (rc)
- audit_log_format(ab, " tsid=%d", tsid);
- else {
- audit_log_format(ab, " tcontext=%s", scontext);
- kfree(scontext);
- }
+ avc_dump_sid(ab, state, ssid, 's');
+ avc_dump_sid(ab, state, tsid, 't');
BUG_ON(!tclass || tclass >= ARRAY_SIZE(secclass_map));
- audit_log_format(ab, " tclass=%s", secclass_map[tclass-1].name);
+ audit_log_format(ab, "tclass=%s", secclass_map[tclass-1].name);
}
/**
--
2.20.1
5 years, 9 months
Audit change
by Nowakowski Media
If the audit messages would shift up 1 from the first_event you could track
the performance of the audit daemon. Having 2 messages typed with the same
number is confusing.
5 years, 9 months
[PATCH ghak59 V4] audit: add syscall information to CONFIG_CHANGE records
by Richard Guy Briggs
Tie syscall information to all CONFIG_CHANGE calls since they are all a
result of user actions.
Exclude user records from syscall context:
Since the function audit_log_common_recv_msg() is shared by a number of
AUDIT_CONFIG_CHANGE and the entire range of AUDIT_USER_* record types,
and since the AUDIT_CONFIG_CHANGE message type has been converted to a
syscall accompanied record type, special-case the AUDIT_USER_* range of
messages so they remain standalone records.
See: https://github.com/linux-audit/audit-kernel/issues/59
See: https://github.com/linux-audit/audit-kernel/issues/50
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
Changelog:
v4:
- rebase on v5.0-rc1
- remove audit_log_config_change_alt() and call
audit_log_common_recv_msg() directly
- remove audit_tree_log_remove_rule() change superceded by patch v3-3/4
Passes audit-testsuite, no issues identified with ausearch-test.
kernel/audit.c | 27 ++++++++++++++++++---------
kernel/audit_fsnotify.c | 2 +-
kernel/audit_watch.c | 2 +-
kernel/auditfilter.c | 2 +-
4 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index d412fb4ae6d5..ca55ccb46b76 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -396,7 +396,7 @@ static int audit_log_config_change(char *function_name, u32 new, u32 old,
struct audit_buffer *ab;
int rc = 0;
- ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
+ ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_CONFIG_CHANGE);
if (unlikely(!ab))
return rc;
audit_log_format(ab, "op=set %s=%u old=%u ", function_name, new, old);
@@ -1053,7 +1053,8 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
return err;
}
-static void audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type)
+static void audit_log_common_recv_msg(struct audit_context *context,
+ struct audit_buffer **ab, u16 msg_type)
{
uid_t uid = from_kuid(&init_user_ns, current_uid());
pid_t pid = task_tgid_nr(current);
@@ -1063,7 +1064,7 @@ static void audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type)
return;
}
- *ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
+ *ab = audit_log_start(context, GFP_KERNEL, msg_type);
if (unlikely(!*ab))
return;
audit_log_format(*ab, "pid=%d uid=%u ", pid, uid);
@@ -1071,6 +1072,11 @@ static void audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type)
audit_log_task_context(*ab);
}
+static inline void audit_log_user_recv_msg(struct audit_buffer **ab, u16 msg_type)
+{
+ audit_log_common_recv_msg(NULL, ab, msg_type);
+}
+
int is_audit_feature_set(int i)
{
return af.features & AUDIT_FEATURE_TO_MASK(i);
@@ -1338,7 +1344,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (err)
break;
}
- audit_log_common_recv_msg(&ab, msg_type);
+ audit_log_user_recv_msg(&ab, msg_type);
if (msg_type != AUDIT_USER_TTY)
audit_log_format(ab, " msg='%.*s'",
AUDIT_MESSAGE_TEXT_MAX,
@@ -1361,7 +1367,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (nlmsg_len(nlh) < sizeof(struct audit_rule_data))
return -EINVAL;
if (audit_enabled == AUDIT_LOCKED) {
- audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE);
+ audit_log_common_recv_msg(audit_context(), &ab,
+ AUDIT_CONFIG_CHANGE);
audit_log_format(ab, " op=%s audit_enabled=%d res=0",
msg_type == AUDIT_ADD_RULE ?
"add_rule" : "remove_rule",
@@ -1376,7 +1383,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
break;
case AUDIT_TRIM:
audit_trim_trees();
- audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE);
+ audit_log_common_recv_msg(audit_context(), &ab,
+ AUDIT_CONFIG_CHANGE);
audit_log_format(ab, " op=trim res=1");
audit_log_end(ab);
break;
@@ -1406,8 +1414,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
/* OK, here comes... */
err = audit_tag_tree(old, new);
- audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE);
-
+ audit_log_common_recv_msg(audit_context(), &ab,
+ AUDIT_CONFIG_CHANGE);
audit_log_format(ab, " op=make_equiv old=");
audit_log_untrustedstring(ab, old);
audit_log_format(ab, " new=");
@@ -1474,7 +1482,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
old.enabled = t & AUDIT_TTY_ENABLE;
old.log_passwd = !!(t & AUDIT_TTY_LOG_PASSWD);
- audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE);
+ audit_log_common_recv_msg(audit_context(), &ab,
+ AUDIT_CONFIG_CHANGE);
audit_log_format(ab, " op=tty_set old-enabled=%d new-enabled=%d"
" old-log_passwd=%d new-log_passwd=%d res=%d",
old.enabled, s.enabled, old.log_passwd,
diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c
index cf4512a33675..37ae95cfb7f4 100644
--- a/kernel/audit_fsnotify.c
+++ b/kernel/audit_fsnotify.c
@@ -127,7 +127,7 @@ static void audit_mark_log_rule_change(struct audit_fsnotify_mark *audit_mark, c
if (!audit_enabled)
return;
- ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE);
+ ab = audit_log_start(audit_context(), GFP_NOFS, AUDIT_CONFIG_CHANGE);
if (unlikely(!ab))
return;
audit_log_session_info(ab);
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index 20ef9ba134b0..e8d1adeb2223 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -242,7 +242,7 @@ static void audit_watch_log_rule_change(struct audit_krule *r, struct audit_watc
if (!audit_enabled)
return;
- ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE);
+ ab = audit_log_start(audit_context(), GFP_NOFS, AUDIT_CONFIG_CHANGE);
if (!ab)
return;
audit_log_session_info(ab);
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index bf309f2592c4..26a80a9d43a9 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -1091,7 +1091,7 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re
if (!audit_enabled)
return;
- ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
+ ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_CONFIG_CHANGE);
if (!ab)
return;
audit_log_session_info(ab);
--
1.8.3.1
5 years, 9 months
[PATCH ghak59 V3 0/4] audit: config_change normalizations and event record gathering
by Richard Guy Briggs
Make a number of changes to normalize CONFIG_CHANGE records by adding
missing op= fields, providing more information in existing op fields
(optional last patch) and connecting all records to existing audit
events. The user record needs special-casing since its content isn't
directly related to the call that logs it.
Since tree purge records are processed after the EOE record is produced,
the order of operation of the EOE record and the purge will have to be
reversed so that the purge records can be included in the event.
The last patch is included for completeness understanding it may be more
information than necessary.
For reference, here are the calling methods and function tree for all
CONFIG_CHANGE events with fields:
- audit_log_config_change()
- add "op=set" to fields: "[op] <param-name> old auid ses subj res"
- AUDIT_SET:AUDIT_STATUS_PID
- AUDIT_SET:AUDIT_STATUS_LOST
- audit_do_config_change()
- AUDIT_SET:AUDIT_STATUS_FAILURE
- AUDIT_SET:AUDIT_STATUS_ENABLED
- AUDIT_SET:AUDIT_STATUS_RATE_LIMIT
- AUDIT_SET:AUDIT_STATUS_BACKLOG_LIMIT
- AUDIT_SET:AUDIT_STATUS_BACKLOG_WAIT_TIME
- audit_log_rule_change()
- fields: "auid ses subj op key list res"
- AUDIT_ADD_RULE -F dir=...
- AUDIT_DEL_RULE -F dir=...
- audit_log_common_recv_msg()
- fields: "pid uid auid ses subj ..."
- AUDIT_*USER* events (not CONFIG_CHANGE like all the rest)
- AUDIT_LOCKED add "op={add,remove}_rule" to "[op] audit_enabled res"
- AUDIT_TRIM "op=trim res"
- AUDIT_MAKE_EQUIV: "op=make_equiv old new res"
- AUDIT_TTY_SET: "op=tty_set old-enabled new-enabled old-log_passwd new-log_passwd res"
- audit_mark_log_rule_change()
- add ":mark" to op in fields: "uid ses op=autoremove_rule[] path key list res"
- audit_autoremove_mark_rule()
- audit_mark_handle_event()
- audit_mark_fsnotify_ops.handle_event
- audit_tree_log_remove_rule() called from kill_rules()
- add to op ":tree:%s" to fields: "op=remove_rule[] dir key list res"
- from trim_marked()
- AUDIT_TRIM: audit_trim_trees() "trim"
- audit_add_tree_rule() iterate_mounts err "add"
- audit_add_rule()
- audit_rule_change()
- AUDIT_ADD_RULE -F dir=...
- AUDIT_MAKE_EQUIV: audit_tag_tree() iterate_mounts err "equiv"
- from audit_kill_trees()
- __audit_free() "free"
- do_exit()
- copy_process() err
- __audit_syscall_exit() "exit"
- from evict_chunk() "evict"
- audit_tree_freeing_mark()
- audit_tree_ops.freeing_mark
- audit_watch_log_rule_change()
add to op ":watch:%s" to fields "auid ses op={updated,remove}_rule[] path key list res"
- audit_update_watch() "updated_rules:watch:inval" : "updated_rules:watch:set"
- audit_watch_handle_event() FS_CREATE|FS_MOVED_TO, FS_DELETE|FS_MOVED_FROM
- audit_watch_fsnotify_ops.handle_event
- audit_remove_parent_watches() "remove_rule:watch:parent"
- audit_watch_handle_event() FS_DELETE_SELF|FS_UNMOUNT|FS_MOVE_SELF
- audit_watch_fsnotify_ops.handle_event
- audit_seccomp_actions_logged()
- fields: "op actions old-actions res"
See: https://github.com/linux-audit/audit-kernel/issues/50
See: https://github.com/linux-audit/audit-kernel/issues/59
Sources of AUDIT_CONFIG_CHANGE records and their current and proposed
fields are listed here
https://github.com/linux-audit/audit-kernel/issues/59#issuecomment-445055154
Changelog:
v3:
- un-clever %s_rule to not break up op values
- create audit_log_user_recv_msg() and squash into record connection
- squash kill_trees context handling with kill-trees before EOE
- rebase on audit/next (v4.20-rc1) with 2a1fe215e730 ("audit: use current whenever possible")
- remove parens in extended format
v2:
- re-order audit_log_exit() and audit_kill_trees()
- drop EOE reordering patch
- rebase on 4.18-rc1 (audit/next)
Richard Guy Briggs (4):
audit: give a clue what CONFIG_CHANGE op was involved
audit: add syscall information to CONFIG_CHANGE records
audit: hand taken context to audit_kill_trees for syscall logging
audit: extend config_change mark/watch/tree rule changes
kernel/audit.c | 33 +++++++++++++++++++++++----------
kernel/audit.h | 4 ++--
kernel/audit_fsnotify.c | 4 ++--
kernel/audit_tree.c | 28 +++++++++++++++-------------
kernel/audit_watch.c | 8 +++++---
kernel/auditfilter.c | 2 +-
kernel/auditsc.c | 12 ++++++------
7 files changed, 54 insertions(+), 37 deletions(-)
--
1.8.3.1
5 years, 9 months
Audit filtering by parent process path
by Simon Außerlechner
Hi,
Using the Linux kernel audit system I audit program executions with the
following audit rule.
-w /usr/sbin/my-program -p x -k my-program-audit-class
In order to keep the audit log clean I want to suppress executions of
my-program if done by a defined set of applications given their path.
Since the PPID is available in the audit log entry (type=SYSCALL), there
might be some means to filter out by parent program path at the time the
audit log is generated, however, I cannot find a solution, also not by
looking at audit_filter_rules(). Introducing helper scripts to clean up
audit.log by filtering out later on as well as distinguishing by
user/group, security context are not my preferred options.
Thank you,
Simon
5 years, 9 months
[PATCH v7 00/22] ptrace: add PTRACE_GET_SYSCALL_INFO request
by Dmitry V. Levin
PTRACE_GET_SYSCALL_INFO is a generic ptrace API that lets ptracer obtain
details of the syscall the tracee is blocked in.
There are two reasons for a special syscall-related ptrace request.
Firstly, with the current ptrace API there are cases when ptracer cannot
retrieve necessary information about syscalls. Some examples include:
* The notorious int-0x80-from-64-bit-task issue. See [1] for details.
In short, if a 64-bit task performs a syscall through int 0x80, its tracer
has no reliable means to find out that the syscall was, in fact,
a compat syscall, and misidentifies it.
* Syscall-enter-stop and syscall-exit-stop look the same for the tracer.
Common practice is to keep track of the sequence of ptrace-stops in order
not to mix the two syscall-stops up. But it is not as simple as it looks;
for example, strace had a (just recently fixed) long-standing bug where
attaching strace to a tracee that is performing the execve system call
led to the tracer identifying the following syscall-exit-stop as
syscall-enter-stop, which messed up all the state tracking.
* Since the introduction of commit 84d77d3f06e7e8dea057d10e8ec77ad71f721be3
("ptrace: Don't allow accessing an undumpable mm"), both PTRACE_PEEKDATA
and process_vm_readv become unavailable when the process dumpable flag
is cleared. On such architectures as ia64 this results in all syscall
arguments being unavailable for the tracer.
Secondly, ptracers also have to support a lot of arch-specific code for
obtaining information about the tracee. For some architectures, this
requires a ptrace(PTRACE_PEEKUSER, ...) invocation for every syscall
argument and return value.
PTRACE_GET_SYSCALL_INFO returns the following structure:
struct ptrace_syscall_info {
__u8 op; /* PTRACE_SYSCALL_INFO_* */
__u32 arch __attribute__((__aligned__(sizeof(__u32))));
__u64 instruction_pointer;
__u64 stack_pointer;
union {
struct {
__u64 nr;
__u64 args[6];
} entry;
struct {
__s64 rval;
__u8 is_error;
} exit;
struct {
__u64 nr;
__u64 args[6];
__u32 ret_data;
} seccomp;
};
};
The structure was chosen according to [2], except for the following
changes:
* seccomp substructure was added as a superset of entry substructure;
* the type of nr field was changed from int to __u64 because syscall
numbers are, as a practical matter, 64 bits;
* stack_pointer field was added along with instruction_pointer field
since it is readily available and can save the tracer from extra
PTRACE_GETREGS/PTRACE_GETREGSET calls;
* arch is always initialized to aid with tracing system calls
* such as execve();
* instruction_pointer and stack_pointer are always initialized
so they could be easily obtained for non-syscall stops;
* a boolean is_error field was added along with rval field, this way
the tracer can more reliably distinguish a return value
from an error value.
strace has been ported to PTRACE_GET_SYSCALL_INFO.
Starting with release 4.26, strace uses PTRACE_GET_SYSCALL_INFO API
as the preferred mechanism of obtaining syscall information.
[1] https://lore.kernel.org/lkml/CA+55aFzcSVmdDj9Lh_gdbz1OzHyEm6ZrGPBDAJnywm2...
[2] https://lore.kernel.org/lkml/CAObL_7GM0n80N7J_DFw_eQyfLyzq+sf4y2AvsCCV88T...
---
Notes:
v7:
* Rebased to v5.0-rc1.
* 5 arch-specific preparatory patches out of 25 have been merged
into v5.0-rc1 via arch trees.
v6:
* Add syscall_get_arguments and syscall_set_arguments wrappers
to asm-generic/syscall.h, requested by Geert.
* Change PTRACE_GET_SYSCALL_INFO return code: do not take trailing paddings
into account, use the end of the last field of the structure being written.
* Change struct ptrace_syscall_info:
* remove .frame_pointer field, is is not needed and not portable;
* make .arch field explicitly aligned, remove no longer needed
padding before .arch field;
* remove trailing pads, they are no longer needed.
v5:
* Merge separate series and patches into the single series.
* Change PTRACE_EVENTMSG_SYSCALL_{ENTRY,EXIT} values as requested by Oleg.
* Change struct ptrace_syscall_info: generalize instruction_pointer,
stack_pointer, and frame_pointer fields by moving them from
ptrace_syscall_info.{entry,seccomp} substructures to ptrace_syscall_info
and initializing them for all stops.
* Add PTRACE_SYSCALL_INFO_NONE, set it when not in a syscall stop,
so e.g. "strace -i" could use PTRACE_SYSCALL_INFO_SECCOMP to obtain
instruction_pointer when the tracee is in a signal stop.
* Patch all remaining architectures to provide all necessary
syscall_get_* functions.
* Make available for all architectures: do not conditionalize on
CONFIG_HAVE_ARCH_TRACEHOOK since all syscall_get_* functions
are implemented on all architectures.
* Add a test for PTRACE_GET_SYSCALL_INFO to selftests/ptrace.
v4:
* Do not introduce task_struct.ptrace_event,
use child->last_siginfo->si_code instead.
* Implement PTRACE_SYSCALL_INFO_SECCOMP and ptrace_syscall_info.seccomp
support along with PTRACE_SYSCALL_INFO_{ENTRY,EXIT} and
ptrace_syscall_info.{entry,exit}.
v3:
* Change struct ptrace_syscall_info.
* Support PTRACE_EVENT_SECCOMP by adding ptrace_event to task_struct.
* Add proper defines for ptrace_syscall_info.op values.
* Rename PT_SYSCALL_IS_ENTERING and PT_SYSCALL_IS_EXITING to
PTRACE_EVENTMSG_SYSCALL_ENTRY and PTRACE_EVENTMSG_SYSCALL_EXIT
* and move them to uapi.
v2:
* Do not use task->ptrace.
* Replace entry_info.is_compat with entry_info.arch, use syscall_get_arch().
* Use addr argument of sys_ptrace to get expected size of the struct;
return full size of the struct.
Dmitry V. Levin (21):
asm-generic/syscall.h: prepare for inclusion by other files
asm-generic/syscall.h: turn syscall_[gs]et_arguments into wrappers
alpha: define remaining syscall_get_* functions
Move EM_ARCOMPACT and EM_ARCV2 to uapi/linux/elf-em.h
arc: define syscall_get_arch()
c6x: define syscall_get_arch()
h8300: define remaining syscall_get_* functions
Move EM_HEXAGON to uapi/linux/elf-em.h
hexagon: define remaining syscall_get_* functions
Move EM_NDS32 to uapi/linux/elf-em.h
nds32: define syscall_get_arch()
nios2: define syscall_get_arch()
m68k: add asm/syscall.h
mips: define syscall_get_error()
parisc: define syscall_get_error()
powerpc: define syscall_get_error()
riscv: define syscall_get_arch()
Move EM_UNICORE to uapi/linux/elf-em.h
unicore32: add asm/syscall.h
syscall_get_arch: add "struct task_struct *" argument
selftests/ptrace: add a test case for PTRACE_GET_SYSCALL_INFO
Elvira Khabirova (1):
ptrace: add PTRACE_GET_SYSCALL_INFO request
arch/alpha/include/asm/syscall.h | 31 +-
arch/arc/include/asm/elf.h | 6 +-
arch/arc/include/asm/syscall.h | 11 +
arch/arm/include/asm/syscall.h | 2 +-
arch/arm64/include/asm/syscall.h | 4 +-
arch/c6x/include/asm/syscall.h | 7 +
arch/csky/include/asm/syscall.h | 2 +-
arch/h8300/include/asm/syscall.h | 19 ++
arch/hexagon/include/asm/elf.h | 6 +-
arch/hexagon/include/asm/syscall.h | 22 ++
arch/ia64/include/asm/syscall.h | 2 +-
arch/m68k/include/asm/syscall.h | 42 +++
arch/microblaze/include/asm/syscall.h | 2 +-
arch/mips/include/asm/syscall.h | 12 +-
arch/mips/kernel/ptrace.c | 2 +-
arch/nds32/include/asm/elf.h | 3 +-
arch/nds32/include/asm/syscall.h | 8 +
arch/nios2/include/asm/syscall.h | 6 +
arch/openrisc/include/asm/syscall.h | 2 +-
arch/parisc/include/asm/syscall.h | 11 +-
arch/powerpc/include/asm/syscall.h | 20 +-
arch/riscv/include/asm/syscall.h | 10 +
arch/s390/include/asm/syscall.h | 4 +-
arch/sh/include/asm/syscall_32.h | 2 +-
arch/sh/include/asm/syscall_64.h | 2 +-
arch/sparc/include/asm/syscall.h | 5 +-
arch/unicore32/include/asm/elf.h | 3 +-
arch/unicore32/include/asm/syscall.h | 47 +++
arch/x86/include/asm/syscall.h | 8 +-
arch/x86/um/asm/syscall.h | 2 +-
arch/xtensa/include/asm/syscall.h | 2 +-
include/asm-generic/syscall.h | 85 ++++--
include/linux/tracehook.h | 9 +-
include/uapi/linux/audit.h | 14 +
include/uapi/linux/elf-em.h | 6 +
include/uapi/linux/ptrace.h | 35 +++
kernel/auditsc.c | 4 +-
kernel/ptrace.c | 101 ++++++-
kernel/seccomp.c | 4 +-
tools/testing/selftests/ptrace/.gitignore | 1 +
tools/testing/selftests/ptrace/Makefile | 2 +-
.../selftests/ptrace/get_syscall_info.c | 271 ++++++++++++++++++
42 files changed, 771 insertions(+), 66 deletions(-)
create mode 100644 arch/m68k/include/asm/syscall.h
create mode 100644 arch/unicore32/include/asm/syscall.h
create mode 100644 tools/testing/selftests/ptrace/get_syscall_info.c
--
ldv
5 years, 9 months