Linux-audit Archive on lore.kernel.org
 help / color / mirror / Atom feed
* 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

* Re: [PATCH V6 05/10] audit: log creation and deletion of namespace instances
From: Steve Grubb @ 2015-05-05 15:16 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-api-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	pmoore-H+wXaHxf7aLQT0dZR+AlfA, linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	eparis-FjpueFixGhCM4zKIHC2jIg,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8
In-Reply-To: <87pp6fhy4c.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>

On Tuesday, May 05, 2015 09:56:03 AM Eric W. Biederman wrote:
> Steve Grubb <sgrubb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:
> > 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.
> 
> That is technically impossible.  Nested containers exist.

OK, then lets talk about that, too. When something is 2 layers deep, the 
outside world cannot make sense of it. The inner one can be a loopback mounted 
file in the outer one. That means that I need the container itself to be 
responsible for events so that things are recorded using paths, uids, and pids 
that make sense to it. It can enrich the events and send them to the outer 
container.


> That is when container G is nested in container F which is in turn
> nested in container E which is in turn nested in container D which is in
> turn nested in container C which is in turn nested in container B which
> is nested in container A there is no one label you can put on audit
> messages from container G which is the ``correct'' one.
> 
> Or are you proposing that something in container G have labels
> A B C D E F G included on every audit message?

We need to have audit events to either be globally tagged so that the outside 
world understand what happening no matter how deep. Or we need each layer to 
be responsible for itself. This means having an audit rule match engine for 
each namespace like netfilter is to networking.


> That introduces enough complexity in generating and parsing the messages I
> wouldn't trust those messages as the least bug in generation and parsing
> would be a security issue.

That goes with the territory.


> What is the world is VPP?

Virtualization Protection Profile. Before people say it doesn't apply, it kind 
of does. It defines the necessary security mechanisms for either full blown 
virt like QEMU/Xen based or it gives enough wiggle room for containers and 
other types of VMs. Specifically, it defines the audit requirements needed for 
this kind of technology.


> It sounds like something non-public thing. Certainly it has never been a
> part of the public container discussion and as such it appears to be
> completely ridiculous to bring up in a public discussion.

No, its a public thing. Audit requirements start in section 5.2:

https://www.niap-ccevs.org/pp/PP_SV_V1.0/

-Steve

^ permalink raw reply

* Re: [PATCH V6 05/10] audit: log creation and deletion of namespace instances
From: Eric W. Biederman @ 2015-05-05 14:56 UTC (permalink / raw)
  To: Steve Grubb
  Cc: linux-api-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	pmoore-H+wXaHxf7aLQT0dZR+AlfA, linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	eparis-FjpueFixGhCM4zKIHC2jIg,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8
In-Reply-To: <2487286.y6vyJ9A3er@x2>

Steve Grubb <sgrubb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:

> 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.

That is technically impossible.  Nested containers exist.

That is when container G is nested in container F which is in turn
nested in container E which is in turn nested in container D which is in
turn nested in container C which is in turn nested in container B which
is nested in container A there is no one label you can put on audit
messages from container G which is the ``correct'' one.

Or are you proposing that something in container G have labels
A B C D E F G included on every audit message?   That introduces enough
complexity in generating and parsing the messages I wouldn't trust those
messages as the least bug in generation and parsing would be a security
issue.

What is the world is VPP?  It sounds like something non-public thing.
Certainly it has never been a part of the public container discussion
and as such it appears to be completely ridiculous to bring up in a
public discussion.

Eric

^ permalink raw reply

* Re: [PATCH V6 05/10] audit: log creation and deletion of namespace instances
From: Steve Grubb @ 2015-05-05 14:46 UTC (permalink / raw)
  To: Aristeu Rozanski
  Cc: linux-api-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	pmoore-H+wXaHxf7aLQT0dZR+AlfA, linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	eparis-FjpueFixGhCM4zKIHC2jIg,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8
In-Reply-To: <20150505143119.GA4350-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

On Tuesday, May 05, 2015 10:31:20 AM Aristeu Rozanski wrote:
> Hi Steve,
> 
> On Tue, May 05, 2015 at 10:22:32AM -0400, Steve Grubb wrote:
> > 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.
> > 
> > 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.
> > 
> > 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.
> > 
> > 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.
> > 
> > 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.
> 
> what about cases you don't use lxc, libvirt to create namespaces?

There's a pretty good chance that we don't care. We've had file system 
namespace for about 8 or 9 years and we never needed to have a namespace 
identifier added.

> It's easier if the logging is done by namespaces and in case they're created
> by any container manager, it can generate a new event notifying it
> created a container named "foo" with these namespaces: x, y, z, w and
> from that you can piece together everything that happened.

OK, if they are emitted they should be an auxiliary record to clone, setns, or 
unshare system calls. But lets go down this path. We have 6 or so name spaces. 
These identifiers will need to be added to every single event in the system so 
that I can figure out what event belongs to which container. 


> Userspace tools can change to adapt to using namespaces and the idea of
> container to make it easier to lookup for events instead of relying on a
> number that might not be there (think someone using unshare, ip netns, ...).

That's what I am trying to do...figure out how I can these identifiers to see if 
this actually solves the problem. This is why I wanted to state the actual 
requirements. Its easy to lose the overall view.

Also, I am concerned about how much extra disk space this is going to eat up.


> It was discussed in the past and having the concept of "container" in
> kernel space and it's not going to happen, so userspace should deal with
> it.

This is what I am asking for help with. How do I locate an authentication 
event from container using the information in these events?

-Steve

^ permalink raw reply

* Re: [PATCH V6 05/10] audit: log creation and deletion of namespace instances
From: Aristeu Rozanski @ 2015-05-05 14:31 UTC (permalink / raw)
  To: Steve Grubb
  Cc: linux-api-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	pmoore-H+wXaHxf7aLQT0dZR+AlfA, linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	eparis-FjpueFixGhCM4zKIHC2jIg,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8
In-Reply-To: <2487286.y6vyJ9A3er@x2>

Hi Steve,
On Tue, May 05, 2015 at 10:22:32AM -0400, Steve Grubb wrote:
> 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.
> 
> 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.
> 
> 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.
> 
> 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.
> 
> 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.

what about cases you don't use lxc, libvirt to create namespaces? It's
easier if the logging is done by namespaces and in case they're created
by any container manager, it can generate a new event notifying it
created a container named "foo" with these namespaces: x, y, z, w and
from that you can piece together everything that happened. Userspace
tools can change to adapt to using namespaces and the idea of container
to make it easier to lookup for events instead of relying on a number
that might not be there (think someone using unshare, ip netns, ...). It
was discussed in the past and having the concept of "container" in
kernel space and it's not going to happen, so userspace should deal with
it.

-- 
Aristeu

^ permalink raw reply

* Re: [PATCH V6 05/10] audit: log creation and deletion of namespace instances
From: Steve Grubb @ 2015-05-05 14:22 UTC (permalink / raw)
  To: Richard Guy Briggs
  Cc: linux-api-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	pmoore-H+wXaHxf7aLQT0dZR+AlfA, linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	eparis-FjpueFixGhCM4zKIHC2jIg,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <11270b0b1afd0a25b108915673e1e1b38dfeeafa.1429252659.git.rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

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.

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.

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.

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.

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.

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.

-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)

^ permalink raw reply

* audit 2.4.2 released
From: Steve Grubb @ 2015-04-28 20:33 UTC (permalink / raw)
  To: linux audit

Hello,

I've just released a new version of the audit daemon. It can be downloaded 
from http://people.redhat.com/sgrubb/audit. It will also be in rawhide
soon. The ChangeLog is:

- Ausearch should parse exe field in SECCOMP events
- Improve output for short mode interpretations in auparse
- Add CRYPTO_IKE_SA and CRYPTO_IPSEC_SA events
- If auditctl is reading rules from a file, send messages to syslog (#1144252)
- Correct lookup of ppc64le when determining machine type
- Increase time buffer for wide character numbers in ausearch/report (#1200314)
- In aureport, add USER_TTY events to tty report
- In audispd, limit reporting of queue full messages (#1203810)
- In auditctl, don't segfault when invalid options passed (#1206516)
- In autrace, remove some older unimplemented syscalls for aarch64 (#1185892)
- In auditctl, correct lookup of aarch64 in arch field (#1186313)
- Update lookup tables for 4.1 kernel

Please let me know if you run across any problems with this release.

-Steve

^ permalink raw reply

* Re: [PATCH V6 00/10] namespaces: log namespaces per task
From: Eric W. Biederman @ 2015-04-28  2:16 UTC (permalink / raw)
  To: Richard Guy Briggs
  Cc: containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	pmoore-H+wXaHxf7aLQT0dZR+AlfA, linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
	eparis-FjpueFixGhCM4zKIHC2jIg, sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8
In-Reply-To: <20150428020555.GB20713-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org>

Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:

> On 15/04/24, Eric W. Biederman wrote:
>> Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:
>> > On 15/04/22, Richard Guy Briggs wrote:
>> >> On 15/04/20, Eric W. Biederman wrote:
>> >> > Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> 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.

>> >> 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.

> 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.

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

^ permalink raw reply

* Re: [PATCH V6 00/10] namespaces: log namespaces per task
From: Richard Guy Briggs @ 2015-04-28  2:05 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	pmoore-H+wXaHxf7aLQT0dZR+AlfA, linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
	eparis-FjpueFixGhCM4zKIHC2jIg, sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8
In-Reply-To: <87bnid9v4f.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>

On 15/04/24, Eric W. Biederman wrote:
> Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:
> > On 15/04/22, Richard Guy Briggs wrote:
> >> On 15/04/20, Eric W. Biederman wrote:
> >> > Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:
> >> > 
> >> > > The purpose is to track namespace instances in use by logged processes from the
> >> > > perspective of init_*_ns by logging the namespace IDs (device ID and namespace
> >> > > inode - offset).
> >> > 
> >> > In broad strokes the user interface appears correct.
> >> > 
> >> > Things that I see that concern me:
> >> > 
> >> > - After Als most recent changes these inodes no longer live in the proc
> >> >   superblock so the device number reported in these patches is
> >> >   incorrect.
> >> 
> >> Ok, found the patchset you're talking about:
> >> 	3d3d35b kill proc_ns completely
> >> 	e149ed2 take the targets of /proc/*/ns/* symlinks to separate fs
> >> 	f77c801 bury struct proc_ns in fs/proc
> >> 	33c4294 copy address of proc_ns_ops into ns_common
> >> 	6344c43 new helpers: ns_alloc_inum/ns_free_inum
> >> 	6496452 make proc_ns_operations work with struct ns_common * instead of void *
> >> 	3c04118 switch the rest of proc_ns_operations to working with &...->ns
> >> 	ff24870 netns: switch ->get()/->put()/->install()/->inum() to working with &net->ns
> >> 	58be2825 make mntns ->get()/->put()/->install()/->inum() work with &mnt_ns->ns
> >> 	435d5f4 common object embedded into various struct ....ns
> >> 
> >> Ok, I've got some minor jigging to do to get inum too...
> >
> > 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?

> > In fact, I never needed to
> > report the device since proc ida/idr and inodes are kernel-global and
> > namespace-oblivious.
> 
> This is the bit I really want to keep to be forward looking.  If we
> every need to preserve the inode numbers across a migration we could
> have different super blocks with different inode numbers for the same
> namespace.

I don't quite follow your argument here, but can accept that in the
future we might add other namespace devices.  I wonder if we might do
that augmentation later and leave out the device number for now...

> >> > - I am nervous about audit logs being flooded with users creating lots
> >> >   of namespaces.  But that is more your lookout than mine.
> >> 
> >> There was a thought to create a filter to en/disable this logging...
> >> It is an auxiliary record to syscalls, so they can be ignored by userspace tools.
> >> 
> >> > - unshare is not logging when it creates new namespaces.
> >> 
> >> 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.

> >> > As small numbers are nice and these inodes all live in their own
> >> > superblock now we should be able to remove the games with
> >> > PROC_DYNAMIC_FIRST and just use small numbers for these inodes
> >> > everywhere.
> >> 
> >> That is compelling if I can untangle the proc inode allocation code from the
> >> ida/idr.  Should be as easy as defining a new ns_alloc_inum (and ns_free_inum)
> >> to use instead of proc_alloc_inum with its own ns_inum_ida and ns_inum_lock,
> >> then defining a NS_DYNAMIC_FIRST and defining NS_{IPC,UTS,USER,PID}_INIT_INO in
> >> the place of the existing PROC_*_INIT_INO.
> 
> Something like that.  Just a new ida/idr allocator specific to that
> superblock.
> 
> Yeah.  It is somewhere on my todo, but I have been prioritizing getting
> the bugs that look potentially expoloitable fixed in the mount
> namespace.  Al made things nice for one case but left a mess for a bunch
> of others.
> 
> >> > I honestly don't know how much we are going to care about namespace ids
> >> > during migration.  So far this is not a problem that has come up.
> >> 
> >> Not for CRIU, but it will be an issue for a container auditor that aggregates
> >> information from individually auditted hosts.
> >> 
> >> > I don't think migration becomes a practical concern (other than
> >> > interface wise) until achieve a non-init namespace auditd.  The easy way
> >> > to handle migration would be to log a setns of every process from their
> >> > old namespaces to their new namespaces.  As you appear to have a setns
> >> > event defined.
> >> 
> >> Again, this would be taken care of by a layer above that is container-aware
> >> across multiple hosts.
> 
> 
> >> > How to handle the more general case beyond audit remains unclear.  I
> >> > think it will be a little while yet before we start dealing with
> >> > migrating applications that care.  When we do we will either need to
> >> > generate some kind of hot-plug event that userspace can respond to and
> >> > discover all of the appropriate file-system nodes have changed, or we
> >> > will need to build a mechanism in the kernel to preserve these numbers.
> >> 
> >> I don't expect to need to preserve these numbers.  The higher layer application
> >> will be able to do that translation.
> 
> We need to be very aware of what is happening.
> 
> The situation I am concerned about looks something like.
> 
> Program A:
>   fd1 = open(/proc/self/ns/net);
>   fstat(fd1, &stat1)
> 
>   ... later ...
> 
>   fd2 = open(/var/run/netns/johnny);
>   fstat(fd2, &stat2);
> 
>   if ((stat1.st_dev == stat2.st_dev) &&
>       (stat1.st_ino == stat2.st_ino)) {
> 	/* Same netns do something... */
>   }
> 
> 
> What happens when we migrate Program A with it's cached stat data of
> of a network namespace file?
> 
> This requires either a hotplug event that Program A listens to or that
> the inode number and device number are preserved across migration.
> 
> Exactly what we do depends on where we are when it comes up.  But this
> is not something some layer about the program can abstract it all out so
> we don't need to worry about it.

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.

> Eric

- 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: [PATCH V6 00/10] namespaces: log namespaces per task
From: Eric W. Biederman @ 2015-04-24 19:36 UTC (permalink / raw)
  To: Richard Guy Briggs
  Cc: containers, linux-kernel, pmoore, linux-audit, eparis, sgrubb,
	zohar
In-Reply-To: <20150423204429.GA25794@madcap2.tricolour.ca>

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:
>> > 
>> > > The purpose is to track namespace instances in use by logged processes from the
>> > > perspective of init_*_ns by logging the namespace IDs (device ID and namespace
>> > > inode - offset).
>> > 
>> > In broad strokes the user interface appears correct.
>> > 
>> > Things that I see that concern me:
>> > 
>> > - After Als most recent changes these inodes no longer live in the proc
>> >   superblock so the device number reported in these patches is
>> >   incorrect.
>> 
>> Ok, found the patchset you're talking about:
>> 	3d3d35b kill proc_ns completely
>> 	e149ed2 take the targets of /proc/*/ns/* symlinks to separate fs
>> 	f77c801 bury struct proc_ns in fs/proc
>> 	33c4294 copy address of proc_ns_ops into ns_common
>> 	6344c43 new helpers: ns_alloc_inum/ns_free_inum
>> 	6496452 make proc_ns_operations work with struct ns_common * instead of void *
>> 	3c04118 switch the rest of proc_ns_operations to working with &...->ns
>> 	ff24870 netns: switch ->get()/->put()/->install()/->inum() to working with &net->ns
>> 	58be2825 make mntns ->get()/->put()/->install()/->inum() work with &mnt_ns->ns
>> 	435d5f4 common object embedded into various struct ....ns
>> 
>> Ok, I've got some minor jigging to do to get inum too...
>
> 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.

> In fact, I never needed to
> report the device since proc ida/idr and inodes are kernel-global and
> namespace-oblivious.

This is the bit I really want to keep to be forward looking.  If we
every need to preserve the inode numbers across a migration we could
have different super blocks with different inode numbers for the same
namespace.

>> > - I am nervous about audit logs being flooded with users creating lots
>> >   of namespaces.  But that is more your lookout than mine.
>> 
>> There was a thought to create a filter to en/disable this logging...
>> It is an auxiliary record to syscalls, so they can be ignored by userspace tools.
>> 
>> > - unshare is not logging when it creates new namespaces.
>> 
>> 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.

>> > As small numbers are nice and these inodes all live in their own
>> > superblock now we should be able to remove the games with
>> > PROC_DYNAMIC_FIRST and just use small numbers for these inodes
>> > everywhere.
>> 
>> That is compelling if I can untangle the proc inode allocation code from the
>> ida/idr.  Should be as easy as defining a new ns_alloc_inum (and ns_free_inum)
>> to use instead of proc_alloc_inum with its own ns_inum_ida and ns_inum_lock,
>> then defining a NS_DYNAMIC_FIRST and defining NS_{IPC,UTS,USER,PID}_INIT_INO in
>> the place of the existing PROC_*_INIT_INO.

Something like that.  Just a new ida/idr allocator specific to that
superblock.

Yeah.  It is somewhere on my todo, but I have been prioritizing getting
the bugs that look potentially expoloitable fixed in the mount
namespace.  Al made things nice for one case but left a mess for a bunch
of others.

>> > I honestly don't know how much we are going to care about namespace ids
>> > during migration.  So far this is not a problem that has come up.
>> 
>> Not for CRIU, but it will be an issue for a container auditor that aggregates
>> information from individually auditted hosts.
>> 
>> > I don't think migration becomes a practical concern (other than
>> > interface wise) until achieve a non-init namespace auditd.  The easy way
>> > to handle migration would be to log a setns of every process from their
>> > old namespaces to their new namespaces.  As you appear to have a setns
>> > event defined.
>> 
>> Again, this would be taken care of by a layer above that is container-aware
>> across multiple hosts.


>> > How to handle the more general case beyond audit remains unclear.  I
>> > think it will be a little while yet before we start dealing with
>> > migrating applications that care.  When we do we will either need to
>> > generate some kind of hot-plug event that userspace can respond to and
>> > discover all of the appropriate file-system nodes have changed, or we
>> > will need to build a mechanism in the kernel to preserve these numbers.
>> 
>> I don't expect to need to preserve these numbers.  The higher layer application
>> will be able to do that translation.

We need to be very aware of what is happening.

The situation I am concerned about looks something like.

Program A:
  fd1 = open(/proc/self/ns/net);
  fstat(fd1, &stat1)

  ... later ...

  fd2 = open(/var/run/netns/johnny);
  fstat(fd2, &stat2);

  if ((stat1.st_dev == stat2.st_dev) &&
      (stat1.st_ino == stat2.st_ino)) {
	/* Same netns do something... */
  }


What happens when we migrate Program A with it's cached stat data of
of a network namespace file?

This requires either a hotplug event that Program A listens to or that
the inode number and device number are preserved across migration.

Exactly what we do depends on where we are when it comes up.  But this
is not something some layer about the program can abstract it all out so
we don't need to worry about it.

Eric

^ permalink raw reply

* Changes to the git repository
From: Paul Moore @ 2015-04-23 21:05 UTC (permalink / raw)
  To: linux-audit

Hello All,

A quick update on some changes to the git repository: we've reached that point 
in time where we need to resync with Linus to catch all the upstream changes 
that have been occurring since we last rebased the audit tree.  In a perfect 
world I would have realized this before I sent the v4.1 pull request to Linus 
and rebased audit#upstream before merging in audit#next, but we did not live 
in a perfect world as evidenced by the fact that you have this yahoo looking 
after the audit tree :)

So ... here is what we're going to do, my apologies in advance if this causes 
you some porting headaches (if it does, let me know and we'll try to work 
something out):

[NOTE: a few slight tweaks to our normal process for this round of branch 
rotations only, after this we will resume our normal operation]

1. Create a new stable branch, stable-4.1, set to audit#upstream at the time 
of the v4.1 pull request.

2. Reset the next branch to v4.0.

3. Accept new features into the next branch and fixes into the stable-4.1 
branch.

4. As necessary, merge stable-4.1 into upstream and send pull requests 
upstream.

5. When v4.1 is released, reset upstream to v4.1, merge audit#next into 
upstream and send a pull request for the upstream branch.

6. Resume normal operation.

If you've got any questions, let me know.

-Paul

-- 
paul moore
www.paul-moore.com

^ permalink raw reply

* Re: [PATCH V6 00/10] namespaces: log namespaces per task
From: Richard Guy Briggs @ 2015-04-23 20:44 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: containers, linux-kernel, linux-audit, sgrubb, eparis, pmoore,
	arozansk, serge, zohar
In-Reply-To: <20150423030751.GA6712@madcap2.tricolour.ca>

On 15/04/22, Richard Guy Briggs wrote:
> On 15/04/20, Eric W. Biederman wrote:
> > Richard Guy Briggs <rgb@redhat.com> writes:
> > 
> > > The purpose is to track namespace instances in use by logged processes from the
> > > perspective of init_*_ns by logging the namespace IDs (device ID and namespace
> > > inode - offset).
> > 
> > In broad strokes the user interface appears correct.
> > 
> > Things that I see that concern me:
> > 
> > - After Als most recent changes these inodes no longer live in the proc
> >   superblock so the device number reported in these patches is
> >   incorrect.
> 
> Ok, found the patchset you're talking about:
> 	3d3d35b kill proc_ns completely
> 	e149ed2 take the targets of /proc/*/ns/* symlinks to separate fs
> 	f77c801 bury struct proc_ns in fs/proc
> 	33c4294 copy address of proc_ns_ops into ns_common
> 	6344c43 new helpers: ns_alloc_inum/ns_free_inum
> 	6496452 make proc_ns_operations work with struct ns_common * instead of void *
> 	3c04118 switch the rest of proc_ns_operations to working with &...->ns
> 	ff24870 netns: switch ->get()/->put()/->install()/->inum() to working with &net->ns
> 	58be2825 make mntns ->get()/->put()/->install()/->inum() work with &mnt_ns->ns
> 	435d5f4 common object embedded into various struct ....ns
> 
> Ok, I've got some minor jigging to do to get inum too...

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?  In fact, I never needed to
report the device since proc ida/idr and inodes are kernel-global and
namespace-oblivious.

> > - I am nervous about audit logs being flooded with users creating lots
> >   of namespaces.  But that is more your lookout than mine.
> 
> There was a thought to create a filter to en/disable this logging...
> It is an auxiliary record to syscalls, so they can be ignored by userspace tools.
> 
> > - unshare is not logging when it creates new namespaces.
> 
> 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
> 
> > As small numbers are nice and these inodes all live in their own
> > superblock now we should be able to remove the games with
> > PROC_DYNAMIC_FIRST and just use small numbers for these inodes
> > everywhere.
> 
> That is compelling if I can untangle the proc inode allocation code from the
> ida/idr.  Should be as easy as defining a new ns_alloc_inum (and ns_free_inum)
> to use instead of proc_alloc_inum with its own ns_inum_ida and ns_inum_lock,
> then defining a NS_DYNAMIC_FIRST and defining NS_{IPC,UTS,USER,PID}_INIT_INO in
> the place of the existing PROC_*_INIT_INO.
> 
> > I have answered your comments below.
> 
> More below...
> 
> > > 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  proc_ns: define PROC_*_INIT_INO in terms of PROC_DYNAMIC_FIRST
> > >
> > > 3/10 provides an example of usage for audit_log_task_info() which is used by
> > > syscall audits, among others.  audit_log_task() and audit_common_recv_message()
> > > would be other potential use cases.
> > >
> > > 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.  It has now returned to being a seperate record.  The proc device
> > > major/minor are listed in hexadecimal and namespace IDs are the proc inode
> > > minus the base offset.
> > > 	type=NS_INFO msg=audit(1408577535.306:82): dev=00:03 netns=3 utsns=-3 ipcns=-4 pidns=-1 userns=-2 mntns=0
> > >
> > > 4/10 change audit startup from __initcall to subsys_initcall to get it started
> > > earlier to be able to receive initial namespace log messages.
> > >
> > > 5/10 tracks the creation and deletion of namespaces, listing the type of
> > > namespace instance, proc 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(1408577534.868:5): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=kernel dev=00:03 old_utsns=(none) utsns=-3 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=-2 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=-1 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=-4 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
> > >
> > > 6/10 accepts a PID from userspace and requests logging an AUDIT_NS_INFO record
> > > type (CAP_AUDIT_CONTROL required).
> > >
> > > 7/10 is a macro for CLONE_NEW_* flags.
> > >
> > > 8/10 adds auditing on creation of namespace(s) in fork.
> > >
> > > 9/10 adds auditing a change of namespace on setns.
> > >
> > > 10/10 attaches a AUDIT_NS_INFO record to AUDIT_VIRT_CONTROL records
> > > (CAP_AUDIT_WRITE required).
> > >
> > >
> > > 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.
> > 
> > I honestly don't know how much we are going to care about namespace ids
> > during migration.  So far this is not a problem that has come up.
> 
> Not for CRIU, but it will be an issue for a container auditor that aggregates
> information from individually auditted hosts.
> 
> > I don't think migration becomes a practical concern (other than
> > interface wise) until achieve a non-init namespace auditd.  The easy way
> > to handle migration would be to log a setns of every process from their
> > old namespaces to their new namespaces.  As you appear to have a setns
> > event defined.
> 
> Again, this would be taken care of by a layer above that is container-aware
> across multiple hosts.
> 
> > How to handle the more general case beyond audit remains unclear.  I
> > think it will be a little while yet before we start dealing with
> > migrating applications that care.  When we do we will either need to
> > generate some kind of hot-plug event that userspace can respond to and
> > discover all of the appropriate file-system nodes have changed, or we
> > will need to build a mechanism in the kernel to preserve these numbers.
> 
> I don't expect to need to preserve these numbers.  The higher layer application
> will be able to do that translation.
> 
> > I really don't know which solution we will wind up with in the kernel at
> > this point.
> > 
> > > What additional events should list this information?
> > 
> > At least unshare.
> 
> Already covered as noted above.  If it is a brand new namespace, it will show
> the old one as "(none)" (or maybe zero now that we are looking at renumbering
> the NS inodes).  If it is an unshared one, it will show the old one from which
> it was unshared.
> 
> > > 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.
> > 
> > Good question.  Today access to this information is generally guarded
> > with CAP_SYS_PTRACE.
> > 
> > I suspect for some of audits tracing features like this one we should
> > also use CAP_SYS_PTRACE so that we have a consistent set of checks for
> > getting information about applications.
> 
> I assume CAP_SYS_PTRACE is orthogonal to CAP_AUDIT_{CONTROL,READ} and that
> CAP_SYS_PTRACE would need to be insufficient to get that information.
> 
> 
> Thanks for your thoughtful feedback, Eric.
> 
> > Eric
> > 
> > > Richard Guy Briggs (10):
> > >   namespaces: expose ns_entries
> > >   proc_ns: define PROC_*_INIT_INO in terms of PROC_DYNAMIC_FIRST
> > >   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
> > >   sched: add a macro to ref all CLONE_NEW* flags
> > >   fork: audit on creation of new namespace(s)
> > >   audit: log on switching namespace (setns)
> > >   audit: emit AUDIT_NS_INFO record with AUDIT_VIRT_CONTROL record
> > >
> > >  fs/namespace.c                   |   13 +++
> > >  fs/proc/generic.c                |    3 +-
> > >  fs/proc/namespaces.c             |    2 +-
> > >  include/linux/audit.h            |   20 +++++
> > >  include/linux/proc_ns.h          |   10 ++-
> > >  include/uapi/linux/audit.h       |   21 +++++
> > >  include/uapi/linux/sched.h       |    6 ++
> > >  ipc/namespace.c                  |   12 +++
> > >  kernel/audit.c                   |  169 +++++++++++++++++++++++++++++++++++++-
> > >  kernel/auditsc.c                 |    2 +
> > >  kernel/fork.c                    |    3 +
> > >  kernel/nsproxy.c                 |    4 +
> > >  kernel/pid_namespace.c           |   13 +++
> > >  kernel/user_namespace.c          |   13 +++
> > >  kernel/utsname.c                 |   12 +++
> > >  net/core/net_namespace.c         |   12 +++
> > >  security/integrity/ima/ima_api.c |    2 +
> > >  17 files changed, 309 insertions(+), 8 deletions(-)
> 
> - RGB

- 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: [PATCH V6 00/10] namespaces: log namespaces per task
From: Richard Guy Briggs @ 2015-04-23  3:07 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	pmoore-H+wXaHxf7aLQT0dZR+AlfA, linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
	eparis-FjpueFixGhCM4zKIHC2jIg, sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8
In-Reply-To: <87vbgqw163.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>

On 15/04/20, Eric W. Biederman wrote:
> Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:
> 
> > The purpose is to track namespace instances in use by logged processes from the
> > perspective of init_*_ns by logging the namespace IDs (device ID and namespace
> > inode - offset).
> 
> In broad strokes the user interface appears correct.
> 
> Things that I see that concern me:
> 
> - After Als most recent changes these inodes no longer live in the proc
>   superblock so the device number reported in these patches is
>   incorrect.

Ok, found the patchset you're talking about:
	3d3d35b kill proc_ns completely
	e149ed2 take the targets of /proc/*/ns/* symlinks to separate fs
	f77c801 bury struct proc_ns in fs/proc
	33c4294 copy address of proc_ns_ops into ns_common
	6344c43 new helpers: ns_alloc_inum/ns_free_inum
	6496452 make proc_ns_operations work with struct ns_common * instead of void *
	3c04118 switch the rest of proc_ns_operations to working with &...->ns
	ff24870 netns: switch ->get()/->put()/->install()/->inum() to working with &net->ns
	58be2825 make mntns ->get()/->put()/->install()/->inum() work with &mnt_ns->ns
	435d5f4 common object embedded into various struct ....ns

Ok, I've got some minor jigging to do to get inum too...

> - I am nervous about audit logs being flooded with users creating lots
>   of namespaces.  But that is more your lookout than mine.

There was a thought to create a filter to en/disable this logging...
It is an auxiliary record to syscalls, so they can be ignored by userspace tools.

> - unshare is not logging when it creates new namespaces.

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

> As small numbers are nice and these inodes all live in their own
> superblock now we should be able to remove the games with
> PROC_DYNAMIC_FIRST and just use small numbers for these inodes
> everywhere.

That is compelling if I can untangle the proc inode allocation code from the
ida/idr.  Should be as easy as defining a new ns_alloc_inum (and ns_free_inum)
to use instead of proc_alloc_inum with its own ns_inum_ida and ns_inum_lock,
then defining a NS_DYNAMIC_FIRST and defining NS_{IPC,UTS,USER,PID}_INIT_INO in
the place of the existing PROC_*_INIT_INO.

> I have answered your comments below.

More below...

> > 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  proc_ns: define PROC_*_INIT_INO in terms of PROC_DYNAMIC_FIRST
> >
> > 3/10 provides an example of usage for audit_log_task_info() which is used by
> > syscall audits, among others.  audit_log_task() and audit_common_recv_message()
> > would be other potential use cases.
> >
> > 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.  It has now returned to being a seperate record.  The proc device
> > major/minor are listed in hexadecimal and namespace IDs are the proc inode
> > minus the base offset.
> > 	type=NS_INFO msg=audit(1408577535.306:82): dev=00:03 netns=3 utsns=-3 ipcns=-4 pidns=-1 userns=-2 mntns=0
> >
> > 4/10 change audit startup from __initcall to subsys_initcall to get it started
> > earlier to be able to receive initial namespace log messages.
> >
> > 5/10 tracks the creation and deletion of namespaces, listing the type of
> > namespace instance, proc 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(1408577534.868:5): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=kernel dev=00:03 old_utsns=(none) utsns=-3 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=-2 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=-1 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=-4 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
> >
> > 6/10 accepts a PID from userspace and requests logging an AUDIT_NS_INFO record
> > type (CAP_AUDIT_CONTROL required).
> >
> > 7/10 is a macro for CLONE_NEW_* flags.
> >
> > 8/10 adds auditing on creation of namespace(s) in fork.
> >
> > 9/10 adds auditing a change of namespace on setns.
> >
> > 10/10 attaches a AUDIT_NS_INFO record to AUDIT_VIRT_CONTROL records
> > (CAP_AUDIT_WRITE required).
> >
> >
> > 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.
> 
> I honestly don't know how much we are going to care about namespace ids
> during migration.  So far this is not a problem that has come up.

Not for CRIU, but it will be an issue for a container auditor that aggregates
information from individually auditted hosts.

> I don't think migration becomes a practical concern (other than
> interface wise) until achieve a non-init namespace auditd.  The easy way
> to handle migration would be to log a setns of every process from their
> old namespaces to their new namespaces.  As you appear to have a setns
> event defined.

Again, this would be taken care of by a layer above that is container-aware
across multiple hosts.

> How to handle the more general case beyond audit remains unclear.  I
> think it will be a little while yet before we start dealing with
> migrating applications that care.  When we do we will either need to
> generate some kind of hot-plug event that userspace can respond to and
> discover all of the appropriate file-system nodes have changed, or we
> will need to build a mechanism in the kernel to preserve these numbers.

I don't expect to need to preserve these numbers.  The higher layer application
will be able to do that translation.

> I really don't know which solution we will wind up with in the kernel at
> this point.
> 
> > What additional events should list this information?
> 
> At least unshare.

Already covered as noted above.  If it is a brand new namespace, it will show
the old one as "(none)" (or maybe zero now that we are looking at renumbering
the NS inodes).  If it is an unshared one, it will show the old one from which
it was unshared.

> > 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.
> 
> Good question.  Today access to this information is generally guarded
> with CAP_SYS_PTRACE.
> 
> I suspect for some of audits tracing features like this one we should
> also use CAP_SYS_PTRACE so that we have a consistent set of checks for
> getting information about applications.

I assume CAP_SYS_PTRACE is orthogonal to CAP_AUDIT_{CONTROL,READ} and that
CAP_SYS_PTRACE would need to be insufficient to get that information.


Thanks for your thoughtful feedback, Eric.

> Eric
> 
> > Richard Guy Briggs (10):
> >   namespaces: expose ns_entries
> >   proc_ns: define PROC_*_INIT_INO in terms of PROC_DYNAMIC_FIRST
> >   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
> >   sched: add a macro to ref all CLONE_NEW* flags
> >   fork: audit on creation of new namespace(s)
> >   audit: log on switching namespace (setns)
> >   audit: emit AUDIT_NS_INFO record with AUDIT_VIRT_CONTROL record
> >
> >  fs/namespace.c                   |   13 +++
> >  fs/proc/generic.c                |    3 +-
> >  fs/proc/namespaces.c             |    2 +-
> >  include/linux/audit.h            |   20 +++++
> >  include/linux/proc_ns.h          |   10 ++-
> >  include/uapi/linux/audit.h       |   21 +++++
> >  include/uapi/linux/sched.h       |    6 ++
> >  ipc/namespace.c                  |   12 +++
> >  kernel/audit.c                   |  169 +++++++++++++++++++++++++++++++++++++-
> >  kernel/auditsc.c                 |    2 +
> >  kernel/fork.c                    |    3 +
> >  kernel/nsproxy.c                 |    4 +
> >  kernel/pid_namespace.c           |   13 +++
> >  kernel/user_namespace.c          |   13 +++
> >  kernel/utsname.c                 |   12 +++
> >  net/core/net_namespace.c         |   12 +++
> >  security/integrity/ima/ima_api.c |    2 +
> >  17 files changed, 309 insertions(+), 8 deletions(-)

- 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

* [GIT PULL] Audit patches for 4.1
From: Paul Moore @ 2015-04-22 20:57 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-audit, linux-kernel

Hi Linus,

Seven audit patches for v4.1, all bug fixes.  The largest, and perhaps most 
significant commit helps resolve some memory pressure issues related to the 
inode cache and audit, there are also a few small commits which help resolve 
some timing issues with the audit log queue, and the rest fall into the always 
popular "code clean-up" category.  In general, nothing really substantial, 
just a nice set of maintenance patches.

Thanks,
-Paul

---
The following changes since commit 2fded7f44b8fcf79e274c3f0cfbd0298f95308f3:

  audit: remove vestiges of vers_ops (2015-01-20 10:48:32 -0500)

are available in the git repository at:

  git://git.infradead.org/users/pcmoore/audit upstream

for you to fetch changes up to 724e7bfcc566375158219c1454b4b6fc416b2c4a:

  audit: Remove condition which always evaluates to false
         (2015-03-13 17:32:52 -0400)

----------------------------------------------------------------
Ameen Ali (1):
      audit: code clean up

Davidlohr Bueso (2):
      audit: consolidate handling of mm->exe_file
      audit: reduce mmap_sem hold for mm->exe_file

Imre Palik (1):
      audit: move the tree pruning to a dedicated thread

Pranith Kumar (1):
      audit: Remove condition which always evaluates to false

Richard Guy Briggs (2):
      audit: don't lose set wait time on first successful call to
             audit_log_start()
      audit: don't reset working wait time accidentally with auditd

 kernel/audit.c      | 47 +++++++++++++++++-----------
 kernel/audit.h      |  3 ++
 kernel/audit_tree.c | 88 ++++++++++++++++++++++++++++++++++----------------
 kernel/auditsc.c    |  9 +-----
 4 files changed, 94 insertions(+), 53 deletions(-)

-- 
paul moore
security @ redhat

^ permalink raw reply

* Re: [PATCH V6 00/10] namespaces: log namespaces per task
From: Eric W. Biederman @ 2015-04-21  4:33 UTC (permalink / raw)
  To: Richard Guy Briggs
  Cc: containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	pmoore-H+wXaHxf7aLQT0dZR+AlfA, linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
	eparis-FjpueFixGhCM4zKIHC2jIg, sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8
In-Reply-To: <cover.1429252659.git.rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:

> The purpose is to track namespace instances in use by logged processes from the
> perspective of init_*_ns by logging the namespace IDs (device ID and namespace
> inode - offset).

In broad strokes the user interface appears correct.

Things that I see that concern me:

- After Als most recent changes these inodes no longer live in the proc
  superblock so the device number reported in these patches is
  incorrect.

- I am nervous about audit logs being flooded with users creating lots
  of namespaces.  But that is more your lookout than mine.

- unshare is not logging when it creates new namespaces.

As small numbers are nice and these inodes all live in their own
superblock now we should be able to remove the games with
PROC_DYNAMIC_FIRST and just use small numbers for these inodes
everywhere.

I have answered your comments below.

> 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  proc_ns: define PROC_*_INIT_INO in terms of PROC_DYNAMIC_FIRST
>
> 3/10 provides an example of usage for audit_log_task_info() which is used by
> syscall audits, among others.  audit_log_task() and audit_common_recv_message()
> would be other potential use cases.
>
> 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.  It has now returned to being a seperate record.  The proc device
> major/minor are listed in hexadecimal and namespace IDs are the proc inode
> minus the base offset.
> 	type=NS_INFO msg=audit(1408577535.306:82): dev=00:03 netns=3 utsns=-3 ipcns=-4 pidns=-1 userns=-2 mntns=0
>
> 4/10 change audit startup from __initcall to subsys_initcall to get it started
> earlier to be able to receive initial namespace log messages.
>
> 5/10 tracks the creation and deletion of namespaces, listing the type of
> namespace instance, proc 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(1408577534.868:5): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=kernel dev=00:03 old_utsns=(none) utsns=-3 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=-2 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=-1 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=-4 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
>
> 6/10 accepts a PID from userspace and requests logging an AUDIT_NS_INFO record
> type (CAP_AUDIT_CONTROL required).
>
> 7/10 is a macro for CLONE_NEW_* flags.
>
> 8/10 adds auditing on creation of namespace(s) in fork.
>
> 9/10 adds auditing a change of namespace on setns.
>
> 10/10 attaches a AUDIT_NS_INFO record to AUDIT_VIRT_CONTROL records
> (CAP_AUDIT_WRITE required).
>
>
> 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.

I honestly don't know how much we are going to care about namespace ids
during migration.  So far this is not a problem that has come up.

I don't think migration becomes a practical concern (other than
interface wise) until achieve a non-init namespace auditd.  The easy way
to handle migration would be to log a setns of every process from their
old namespaces to their new namespaces.  As you appear to have a setns
event defined.

How to handle the more general case beyond audit remains unclear.  I
think it will be a little while yet before we start dealing with
migrating applications that care.  When we do we will either need to
generate some kind of hot-plug event that userspace can respond to and
discover all of the appropriate file-system nodes have changed, or we
will need to build a mechanism in the kernel to preserve these numbers.

I really don't know which solution we will wind up with in the kernel at
this point.

> What additional events should list this information?

At least unshare.

> 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.

Good question.  Today access to this information is generally guarded
with CAP_SYS_PTRACE.

I suspect for some of audits tracing features like this one we should
also use CAP_SYS_PTRACE so that we have a consistent set of checks for
getting information about applications.

Eric


> Richard Guy Briggs (10):
>   namespaces: expose ns_entries
>   proc_ns: define PROC_*_INIT_INO in terms of PROC_DYNAMIC_FIRST
>   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
>   sched: add a macro to ref all CLONE_NEW* flags
>   fork: audit on creation of new namespace(s)
>   audit: log on switching namespace (setns)
>   audit: emit AUDIT_NS_INFO record with AUDIT_VIRT_CONTROL record
>
>  fs/namespace.c                   |   13 +++
>  fs/proc/generic.c                |    3 +-
>  fs/proc/namespaces.c             |    2 +-
>  include/linux/audit.h            |   20 +++++
>  include/linux/proc_ns.h          |   10 ++-
>  include/uapi/linux/audit.h       |   21 +++++
>  include/uapi/linux/sched.h       |    6 ++
>  ipc/namespace.c                  |   12 +++
>  kernel/audit.c                   |  169 +++++++++++++++++++++++++++++++++++++-
>  kernel/auditsc.c                 |    2 +
>  kernel/fork.c                    |    3 +
>  kernel/nsproxy.c                 |    4 +
>  kernel/pid_namespace.c           |   13 +++
>  kernel/user_namespace.c          |   13 +++
>  kernel/utsname.c                 |   12 +++
>  net/core/net_namespace.c         |   12 +++
>  security/integrity/ima/ima_api.c |    2 +
>  17 files changed, 309 insertions(+), 8 deletions(-)

^ permalink raw reply

* Re: [PATCH V6 07/10] sched: add a macro to ref all CLONE_NEW* flags
From: Richard Guy Briggs @ 2015-04-17 22:00 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: linux-api-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	pmoore-H+wXaHxf7aLQT0dZR+AlfA, linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
	eparis-FjpueFixGhCM4zKIHC2jIg, sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	mingo-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <20150417174131.GL23123-ndre7Fmf5hadTX5a5knrm8zTDFooKrT+cvkQGrU6aU0@public.gmane.org>

On 15/04/17, Peter Zijlstra wrote:
> On Fri, Apr 17, 2015 at 11:42:50AM -0400, Richard Guy Briggs wrote:
> > On 15/04/17, Peter Zijlstra wrote:
> > > On Fri, Apr 17, 2015 at 03:35:54AM -0400, Richard Guy Briggs wrote:
> > > > Added the macro CLONE_NEW_MASK_ALL to refer to all CLONE_NEW* flags.
> > > 
> > > A wee bit about why might be nice..
> > 
> > It makes the following patch much cleaner to read:
> > 	[PATCH V6 08/10] fork: audit on creation of new namespace(s)
> > 	https://lkml.org/lkml/2015/4/17/50
> > 
> > I was hoping it might also make a lot of other code cleaner, but most of
> > the other places where multiple CLONE_NEW* flags are used, not all six
> > are used together, but only 5 are used.  Ok, so it is helpful in 1 of 3:
> > 
> > It would actually be useful in check_unshare_flags():
> > 	https://github.com/torvalds/linux/blob/v3.17/kernel/fork.c#L1791
> > 
> > but not in copy_namespaces() or unshare_nsproxy_namespaces():
> > 	https://github.com/torvalds/linux/blob/v3.17/kernel/nsproxy.c#L130
> > 	https://github.com/torvalds/linux/blob/v3.17/kernel/nsproxy.c#L183
> 
> Right, so no objections from me on this, its just that I only saw this
> one patch in isolation without context and the changelog failed on
> rationale.

I realize you only saw a small window of this patchset, but this feels
like bike shedding about the main objective of the set...

I'll add a bit more justification and context if/when I respin for the
rest of the set.

> Does it perchance make sense to fold this patch into the next patch that
> actually makes use of it?

It would if it were the only potential user.  I don't want to bury a
surprise in something bigger.  Is there a preferred way to use such a
macro to make the other three examples cleaner, or is that just useless
churn and obfuscation?  Would there be a concise way to express all
CLONE_NEW* flags *except* user?

- 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: [PATCH V6 07/10] sched: add a macro to ref all CLONE_NEW* flags
From: Peter Zijlstra @ 2015-04-17 17:41 UTC (permalink / raw)
  To: Richard Guy Briggs
  Cc: linux-api-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	pmoore-H+wXaHxf7aLQT0dZR+AlfA, linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
	eparis-FjpueFixGhCM4zKIHC2jIg, sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	mingo-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <20150417154250.GA26233-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org>

On Fri, Apr 17, 2015 at 11:42:50AM -0400, Richard Guy Briggs wrote:
> On 15/04/17, Peter Zijlstra wrote:
> > On Fri, Apr 17, 2015 at 03:35:54AM -0400, Richard Guy Briggs wrote:
> > > Added the macro CLONE_NEW_MASK_ALL to refer to all CLONE_NEW* flags.
> > 
> > A wee bit about why might be nice..
> 
> It makes the following patch much cleaner to read:
> 	[PATCH V6 08/10] fork: audit on creation of new namespace(s)
> 	https://lkml.org/lkml/2015/4/17/50
> 
> I was hoping it might also make a lot of other code cleaner, but most of
> the other places where multiple CLONE_NEW* flags are used, not all six
> are used together, but only 5 are used.  Ok, so it is helpful in 1 of 3:
> 
> It would actually be useful in check_unshare_flags():
> 	https://github.com/torvalds/linux/blob/v3.17/kernel/fork.c#L1791
> 
> but not in copy_namespaces() or unshare_nsproxy_namespaces():
> 	https://github.com/torvalds/linux/blob/v3.17/kernel/nsproxy.c#L130
> 	https://github.com/torvalds/linux/blob/v3.17/kernel/nsproxy.c#L183
> 

Right, so no objections from me on this, its just that I only saw this
one patch in isolation without context and the changelog failed on
rationale.

Does it perchance make sense to fold this patch into the next patch that
actually makes use of it?

^ permalink raw reply

* Re: [PATCH V6 07/10] sched: add a macro to ref all CLONE_NEW* flags
From: Richard Guy Briggs @ 2015-04-17 15:42 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: containers, linux-kernel, linux-audit, sgrubb, eparis, pmoore,
	arozansk, ebiederm, serge, zohar, linux-api, mingo
In-Reply-To: <20150417081843.GE23123@twins.programming.kicks-ass.net>

On 15/04/17, Peter Zijlstra wrote:
> On Fri, Apr 17, 2015 at 03:35:54AM -0400, Richard Guy Briggs wrote:
> > Added the macro CLONE_NEW_MASK_ALL to refer to all CLONE_NEW* flags.
> 
> A wee bit about why might be nice..

It makes the following patch much cleaner to read:
	[PATCH V6 08/10] fork: audit on creation of new namespace(s)
	https://lkml.org/lkml/2015/4/17/50

I was hoping it might also make a lot of other code cleaner, but most of
the other places where multiple CLONE_NEW* flags are used, not all six
are used together, but only 5 are used.  Ok, so it is helpful in 1 of 3:

It would actually be useful in check_unshare_flags():
	https://github.com/torvalds/linux/blob/v3.17/kernel/fork.c#L1791

but not in copy_namespaces() or unshare_nsproxy_namespaces():
	https://github.com/torvalds/linux/blob/v3.17/kernel/nsproxy.c#L130
	https://github.com/torvalds/linux/blob/v3.17/kernel/nsproxy.c#L183

- 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: [PATCH V6 07/10] sched: add a macro to ref all CLONE_NEW* flags
From: Peter Zijlstra @ 2015-04-17  8:18 UTC (permalink / raw)
  To: Richard Guy Briggs
  Cc: linux-api-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	pmoore-H+wXaHxf7aLQT0dZR+AlfA, linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
	eparis-FjpueFixGhCM4zKIHC2jIg, sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	mingo-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <cf1ed24f71743ea7f85682f26f3185202a1f8a32.1429252659.git.rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

On Fri, Apr 17, 2015 at 03:35:54AM -0400, Richard Guy Briggs wrote:
> Added the macro CLONE_NEW_MASK_ALL to refer to all CLONE_NEW* flags.

A wee bit about why might be nice..

^ permalink raw reply

* [PATCH V6 10/10] audit: emit AUDIT_NS_INFO record with AUDIT_VIRT_CONTROL record
From: Richard Guy Briggs @ 2015-04-17  7:35 UTC (permalink / raw)
  To: containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-audit-H+wXaHxf7aLQT0dZR+AlfA
  Cc: linux-api-u79uwXL29TY76Z2rM5mHXA, pmoore-H+wXaHxf7aLQT0dZR+AlfA,
	eparis-FjpueFixGhCM4zKIHC2jIg, sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <cover.1429252659.git.rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

Signed-off-by: Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 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 567b45f..b6a55fe 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 a7b1b61..8a01d88 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -943,6 +943,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(NULL);
 			mutex_lock(&audit_cmd_mutex);
 		}
 		break;
-- 
1.7.1

^ permalink raw reply related

* [PATCH V6 09/10] audit: log on switching namespace (setns)
From: Richard Guy Briggs @ 2015-04-17  7:35 UTC (permalink / raw)
  To: containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-audit-H+wXaHxf7aLQT0dZR+AlfA
  Cc: linux-api-u79uwXL29TY76Z2rM5mHXA, pmoore-H+wXaHxf7aLQT0dZR+AlfA,
	eparis-FjpueFixGhCM4zKIHC2jIg, sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <cover.1429252659.git.rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

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-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 include/linux/audit.h      |    4 +++
 include/uapi/linux/audit.h |    6 +++++
 kernel/audit.c             |   52 ++++++++++++++++++++++++++++++++++++++++++++
 kernel/nsproxy.c           |    3 ++
 4 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index b28dfb0..c71c819 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;
@@ -487,6 +488,7 @@ static inline void	    audit_log_ns_info(struct task_struct *tsk)
 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 void		    audit_log_ns_set(const struct proc_ns_operations *ops, void *ns);
 
 extern int		    audit_update_lsm_rules(void);
 
@@ -550,6 +552,8 @@ static inline int audit_log_ns_init(int type, unsigned int old_inum,
 { }
 static inline int audit_log_ns_del(int type, unsigned int inum)
 { }
+static inline void audit_log_ns_set(const struct proc_ns_operations *ops, void *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 487cad6..567b45f 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 b7f10e9..a7b1b61 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2054,6 +2054,58 @@ void audit_log_ns_del(int type, unsigned int inum)
 			 inum - PROC_DYNAMIC_FIRST);
 	audit_log_end(ab);
 }
+
+/**
+ * audit_log_ns_set - report a namespace set change
+ * @ops: the ops structure for the namespace to be changed
+ * @ns: the new namespace
+ */
+void audit_log_ns_set(const struct proc_ns_operations *ops, void *ns)
+{
+	struct audit_buffer *ab;
+	void *old_ns;
+	int msg_type;
+	struct vfsmount *mnt = task_active_pid_ns(current)->proc_mnt;
+	struct super_block *sb = mnt->mnt_sb;
+	char old_ns_s[16];
+
+	switch (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;
+	}
+	audit_log_common_recv_msg(&ab, ops->type);
+	if (!ab)
+		return;
+	old_ns = ops->get(current);
+	if (!ops->inum(old_ns))
+		sprintf(old_ns_s, "(none)");
+	else
+		sprintf(old_ns_s, "%d", ops->inum(old_ns) - PROC_DYNAMIC_FIRST);
+	audit_log_format(ab, " dev=%02x:%02x old_%sns=%s %sns=%d res=1",
+			 MAJOR(sb->s_dev), MINOR(sb->s_dev),
+			 ops->name, old_ns_s,
+			 ops->name, ops->inum(ns));
+	ops->put(old_ns);
+	audit_log_end(ab);
+}
 #endif /* CONFIG_NAMESPACES */
 
 /**
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index d5353c2..2ca86cf 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -257,6 +257,9 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype)
 		goto out;
 	}
 	switch_task_namespaces(tsk, new_nsproxy);
+
+	audit_log_ns_set(ops, ei->ns);
+
 out:
 	fput(file);
 	return err;
-- 
1.7.1

^ permalink raw reply related

* [PATCH V6 08/10] fork: audit on creation of new namespace(s)
From: Richard Guy Briggs @ 2015-04-17  7:35 UTC (permalink / raw)
  To: containers, linux-kernel, linux-audit
  Cc: Richard Guy Briggs, sgrubb, eparis, pmoore, arozansk, ebiederm,
	serge, zohar
In-Reply-To: <cover.1429252659.git.rgb@redhat.com>

When clone(2) is called to fork a new process creating one or more namespaces,
audit the event to tie the new pid with the namespace IDs.

Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
---
 kernel/fork.c    |    3 +++
 kernel/nsproxy.c |    1 +
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/kernel/fork.c b/kernel/fork.c
index 6a13c46..2ea1225 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1624,6 +1624,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 */
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index 8e78110..d5353c2 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;
 
-- 
1.7.1

^ permalink raw reply related

* [PATCH V6 07/10] sched: add a macro to ref all CLONE_NEW* flags
From: Richard Guy Briggs @ 2015-04-17  7:35 UTC (permalink / raw)
  To: containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-audit-H+wXaHxf7aLQT0dZR+AlfA
  Cc: linux-api-u79uwXL29TY76Z2rM5mHXA, pmoore-H+wXaHxf7aLQT0dZR+AlfA,
	mingo-H+wXaHxf7aLQT0dZR+AlfA, eparis-FjpueFixGhCM4zKIHC2jIg,
	sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <cover.1429252659.git.rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

Added the macro CLONE_NEW_MASK_ALL to refer to all CLONE_NEW* flags.

Signed-off-by: Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 include/uapi/linux/sched.h |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/include/uapi/linux/sched.h b/include/uapi/linux/sched.h
index 34f9d73..21ed8f4 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 */
 
 /*
-- 
1.7.1

^ permalink raw reply related

* [PATCH V6 06/10] audit: dump namespace IDs for pid on receipt of AUDIT_NS_INFO
From: Richard Guy Briggs @ 2015-04-17  7:35 UTC (permalink / raw)
  To: containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-audit-H+wXaHxf7aLQT0dZR+AlfA
  Cc: pmoore-H+wXaHxf7aLQT0dZR+AlfA, eparis-FjpueFixGhCM4zKIHC2jIg,
	sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <cover.1429252659.git.rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

When a task with CAP_AUDIT_CONTROL sends a NETLINK_AUDIT message of type
AUDIT_NS_INFO with a PID of interest, 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 |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/kernel/audit.c b/kernel/audit.c
index e6230c4..b7f10e9 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -674,6 +674,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)
@@ -1070,6 +1071,19 @@ 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();
+		audit_log_ns_info(tsk);
+	}
+#else /* CONFIG_NAMESPACES */
+		err = -EOPNOTSUPP;
+#endif /* CONFIG_NAMESPACES */
 	default:
 		err = -EINVAL;
 		break;
-- 
1.7.1

^ permalink raw reply related

* [PATCH V6 05/10] audit: log creation and deletion of namespace instances
From: Richard Guy Briggs @ 2015-04-17  7:35 UTC (permalink / raw)
  To: containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-audit-H+wXaHxf7aLQT0dZR+AlfA
  Cc: linux-api-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	pmoore-H+wXaHxf7aLQT0dZR+AlfA, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	eparis-FjpueFixGhCM4zKIHC2jIg, sgrubb-H+wXaHxf7aLQT0dZR+AlfA,
	zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <cover.1429252659.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=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)
-- 
1.7.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox