[PATCH] Support for auditing on the actions of a not-yet-executed process.
by Peter Moody
eg:
-a exit,always -F arch=b64 -S socket -F 'a0!=1' -F exe=/bin/bash -F success=1
to see instances of /bin/bash opening a non-local socket. Or
-a exit,always -F arch=b64 -S socket -F 'a0!=1' -F exe_children=/bin/bash -F success=1
to instances of /bin/bash, and any descendant processes, opening a non local socket.
proposed https://www.redhat.com/archives/linux-audit/2012-June/msg00002.html
and it seemed like there was interest.
Signed-off-by: Peter Moody <pmoody(a)google.com>
---
trunk/lib/errormsg.h | 2 +-
trunk/lib/fieldtab.h | 2 ++
trunk/lib/libaudit.c | 11 +++++++++++
trunk/lib/libaudit.h | 7 ++++++-
4 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/trunk/lib/errormsg.h b/trunk/lib/errormsg.h
index 4d996d5..cd595ec 100644
--- a/trunk/lib/errormsg.h
+++ b/trunk/lib/errormsg.h
@@ -51,7 +51,7 @@ static const struct msg_tab err_msgtab[] = {
{ -15, 2, "-F unknown errno -"},
{ -16, 2, "-F unknown file type - " },
{ -17, 1, "can only be used with exit and entry filter list" },
- { -18, 1, "" }, // Unused
+ { -18, 1, "only takes = operator" },
{ -19, 0, "Key field needs a watch or syscall given prior to it" },
{ -20, 2, "-F missing value after operation for" },
{ -21, 2, "-F value should be number for" },
diff --git a/trunk/lib/fieldtab.h b/trunk/lib/fieldtab.h
index c0432cc..245b541 100644
--- a/trunk/lib/fieldtab.h
+++ b/trunk/lib/fieldtab.h
@@ -66,3 +66,5 @@ _S(AUDIT_ARG3, "a3" )
_S(AUDIT_FILTERKEY, "key" )
_S(AUDIT_FIELD_COMPARE, "field_compare" )
+_S(AUDIT_EXE, "exe" )
+_S(AUDIT_EXE_CHILDREN, "exe_children" )
diff --git a/trunk/lib/libaudit.c b/trunk/lib/libaudit.c
index 20eaf5f..06eed86 100644
--- a/trunk/lib/libaudit.c
+++ b/trunk/lib/libaudit.c
@@ -1400,6 +1400,17 @@ int audit_rule_fieldpair_data(struct audit_rule_data **rulep, const char *pair,
else
return -21;
break;
+ case AUDIT_EXE_CHILDREN:
+ case AUDIT_EXE:
+ {
+ struct stat buf;
+ if ((stat(v, &buf)) < 0)
+ return -2;
+ if (op != AUDIT_EQUAL)
+ return -18;
+ rule->values[rule->field_count] = (unsigned long)buf.st_ino;
+ }
+ break;
case AUDIT_DEVMAJOR...AUDIT_INODE:
case AUDIT_SUCCESS:
if (flags != AUDIT_FILTER_EXIT)
diff --git a/trunk/lib/libaudit.h b/trunk/lib/libaudit.h
index 89dd588..2c8a802 100644
--- a/trunk/lib/libaudit.h
+++ b/trunk/lib/libaudit.h
@@ -243,6 +243,12 @@ extern "C" {
#ifndef AUDIT_FIELD_COMPARE
#define AUDIT_FIELD_COMPARE 111
#endif
+#ifndef AUDIT_EXE
+#define AUDIT_EXE 112
+#endif
+#ifndef AUDIT_EXE_CHILDREN
+#define AUDIT_EXE_CHILDREN 113
+#endif
#ifndef AUDIT_COMPARE_UID_TO_OBJ_UID
#define AUDIT_COMPARE_UID_TO_OBJ_UID 1
@@ -524,4 +530,3 @@ extern void audit_rule_free_data(struct audit_rule_data *rule);
#endif
#endif
-
--
1.7.7.3
10 years, 7 months
Re: [PATCH RFC 7/8] audit: report namespace information along with USER events
by Eric W. Biederman
Aristeu Rozanski <arozansk(a)redhat.com> writes:
> For userspace generated events, include a record with the namespace
> procfs inode numbers the process belongs to. This allows to track down
> and filter audit messages by userspace.
I am not comfortable with using the inode numbers this way. It does not
pass the test of can I migrate a container and still have this work
test. Any kind of kernel assigned name for namespaces fails that test.
I also don't like that you don't include the procfs device number. An
inode number means nothing without knowing which filesystem you are
referring to.
It may never happen but I reserve the right to have the inode numbers
for namespaces to show up differently in different instances of procfs.
Beyond that I think this usage is possibly buggy by using two audit
records for one event.
> Signed-off-by: Aristeu Rozanski <arozansk(a)redhat.com>
> ---
> include/uapi/linux/audit.h | 1 +
> kernel/audit.c | 51 +++++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 51 insertions(+), 1 deletions(-)
>
> diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
> index 9f096f1..3ec3ccb 100644
> --- a/include/uapi/linux/audit.h
> +++ b/include/uapi/linux/audit.h
> @@ -106,6 +106,7 @@
> #define AUDIT_NETFILTER_PKT 1324 /* Packets traversing netfilter chains */
> #define AUDIT_NETFILTER_CFG 1325 /* Netfilter chain modifications */
> #define AUDIT_SECCOMP 1326 /* Secure Computing event */
> +#define AUDIT_USER_NAMESPACE 1327 /* Information about process' namespaces */
>
> #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
> #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
> diff --git a/kernel/audit.c b/kernel/audit.c
> index 58db117..b17f9c0 100644
> --- a/kernel/audit.c
> +++ b/kernel/audit.c
> @@ -62,6 +62,11 @@
> #include <linux/freezer.h>
> #include <linux/tty.h>
> #include <linux/pid_namespace.h>
> +#include <linux/ipc_namespace.h>
> +#include <linux/mnt_namespace.h>
> +#include <linux/utsname.h>
> +#include <linux/user_namespace.h>
> +#include <net/net_namespace.h>
>
> #include "audit.h"
>
> @@ -641,6 +646,49 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type,
> return rc;
> }
>
> +#ifdef CONFIG_NAMESPACES
> +static int audit_log_namespaces(struct task_struct *tsk,
> + struct sk_buff *skb)
> +{
> + struct audit_context *ctx = tsk->audit_context;
> + struct audit_buffer *ab;
> +
> + if (!audit_enabled)
> + return 0;
> +
> + ab = audit_log_start(ctx, GFP_KERNEL, AUDIT_USER_NAMESPACE);
> + if (unlikely(!ab))
> + return -ENOMEM;
> +
> + audit_log_format(ab, "mnt=%u", mntns_get_inum(tsk));
> +#ifdef CONFIG_NET_NS
> + audit_log_format(ab, " net=%u", netns_get_inum(tsk));
> +#endif
> +#ifdef CONFIG_UTS_NS
> + audit_log_format(ab, " uts=%u", utsns_get_inum(tsk));
> +#endif
> +#ifdef CONFIG_IPC_NS
> + audit_log_format(ab, " ipc=%u", ipcns_get_inum(tsk));
> +#endif
> +#ifdef CONFIG_PID_NS
> + audit_log_format(ab, " pid=%u", pidns_get_inum(tsk));
> +#endif
> +#ifdef CONFIG_USER_NS
> + audit_log_format(ab, " user=%u", userns_get_inum(tsk));
> +#endif
> + audit_set_pid(ab, NETLINK_CB(skb).portid);
> + audit_log_end(ab);
> +
> + return 0;
> +}
> +#else
> +static inline int audit_log_namespaces(struct task_struct *tsk,
> + struct sk_buff *skb)
> +{
> + return 0;
> +}
> +#endif
> +
> static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
> {
> u32 seq, sid;
> @@ -741,7 +789,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
> }
> audit_log_common_recv_msg(&ab, msg_type,
> loginuid, sessionid, sid,
> - NULL);
> + current->audit_context);
>
> if (msg_type != AUDIT_USER_TTY)
> audit_log_format(ab, " msg='%.1024s'",
> @@ -758,6 +806,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
> }
> audit_set_pid(ab, NETLINK_CB(skb).portid);
> audit_log_end(ab);
> + audit_log_namespaces(current, skb);
> }
> break;
> case AUDIT_ADD:
10 years, 11 months
[PATCH] audit: audit on the future execution of a binary.
by Peter Moody
This adds the ability audit the actions of a not-yet-running process,
as well as the children of a not-yet-running process.
Signed-off-by: Peter Moody <pmoody(a)google.com>
---
include/linux/audit.h | 2 ++
kernel/auditfilter.c | 6 ++++++
kernel/auditsc.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 22f292a..5506cb1 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -260,6 +260,8 @@
#define AUDIT_OBJ_UID 109
#define AUDIT_OBJ_GID 110
#define AUDIT_FIELD_COMPARE 111
+#define AUDIT_EXE 112
+#define AUDIT_EXE_CHILDREN 113
#define AUDIT_ARG0 200
#define AUDIT_ARG1 (AUDIT_ARG0+1)
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index a6c3f1a..1e6c571 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -546,6 +546,12 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
if (f->val > AUDIT_MAX_FIELD_COMPARE)
goto exit_free;
break;
+ case AUDIT_EXE:
+ case AUDIT_EXE_CHILDREN:
+ if (f->op != Audit_equal) {
+ goto exit_free;
+ }
+ break;
default:
goto exit_free;
}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 4b96415..9cebe95 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -46,6 +46,7 @@
#include <asm/types.h>
#include <linux/atomic.h>
#include <linux/fs.h>
+#include <linux/dcache.h>
#include <linux/namei.h>
#include <linux/mm.h>
#include <linux/export.h>
@@ -68,6 +69,7 @@
#include <linux/capability.h>
#include <linux/fs_struct.h>
#include <linux/compat.h>
+#include <linux/sched.h>
#include "audit.h"
@@ -592,6 +594,35 @@ static int audit_field_compare(struct task_struct *tsk,
return 0;
}
+int audit_match_exe(struct task_struct *tsk, struct audit_field *f)
+{
+ int result = 0;
+ struct mm_struct *mm;
+ struct vm_area_struct *vma;
+
+ if (!tsk)
+ goto out;
+
+ mm = tsk->mm;
+ if (!mm)
+ goto out;
+
+ down_read(&mm->mmap_sem);
+ vma = mm->mmap;
+ while (vma) {
+ if ((vma->vm_flags & VM_EXECUTABLE) &&
+ vma->vm_file) {
+ struct inode *ino = vma->vm_file->f_path.dentry->d_inode;
+ result = audit_comparator(ino->i_ino, f->op, f->val);
+ break;
+ }
+ vma = vma->vm_next;
+ }
+ up_read(&mm->mmap_sem);
+out:
+ return result;
+}
+
/* Determine if any context name data matches a rule's watch data */
/* Compare a task_struct with an audit_rule. Return 1 on match, 0
* otherwise.
@@ -629,6 +660,22 @@ static int audit_filter_rules(struct task_struct *tsk,
result = audit_comparator(ctx->ppid, f->op, f->val);
}
break;
+ case AUDIT_EXE:
+ result = audit_match_exe(tsk, f);
+ break;
+ case AUDIT_EXE_CHILDREN:
+ {
+ struct task_struct *ptsk;
+ for (ptsk = tsk;
+ ptsk->parent->pid > 0;
+ ptsk = find_task_by_vpid(ptsk->parent->pid)) {
+ if (audit_match_exe(ptsk, f)) {
+ ++result;
+ break;
+ }
+ }
+ }
+ break;
case AUDIT_UID:
result = audit_comparator(cred->uid, f->op, f->val);
break;
--
1.7.7.3
11 years, 3 months
user message limits
by LC Bruzenak
I know I can go look at the code, however I figured I'd ask here first
about the limits on the user message in both audit_log_user_message and
ausearch.
With audit_log_user_message the maximum length allowed appears to be
around MAX_AUDIT_MESSAGE_LENGTH-100. I think it may depend on the
executable name length (and other stuff auto-pushed into the string)
which is why I say "around".
Even when I get a successful return value (from audit_log_user_message),
I don't get my string back out in "ausearch" unless it is WAY smaller -
~1K or less I think.
Any ideas/thoughts?
This is the latest (1.7.11-2) audit package.
Thx,
LCB.
--
LC (Lenny) Bruzenak
lenny(a)magitekltd.com
11 years, 3 months
[PATCH] [BZ905179] audit: omit check for uid and gid validity in audit rules and data
by Richard Guy Briggs
audit rule additions containing "-F auid!=4294967295" were failing with EINVAL.
UID_INVALID (and GID_INVALID) is actually a valid uid (gid) for setting and
testing against audit rules. Remove the check for invalid uid and gid when
parsing rules and data for logging.
Revert part of ca57ec0f00c3f139c41bf6b0a5b9bcc95bbb2ad7 (2012-09-11) to fix
this.
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
kernel/auditfilter.c | 12 ------------
1 files changed, 0 insertions(+), 12 deletions(-)
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index f9fc54b..457ee39 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -360,10 +360,7 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
/* bit ops not implemented for uid comparisons */
if (f->op == Audit_bitmask || f->op == Audit_bittest)
goto exit_free;
-
f->uid = make_kuid(current_user_ns(), f->val);
- if (!uid_valid(f->uid))
- goto exit_free;
break;
case AUDIT_GID:
case AUDIT_EGID:
@@ -372,10 +369,7 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
/* bit ops not implemented for gid comparisons */
if (f->op == Audit_bitmask || f->op == Audit_bittest)
goto exit_free;
-
f->gid = make_kgid(current_user_ns(), f->val);
- if (!gid_valid(f->gid))
- goto exit_free;
break;
case AUDIT_PID:
case AUDIT_PERS:
@@ -469,10 +463,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
/* bit ops not implemented for uid comparisons */
if (f->op == Audit_bitmask || f->op == Audit_bittest)
goto exit_free;
-
f->uid = make_kuid(current_user_ns(), f->val);
- if (!uid_valid(f->uid))
- goto exit_free;
break;
case AUDIT_GID:
case AUDIT_EGID:
@@ -482,10 +473,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
/* bit ops not implemented for gid comparisons */
if (f->op == Audit_bitmask || f->op == Audit_bittest)
goto exit_free;
-
f->gid = make_kgid(current_user_ns(), f->val);
- if (!gid_valid(f->gid))
- goto exit_free;
break;
case AUDIT_PID:
case AUDIT_PERS:
--
1.7.1
11 years, 7 months
pam_tty_audit icanon log switch
by Richard Guy Briggs
Hi folks,
There's been a couple of requests to add a switch to pam_tty_audit to
*not* log passwords when logging user commands.
Most commands are entered one line at a time and processed as complete
lines in non-canonical mode. Commands that interactively require a
password, enter canonical mode to do this. This feature (icanon) can be
used to avoid logging passwords by audit while still logging the rest of
the command.
Adding a member to the struct audit_tty_status passed in by
pam_tty_audit allows control of canonical mode per task.
Note: The original patch added a sysctl to control this system-wide,
which did work fine as expected, but it was recommended to keep the
switch with the module invocation, turning it into a per-task switch.
This method has also been tested.
Here are two patches, the first to pam to add the switch to
the pam_tty_audit module. The second is to the kernel to add the
necessary bits in audit and tty:
pam_tty_audit: add an option to control logging of passwords
tty: add an option to control logging of passwords with pam_tty_audit
Please have a quick look and with some initial feedback I'll post them
upstream. I'd normally use git send-email and in-line it, but since
they were patches for two different entities, thought it best to do it
this way instead.
- RGB
--
Richard Guy Briggs <rbriggs(a)redhat.com>
Senior Software Engineer
AMER ENG Base Operating Systems
Remote, Canada, Ottawa
Voice: 1.647.777.2635
Internal: (81) 32635
11 years, 7 months
Adding enterprise capability - an includeConfig directive for audit.rules?
by Burn Alting
All,
Has anyone considered allowing an includeConfig statement for
audit.rules (or auditd.conf if need be)?
The action would be to, at that point in the parse (or the end of the
file, if auditd.conf holds the directive), open the nominated directory
and any files within, and parse them.
The idea is to allow for localization of audit. At an enterprise level
one would deploy the common, corporate set of rules
in /etc/audit/audit.rules. Should a local system need additional rules
such as tailored file watches, workstation or capability specific
monitoring, these could appear in files in the includeConfig directory.
That way, distribution mechanisms such as puppet, rpm satellite server,
apt repositories, etc can maintain the corporate set of rules without
changing localized configurations on updates.
I'm happy to author this.
Regards
Burn Alting
11 years, 8 months
How to offer a patch
by Burn Alting
All,
I've made some mods to auditctl to allow it to read a directory of 'rule
files'. The idea is that within an enterprise, one would distribute a
standard /etc/audit/audit.rules which can be updated from the corporate
repository. Should a system require localized audit rules, then a
directory containing files of rules can be maintained locally. The
reasoning for a directory as opposed to just an additional file is to
offer granularity of 'rule sets'.
I would like to know the convention for patching to this list. Should I
git clone the svn repository then supply a git diff? Can I just provide
an old-fashioned diff -rupN or C_ALL=C TZ=UTC0 diff -Naur?
Regards
Burn Alting
11 years, 8 months
Re: [PATCH RFC] audit: provide namespace information in user originated records
by Eric W. Biederman
Adding the containers list so folks with container expertise can see
what is being proposed.
Aristeu Rozanski <arozansk(a)redhat.com> writes:
> This patchset introduces a new audit record to follow all USER records which
> provides namespace information of the process. The idea is to allow processes
> in containers to create records in the host system while providing means to be
> filtered out.
It looks like this mechanism makes it easy for an unprivileged program
to spam and overwhelm the audit log.
> For each new namespace, a unique procfs inode number is allocated and this
> number has been used by userspace to determine which processes belong to the
> same namespace. These numbers are used in the new audit record.
>
> Applications such as libvirt-sandbox and lxc can then report the same numbers
> when a container is created and destroyed allowing to map records to a certain
> container. Maybe the next step would be having a record for whenever a new
> namespace is created?
>
> First 6 patches are needed in order to get each namespace's inode number.
Grumble the existing methods can be used you don't have to introduce a
whole new set of methods. Grumble. Besides the bug of assuming that
the inodes now and forever will be the same across all instances of
proc.
> Patch 7 properly defines the new record that is related to the USER
> record
Not agmenting the current user records seems a little odd to me.
You also continue in this my current policy of not allowing any audit
records in the container itself, so I a don't quite know what the point
of all of this is.
> Patch 8 allows USER records to be generated from different namespaces
Which essentially allows any user to create any USER record they want
whenever they want.
> Here's an example of output:
> type=CRED_DISP msg=audit(1363528861.403:311): pid=20016 uid=0 auid=0 ses=45 subj=system_u:system_r:crond_t:s0-s0:c0.c1023 msg='op=PAM:setcred acct="root" exe="/usr/sbin/crond" hostname=? addr=? terminal=cron res=success'
Ok. This seems totally bizarre. You are running a container with a
user namespace with some uid mapped to uid 0?
That defeats about half the point of having user namespaces, as half the
files in the world are owned by uid 0, and can be written by uid 0
outside of your user namespace.
Hmm. I need to look at this in a little more detail but I believe our
use of task_pid_vnr here in the audit record is a long standing bug.
> type=UNKNOWN[1327] msg=audit(1363528861.403:311): mnt=4026531840 net=4026531956 uts=4026531838 ipc=4026531839 pid=4026531836 user=4026531837
>
> Notes:
> - this is a RFC, all sorts of feedback are much appreciated
> - while the last patch allows a new userns to send audit records, I haven't
> look yet on making sure it has proper capabilities so regular users'
> containers can create records
I don't think it does.
> - the record number allocated is just a draft. If this patchset evolves into
> something that can be merged, please advise which number number is the best
> choice
> - I'm not subscribed to the list, so please make sure I'm on the Cc list
>
> fs/namespace.c | 14 +++++++
> include/linux/ipc_namespace.h | 1
> include/linux/mnt_namespace.h | 2 +
> include/linux/pid_namespace.h | 1
> include/linux/user_namespace.h | 1
> include/linux/utsname.h | 1
> include/net/net_namespace.h | 1
> include/uapi/linux/audit.h | 1
> ipc/namespace.c | 14 +++++++
> kernel/audit.c | 76 +++++++++++++++++++++++++++++++++++++----
> kernel/pid_namespace.c | 11 +++++
> kernel/user_namespace.c | 5 ++
> kernel/utsname.c | 14 +++++++
> net/core/net_namespace.c | 14 +++++++
> 14 files changed, 150 insertions(+), 6 deletions(-)
11 years, 9 months
Thoughts on adding sd-journal as a log_format to auditd
by George McCollister
Recently I've been switching over my embedded distro to relying on
systemd for logging. The thought crossed my mind that it would be
convenient if auditd supported storing log information in systemd's
journal with the sd-journal API. It would be great if syslog data and
audit log data were stored in systemd's journal so common a interface
could be used to query, send alerts, generate reports, etc.
I suppose several different approaches could be taken:
1) Use audispd's builtin syslog plugin to send the events to syslog
which in my case would be systemd storing them to the journal. The
problem with this would be that all of the event information would be
stored in the message, it would be much more useful if each audit log
field resulted in a journal field.
2) Write an audispd plugin that used the sd-journal API to store
audit events in the journal.
3) Add sd-journal as a log format to auditd.
Does anyone have any thoughts/comments on why this would be either a
good or bad idea? Further more if I don't receive convincing arguments
why this shouldn't be I'll probably take a shot a write a patch to add
it, so any tips/suggestions relevant would be greatly appreciated.
Thanks,
George McCollister
11 years, 9 months