* Re: [PATCH V6 05/10] audit: log creation and deletion of namespace instances
From: Steve Grubb @ 2015-05-14 14:57 UTC (permalink / raw)
To: Richard Guy Briggs
Cc: containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA, eparis-FjpueFixGhCM4zKIHC2jIg,
pmoore-H+wXaHxf7aLQT0dZR+AlfA, arozansk-H+wXaHxf7aLQT0dZR+AlfA,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, serge-A9i7LUbDfNHQT0dZR+AlfA,
zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20150512195759.GA9832-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org>
On Tuesday, May 12, 2015 03:57:59 PM Richard Guy Briggs wrote:
> On 15/05/05, Steve Grubb wrote:
> > I think there needs to be some more discussion around this. It seems like
> > this is not exactly recording things that are useful for audit.
>
> It seems to me that either audit has to assemble that information, or
> the kernel has to do so. The kernel doesn't know about containers
> (yet?).
Auditing is something that has a lot of requirements imposed on it by security
standards. There was no requirement to have an auid until audit came along and
said that uid is not good enough to know who is issuing commands because of su
or sudo. There was no requirement for sessionid until we had to track each
action back to a login so we could see if the login came from the expected
place.
What I am saying is we have the same situation. Audit needs to track a
container and we need an ID. The information that is being logged is not
useful for auditing. Maybe someone wants that info in syslog, but I doubt it.
The audit trail's purpose is to allow a security officer to reconstruct the
events to determine what happened during some security incident.
What they would want to know is what resources were assigned; if two
containers shared a resource, what resource and container was it shared with;
if two containers can communicate, we need to see or control information flow
when necessary; and we need to see termination and release of resources.
Also, if the host OS cannot make sense of the information being logged because
the pid maps to another process name, or a uid maps to another user, or a file
access maps to something not in the host's, then we need the container to do
its own auditing and resolve these mappings and optionally pass these to an
aggregation server.
Nothing else makes sense.
> > On Friday, April 17, 2015 03:35:52 AM Richard Guy Briggs wrote:
> > > Log the creation and deletion of namespace instances in all 6 types of
> > > namespaces.
> > >
> > > Twelve new audit message types have been introduced:
> > > AUDIT_NS_INIT_MNT 1330 /* Record mount namespace instance
> > > creation
> > > */ AUDIT_NS_INIT_UTS 1331 /* Record UTS namespace instance
> > > creation */ AUDIT_NS_INIT_IPC 1332 /* Record IPC namespace
> > > instance creation */ AUDIT_NS_INIT_USER 1333 /* Record USER
> > > namespace instance creation */ AUDIT_NS_INIT_PID 1334 /* Record
> > > PID namespace instance creation */ AUDIT_NS_INIT_NET 1335 /*
> > > Record NET namespace instance creation */ AUDIT_NS_DEL_MNT 1336
> > > /* Record mount namespace instance deletion */ AUDIT_NS_DEL_UTS
> > > 1337
> > >
> > > /* Record UTS namespace instance deletion */ AUDIT_NS_DEL_IPC
> > >
> > > 1338 /* Record IPC namespace instance deletion */ AUDIT_NS_DEL_USER
> > >
> > > 1339 /* Record USER namespace instance deletion */ AUDIT_NS_DEL_PID
> > >
> > > 1340 /* Record PID namespace instance deletion */ AUDIT_NS_DEL_NET
> > >
> > > 1341 /* Record NET namespace instance deletion */
> >
> > The requirements for auditing of containers should be derived from VPP. In
> > it, it asks for selectable auditing, selective audit, and selective audit
> > review. What this means is that we need the container and all its
> > children to have one identifier that is inserted into all the events that
> > are associated with the container.
>
> Is that requirement for the records that are sent from the kernel, or
> for the records stored by auditd, or by another facility that delivers
> those records to a final consumer?
A little of both. Selective audit means that you can set rules to include or
exclude an event. This is done in the kernel. Selectable review means that the
user space tools need to be able to skip past records not of interest to a
specific line of inquiry. Also, logging everything and letting user space work
it out later is also not a solution because the needle is harder to find in a
larger haystack. Or, the logs may rotate and its gone forever because the
partition is filled.
> > With this, its possible to do a search for all events related to a
> > container. Its possible to exclude events from a container. Its possible
> > to not get any events.
> >
> > The requirements also call out for the identification of the subject. This
> > means that the event should be bound to a syscall such as clone, setns, or
> > unshare.
>
> Is it useful to have a reference of the init namespace set from which
> all others are spawned?
For things directly observable by the init name space, yes.
> If it isn't bound, I assume the subject should be added to the message
> format? I'm thinking of messages without an audit_context such as audit
> user messages (such as AUDIT_NS_INFO and AUDIT_VIRT_CONTROL).
Making these events auxiliary records to a syscall is all that is needed. The
same way that PATH is added to an open event. If someone wants to have
container/namespace events, they add a rule on clone(2).
> For now, we should not need to log namespaces with AUDIT_FEATURE_CHANGE
> or AUDIT_CONFIG_CHANGE messages since only initial user namespace with
> initial pid namespace has permission to do so. This will need to be
> addressed by having non-init config changes be limited to that container
> or set of namespaces and possibly its children. The other possibility
> is to add the subject to the stand-alone message.
>
> > Also, any user space events originating inside the container needs to have
> > the container ID added to the user space event - just like auid and
> > session id.
>
> This sounds like every task needs to record a container ID since that
> information is otherwise unknown by the kernel except by what might be
> provided by an audit user message such as AUDIT_VIRT_CONTROL or possibly
> the new AUDIT_NS_INFO request.
Right. The same as we record auid and ses on every event. We'll need a
container ID logged with everything. -1 for unset, meaning init namespace.
> It could be stored in struct task_struct or in struct audit_context. I
> don't have a suggestion on how to get that information securely into the
> kernel.
That is where I'd suggest. Its for audit subsystem needs.
> > Recording each instance of a name space is giving me something that I
> > cannot use to do queries required by the security target. Given these
> > events, how do I locate a web server event where it accesses a watched
> > file? That authentication failed? That an update within the container
> > failed?
> >
> > The requirements are that we have to log the creation, suspension,
> > migration, and termination of a container. The requirements are not on
> > the individual name space.
>
> Ok. Do we have a robust definition of a container?
We call the combination of name spaces, cgroups, and seccomp rules a
container.
> Where is that definition managed?
In the thing that invokes a container.
> If it is a userspace concept, then I think either userspace should be
> assembling this information, or providing that information to the entity
> that will be expected to know about and provide it.
Well, uid is a userspace concept, too. But we record an auid and keep it
immutable so that we can check enforcement of system security policy which is
also a user space concept. These things need to be collected to a place that
can be associated with events as needed. That place is the kernel.
> > Maybe I'm missing how these events give me that. But I'd like to hear how
> > I
> > would be able to meet requirements with these 12 events.
>
> Adding the infrastructure to give each of those 12 events an audit
> context to be able to give meaningful subject fields in audit records
> appears to require adding a struct task_struct argument to calls to
> copy_mnt_ns(), copy_utsname(), copy_ipcs(), copy_pid_ns(),
> copy_net_ns(), create_user_ns() unless I use current. I think we must
> use current since the userns is created before the spawned process is
> mature or has an audit context in the case of clone.
I think you are heading down the wrong path. We can tell from syscall flags
what is being done. Try this:
## Optional - log container creation
-a always,exit -F arch=b32 -S clone -F a0&0x7C020000 -F key=container-create
-a always,exit -F arch=b64 -S clone -F a0&0x7C020000 -F key=container-create
## Optional - watch for containers that may change their configuration
-a always,exit -F arch=b32 -S unshare,setns -F key=container-config
-a always,exit -F arch=b64 -S unshare,setns -F key=container-config
Then muck with containers, then use ausearch --start recent -k container -i. I
think you'll see that we know a bit about what's happening. What's needed is
the breadcrumb trail to tie future events back to the container so that we can
check for violations of host security policy.
> Either that, or I have mis-understood and I should be stashing this
> namespace ID information in an audit_aux_data structure or a more
> permanent part of struct audit_context to be printed when required on
> syscall exit. I'm trying to think through if it is needed in any
> non-syscall audit messages.
I think this is what is required. But we also have the issue where an event's
meaning can't be determined outside of a container. (For example, login,
account creation, password change, uid change, file access, etc.) So, I think
auditing needs to be local to the container for enrichment and ultimately
forwarded to an aggregating server.
-Steve
^ permalink raw reply
* [PATCH V7 10/10] audit: emit AUDIT_NS_INFO record with AUDIT_VIRT_CONTROL record
From: Richard Guy Briggs @ 2015-05-12 20:02 UTC (permalink / raw)
To: linux-audit, linux-kernel, containers
Cc: Richard Guy Briggs, sgrubb, eparis, pmoore, arozansk, ebiederm,
serge, zohar
In-Reply-To: <cover.1431451547.git.rgb@redhat.com>
Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
---
include/uapi/linux/audit.h | 2 ++
kernel/audit.c | 2 ++
2 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 55da5c7..e5cae10 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -163,6 +163,8 @@
#define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */
+#define AUDIT_VIRT_CONTROL 2500 /* Start, Pause, Stop VM */
+
/* Rule flags */
#define AUDIT_FILTER_USER 0x00 /* Apply rule to user-generated messages */
#define AUDIT_FILTER_TASK 0x01 /* Apply rule at task creation (not syscall) */
diff --git a/kernel/audit.c b/kernel/audit.c
index 97fcb64..3a16607 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -930,6 +930,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
}
audit_set_portid(ab, NETLINK_CB(skb).portid);
audit_log_end(ab);
+ if (msg_type == AUDIT_VIRT_CONTROL)
+ audit_log_ns_info(current);
mutex_lock(&audit_cmd_mutex);
}
break;
--
1.7.1
^ permalink raw reply related
* [PATCH V7 09/10] audit: log on switching namespace (setns)
From: Richard Guy Briggs @ 2015-05-12 20:02 UTC (permalink / raw)
To: linux-audit, linux-kernel, containers
Cc: Richard Guy Briggs, sgrubb, eparis, pmoore, arozansk, ebiederm,
serge, zohar
In-Reply-To: <cover.1431451547.git.rgb@redhat.com>
Added six new audit message types, AUDIT_NS_SET_* and function
audit_log_ns_set() to log a switch of namespace.
Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
---
include/linux/audit.h | 5 ++++
include/uapi/linux/audit.h | 6 +++++
kernel/audit.c | 51 ++++++++++++++++++++++++++++++++++++++++++++
kernel/nsproxy.c | 2 +
4 files changed, 64 insertions(+), 0 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index f922ea6..9adb538 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -490,6 +490,7 @@ extern void audit_log_ns_info(struct task_struct *tsk);
extern void audit_log_ns_init(int type, struct ns_common *old_ns,
struct ns_common *ns);
extern void audit_log_ns_del(int type, struct ns_common *ns);
+extern void audit_log_ns_set(struct ns_common *ns);
#else
static inline void audit_log_ns_info(struct task_struct *tsk)
{ }
@@ -498,6 +499,8 @@ static inline void audit_log_ns_init(int type, struct ns_common *old_ns,
{ }
static inline void audit_log_ns_del(int type, struct ns_common *ns)
{ }
+static inline void audit_log_ns_set(struct ns_common *ns)
+{ }
#endif
extern int audit_update_lsm_rules(void);
@@ -562,6 +565,8 @@ static inline void audit_log_ns_init(int type, struct ns_common *old_ns,
{ }
static inline void audit_log_ns_del(int type, struct ns_common *ns)
{ }
+static inline void audit_log_ns_set(struct ns_common *ns)
+{ }
#define audit_enabled 0
#endif /* CONFIG_AUDIT */
static inline void audit_log_string(struct audit_buffer *ab, const char *buf)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index c4b7f15..55da5c7 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -123,6 +123,12 @@
#define AUDIT_NS_DEL_USER 1339 /* Record USER namespace instance deletion */
#define AUDIT_NS_DEL_PID 1340 /* Record PID namespace instance deletion */
#define AUDIT_NS_DEL_NET 1341 /* Record NET namespace instance deletion */
+#define AUDIT_NS_SET_MNT 1342 /* Record mount namespace instance deletion */
+#define AUDIT_NS_SET_UTS 1343 /* Record UTS namespace instance deletion */
+#define AUDIT_NS_SET_IPC 1344 /* Record IPC namespace instance deletion */
+#define AUDIT_NS_SET_USER 1345 /* Record USER namespace instance deletion */
+#define AUDIT_NS_SET_PID 1346 /* Record PID namespace instance deletion */
+#define AUDIT_NS_SET_NET 1347 /* Record NET namespace instance deletion */
#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 af143b5..97fcb64 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2044,6 +2044,57 @@ void audit_log_ns_del(int type, struct ns_common *ns)
ns->inum);
audit_log_end(ab);
}
+
+/**
+ * audit_log_ns_set - report a namespace set change
+ * @ns: the new namespace
+ */
+void audit_log_ns_set(struct ns_common *ns)
+{
+ struct audit_buffer *ab;
+ struct ns_common *old_ns;
+ int msg_type;
+ char old_ns_s[16];
+
+ if (!audit_enabled)
+ return;
+
+ switch (ns->ops->type) {
+ case CLONE_NEWNS:
+ msg_type = AUDIT_NS_SET_MNT;
+ break;
+ case CLONE_NEWUTS:
+ msg_type = AUDIT_NS_SET_UTS;
+ break;
+ case CLONE_NEWIPC:
+ msg_type = AUDIT_NS_SET_IPC;
+ break;
+ case CLONE_NEWUSER:
+ msg_type = AUDIT_NS_SET_USER;
+ break;
+ case CLONE_NEWPID:
+ msg_type = AUDIT_NS_SET_PID;
+ break;
+ case CLONE_NEWNET:
+ msg_type = AUDIT_NS_SET_NET;
+ break;
+ default:
+ return;
+ }
+ ab = audit_log_start(current->audit_context, GFP_KERNEL, ns->ops->type);
+ if (unlikely(!ab))
+ return;
+ old_ns = ns->ops->get(current);
+ if (!old_ns->inum)
+ sprintf(old_ns_s, "(none)");
+ else
+ sprintf(old_ns_s, "%d", old_ns->inum);
+ audit_log_format(ab, " dev=%02x:%02x old_%sns=%s %sns=%d res=1",
+ MAJOR(ns->dev), MINOR(ns->dev), ns->ops->name,
+ old_ns_s, ns->ops->name, ns->inum);
+ ns->ops->put(old_ns);
+ audit_log_end(ab);
+}
#endif /* CONFIG_NAMESPACES */
/**
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index 49746c8..64147d0 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -25,6 +25,7 @@
#include <linux/proc_ns.h>
#include <linux/file.h>
#include <linux/syscalls.h>
+#include <linux/audit.h>
static struct kmem_cache *nsproxy_cachep;
@@ -246,6 +247,7 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype)
free_nsproxy(new_nsproxy);
goto out;
}
+ audit_log_ns_set(ns);
switch_task_namespaces(tsk, new_nsproxy);
out:
fput(file);
--
1.7.1
^ permalink raw reply related
* [PATCH V7 08/10] fork: audit on creation of new namespace(s) with clone and unshare
From: Richard Guy Briggs @ 2015-05-12 20:02 UTC (permalink / raw)
To: linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Cc: pmoore-H+wXaHxf7aLQT0dZR+AlfA, eparis-FjpueFixGhCM4zKIHC2jIg,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <cover.1431451547.git.rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
When clone(2) is called to fork a new process or unshare(2) creating one or
more namespaces, audit the event to tie the new pid with the namespace IDs.
Added the macro CLONE_NEW_MASK_ALL to refer to all CLONE_NEW* flags.
Cleaned up check_unshare_flags() to make it more readable using this new macro.
Signed-off-by: Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
include/uapi/linux/sched.h | 6 ++++++
kernel/fork.c | 13 +++++++++----
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/include/uapi/linux/sched.h b/include/uapi/linux/sched.h
index cc89dde..5f03ce9 100644
--- a/include/uapi/linux/sched.h
+++ b/include/uapi/linux/sched.h
@@ -28,6 +28,12 @@
#define CLONE_NEWUSER 0x10000000 /* New user namespace */
#define CLONE_NEWPID 0x20000000 /* New pid namespace */
#define CLONE_NEWNET 0x40000000 /* New network namespace */
+#define CLONE_NEW_MASK_ALL (CLONE_NEWNS \
+ | CLONE_NEWUTS \
+ | CLONE_NEWIPC \
+ | CLONE_NEWUSER \
+ | CLONE_NEWPID \
+ | CLONE_NEWNET) /* mask of all namespace type flags */
#define CLONE_IO 0x80000000 /* Clone io context */
/*
diff --git a/kernel/fork.c b/kernel/fork.c
index cf65139..c09c5df 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1680,6 +1680,9 @@ long do_fork(unsigned long clone_flags,
get_task_struct(p);
}
+ if (unlikely(clone_flags & CLONE_NEW_MASK_ALL))
+ audit_log_ns_info(p);
+
wake_up_new_task(p);
/* forking complete and child started to run, tell ptracer */
@@ -1802,10 +1805,9 @@ void __init proc_caches_init(void)
*/
static int check_unshare_flags(unsigned long unshare_flags)
{
- if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
- CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
- CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET|
- CLONE_NEWUSER|CLONE_NEWPID))
+ if (unshare_flags & ~(CLONE_THREAD | CLONE_FS | CLONE_SIGHAND |
+ CLONE_VM | CLONE_FILES | CLONE_SYSVSEM |
+ CLONE_NEW_MASK_ALL))
return -EINVAL;
/*
* Not implemented, but pretend it works if there is nothing to
@@ -1964,6 +1966,9 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
commit_creds(new_cred);
new_cred = NULL;
}
+
+ if (unshare_flags & CLONE_NEW_MASK_ALL)
+ audit_log_ns_info(current);
}
bad_unshare_cleanup_cred:
--
1.7.1
^ permalink raw reply related
* [PATCH V7 07/10] audit: dump namespace IDs for pid on receipt of AUDIT_NS_INFO
From: Richard Guy Briggs @ 2015-05-12 20:02 UTC (permalink / raw)
To: linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Cc: pmoore-H+wXaHxf7aLQT0dZR+AlfA, eparis-FjpueFixGhCM4zKIHC2jIg,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <cover.1431451547.git.rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
When a task with CAP_AUDIT_CONTROL sends a NETLINK_AUDIT message of type
UDIT_NS_INFO with a PID of interest formatted as pid_t as the first and only
data, dump the namespace IDs of that task to the audit log.
Signed-off-by: Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
kernel/audit.c | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index 229fd5a..af143b5 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -662,6 +662,7 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
case AUDIT_TTY_SET:
case AUDIT_TRIM:
case AUDIT_MAKE_EQUIV:
+ case AUDIT_NS_INFO:
/* Only support auditd and auditctl in initial pid namespace
* for now. */
if ((task_active_pid_ns(current) != &init_pid_ns))
@@ -1057,6 +1058,22 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
audit_log_end(ab);
break;
}
+ case AUDIT_NS_INFO:
+#ifdef CONFIG_NAMESPACES
+ {
+ struct task_struct *tsk;
+
+ rcu_read_lock();
+ tsk = find_task_by_vpid(*(pid_t *)data);
+ rcu_read_unlock();
+ if (tsk)
+ audit_log_ns_info(tsk);
+ else
+ err = -EINVAL;
+ }
+#else /* CONFIG_NAMESPACES */
+ err = -EOPNOTSUPP;
+#endif /* CONFIG_NAMESPACES */
default:
err = -EINVAL;
break;
--
1.7.1
^ permalink raw reply related
* [PATCH V7 06/10] audit: log creation and deletion of namespace instances
From: Richard Guy Briggs @ 2015-05-12 20:02 UTC (permalink / raw)
To: linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Cc: pmoore-H+wXaHxf7aLQT0dZR+AlfA, eparis-FjpueFixGhCM4zKIHC2jIg,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <cover.1431451547.git.rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Log the creation and deletion of namespace instances in all 6 types of
namespaces.
Twelve new audit message types have been introduced:
AUDIT_NS_INIT_MNT 1330 /* Record mount namespace instance creation */
AUDIT_NS_INIT_UTS 1331 /* Record UTS namespace instance creation */
AUDIT_NS_INIT_IPC 1332 /* Record IPC namespace instance creation */
AUDIT_NS_INIT_USER 1333 /* Record USER namespace instance creation */
AUDIT_NS_INIT_PID 1334 /* Record PID namespace instance creation */
AUDIT_NS_INIT_NET 1335 /* Record NET namespace instance creation */
AUDIT_NS_DEL_MNT 1336 /* Record mount namespace instance deletion */
AUDIT_NS_DEL_UTS 1337 /* Record UTS namespace instance deletion */
AUDIT_NS_DEL_IPC 1338 /* Record IPC namespace instance deletion */
AUDIT_NS_DEL_USER 1339 /* Record USER namespace instance deletion */
AUDIT_NS_DEL_PID 1340 /* Record PID namespace instance deletion */
AUDIT_NS_DEL_NET 1341 /* Record NET namespace instance deletion */
As suggested by Eric Paris, there are 12 message types, one for each of
creation and deletion, one for each type of namespace so that text searches are
easier in conjunction with the AUDIT_NS_INFO message type, being able to search
for all records such as "netns=7 " and to avoid fields disappearing per message
type to make ausearch more efficient.
A typical startup would look roughly like:
type=AUDIT_NS_INIT_UTS msg=audit(1408577534.868:5): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=kernel dev=00:03 old_utsns=(none) utsns=2 res=1
type=AUDIT_NS_INIT_USER msg=audit(1408577534.868:6): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=kernel dev=00:03 old_userns=(none) userns=3 res=1
type=AUDIT_NS_INIT_PID msg=audit(1408577534.868:7): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=kernel dev=00:03 old_pidns=(none) pidns=4 res=1
type=AUDIT_NS_INIT_MNT msg=audit(1408577534.868:8): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=kernel dev=00:03 old_mntns=(none) mntns=5 res=1
type=AUDIT_NS_INIT_IPC msg=audit(1408577534.868:9): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=kernel dev=00:03 old_ipcns=(none) ipcns=1 res=1
type=AUDIT_NS_INIT_NET msg=audit(1408577533.500:10): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=kernel dev=00:03 old_netns=(none) netns=7 res=1
And a CLONE action would result in:
type=type=AUDIT_NS_INIT_NET msg=audit(1408577535.306:81): pid=481 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 dev=00:03 old_netns=7 netns=8 res=1
While deleting a namespace would result in:
type=type=AUDIT_NS_DEL_MNT msg=audit(1408577552.221:85): pid=481 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 dev=00:03 mntns=5 res=1
If not "(none)", old_XXXns lists the namespace from which it was cloned.
Signed-off-by: Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
fs/namespace.c | 13 ++++++++
include/linux/audit.h | 14 ++++++++
include/uapi/linux/audit.h | 12 +++++++
ipc/namespace.c | 12 +++++++
kernel/audit.c | 73 ++++++++++++++++++++++++++++++++++++++++++++
kernel/pid_namespace.c | 12 +++++++
kernel/user_namespace.c | 12 +++++++
kernel/utsname.c | 11 ++++++
net/core/net_namespace.c | 11 ++++++
9 files changed, 170 insertions(+), 0 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index c680675..e583a7c 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -24,6 +24,7 @@
#include <linux/magic.h>
#include <linux/bootmem.h>
#include <linux/task_work.h>
+#include <linux/audit.h>
#include "pnode.h"
#include "internal.h"
@@ -2640,6 +2641,7 @@ dput_out:
static void free_mnt_ns(struct mnt_namespace *ns)
{
+ audit_log_ns_del(AUDIT_NS_DEL_MNT, &ns->ns);
ns_free_inum(&ns->ns);
put_user_ns(ns->user_ns);
kfree(ns);
@@ -2701,6 +2703,7 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
new_ns->ns.dev = ns->ns.dev;
if (IS_ERR(new_ns))
return new_ns;
+ audit_log_ns_init(AUDIT_NS_INIT_MNT, &ns->ns, &new_ns->ns);
namespace_lock();
/* First pass: copy the tree topology */
@@ -3013,6 +3016,16 @@ static void __init init_mount_tree(void)
set_fs_root(current->fs, &root);
}
+/* log the ID of init mnt namespace after audit service starts */
+static int __init mnt_ns_init_log(void)
+{
+ struct mnt_namespace *init_mnt_ns = init_task.nsproxy->mnt_ns;
+
+ audit_log_ns_init(AUDIT_NS_INIT_MNT, 0, &init_mnt_ns->ns);
+ return 0;
+}
+late_initcall(mnt_ns_init_log);
+
void __init mnt_init(void)
{
unsigned u;
diff --git a/include/linux/audit.h b/include/linux/audit.h
index acc4685..f922ea6 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -26,6 +26,7 @@
#include <linux/sched.h>
#include <linux/ptrace.h>
#include <uapi/linux/audit.h>
+#include <linux/proc_ns.h>
struct audit_sig_info {
uid_t uid;
@@ -486,9 +487,17 @@ extern void audit_log_task_info(struct audit_buffer *ab,
struct task_struct *tsk);
#ifdef CONFIG_NAMESPACES
extern void audit_log_ns_info(struct task_struct *tsk);
+extern void audit_log_ns_init(int type, struct ns_common *old_ns,
+ struct ns_common *ns);
+extern void audit_log_ns_del(int type, struct ns_common *ns);
#else
static inline void audit_log_ns_info(struct task_struct *tsk)
{ }
+static inline void audit_log_ns_init(int type, struct ns_common *old_ns,
+ struct ns_common *ns)
+{ }
+static inline void audit_log_ns_del(int type, struct ns_common *ns)
+{ }
#endif
extern int audit_update_lsm_rules(void);
@@ -548,6 +557,11 @@ static inline void audit_log_task_info(struct audit_buffer *ab,
{ }
static inline void audit_log_ns_info(struct task_struct *tsk)
{ }
+static inline void audit_log_ns_init(int type, struct ns_common *old_ns,
+ struct ns_common *ns)
+{ }
+static inline void audit_log_ns_del(int type, struct ns_common *ns)
+{ }
#define audit_enabled 0
#endif /* CONFIG_AUDIT */
static inline void audit_log_string(struct audit_buffer *ab, const char *buf)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 8eca5ae..c4b7f15 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -111,6 +111,18 @@
#define AUDIT_PROCTITLE 1327 /* Proctitle emit event */
#define AUDIT_FEATURE_CHANGE 1328 /* audit log listing feature changes */
#define AUDIT_NS_INFO 1329 /* Record process namespace IDs */
+#define AUDIT_NS_INIT_MNT 1330 /* Record mount namespace instance creation */
+#define AUDIT_NS_INIT_UTS 1331 /* Record UTS namespace instance creation */
+#define AUDIT_NS_INIT_IPC 1332 /* Record IPC namespace instance creation */
+#define AUDIT_NS_INIT_USER 1333 /* Record USER namespace instance creation */
+#define AUDIT_NS_INIT_PID 1334 /* Record PID namespace instance creation */
+#define AUDIT_NS_INIT_NET 1335 /* Record NET namespace instance creation */
+#define AUDIT_NS_DEL_MNT 1336 /* Record mount namespace instance deletion */
+#define AUDIT_NS_DEL_UTS 1337 /* Record UTS namespace instance deletion */
+#define AUDIT_NS_DEL_IPC 1338 /* Record IPC namespace instance deletion */
+#define AUDIT_NS_DEL_USER 1339 /* Record USER namespace instance deletion */
+#define AUDIT_NS_DEL_PID 1340 /* Record PID namespace instance deletion */
+#define AUDIT_NS_DEL_NET 1341 /* Record NET namespace instance deletion */
#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
diff --git a/ipc/namespace.c b/ipc/namespace.c
index b24da44..494ccd1 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -13,6 +13,7 @@
#include <linux/mount.h>
#include <linux/user_namespace.h>
#include <linux/proc_ns.h>
+#include <linux/audit.h>
#include "util.h"
@@ -43,6 +44,8 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
}
atomic_inc(&nr_ipc_ns);
+ audit_log_ns_init(AUDIT_NS_INIT_IPC, &old_ns->ns, &ns->ns);
+
sem_init_ns(ns);
msg_init_ns(ns);
shm_init_ns(ns);
@@ -99,6 +102,7 @@ static void free_ipc_ns(struct ipc_namespace *ns)
atomic_dec(&nr_ipc_ns);
put_user_ns(ns->user_ns);
+ audit_log_ns_del(AUDIT_NS_DEL_IPC, &ns->ns);
ns_free_inum(&ns->ns);
kfree(ns);
}
@@ -174,3 +178,11 @@ const struct proc_ns_operations ipcns_operations = {
.put = ipcns_put,
.install = ipcns_install,
};
+
+/* log the ID of init IPC namespace after audit service starts */
+static int __init ipc_namespaces_init(void)
+{
+ audit_log_ns_init(AUDIT_NS_INIT_IPC, 0, &init_ipc_ns.ns);
+ return 0;
+}
+late_initcall(ipc_namespaces_init);
diff --git a/kernel/audit.c b/kernel/audit.c
index 81ffa5b..229fd5a 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1956,6 +1956,79 @@ out:
kfree(name);
}
+#ifdef CONFIG_NAMESPACES
+static char *ns_name[] = {
+ "mnt",
+ "uts",
+ "ipc",
+ "user",
+ "pid",
+ "net",
+};
+
+/**
+ * audit_log_ns_init - report a namespace instance creation
+ * @type: type of audit namespace instance created message
+ * @old_ns: the ns_common of the cloned namespace instance
+ * @ns: the ns_common of the new namespace instance
+ */
+void audit_log_ns_init(int type, struct ns_common *old_ns, struct ns_common *ns)
+{
+ struct audit_buffer *ab;
+ char *audit_ns_name = ns_name[type - AUDIT_NS_INIT_MNT];
+ char old_ns_s[16];
+
+ if (!audit_enabled)
+ return;
+
+ if (type < AUDIT_NS_INIT_MNT || type > AUDIT_NS_INIT_NET) {
+ WARN(1, "audit_log_ns_init: type:%d out of range", type);
+ return;
+ }
+ if (!ns) {
+ WARN(1, "ns should not be NULL");
+ return;
+ }
+ if (!old_ns || !old_ns->inum)
+ sprintf(old_ns_s, "(none)");
+ else
+ sprintf(old_ns_s, "%d", old_ns->inum);
+ ab = audit_log_start(current->audit_context, GFP_KERNEL, type);
+ if (unlikely(!ab))
+ return;
+ audit_log_format(ab, "dev=%02x:%02x old_%sns=%s %sns=%d res=1",
+ MAJOR(ns->dev), MINOR(ns->dev), audit_ns_name, old_ns_s,
+ audit_ns_name, ns->inum);
+ audit_log_end(ab);
+}
+
+/**
+ * audit_log_ns_del - report a namespace instance deleted
+ * @type: type of audit namespace instance deleted message
+ * @ns: the ns_common of the namespace instance
+ */
+void audit_log_ns_del(int type, struct ns_common *ns)
+{
+ struct audit_buffer *ab;
+ char *audit_ns_name = ns_name[type - AUDIT_NS_DEL_MNT];
+
+ if (!audit_enabled)
+ return;
+
+ if (type < AUDIT_NS_DEL_MNT || type > AUDIT_NS_DEL_NET) {
+ WARN(1, "audit_log_ns_del: type:%d out of range", type);
+ return;
+ }
+ ab = audit_log_start(current->audit_context, GFP_KERNEL, type);
+ if (unlikely(!ab))
+ return;
+ audit_log_format(ab, "dev=%02x:%02x %sns=%d res=1",
+ MAJOR(ns->dev), MINOR(ns->dev), audit_ns_name,
+ ns->inum);
+ audit_log_end(ab);
+}
+#endif /* CONFIG_NAMESPACES */
+
/**
* audit_log_end - end one audit record
* @ab: the audit_buffer
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
index 691b9ac..21cffe1 100644
--- a/kernel/pid_namespace.c
+++ b/kernel/pid_namespace.c
@@ -18,6 +18,7 @@
#include <linux/proc_ns.h>
#include <linux/reboot.h>
#include <linux/export.h>
+#include <linux/audit.h>
struct pid_cache {
int nr_ids;
@@ -111,6 +112,8 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns
ns->ns.dev = parent_pid_ns->ns.dev;
ns->ns.ops = &pidns_operations;
+ audit_log_ns_init(AUDIT_NS_INIT_PID, &parent_pid_ns->ns, &ns->ns);
+
kref_init(&ns->kref);
ns->level = level;
ns->parent = get_pid_ns(parent_pid_ns);
@@ -144,6 +147,7 @@ static void destroy_pid_namespace(struct pid_namespace *ns)
{
int i;
+ audit_log_ns_del(AUDIT_NS_DEL_PID, &ns->ns);
ns_free_inum(&ns->ns);
for (i = 0; i < PIDMAP_ENTRIES; i++)
kfree(ns->pidmap[i].page);
@@ -408,3 +412,11 @@ static __init int pid_namespaces_init(void)
}
__initcall(pid_namespaces_init);
+
+/* log the ID of init PID namespace after audit service starts */
+static __init int pid_namespaces_late_init(void)
+{
+ audit_log_ns_init(AUDIT_NS_INIT_PID, 0, &init_pid_ns.ns);
+ return 0;
+}
+late_initcall(pid_namespaces_late_init);
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index ec29cd9..2dbf601 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -22,6 +22,7 @@
#include <linux/ctype.h>
#include <linux/projid.h>
#include <linux/fs_struct.h>
+#include <linux/audit.h>
static struct kmem_cache *user_ns_cachep __read_mostly;
static DEFINE_MUTEX(userns_state_mutex);
@@ -95,6 +96,8 @@ int create_user_ns(struct cred *new)
ns->ns.dev = parent_ns->ns.dev;
ns->ns.ops = &userns_operations;
+ audit_log_ns_init(AUDIT_NS_INIT_USER, &parent_ns->ns, &ns->ns);
+
atomic_set(&ns->count, 1);
/* Leave the new->user_ns reference with the new user namespace. */
ns->parent = parent_ns;
@@ -144,6 +147,7 @@ void free_user_ns(struct user_namespace *ns)
#ifdef CONFIG_PERSISTENT_KEYRINGS
key_put(ns->persistent_keyring_register);
#endif
+ audit_log_ns_del(AUDIT_NS_DEL_USER, &ns->ns);
ns_free_inum(&ns->ns);
kmem_cache_free(user_ns_cachep, ns);
ns = parent;
@@ -1011,3 +1015,11 @@ static __init int user_namespaces_init(void)
return 0;
}
subsys_initcall(user_namespaces_init);
+
+/* log the ID of init user namespace after audit service starts */
+static __init int user_namespaces_late_init(void)
+{
+ audit_log_ns_init(AUDIT_NS_INIT_USER, 0, &init_user_ns.ns);
+ return 0;
+}
+late_initcall(user_namespaces_late_init);
diff --git a/kernel/utsname.c b/kernel/utsname.c
index 54c45e1..c987ee6 100644
--- a/kernel/utsname.c
+++ b/kernel/utsname.c
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/user_namespace.h>
#include <linux/proc_ns.h>
+#include <linux/audit.h>
static struct uts_namespace *create_uts_ns(void)
{
@@ -50,6 +51,7 @@ static struct uts_namespace *clone_uts_ns(struct user_namespace *user_ns,
ns->ns.dev = old_ns->ns.dev;
ns->ns.ops = &utsns_operations;
+ audit_log_ns_init(AUDIT_NS_INIT_UTS, &old_ns->ns, &ns->ns);
down_read(&uts_sem);
memcpy(&ns->name, &old_ns->name, sizeof(ns->name));
@@ -87,6 +89,7 @@ void free_uts_ns(struct kref *kref)
ns = container_of(kref, struct uts_namespace, kref);
put_user_ns(ns->user_ns);
+ audit_log_ns_del(AUDIT_NS_DEL_UTS, &ns->ns);
ns_free_inum(&ns->ns);
kfree(ns);
}
@@ -138,3 +141,11 @@ const struct proc_ns_operations utsns_operations = {
.put = utsns_put,
.install = utsns_install,
};
+
+/* log the ID of init UTS namespace after audit service starts */
+static int __init uts_namespaces_init(void)
+{
+ audit_log_ns_init(AUDIT_NS_INIT_UTS, 0, &init_uts_ns.ns);
+ return 0;
+}
+late_initcall(uts_namespaces_init);
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index a706cdd..38d6265 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -21,6 +21,7 @@
#include <net/netlink.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
+#include <linux/audit.h>
/*
* Our network namespace constructor/destructor lists
@@ -333,6 +334,7 @@ struct net *copy_net_ns(unsigned long flags,
rv = setup_net(net, user_ns);
if (rv == 0) {
net->ns.dev = old_net->ns.dev;
+ audit_log_ns_init(AUDIT_NS_INIT_NET, &old_net->ns, &net->ns);
rtnl_lock();
list_add_tail_rcu(&net->list, &net_namespace_list);
rtnl_unlock();
@@ -483,6 +485,7 @@ static __net_init int net_ns_net_init(struct net *net)
static __net_exit void net_ns_net_exit(struct net *net)
{
+ audit_log_ns_del(AUDIT_NS_DEL_NET, &net->ns);
ns_free_inum(&net->ns);
}
@@ -657,6 +660,14 @@ static int __init net_ns_init(void)
pure_initcall(net_ns_init);
+/* log the ID of init_net namespace after audit service starts */
+static int __init net_ns_init_log(void)
+{
+ audit_log_ns_init(AUDIT_NS_INIT_NET, 0, &init_net.ns);
+ return 0;
+}
+late_initcall(net_ns_init_log);
+
#ifdef CONFIG_NET_NS
static int __register_pernet_operations(struct list_head *list,
struct pernet_operations *ops)
--
1.7.1
^ permalink raw reply related
* [PATCH V7 05/10] audit: initialize at subsystem time rather than device time
From: Richard Guy Briggs @ 2015-05-12 20:02 UTC (permalink / raw)
To: linux-audit, linux-kernel, containers
Cc: Richard Guy Briggs, sgrubb, eparis, pmoore, arozansk, ebiederm,
serge, zohar
In-Reply-To: <cover.1431451547.git.rgb@redhat.com>
The audit subsystem should be initialized a bit earlier so that it is in place
in time for initial namespace ID number logging.
Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
---
kernel/audit.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index 25d6719..81ffa5b 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1175,7 +1175,7 @@ static int __init audit_init(void)
return 0;
}
-__initcall(audit_init);
+subsys_initcall(audit_init);
/* Process kernel command-line parameter at boot time. audit=0 or audit=1. */
static int __init audit_enable(char *str)
--
1.7.1
^ permalink raw reply related
* [PATCH V7 04/10] audit: log namespace ID numbers
From: Richard Guy Briggs @ 2015-05-12 20:02 UTC (permalink / raw)
To: linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Cc: pmoore-H+wXaHxf7aLQT0dZR+AlfA, eparis-FjpueFixGhCM4zKIHC2jIg,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <cover.1431451547.git.rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Log the namespace identifiers (nsfs device ID and inode) of a task in a new
record type (1329) (usually accompanies audit_log_task_info() type=SYSCALL
record) which is used by syscall audits, among others..
Idea first presented:
https://www.redhat.com/archives/linux-audit/2013-March/msg00020.html
Typical output format would look something like:
type=NS_INFO msg=audit(1408577535.306:82): pid=374 dev=00:03 netns=7 utsns=2 ipcns=1 pidns=4 userns=3 mntns=5
Suggested-by: Aristeu Rozanski <arozansk-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Acked-by: Serge Hallyn <serge.hallyn-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
---
include/linux/audit.h | 8 ++++++++
include/uapi/linux/audit.h | 1 +
kernel/audit.c | 35 +++++++++++++++++++++++++++++++++++
kernel/auditsc.c | 2 ++
security/integrity/ima/ima_api.c | 2 ++
5 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index c2e7e3a..acc4685 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -484,6 +484,12 @@ static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
extern int audit_log_task_context(struct audit_buffer *ab);
extern void audit_log_task_info(struct audit_buffer *ab,
struct task_struct *tsk);
+#ifdef CONFIG_NAMESPACES
+extern void audit_log_ns_info(struct task_struct *tsk);
+#else
+static inline void audit_log_ns_info(struct task_struct *tsk)
+{ }
+#endif
extern int audit_update_lsm_rules(void);
@@ -540,6 +546,8 @@ static inline int audit_log_task_context(struct audit_buffer *ab)
static inline void audit_log_task_info(struct audit_buffer *ab,
struct task_struct *tsk)
{ }
+static inline void audit_log_ns_info(struct task_struct *tsk)
+{ }
#define audit_enabled 0
#endif /* CONFIG_AUDIT */
static inline void audit_log_string(struct audit_buffer *ab, const char *buf)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index d3475e1..8eca5ae 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -110,6 +110,7 @@
#define AUDIT_SECCOMP 1326 /* Secure Computing event */
#define AUDIT_PROCTITLE 1327 /* Proctitle emit event */
#define AUDIT_FEATURE_CHANGE 1328 /* audit log listing feature changes */
+#define AUDIT_NS_INFO 1329 /* Record process namespace IDs */
#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 72ab759..25d6719 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -65,6 +65,7 @@
#include <linux/freezer.h>
#include <linux/tty.h>
#include <linux/pid_namespace.h>
+#include <linux/proc_ns.h>
#include <net/netns/generic.h>
#include "audit.h"
@@ -1642,6 +1643,38 @@ void audit_log_session_info(struct audit_buffer *ab)
audit_log_format(ab, " auid=%u ses=%u", auid, sessionid);
}
+#ifdef CONFIG_NAMESPACES
+void audit_log_ns_info(struct task_struct *tsk)
+{
+ const struct proc_ns_operations **entry;
+ bool end = false;
+ struct audit_buffer *ab;
+ int devprinted = 0;
+
+ if (!audit_enabled || !tsk)
+ return;
+ ab = audit_log_start(current->audit_context, GFP_KERNEL,
+ AUDIT_NS_INFO);
+ if (!ab)
+ return;
+ audit_log_format(ab, "pid=%d", task_pid_nr(tsk));
+ for (entry = ns_entries; !end; entry++) {
+ struct ns_common *ns = (*entry)->get(tsk);
+
+ if (!devprinted) {
+ audit_log_format(ab, " dev=%02x:%02x", MAJOR(ns->dev),
+ MINOR(ns->dev));
+ devprinted = 1;
+ }
+ audit_log_format(ab, " %sns=%d", (*entry)->name,
+ ns->inum);
+ (*entry)->put(ns);
+ end = (*entry)->type == CLONE_NEWNS;
+ }
+ audit_log_end(ab);
+}
+#endif /* CONFIG_NAMESPACES */
+
void audit_log_key(struct audit_buffer *ab, char *key)
{
audit_log_format(ab, " key=");
@@ -1913,6 +1946,8 @@ void audit_log_link_denied(const char *operation, struct path *link)
audit_log_format(ab, " res=0");
audit_log_end(ab);
+ audit_log_ns_info(current);
+
/* Generate AUDIT_PATH record with object. */
name->type = AUDIT_TYPE_NORMAL;
audit_copy_inode(name, link->dentry, link->dentry->d_inode);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index dc4ae70..dae61fe 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1355,6 +1355,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
audit_log_key(ab, context->filterkey);
audit_log_end(ab);
+ audit_log_ns_info(tsk);
+
for (aux = context->aux; aux; aux = aux->next) {
ab = audit_log_start(context, GFP_KERNEL, aux->type);
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index b8a27c5..1fde0bf 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -317,6 +317,8 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
audit_log_task_info(ab, current);
audit_log_end(ab);
+ audit_log_ns_info(current);
+
iint->flags |= IMA_AUDITED;
}
--
1.7.1
^ permalink raw reply related
* [PATCH V7 03/10] nsfs: add nsfs device ID to ns_common
From: Richard Guy Briggs @ 2015-05-12 20:02 UTC (permalink / raw)
To: linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Cc: pmoore-H+wXaHxf7aLQT0dZR+AlfA, eparis-FjpueFixGhCM4zKIHC2jIg,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <cover.1431451547.git.rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
For speed and convenience of look-up, the nsfs device ID is looked up for the
first instance of a type of namespace, then copied to others of the same type
as they are spawned.
Signed-off-by: Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
fs/namespace.c | 2 ++
fs/nsfs.c | 21 +++++++++++++++++++++
include/linux/ns_common.h | 1 +
include/linux/proc_ns.h | 1 +
ipc/namespace.c | 1 +
kernel/pid_namespace.c | 1 +
kernel/user_namespace.c | 1 +
kernel/utsname.c | 1 +
net/core/net_namespace.c | 2 ++
9 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index 82ef140..c680675 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2698,6 +2698,7 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
old = ns->root;
new_ns = alloc_mnt_ns(user_ns);
+ new_ns->ns.dev = ns->ns.dev;
if (IS_ERR(new_ns))
return new_ns;
@@ -2762,6 +2763,7 @@ static struct mnt_namespace *create_mnt_ns(struct vfsmount *m)
struct mount *mnt = real_mount(m);
mnt->mnt_ns = new_ns;
new_ns->root = mnt;
+ new_ns->ns.dev = nsfs_dev();
list_add(&mnt->mnt_list, &new_ns->list);
} else {
mntput(m);
diff --git a/fs/nsfs.c b/fs/nsfs.c
index 1fcd529..cc785d3 100644
--- a/fs/nsfs.c
+++ b/fs/nsfs.c
@@ -4,6 +4,10 @@
#include <linux/proc_ns.h>
#include <linux/magic.h>
#include <linux/ktime.h>
+#include <linux/init_task.h>
+#include <linux/utsname.h>
+#include <linux/pid_namespace.h>
+#include <linux/ipc_namespace.h>
static struct vfsmount *nsfs_mnt;
@@ -158,6 +162,23 @@ void __init nsfs_init(void)
if (IS_ERR(nsfs_mnt))
panic("can't set nsfs up\n");
nsfs_mnt->mnt_sb->s_flags &= ~MS_NOUSER;
+ init_ipc_ns.ns.dev = init_uts_ns.ns.dev = init_pid_ns.ns.dev
+ = init_user_ns.ns.dev = nsfs_dev();
+}
+
+dev_t nsfs_dev(void)
+{
+ dev_t dev;
+
+ void nssb_to_dev(struct super_block *sb, void *arg){
+ dev_t *dev = arg;
+
+ if (sb->s_magic == NSFS_MAGIC)
+ *dev = sb->s_dev;
+ }
+
+ iterate_supers(nssb_to_dev, (void*)&dev);
+ return dev;
}
static DEFINE_IDA(ns_inum_ida);
diff --git a/include/linux/ns_common.h b/include/linux/ns_common.h
index 85a5c8c..6701070 100644
--- a/include/linux/ns_common.h
+++ b/include/linux/ns_common.h
@@ -7,6 +7,7 @@ struct ns_common {
atomic_long_t stashed;
const struct proc_ns_operations *ops;
unsigned int inum;
+ dev_t dev;
};
#endif
diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h
index 721d0e2..904d9e7 100644
--- a/include/linux/proc_ns.h
+++ b/include/linux/proc_ns.h
@@ -71,4 +71,5 @@ extern int ns_get_name(char *buf, size_t size, struct task_struct *task,
const struct proc_ns_operations *ns_ops);
extern void nsfs_init(void);
+extern dev_t nsfs_dev(void);
#endif /* _LINUX_PROC_NS_H */
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 068caf1..b24da44 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -31,6 +31,7 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
kfree(ns);
return ERR_PTR(err);
}
+ ns->ns.dev = old_ns->ns.dev;
ns->ns.ops = &ipcns_operations;
atomic_set(&ns->count, 1);
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
index a65ba13..691b9ac 100644
--- a/kernel/pid_namespace.c
+++ b/kernel/pid_namespace.c
@@ -108,6 +108,7 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns
err = ns_alloc_inum(&ns->ns);
if (err)
goto out_free_map;
+ ns->ns.dev = parent_pid_ns->ns.dev;
ns->ns.ops = &pidns_operations;
kref_init(&ns->kref);
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 4109f83..ec29cd9 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -92,6 +92,7 @@ int create_user_ns(struct cred *new)
kmem_cache_free(user_ns_cachep, ns);
return ret;
}
+ ns->ns.dev = parent_ns->ns.dev;
ns->ns.ops = &userns_operations;
atomic_set(&ns->count, 1);
diff --git a/kernel/utsname.c b/kernel/utsname.c
index 831ea71..54c45e1 100644
--- a/kernel/utsname.c
+++ b/kernel/utsname.c
@@ -48,6 +48,7 @@ static struct uts_namespace *clone_uts_ns(struct user_namespace *user_ns,
return ERR_PTR(err);
}
+ ns->ns.dev = old_ns->ns.dev;
ns->ns.ops = &utsns_operations;
down_read(&uts_sem);
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 70d3450..a706cdd 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -332,6 +332,7 @@ struct net *copy_net_ns(unsigned long flags,
mutex_lock(&net_mutex);
rv = setup_net(net, user_ns);
if (rv == 0) {
+ net->ns.dev = old_net->ns.dev;
rtnl_lock();
list_add_tail_rcu(&net->list, &net_namespace_list);
rtnl_unlock();
@@ -639,6 +640,7 @@ static int __init net_ns_init(void)
if (setup_net(&init_net, &init_user_ns))
panic("Could not setup the initial network namespace");
+ init_net.ns.dev = nsfs_dev();
rtnl_lock();
list_add_tail_rcu(&init_net.list, &net_namespace_list);
rtnl_unlock();
--
1.7.1
^ permalink raw reply related
* [PATCH V7 02/10] nsfs: switch to dedicated inode pool
From: Richard Guy Briggs @ 2015-05-12 20:02 UTC (permalink / raw)
To: linux-audit, linux-kernel, containers
Cc: Richard Guy Briggs, sgrubb, eparis, pmoore, arozansk, ebiederm,
serge, zohar
In-Reply-To: <cover.1431451547.git.rgb@redhat.com>
Instead of borrowing proc's inode pool and starting at a custom offset, give
nsfs its own dedicated inode pool without an offset.
Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
---
fs/nsfs.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
fs/proc/internal.h | 2 ++
include/linux/proc_ns.h | 20 ++++++++------------
init/version.c | 2 +-
ipc/msgutil.c | 2 +-
kernel/pid.c | 2 +-
kernel/user.c | 2 +-
7 files changed, 58 insertions(+), 16 deletions(-)
diff --git a/fs/nsfs.c b/fs/nsfs.c
index af1b24f..1fcd529 100644
--- a/fs/nsfs.c
+++ b/fs/nsfs.c
@@ -159,3 +159,47 @@ void __init nsfs_init(void)
panic("can't set nsfs up\n");
nsfs_mnt->mnt_sb->s_flags &= ~MS_NOUSER;
}
+
+static DEFINE_IDA(ns_inum_ida);
+static DEFINE_SPINLOCK(ns_inum_lock); /* protects the above */
+
+/*
+ * Return an inode number between PROC_DYNAMIC_FIRST and
+ * 0xffffffff, or zero on failure.
+ */
+int ns_alloc_inum(struct ns_common *ns)
+{
+ unsigned int i;
+ int error;
+
+ atomic_long_set(&ns->stashed, 0);
+retry:
+ if (!ida_pre_get(&ns_inum_ida, GFP_KERNEL))
+ return -ENOMEM;
+
+ spin_lock_irq(&ns_inum_lock);
+ error = ida_get_new(&ns_inum_ida, &i);
+ spin_unlock_irq(&ns_inum_lock);
+ if (error == -EAGAIN)
+ goto retry;
+ else if (error)
+ return error;
+
+ if (i > UINT_MAX) {
+ spin_lock_irq(&ns_inum_lock);
+ ida_remove(&ns_inum_ida, i);
+ spin_unlock_irq(&ns_inum_lock);
+ return -ENOSPC;
+ }
+ ns->inum = NS_DYNAMIC_FIRST + i;
+ return 0;
+}
+
+void ns_free_inum(struct ns_common *ns)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&ns_inum_lock, flags);
+ ida_remove(&ns_inum_ida, ns->inum - NS_DYNAMIC_FIRST);
+ spin_unlock_irqrestore(&ns_inum_lock, flags);
+}
+
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index c835b94..8f89cbb 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -18,6 +18,8 @@
struct ctl_table_header;
struct mempolicy;
+#define PROC_ROOT_INO 1
+
/*
* This is not completely implemented yet. The idea is to
* create an in-memory tree (like the actual /proc filesystem
diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h
index 2654550..721d0e2 100644
--- a/include/linux/proc_ns.h
+++ b/include/linux/proc_ns.h
@@ -30,11 +30,12 @@ extern const struct proc_ns_operations *ns_entries[];
* We always define these enumerators
*/
enum {
- PROC_ROOT_INO = 1,
- PROC_IPC_INIT_INO = 0xEFFFFFFFU,
- PROC_UTS_INIT_INO = 0xEFFFFFFEU,
- PROC_USER_INIT_INO = 0xEFFFFFFDU,
- PROC_PID_INIT_INO = 0xEFFFFFFCU,
+ NS_NULL_INIT_INO,
+ NS_IPC_INIT_INO,
+ NS_UTS_INIT_INO,
+ NS_USER_INIT_INO,
+ NS_PID_INIT_INO,
+ NS_DYNAMIC_FIRST,
};
#ifdef CONFIG_PROC_FS
@@ -58,13 +59,8 @@ static inline void proc_free_inum(unsigned int inum) {}
#endif /* CONFIG_PROC_FS */
-static inline int ns_alloc_inum(struct ns_common *ns)
-{
- atomic_long_set(&ns->stashed, 0);
- return proc_alloc_inum(&ns->inum);
-}
-
-#define ns_free_inum(ns) proc_free_inum((ns)->inum)
+extern int ns_alloc_inum(struct ns_common *ns);
+extern void ns_free_inum(struct ns_common *ns);
extern struct file *proc_ns_fget(int fd);
#define get_proc_ns(inode) ((struct ns_common *)(inode)->i_private)
diff --git a/init/version.c b/init/version.c
index fe41a63..050dda0 100644
--- a/init/version.c
+++ b/init/version.c
@@ -35,7 +35,7 @@ struct uts_namespace init_uts_ns = {
.domainname = UTS_DOMAINNAME,
},
.user_ns = &init_user_ns,
- .ns.inum = PROC_UTS_INIT_INO,
+ .ns.inum = NS_UTS_INIT_INO,
#ifdef CONFIG_UTS_NS
.ns.ops = &utsns_operations,
#endif
diff --git a/ipc/msgutil.c b/ipc/msgutil.c
index 2b49159..aca24bb 100644
--- a/ipc/msgutil.c
+++ b/ipc/msgutil.c
@@ -31,7 +31,7 @@ DEFINE_SPINLOCK(mq_lock);
struct ipc_namespace init_ipc_ns = {
.count = ATOMIC_INIT(1),
.user_ns = &init_user_ns,
- .ns.inum = PROC_IPC_INIT_INO,
+ .ns.inum = NS_IPC_INIT_INO,
#ifdef CONFIG_IPC_NS
.ns.ops = &ipcns_operations,
#endif
diff --git a/kernel/pid.c b/kernel/pid.c
index cd36a5e..a06abc2 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -79,7 +79,7 @@ struct pid_namespace init_pid_ns = {
.level = 0,
.child_reaper = &init_task,
.user_ns = &init_user_ns,
- .ns.inum = PROC_PID_INIT_INO,
+ .ns.inum = NS_PID_INIT_INO,
#ifdef CONFIG_PID_NS
.ns.ops = &pidns_operations,
#endif
diff --git a/kernel/user.c b/kernel/user.c
index b069ccb..deaf107 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -50,7 +50,7 @@ struct user_namespace init_user_ns = {
.count = ATOMIC_INIT(3),
.owner = GLOBAL_ROOT_UID,
.group = GLOBAL_ROOT_GID,
- .ns.inum = PROC_USER_INIT_INO,
+ .ns.inum = NS_USER_INIT_INO,
#ifdef CONFIG_USER_NS
.ns.ops = &userns_operations,
#endif
--
1.7.1
^ permalink raw reply related
* [PATCH V7 01/10] namespaces: expose ns_entries
From: Richard Guy Briggs @ 2015-05-12 20:02 UTC (permalink / raw)
To: linux-audit, linux-kernel, containers
Cc: Richard Guy Briggs, sgrubb, eparis, pmoore, arozansk, ebiederm,
serge, zohar
In-Reply-To: <cover.1431451547.git.rgb@redhat.com>
Expose ns_entries so subsystems other than proc can use this set of namespace
operations.
Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
---
fs/proc/namespaces.c | 2 +-
include/linux/proc_ns.h | 1 +
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c
index c9eac45..41da5f1 100644
--- a/fs/proc/namespaces.c
+++ b/fs/proc/namespaces.c
@@ -11,7 +11,7 @@
#include "internal.h"
-static const struct proc_ns_operations *ns_entries[] = {
+const struct proc_ns_operations *ns_entries[] = {
#ifdef CONFIG_NET_NS
&netns_operations,
#endif
diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h
index 42dfc61..2654550 100644
--- a/include/linux/proc_ns.h
+++ b/include/linux/proc_ns.h
@@ -24,6 +24,7 @@ extern const struct proc_ns_operations ipcns_operations;
extern const struct proc_ns_operations pidns_operations;
extern const struct proc_ns_operations userns_operations;
extern const struct proc_ns_operations mntns_operations;
+extern const struct proc_ns_operations *ns_entries[];
/*
* We always define these enumerators
--
1.7.1
^ permalink raw reply related
* [PATCH V7 00/10] namespaces: log namespaces per task
From: Richard Guy Briggs @ 2015-05-12 20:02 UTC (permalink / raw)
To: linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Cc: pmoore-H+wXaHxf7aLQT0dZR+AlfA, eparis-FjpueFixGhCM4zKIHC2jIg,
sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
ebiederm-aS9lmoZGLiVWk0Htik3J/w
The purpose is to track namespace instances in use by logged processes from the
perspective of init_*_ns by logging the namespace IDs (namespace device ID and
namespace inode).
1/10 exposes proc's ns entries structure which lists a number of useful
operations per namespace type for other subsystems to use.
2/10 creates and switches to a dedicated inode pool for the namespace
filesystem.
3/10 add the nsfs device ID to ns_common for each namespace instance for quick
access.
4/10 provides an example of usage for audit_log_task_info() which is used by
syscall audits, among others.
Proposed output format:
This differs slightly from Aristeu's patch because of the label conflict with
"pid=" due to including it in existing records rather than it being a seperate
record. "pid=" here is the target pid for a potentially unactivated task for
which the nsproxy has been created. It has now returned to being a seperate
record. The nsfs device major/minor are listed in hexadecimal and namespace
IDs are the ns inode.
type=NS_INFO msg=audit(1408577535.306:82): pid=310 dev=00:03 netns=7 utsns=3 ipcns=4 pidns=1 userns=2 mntns=5
5/10 change audit startup from __initcall to subsys_initcall to get it started
earlier to be able to receive initial namespace log messages.
6/10 tracks the creation and deletion of namespaces, listing the type of
namespace instance, nsfs device ID, related namespace id if there is one and
the newly minted namespace ID.
Proposed output format for initial namespace creation:
type=AUDIT_NS_INIT_UTS msg=audit(1431115986.147:5): dev=00:03 old_utsns=(none) utsns=2 res=1
type=AUDIT_NS_INIT_USER msg=audit(1431115986.148:6): dev=00:03 old_userns=(none) userns=3 res=1
type=AUDIT_NS_INIT_PID msg=audit(1431115986.149:7): dev=00:03 old_pidns=(none) pidns=4 res=1
type=AUDIT_NS_INIT_MNT msg=audit(1431115986.150:8): dev=00:00 old_mntns=(none) mntns=5 res=1
type=AUDIT_NS_INIT_IPC msg=audit(1431115986.151:9): dev=00:03 old_ipcns=(none) ipcns=1 res=1
type=AUDIT_NS_INIT_NET msg=audit(1431115985.500:10): dev=00:03 old_netns=(none) netns=7 res=1
And a CLONE action would result in:
type=AUDIT_NS_INIT_NET msg=audit(1408577535.306:81): dev=00:03 old_netns=7 netns=8 res=1
While deleting a namespace would result in:
type=AUDIT_NS_DEL_MNT msg=audit(1431116003.205:534): dev=00:03 mntns=8 res=1
7/10 accepts a PID from userspace and requests logging an AUDIT_NS_INFO record
type (CAP_AUDIT_CONTROL required).
8/10 adds auditing on creation of namespace(s) in fork for unshare(2) and
clone(2), adding the CLONE_NEW_*ALL macro.
9/10 adds auditing a change of namespace on setns(2).
type=AUDIT_NS_SET_NET msg=audit(1408577535.306:81): dev=00:03 old_netns=7 netns=8 res=1
10/10 attaches a AUDIT_NS_INFO record to AUDIT_VIRT_CONTROL records
(CAP_AUDIT_WRITE required).
v6 -> v7:
Added sys_unshare to the sys_clone patch.
Combined the CLONE_NEW_*_ALL macro and audit clone and unshare patches.
Rebased on Al Viro's NSFS from v3.19-rc1 adding nsfs device ID to ns_common.
Create and switch to an nsfs inode db.
Switch AUDIT_NS_{INIT,DEL,SET}_* to auxiliary records.
Fix NULL dereference bug in AUDIT_NS_INFO call from AUDIT_VIRT_CONTROL type.
Remove call for audit_log_common_recv_msg.
Only emit info, init, del, set messages on audit_enabled.
v5 -> v6:
Switch to using namespace ID based on namespace proc inode minus base offset
Added proc device ID to qualify proc inode reference
Eliminate exposed /proc interface
v4 -> v5:
Clean up prototypes for dependencies on CONFIG_NAMESPACES.
Add AUDIT_NS_INFO record type to AUDIT_VIRT_CONTROL record.
Log AUDIT_NS_INFO with PID.
Move /proc/<pid>/ns_* patches to end of patchset to deprecate them.
Log on changing ns (setns).
Log on creating new namespaces when forking.
Added a macro for CLONE_NEW*.
v3 -> v4:
Seperate out the NS_INFO message from the SYSCALL message.
Moved audit_log_namespace_info() out of audit_log_task_info().
Use a seperate message type per namespace type for each of INIT/DEL.
Make ns= easier to search across NS_INFO and NS_INIT/DEL_XXX msg types.
Add /proc/<pid>/ns/ documentation.
Fix dynamic initial ns logging.
v2 -> v3:
Use atomic64_t in ns_serial to simplify it.
Avoid funciton duplication in proc, keying on dentry.
Squash down audit patch to avoid rcu sleep issues.
Add tracking for creation and deletion of namespace instances.
v1 -> v2:
Avoid rollover by switching from an int to a long long.
Change rollover behaviour from simply avoiding zero to raising a BUG.
Expose serial numbers in /proc/<pid>/ns/*_snum.
Expose ns_entries and use it in audit.
Notes:
As for CAP_AUDIT_READ, a patchset has been accepted upstream to check
capabilities of userspace processes that try to join netlink broadcast groups.
This set does not try to solve the non-init namespace audit messages and
auditd problem yet. That will come later, likely with additional auditd
instances running in another namespace with a limited ability to influence the
master auditd. I echo Eric B's idea that messages destined for different
namespaces would have to be tailored for that namespace with references that
make sense (such as the right pid number reported to that pid namespace, and
not leaking info about parents or peers).
Questions:
Is there a way to link serial numbers of namespaces involved in migration of a
container to another kernel? It sounds like what is needed is a part of a
mangement application that is able to pull the audit records from constituent
hosts to build an audit trail of a container.
Do any additional events need this information?
Does this present any problematic information leaks? Only CAP_AUDIT_CONTROL
(and now CAP_AUDIT_READ) in init_user_ns can get to this information in
the init namespace at the moment from audit.
Richard Guy Briggs (10):
namespaces: expose ns_entries
nsfs: switch to dedicated inode pool
nsfs: add nsfs device ID to ns_common
audit: log namespace ID numbers
audit: initialize at subsystem time rather than device time
audit: log creation and deletion of namespace instances
audit: dump namespace IDs for pid on receipt of AUDIT_NS_INFO
fork: audit on creation of new namespace(s) with clone and unshare
audit: log on switching namespace (setns)
audit: emit AUDIT_NS_INFO record with AUDIT_VIRT_CONTROL record
fs/namespace.c | 15 +++
fs/nsfs.c | 65 ++++++++++++++
fs/proc/internal.h | 2 +
fs/proc/namespaces.c | 2 +-
include/linux/audit.h | 27 ++++++
include/linux/ns_common.h | 1 +
include/linux/proc_ns.h | 22 ++---
include/uapi/linux/audit.h | 21 +++++
include/uapi/linux/sched.h | 6 ++
init/version.c | 2 +-
ipc/msgutil.c | 2 +-
ipc/namespace.c | 13 +++
kernel/audit.c | 180 +++++++++++++++++++++++++++++++++++++-
kernel/auditsc.c | 2 +
kernel/fork.c | 13 ++-
kernel/nsproxy.c | 2 +
kernel/pid.c | 2 +-
kernel/pid_namespace.c | 13 +++
kernel/user.c | 2 +-
kernel/user_namespace.c | 13 +++
kernel/utsname.c | 12 +++
net/core/net_namespace.c | 13 +++
security/integrity/ima/ima_api.c | 2 +
23 files changed, 410 insertions(+), 22 deletions(-)
^ permalink raw reply
* Re: [PATCH V6 05/10] audit: log creation and deletion of namespace instances
From: Richard Guy Briggs @ 2015-05-12 19:57 UTC (permalink / raw)
To: Steve Grubb
Cc: containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA, eparis-FjpueFixGhCM4zKIHC2jIg,
pmoore-H+wXaHxf7aLQT0dZR+AlfA, arozansk-H+wXaHxf7aLQT0dZR+AlfA,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, serge-A9i7LUbDfNHQT0dZR+AlfA,
zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <2487286.y6vyJ9A3er@x2>
On 15/05/05, Steve Grubb wrote:
> Hello,
>
> I think there needs to be some more discussion around this. It seems like this
> is not exactly recording things that are useful for audit.
It seems to me that either audit has to assemble that information, or
the kernel has to do so. The kernel doesn't know about containers
(yet?).
> On Friday, April 17, 2015 03:35:52 AM Richard Guy Briggs wrote:
> > Log the creation and deletion of namespace instances in all 6 types of
> > namespaces.
> >
> > Twelve new audit message types have been introduced:
> > AUDIT_NS_INIT_MNT 1330 /* Record mount namespace instance creation
> > */ AUDIT_NS_INIT_UTS 1331 /* Record UTS namespace instance
> > creation */ AUDIT_NS_INIT_IPC 1332 /* Record IPC namespace
> > instance creation */ AUDIT_NS_INIT_USER 1333 /* Record USER
> > namespace instance creation */ AUDIT_NS_INIT_PID 1334 /* Record
> > PID namespace instance creation */ AUDIT_NS_INIT_NET 1335 /*
> > Record NET namespace instance creation */ AUDIT_NS_DEL_MNT 1336
> > /* Record mount namespace instance deletion */ AUDIT_NS_DEL_UTS 1337
> > /* Record UTS namespace instance deletion */ AUDIT_NS_DEL_IPC
> > 1338 /* Record IPC namespace instance deletion */ AUDIT_NS_DEL_USER
> > 1339 /* Record USER namespace instance deletion */ AUDIT_NS_DEL_PID
> > 1340 /* Record PID namespace instance deletion */ AUDIT_NS_DEL_NET
> > 1341 /* Record NET namespace instance deletion */
>
> The requirements for auditing of containers should be derived from VPP. In it,
> it asks for selectable auditing, selective audit, and selective audit review.
> What this means is that we need the container and all its children to have one
> identifier that is inserted into all the events that are associated with the
> container.
Is that requirement for the records that are sent from the kernel, or
for the records stored by auditd, or by another facility that delivers
those records to a final consumer?
> With this, its possible to do a search for all events related to a container.
> Its possible to exclude events from a container. Its possible to not get any
> events.
>
> The requirements also call out for the identification of the subject. This
> means that the event should be bound to a syscall such as clone, setns, or
> unshare.
Is it useful to have a reference of the init namespace set from which
all others are spawned?
If it isn't bound, I assume the subject should be added to the message
format? I'm thinking of messages without an audit_context such as audit
user messages (such as AUDIT_NS_INFO and AUDIT_VIRT_CONTROL).
For now, we should not need to log namespaces with AUDIT_FEATURE_CHANGE
or AUDIT_CONFIG_CHANGE messages since only initial user namespace with
initial pid namespace has permission to do so. This will need to be
addressed by having non-init config changes be limited to that container
or set of namespaces and possibly its children. The other possibility
is to add the subject to the stand-alone message.
> Also, any user space events originating inside the container needs to have the
> container ID added to the user space event - just like auid and session id.
This sounds like every task needs to record a container ID since that
information is otherwise unknown by the kernel except by what might be
provided by an audit user message such as AUDIT_VIRT_CONTROL or possibly
the new AUDIT_NS_INFO request. It could be stored in struct task_struct
or in struct audit_context. I don't have a suggestion on how to get
that information securely into the kernel.
> Recording each instance of a name space is giving me something that I cannot
> use to do queries required by the security target. Given these events, how do
> I locate a web server event where it accesses a watched file? That
> authentication failed? That an update within the container failed?
>
> The requirements are that we have to log the creation, suspension, migration,
> and termination of a container. The requirements are not on the individual
> name space.
Ok. Do we have a robust definition of a container? Where is that
definition managed? If it is a userspace concept, then I think either
userspace should be assembling this information, or providing that
information to the entity that will be expected to know about and
provide it.
> Maybe I'm missing how these events give me that. But I'd like to hear how I
> would be able to meet requirements with these 12 events.
Adding the infrastructure to give each of those 12 events an audit
context to be able to give meaningful subject fields in audit records
appears to require adding a struct task_struct argument to calls to
copy_mnt_ns(), copy_utsname(), copy_ipcs(), copy_pid_ns(),
copy_net_ns(), create_user_ns() unless I use current. I think we must
use current since the userns is created before the spawned process is
mature or has an audit context in the case of clone.
Either that, or I have mis-understood and I should be stashing this
namespace ID information in an audit_aux_data structure or a more
permanent part of struct audit_context to be printed when required on
syscall exit. I'm trying to think through if it is needed in any
non-syscall audit messages.
Another RFC patch set coming...
> -Steve
>
> > As suggested by Eric Paris, there are 12 message types, one for each of
> > creation and deletion, one for each type of namespace so that text searches
> > are easier in conjunction with the AUDIT_NS_INFO message type, being able
> > to search for all records such as "netns=4 " and to avoid fields
> > disappearing per message type to make ausearch more efficient.
> >
> > A typical startup would look roughly like:
> >
> > type=AUDIT_NS_INIT_UTS msg=audit(1408577534.868:5): pid=1 uid=0
> > auid=4294967295 ses=4294967295 subj=kernel dev=00:03 old_utsns=(none)
> > utsns=-2 res=1 type=AUDIT_NS_INIT_USER msg=audit(1408577534.868:6): pid=1
> > uid=0 auid=4294967295 ses=4294967295 subj=kernel dev=00:03
> > old_userns=(none) userns=-3 res=1 type=AUDIT_NS_INIT_PID
> > msg=audit(1408577534.868:7): pid=1 uid=0 auid=4294967295 ses=4294967295
> > subj=kernel dev=00:03 old_pidns=(none) pidns=-4 res=1
> > type=AUDIT_NS_INIT_MNT msg=audit(1408577534.868:8): pid=1 uid=0
> > auid=4294967295 ses=4294967295 subj=kernel dev=00:03 old_mntns=(none)
> > mntns=0 res=1 type=AUDIT_NS_INIT_IPC msg=audit(1408577534.868:9): pid=1
> > uid=0 auid=4294967295 ses=4294967295 subj=kernel dev=00:03 old_ipcns=(none)
> > ipcns=-1 res=1 type=AUDIT_NS_INIT_NET msg=audit(1408577533.500:10): pid=1
> > uid=0 auid=4294967295 ses=4294967295 subj=kernel dev=00:03 old_netns=(none)
> > netns=2 res=1
> >
> > And a CLONE action would result in:
> > type=type=AUDIT_NS_INIT_NET msg=audit(1408577535.306:81): pid=481 uid=0
> > auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 dev=00:03
> > old_netns=2 netns=3 res=1
> >
> > While deleting a namespace would result in:
> > type=type=AUDIT_NS_DEL_MNT msg=audit(1408577552.221:85): pid=481 uid=0
> > auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 dev=00:03
> > mntns=4 res=1
> >
> > If not "(none)", old_XXXns lists the namespace from which it was cloned.
> >
> > Signed-off-by: Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> > ---
> > fs/namespace.c | 13 +++++++++
> > include/linux/audit.h | 8 +++++
> > include/uapi/linux/audit.h | 12 ++++++++
> > ipc/namespace.c | 12 ++++++++
> > kernel/audit.c | 64
> > ++++++++++++++++++++++++++++++++++++++++++++ kernel/pid_namespace.c |
> > 13 +++++++++
> > kernel/user_namespace.c | 13 +++++++++
> > kernel/utsname.c | 12 ++++++++
> > net/core/net_namespace.c | 12 ++++++++
> > 9 files changed, 159 insertions(+), 0 deletions(-)
> >
> > diff --git a/fs/namespace.c b/fs/namespace.c
> > index 182bc41..7b62543 100644
> > --- a/fs/namespace.c
> > +++ b/fs/namespace.c
> > @@ -24,6 +24,7 @@
> > #include <linux/proc_ns.h>
> > #include <linux/magic.h>
> > #include <linux/bootmem.h>
> > +#include <linux/audit.h>
> > #include "pnode.h"
> > #include "internal.h"
> >
> > @@ -2459,6 +2460,7 @@ dput_out:
> >
> > static void free_mnt_ns(struct mnt_namespace *ns)
> > {
> > + audit_log_ns_del(AUDIT_NS_DEL_MNT, ns->proc_inum);
> > proc_free_inum(ns->proc_inum);
> > put_user_ns(ns->user_ns);
> > kfree(ns);
> > @@ -2518,6 +2520,7 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags,
> > struct mnt_namespace *ns, new_ns = alloc_mnt_ns(user_ns);
> > if (IS_ERR(new_ns))
> > return new_ns;
> > + audit_log_ns_init(AUDIT_NS_INIT_MNT, ns->proc_inum, new_ns->proc_inum);
> >
> > namespace_lock();
> > /* First pass: copy the tree topology */
> > @@ -2830,6 +2833,16 @@ static void __init init_mount_tree(void)
> > set_fs_root(current->fs, &root);
> > }
> >
> > +/* log the ID of init mnt namespace after audit service starts */
> > +static int __init mnt_ns_init_log(void)
> > +{
> > + struct mnt_namespace *init_mnt_ns = init_task.nsproxy->mnt_ns;
> > +
> > + audit_log_ns_init(AUDIT_NS_INIT_MNT, 0, init_mnt_ns->proc_inum);
> > + return 0;
> > +}
> > +late_initcall(mnt_ns_init_log);
> > +
> > void __init mnt_init(void)
> > {
> > unsigned u;
> > diff --git a/include/linux/audit.h b/include/linux/audit.h
> > index 71698ec..b28dfb0 100644
> > --- a/include/linux/audit.h
> > +++ b/include/linux/audit.h
> > @@ -484,6 +484,9 @@ extern void audit_log_ns_info(struct
> task_struct
> > *tsk); static inline void audit_log_ns_info(struct task_struct *tsk) {
> > }
> > #endif
> > +extern void audit_log_ns_init(int type, unsigned int old_inum,
> > + unsigned int inum);
> > +extern void audit_log_ns_del(int type, unsigned int inum);
> >
> > extern int audit_update_lsm_rules(void);
> >
> > @@ -542,6 +545,11 @@ static inline void audit_log_task_info(struct
> > audit_buffer *ab, { }
> > static inline void audit_log_ns_info(struct task_struct *tsk)
> > { }
> > +static inline int audit_log_ns_init(int type, unsigned int old_inum,
> > + unsigned int inum)
> > +{ }
> > +static inline int audit_log_ns_del(int type, unsigned int inum)
> > +{ }
> > #define audit_enabled 0
> > #endif /* CONFIG_AUDIT */
> > static inline void audit_log_string(struct audit_buffer *ab, const char
> > *buf) diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
> > index 1ffb151..487cad6 100644
> > --- a/include/uapi/linux/audit.h
> > +++ b/include/uapi/linux/audit.h
> > @@ -111,6 +111,18 @@
> > #define AUDIT_PROCTITLE 1327 /* Proctitle emit event */
> > #define AUDIT_FEATURE_CHANGE 1328 /* audit log listing feature changes
> */
> > #define AUDIT_NS_INFO 1329 /* Record process namespace IDs */
> > +#define AUDIT_NS_INIT_MNT 1330 /* Record mount namespace instance
> creation
> > */ +#define AUDIT_NS_INIT_UTS 1331 /* Record UTS namespace instance
> > creation */ +#define AUDIT_NS_INIT_IPC 1332 /* Record IPC namespace
> > instance creation */ +#define AUDIT_NS_INIT_USER 1333 /* Record USER
> > namespace instance creation */ +#define AUDIT_NS_INIT_PID 1334 /* Record
> > PID namespace instance creation */ +#define AUDIT_NS_INIT_NET 1335 /*
> > Record NET namespace instance creation */ +#define AUDIT_NS_DEL_MNT 1336
> /*
> > Record mount namespace instance deletion */ +#define
> > AUDIT_NS_DEL_UTS 1337 /* Record UTS namespace instance deletion */
> +#define
> > AUDIT_NS_DEL_IPC 1338 /* Record IPC namespace instance deletion */
> +#define
> > AUDIT_NS_DEL_USER 1339 /* Record USER namespace instance deletion */
> > +#define AUDIT_NS_DEL_PID 1340 /* Record PID namespace instance
> deletion */
> > +#define AUDIT_NS_DEL_NET 1341 /* Record NET namespace instance deletion
> */
> >
> > #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
> > #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
> > diff --git a/ipc/namespace.c b/ipc/namespace.c
> > index 59451c1..73727ce 100644
> > --- a/ipc/namespace.c
> > +++ b/ipc/namespace.c
> > @@ -13,6 +13,7 @@
> > #include <linux/mount.h>
> > #include <linux/user_namespace.h>
> > #include <linux/proc_ns.h>
> > +#include <linux/audit.h>
> >
> > #include "util.h"
> >
> > @@ -41,6 +42,8 @@ static struct ipc_namespace *create_ipc_ns(struct
> > user_namespace *user_ns, }
> > atomic_inc(&nr_ipc_ns);
> >
> > + audit_log_ns_init(AUDIT_NS_INIT_IPC, old_ns->proc_inum, ns->proc_inum);
> > +
> > sem_init_ns(ns);
> > msg_init_ns(ns);
> > shm_init_ns(ns);
> > @@ -119,6 +122,7 @@ static void free_ipc_ns(struct ipc_namespace *ns)
> > */
> > ipcns_notify(IPCNS_REMOVED);
> > put_user_ns(ns->user_ns);
> > + audit_log_ns_del(AUDIT_NS_DEL_IPC, ns->proc_inum);
> > proc_free_inum(ns->proc_inum);
> > kfree(ns);
> > }
> > @@ -197,3 +201,11 @@ const struct proc_ns_operations ipcns_operations = {
> > .install = ipcns_install,
> > .inum = ipcns_inum,
> > };
> > +
> > +/* log the ID of init IPC namespace after audit service starts */
> > +static int __init ipc_namespaces_init(void)
> > +{
> > + audit_log_ns_init(AUDIT_NS_INIT_IPC, 0, init_ipc_ns.proc_inum);
> > + return 0;
> > +}
> > +late_initcall(ipc_namespaces_init);
> > diff --git a/kernel/audit.c b/kernel/audit.c
> > index 63f32f4..e6230c4 100644
> > --- a/kernel/audit.c
> > +++ b/kernel/audit.c
> > @@ -1978,6 +1978,70 @@ out:
> > kfree(name);
> > }
> >
> > +#ifdef CONFIG_NAMESPACES
> > +static char *ns_name[] = {
> > + "mnt",
> > + "uts",
> > + "ipc",
> > + "user",
> > + "pid",
> > + "net",
> > +};
> > +
> > +/**
> > + * audit_log_ns_init - report a namespace instance creation
> > + * @type: type of audit namespace instance created message
> > + * @old_inum: the ID number of the cloned namespace instance
> > + * @inum: the ID number of the new namespace instance
> > + */
> > +void audit_log_ns_init(int type, unsigned int old_inum, unsigned int inum)
> > +{
> > + struct audit_buffer *ab;
> > + char *audit_ns_name = ns_name[type - AUDIT_NS_INIT_MNT];
> > + struct vfsmount *mnt = task_active_pid_ns(current)->proc_mnt;
> > + struct super_block *sb = mnt->mnt_sb;
> > + char old_ns[16];
> > +
> > + if (type < AUDIT_NS_INIT_MNT || type > AUDIT_NS_INIT_NET) {
> > + WARN(1, "audit_log_ns_init: type:%d out of range", type);
> > + return;
> > + }
> > + if (!old_inum)
> > + sprintf(old_ns, "(none)");
> > + else
> > + sprintf(old_ns, "%d", old_inum - PROC_DYNAMIC_FIRST);
> > + audit_log_common_recv_msg(&ab, type);
> > + audit_log_format(ab, " dev=%02x:%02x old_%sns=%s %sns=%d res=1",
> > + MAJOR(sb->s_dev), MINOR(sb->s_dev),
> > + audit_ns_name, old_ns,
> > + audit_ns_name, inum - PROC_DYNAMIC_FIRST);
> > + audit_log_end(ab);
> > +}
> > +
> > +/**
> > + * audit_log_ns_del - report a namespace instance deleted
> > + * @type: type of audit namespace instance deleted message
> > + * @inum: the ID number of the namespace instance
> > + */
> > +void audit_log_ns_del(int type, unsigned int inum)
> > +{
> > + struct audit_buffer *ab;
> > + char *audit_ns_name = ns_name[type - AUDIT_NS_DEL_MNT];
> > + struct vfsmount *mnt = task_active_pid_ns(current)->proc_mnt;
> > + struct super_block *sb = mnt->mnt_sb;
> > +
> > + if (type < AUDIT_NS_DEL_MNT || type > AUDIT_NS_DEL_NET) {
> > + WARN(1, "audit_log_ns_del: type:%d out of range", type);
> > + return;
> > + }
> > + audit_log_common_recv_msg(&ab, type);
> > + audit_log_format(ab, " dev=%02x:%02x %sns=%d res=1",
> > + MAJOR(sb->s_dev), MINOR(sb->s_dev), audit_ns_name,
> > + inum - PROC_DYNAMIC_FIRST);
> > + audit_log_end(ab);
> > +}
> > +#endif /* CONFIG_NAMESPACES */
> > +
> > /**
> > * audit_log_end - end one audit record
> > * @ab: the audit_buffer
> > diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
> > index db95d8e..d28fd14 100644
> > --- a/kernel/pid_namespace.c
> > +++ b/kernel/pid_namespace.c
> > @@ -18,6 +18,7 @@
> > #include <linux/proc_ns.h>
> > #include <linux/reboot.h>
> > #include <linux/export.h>
> > +#include <linux/audit.h>
> >
> > struct pid_cache {
> > int nr_ids;
> > @@ -109,6 +110,9 @@ static struct pid_namespace *create_pid_namespace(struct
> > user_namespace *user_ns if (err)
> > goto out_free_map;
> >
> > + audit_log_ns_init(AUDIT_NS_INIT_PID, parent_pid_ns->proc_inum,
> > + ns->proc_inum);
> > +
> > kref_init(&ns->kref);
> > ns->level = level;
> > ns->parent = get_pid_ns(parent_pid_ns);
> > @@ -142,6 +146,7 @@ static void destroy_pid_namespace(struct pid_namespace
> > *ns) {
> > int i;
> >
> > + audit_log_ns_del(AUDIT_NS_DEL_PID, ns->proc_inum);
> > proc_free_inum(ns->proc_inum);
> > for (i = 0; i < PIDMAP_ENTRIES; i++)
> > kfree(ns->pidmap[i].page);
> > @@ -388,3 +393,11 @@ static __init int pid_namespaces_init(void)
> > }
> >
> > __initcall(pid_namespaces_init);
> > +
> > +/* log the ID of init PID namespace after audit service starts */
> > +static __init int pid_namespaces_late_init(void)
> > +{
> > + audit_log_ns_init(AUDIT_NS_INIT_PID, 0, init_pid_ns.proc_inum);
> > + return 0;
> > +}
> > +late_initcall(pid_namespaces_late_init);
> > diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
> > index fcc0256..89c2517 100644
> > --- a/kernel/user_namespace.c
> > +++ b/kernel/user_namespace.c
> > @@ -22,6 +22,7 @@
> > #include <linux/ctype.h>
> > #include <linux/projid.h>
> > #include <linux/fs_struct.h>
> > +#include <linux/audit.h>
> >
> > static struct kmem_cache *user_ns_cachep __read_mostly;
> >
> > @@ -92,6 +93,9 @@ int create_user_ns(struct cred *new)
> > return ret;
> > }
> >
> > + audit_log_ns_init(AUDIT_NS_INIT_USER, parent_ns->proc_inum,
> > + ns->proc_inum);
> > +
> > atomic_set(&ns->count, 1);
> > /* Leave the new->user_ns reference with the new user namespace. */
> > ns->parent = parent_ns;
> > @@ -136,6 +140,7 @@ void free_user_ns(struct user_namespace *ns)
> > #ifdef CONFIG_PERSISTENT_KEYRINGS
> > key_put(ns->persistent_keyring_register);
> > #endif
> > + audit_log_ns_del(AUDIT_NS_DEL_USER, ns->proc_inum);
> > proc_free_inum(ns->proc_inum);
> > kmem_cache_free(user_ns_cachep, ns);
> > ns = parent;
> > @@ -909,3 +914,11 @@ static __init int user_namespaces_init(void)
> > return 0;
> > }
> > subsys_initcall(user_namespaces_init);
> > +
> > +/* log the ID of init user namespace after audit service starts */
> > +static __init int user_namespaces_late_init(void)
> > +{
> > + audit_log_ns_init(AUDIT_NS_INIT_USER, 0, init_user_ns.proc_inum);
> > + return 0;
> > +}
> > +late_initcall(user_namespaces_late_init);
> > diff --git a/kernel/utsname.c b/kernel/utsname.c
> > index fd39312..fa21e8d 100644
> > --- a/kernel/utsname.c
> > +++ b/kernel/utsname.c
> > @@ -16,6 +16,7 @@
> > #include <linux/slab.h>
> > #include <linux/user_namespace.h>
> > #include <linux/proc_ns.h>
> > +#include <linux/audit.h>
> >
> > static struct uts_namespace *create_uts_ns(void)
> > {
> > @@ -48,6 +49,8 @@ static struct uts_namespace *clone_uts_ns(struct
> > user_namespace *user_ns, return ERR_PTR(err);
> > }
> >
> > + audit_log_ns_init(AUDIT_NS_INIT_UTS, old_ns->proc_inum, ns->proc_inum);
> > +
> > down_read(&uts_sem);
> > memcpy(&ns->name, &old_ns->name, sizeof(ns->name));
> > ns->user_ns = get_user_ns(user_ns);
> > @@ -84,6 +87,7 @@ void free_uts_ns(struct kref *kref)
> >
> > ns = container_of(kref, struct uts_namespace, kref);
> > put_user_ns(ns->user_ns);
> > + audit_log_ns_del(AUDIT_NS_DEL_UTS, ns->proc_inum);
> > proc_free_inum(ns->proc_inum);
> > kfree(ns);
> > }
> > @@ -138,3 +142,11 @@ const struct proc_ns_operations utsns_operations = {
> > .install = utsns_install,
> > .inum = utsns_inum,
> > };
> > +
> > +/* log the ID of init UTS namespace after audit service starts */
> > +static int __init uts_namespaces_init(void)
> > +{
> > + audit_log_ns_init(AUDIT_NS_INIT_UTS, 0, init_uts_ns.proc_inum);
> > + return 0;
> > +}
> > +late_initcall(uts_namespaces_init);
> > diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
> > index 85b6269..562eb85 100644
> > --- a/net/core/net_namespace.c
> > +++ b/net/core/net_namespace.c
> > @@ -17,6 +17,7 @@
> > #include <linux/user_namespace.h>
> > #include <net/net_namespace.h>
> > #include <net/netns/generic.h>
> > +#include <linux/audit.h>
> >
> > /*
> > * Our network namespace constructor/destructor lists
> > @@ -253,6 +254,8 @@ struct net *copy_net_ns(unsigned long flags,
> > mutex_lock(&net_mutex);
> > rv = setup_net(net, user_ns);
> > if (rv == 0) {
> > + audit_log_ns_init(AUDIT_NS_INIT_NET, old_net->proc_inum,
> > + net->proc_inum);
> > rtnl_lock();
> > list_add_tail_rcu(&net->list, &net_namespace_list);
> > rtnl_unlock();
> > @@ -389,6 +392,7 @@ static __net_init int net_ns_net_init(struct net *net)
> >
> > static __net_exit void net_ns_net_exit(struct net *net)
> > {
> > + audit_log_ns_del(AUDIT_NS_DEL_NET, net->proc_inum);
> > proc_free_inum(net->proc_inum);
> > }
> >
> > @@ -435,6 +439,14 @@ static int __init net_ns_init(void)
> >
> > pure_initcall(net_ns_init);
> >
> > +/* log the ID of init_net namespace after audit service starts */
> > +static int __init net_ns_init_log(void)
> > +{
> > + audit_log_ns_init(AUDIT_NS_INIT_NET, 0, init_net.proc_inum);
> > + return 0;
> > +}
> > +late_initcall(net_ns_init_log);
> > +
> > #ifdef CONFIG_NET_NS
> > static int __register_pernet_operations(struct list_head *list,
> > struct pernet_operations *ops)
>
- RGB
--
Richard Guy Briggs <rbriggs-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545
^ permalink raw reply
* Re: Latest audit file for DISA STIGS
From: leam hall @ 2015-05-12 13:53 UTC (permalink / raw)
To: linux-audit
In-Reply-To: <F58F8CAA5E24CB479B179D2FC3F5AB912F9054AD@NDEUSAHSWVXCG03.gold.rtgold.nima.mil>
[-- Attachment #1.1: Type: text/plain, Size: 977 bytes --]
Hey Jim,
I'm working on one, mostly based off Steve Grubb's recommendations. I will
share something Steve said though. The STIG has two lines for many audit
events. If I understand correctly, that will cause a performance hit. So an
automated STIG validator may fail if it follows the STIG verbatim.
https://github.com/LeamHall/SecComFrame/tree/master/tasks/audit/puppet/audit/files
Leam
On Tue, May 12, 2015 at 9:18 AM, <James.A.Williams.ctr@nga.mil> wrote:
> Classification: UNCLASSIFIED
> ======================================================
>
> Hi All,
>
> Does anyone have a good audit file that conforms to the DISA STIG (RHEL
> 6)?
>
> Please email the file or copy into email.
>
> Thanks,
> Jim
> ======================================================
> Classification: UNCLASSIFIED
>
>
> --
> Linux-audit mailing list
> Linux-audit@redhat.com
> https://www.redhat.com/mailman/listinfo/linux-audit
>
--
Mind on a Mission <http://leamhall.blogspot.com/>
[-- Attachment #1.2: Type: text/html, Size: 1716 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply
* Re: Latest audit file for DISA STIGS
From: Steve Grubb @ 2015-05-12 13:38 UTC (permalink / raw)
To: linux-audit; +Cc: James.A.Williams.ctr
In-Reply-To: <F58F8CAA5E24CB479B179D2FC3F5AB912F9054AD@NDEUSAHSWVXCG03.gold.rtgold.nima.mil>
On Tuesday, May 12, 2015 01:18:03 PM James.A.Williams.ctr@nga.mil wrote:
> Does anyone have a good audit file that conforms to the DISA STIG (RHEL
> 6)?
>
> Please email the file or copy into email.
The shipping stig.rules file is intended to satisfy the STIG. You can see a
copy here:
https://fedorahosted.org/audit/browser/trunk/contrib/stig.rules
-Steve
^ permalink raw reply
* Latest audit file for DISA STIGS
From: James.A.Williams.ctr @ 2015-05-12 13:18 UTC (permalink / raw)
To: linux-audit
Classification: UNCLASSIFIED
======================================================
Hi All,
Does anyone have a good audit file that conforms to the DISA STIG (RHEL 6)?
Please email the file or copy into email.
Thanks,
Jim
======================================================
Classification: UNCLASSIFIED
^ permalink raw reply
* Re: Seeking auditd help
From: Richard Guy Briggs @ 2015-05-12 12:13 UTC (permalink / raw)
To: Burn Alting; +Cc: Bill Jackson III, linux-audit
In-Reply-To: <1431394570.4708.13.camel@swtf.swtf.dyndns.org>
On 15/05/12, Burn Alting wrote:
> On Mon, 2015-05-11 at 15:52 -0400, Steve Grubb wrote:
> > On Monday, May 11, 2015 11:50:19 AM Bill Jackson III wrote:
> > > Any pointers for troubleshooting auditd missing events for file reads,
> > > edits, etc. ( -w _path_ -p raw) on OEL5/RHEL 5/CentOS 5?
> > >
> > > http://security.stackexchange.com/q/89009/56827
> >
> > The -w notation is the same as
> >
> > -a always,exit -F path=XXX -F perms=rwa
> >
> > What this does is audit the following functions defined in the syscall
> > classifiers
> > :
> > http://lxr.free-electrons.com/source/include/asm-generic/audit_read.h
> > http://lxr.free-electrons.com/source/include/asm-generic/audit_write.h
> > http://lxr.free-electrons.com/source/include/asm-generic/audit_change_attr.h
> >
> > You are not going to get a hit for each and every read system call because
> > read is not audited.
>
> Bill,
>
> Is your question
>
> "Can one apply a file watch using auditd if the file does not exist?"
>
> then I believe the answer is no.
There is a patch set coming to be able to address this case if the
directory exists. Down the road, I'm hoping to be able to accomodate
non-existant directories too.
> Options would be
> - as part of your application deployment standard operating procedures
> (SOPs) add appropriate watches to audit.rules and restart the auditd
> service
> - keep all you sensitive files in one directory location, set a
> directory watch on this directory tree and then as part of your
> application deployment SOPs, place the real files in the sensitive file
> area and then link to them from the application area. (I've just tried
> this on a fc22 system and it works)
>
> Regards
- RGB
--
Richard Guy Briggs <rbriggs@redhat.com>
Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545
^ permalink raw reply
* Re: Seeking auditd help
From: Burn Alting @ 2015-05-12 1:36 UTC (permalink / raw)
To: Steve Grubb; +Cc: Bill Jackson III, linux-audit
In-Reply-To: <3241881.s5W8vqYJFF@x2>
On Mon, 2015-05-11 at 15:52 -0400, Steve Grubb wrote:
> On Monday, May 11, 2015 11:50:19 AM Bill Jackson III wrote:
> > Any pointers for troubleshooting auditd missing events for file reads,
> > edits, etc. ( -w _path_ -p raw) on OEL5/RHEL 5/CentOS 5?
> >
> > http://security.stackexchange.com/q/89009/56827
>
> The -w notation is the same as
>
> -a always,exit -F path=XXX -F perms=rwa
>
> What this does is audit the following functions defined in the syscall
> classifiers
> :
> http://lxr.free-electrons.com/source/include/asm-generic/audit_read.h
> http://lxr.free-electrons.com/source/include/asm-generic/audit_write.h
> http://lxr.free-electrons.com/source/include/asm-generic/audit_change_attr.h
>
> You are not going to get a hit for each and every read system call because
> read is not audited.
Bill,
Is your question
"Can one apply a file watch using auditd if the file does not exist?"
then I believe the answer is no.
Options would be
- as part of your application deployment standard operating procedures
(SOPs) add appropriate watches to audit.rules and restart the auditd
service
- keep all you sensitive files in one directory location, set a
directory watch on this directory tree and then as part of your
application deployment SOPs, place the real files in the sensitive file
area and then link to them from the application area. (I've just tried
this on a fc22 system and it works)
Regards
^ permalink raw reply
* Re: Seeking auditd help
From: Steve Grubb @ 2015-05-11 19:52 UTC (permalink / raw)
To: linux-audit; +Cc: Bill Jackson III
In-Reply-To: <CAH=bzftb=WQU+W-OZJ-pKA9m0cXtmXiOow+6Am=xN5-BZT9srA@mail.gmail.com>
On Monday, May 11, 2015 11:50:19 AM Bill Jackson III wrote:
> Any pointers for troubleshooting auditd missing events for file reads,
> edits, etc. ( -w _path_ -p raw) on OEL5/RHEL 5/CentOS 5?
>
> http://security.stackexchange.com/q/89009/56827
The -w notation is the same as
-a always,exit -F path=XXX -F perms=rwa
What this does is audit the following functions defined in the syscall
classifiers
:
http://lxr.free-electrons.com/source/include/asm-generic/audit_read.h
http://lxr.free-electrons.com/source/include/asm-generic/audit_write.h
http://lxr.free-electrons.com/source/include/asm-generic/audit_change_attr.h
You are not going to get a hit for each and every read system call because
read is not audited.
-Steve
^ permalink raw reply
* Seeking auditd help
From: Bill Jackson III @ 2015-05-11 18:50 UTC (permalink / raw)
To: linux-audit
[-- Attachment #1.1: Type: text/plain, Size: 178 bytes --]
Any pointers for troubleshooting auditd missing events for file reads,
edits, etc. ( -w _path_ -p raw) on OEL5/RHEL 5/CentOS 5?
http://security.stackexchange.com/q/89009/56827
[-- Attachment #1.2: Type: text/html, Size: 289 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply
* Re: [PATCH V6 00/10] namespaces: log namespaces per task
From: Richard Guy Briggs @ 2015-05-08 14:42 UTC (permalink / raw)
To: Eric W. Biederman
Cc: containers, linux-kernel, pmoore, linux-audit, eparis, sgrubb,
zohar
In-Reply-To: <87zj5tgfpb.fsf@x220.int.ebiederm.org>
On 15/04/27, Eric W. Biederman wrote:
> Richard Guy Briggs <rgb@redhat.com> writes:
> > On 15/04/24, Eric W. Biederman wrote:
> >> Richard Guy Briggs <rgb@redhat.com> writes:
> >> > On 15/04/22, Richard Guy Briggs wrote:
> >> >> On 15/04/20, Eric W. Biederman wrote:
> >> >> > Richard Guy Briggs <rgb@redhat.com> writes:
> >> > Do I even need to report the device number anymore since I am concluding
> >> > s_dev is never set (or always zero) in the nsfs filesystem by
> >> > mount_pseudo() and isn't even mountable?
> >>
> >> We still need the dev. We do have a device number get_anon_bdev fills it in.
> >
> > Fine, it has a device number. There appears to be only one of these
> > allocated per kernel. I can get it from &nsfs->fs_supers (and take the
> > first instance given by hlist_for_each_entry and verify there are no
> > others). Why do I need it, again?
>
> Because if we have to preserve the inode number over a migration event I
> want to preserve the fact that we are talking about inode numbers from a
> superblock with a device number.
>
> Otherwise known as I am allergic to kernel global identifiers, because
> they can be major pains. I don't want to have to go back and implement
> a namespace for namespaces.
Alright, I'll change the device over to that... We can figure out how
to select the correct device number of nsfs instances if it increases
beyond one.
> >> >> They are all covered:
> >> >> sys_unshare > unshare_userns > create_user_ns
> >> >> sys_unshare > unshare_nsproxy_namespaces > create_new_namespaces > copy_mnt_ns
> >> >> sys_unshare > unshare_nsproxy_namespaces > create_new_namespaces > copy_utsname > clone_uts_ns
> >> >> sys_unshare > unshare_nsproxy_namespaces > create_new_namespaces > copy_ipcs > get_ipc_ns
> >> >> sys_unshare > unshare_nsproxy_namespaces > create_new_namespaces > copy_pid_ns > create_pid_namespace
> >> >> sys_unshare > unshare_nsproxy_namespaces > create_new_namespaces > copy_net_ns
> >>
> >> Then why the special change to fork? That was not reflected on
> >> the unshare path as far as I could see.
> >
> > Fork can specify more than one CLONE flag at once, so collecting them
> > all in one statementn seemed helpful. setns can only set one at a time.
>
> unshare can also specify more than one CLONE flag at once.
> I just pointed that out becase that seemed really unsymmetrical.
Ah sorry, my mistake, I was thinking setns... I've added a call in
sys_unshare().
> > Ok, understood, we can't just punt this one to a higher layer...
> >
> > So this comes back to a question above, which is how do we determine
> > which device it is from? Sounds like we need something added to
> > ns_common or one of the 6 namespace types structs.
>
> Or we can just hard code reading it off of the appropriate magic
> filesystem. Probably what we want is a well named helper function that
> does the job.
There is a bit of overhead to read that, so I've added a dev_t member to
ns_common. Simplest way I found was to call iterate_supers() since
struct file_system_type *nsfs isn't exposed.
> I just care that when we talk about these things we are talking about
> inode numbers from a superblock that is associated with a given device
> number. That way I don't have nightmares about dealing with a namespace
> for namespaces.
>
> Eric
- RGB
--
Richard Guy Briggs <rbriggs@redhat.com>
Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545
^ permalink raw reply
* Re: auid field when switching user
From: Guillaume L. @ 2015-05-07 9:02 UTC (permalink / raw)
To: burn; +Cc: linux-audit
In-Reply-To: <1430950425.6274.5.camel@swtf.swtf.dyndns.org>
[-- Attachment #1.1: Type: text/plain, Size: 3570 bytes --]
Thank you !
I think you point the "missing". My first try was on debian wheezy. Now I
try on debian jessie. With jessie, all requirements seems presents and the
field auid has the right value !
type=SYSCALL msg=audit(1430989253.292:23716): arch=c000003e syscall=59
success=yes exit=0 a0=940b68 a1=a1aba8 a2=a1c008 a3=7ffd2d4978f0 items=2
ppid=16848 pid=16864 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0
sgid=0 fsgid=0 tty=pts1 ses=39 comm="ps" exe="/bin/ps" key="auditcmd"
type=EXECVE msg=audit(1430989253.292:23716): argc=1 a0="ps"
type=CWD msg=audit(1430989253.292:23716): cwd="/etc/pam.d"
type=PATH msg=audit(1430989253.292:23716): item=0 name="/bin/ps" inode=420
dev=08:01 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL
type=PATH msg=audit(1430989253.292:23716): item=1 name=(null) inode=1478
dev=08:01 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL
type=PROCTITLE msg=audit(1430989253.292:23716): proctitle="ps"
Thank you for your help !
--
Guillaume
On Thu, May 7, 2015 at 12:13 AM, Burn Alting <burn@swtf.dyndns.org> wrote:
> On Wed, 2015-05-06 at 10:56 -0400, Steve Grubb wrote:
> > Hello,
> >
> > On Wednesday, May 06, 2015 04:39:16 PM Guillaume L. wrote:
> > > I'm trying to use auditd to log all actions made by the users on the
> > > system. This part works fine.
> > >
> > > The documentation mention the "auid" field to identify the user from
> the
> > > first connection "even" when the user's identity changes (like with a
> su):
> >
> > Correct.
> >
> > > auid=500
> > > The auid field records the Audit user ID, that is the loginuid. This
> ID is
> > > assigned to a user upon login and is inherited by every process even
> when
> > > the user's identity changes (for example, by switching user accounts
> with
> > > the su - john command).
> > >
> > > But this is not working. If I log with the user "test" (uid 1000) when
> I
> > > switch to the user root, the value of auid is 0 (the uid of root).
> >
> > How did you switch the user? I would like to try recreating the issue.
> It may
> > be that the underlying implementation actually does log you out. You'd
> have to
> > look for one of:
> >
> > AUDIT_USER_LOGOUT - User has logged out
> > AUDIT_USER_END - User session end
> > AUDIT_CRED_DISP - User credential disposed
> >
>
> Perhaps pam_loginuid hasn't been applied
> in
> /etc/pam.d/{atd,crond,gdm,gdm-autologin,gdm-fingerprint,gdm-password,login,remote,sshd,ssh-keycat}
>
> When searching for the module, do you see something like
> # grep pam_loginuid /etc/pam.d/*
> /etc/pam.d/atd:session required pam_loginuid.so
> /etc/pam.d/crond:session required pam_loginuid.so
> /etc/pam.d/gdm:session required pam_loginuid.so
> /etc/pam.d/gdm-autologin:session required pam_loginuid.so
> /etc/pam.d/gdm-fingerprint:session required
> pam_loginuid.so
> /etc/pam.d/gdm-password:session required
> pam_loginuid.so
> /etc/pam.d/login:session required pam_loginuid.so
> /etc/pam.d/remote:session required pam_loginuid.so
> /etc/pam.d/sshd:session required pam_loginuid.so
> /etc/pam.d/ssh-keycat:session required pam_loginuid.so
> #
>
> If not, then read up on how to use required pam modules.
>
> >
> > -Steve
> >
> > --
> > Linux-audit mailing list
> > Linux-audit@redhat.com
> > https://www.redhat.com/mailman/listinfo/linux-audit
>
>
> --
> Linux-audit mailing list
> Linux-audit@redhat.com
> https://www.redhat.com/mailman/listinfo/linux-audit
>
[-- Attachment #1.2: Type: text/html, Size: 4902 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply
* Re: auid field when switching user
From: Burn Alting @ 2015-05-06 22:13 UTC (permalink / raw)
To: linux-audit
In-Reply-To: <2619501.3BvT2m2UX6@x2>
On Wed, 2015-05-06 at 10:56 -0400, Steve Grubb wrote:
> Hello,
>
> On Wednesday, May 06, 2015 04:39:16 PM Guillaume L. wrote:
> > I'm trying to use auditd to log all actions made by the users on the
> > system. This part works fine.
> >
> > The documentation mention the "auid" field to identify the user from the
> > first connection "even" when the user's identity changes (like with a su):
>
> Correct.
>
> > auid=500
> > The auid field records the Audit user ID, that is the loginuid. This ID is
> > assigned to a user upon login and is inherited by every process even when
> > the user's identity changes (for example, by switching user accounts with
> > the su - john command).
> >
> > But this is not working. If I log with the user "test" (uid 1000) when I
> > switch to the user root, the value of auid is 0 (the uid of root).
>
> How did you switch the user? I would like to try recreating the issue. It may
> be that the underlying implementation actually does log you out. You'd have to
> look for one of:
>
> AUDIT_USER_LOGOUT - User has logged out
> AUDIT_USER_END - User session end
> AUDIT_CRED_DISP - User credential disposed
>
Perhaps pam_loginuid hasn't been applied
in /etc/pam.d/{atd,crond,gdm,gdm-autologin,gdm-fingerprint,gdm-password,login,remote,sshd,ssh-keycat}
When searching for the module, do you see something like
# grep pam_loginuid /etc/pam.d/*
/etc/pam.d/atd:session required pam_loginuid.so
/etc/pam.d/crond:session required pam_loginuid.so
/etc/pam.d/gdm:session required pam_loginuid.so
/etc/pam.d/gdm-autologin:session required pam_loginuid.so
/etc/pam.d/gdm-fingerprint:session required
pam_loginuid.so
/etc/pam.d/gdm-password:session required
pam_loginuid.so
/etc/pam.d/login:session required pam_loginuid.so
/etc/pam.d/remote:session required pam_loginuid.so
/etc/pam.d/sshd:session required pam_loginuid.so
/etc/pam.d/ssh-keycat:session required pam_loginuid.so
#
If not, then read up on how to use required pam modules.
>
> -Steve
>
> --
> Linux-audit mailing list
> Linux-audit@redhat.com
> https://www.redhat.com/mailman/listinfo/linux-audit
^ permalink raw reply
* Re: auid field when switching user
From: Steve Grubb @ 2015-05-06 14:56 UTC (permalink / raw)
To: linux-audit
In-Reply-To: <CAGi3Uzqwoi=7BuaXF=0yTqfJ7z4iYrToQP9UNpqqx36iG7zeqw@mail.gmail.com>
Hello,
On Wednesday, May 06, 2015 04:39:16 PM Guillaume L. wrote:
> I'm trying to use auditd to log all actions made by the users on the
> system. This part works fine.
>
> The documentation mention the "auid" field to identify the user from the
> first connection "even" when the user's identity changes (like with a su):
Correct.
> auid=500
> The auid field records the Audit user ID, that is the loginuid. This ID is
> assigned to a user upon login and is inherited by every process even when
> the user's identity changes (for example, by switching user accounts with
> the su - john command).
>
> But this is not working. If I log with the user "test" (uid 1000) when I
> switch to the user root, the value of auid is 0 (the uid of root).
How did you switch the user? I would like to try recreating the issue. It may
be that the underlying implementation actually does log you out. You'd have to
look for one of:
AUDIT_USER_LOGOUT - User has logged out
AUDIT_USER_END - User session end
AUDIT_CRED_DISP - User credential disposed
-Steve
^ permalink raw reply
* auid field when switching user
From: Guillaume L. @ 2015-05-06 14:39 UTC (permalink / raw)
To: linux-audit
[-- Attachment #1.1: Type: text/plain, Size: 730 bytes --]
Bonjour,
I'm trying to use auditd to log all actions made by the users on the
system. This part works fine.
The documentation mention the "auid" field to identify the user from the
first connection "even" when the user's identity changes (like with a su):
auid=500
The auid field records the Audit user ID, that is the loginuid. This ID is
assigned to a user upon login and is inherited by every process even when
the user's identity changes (for example, by switching user accounts with
the su - john command).
But this is not working. If I log with the user "test" (uid 1000) when I
switch to the user root, the value of auid is 0 (the uid of root).
Did I missing something ?
Thank you in advance.
Regards,
--
Guillaume
[-- Attachment #1.2: Type: text/html, Size: 1023 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox