syslog ns proof of concept
Subsystems (3)
RFC PATCH 1/1 syslog ns proof of concept
Introduce a system log namespace. The syslog ns is tied to a user namespace. You must create a new user namespace before you can create a new sylog ns. The syslog ns is created through a new command (11) to the __NR_syslog system call.
Once a task enters a new syslog ns, it's "dmesg", "dmesg -c" and /dev/kmsg actions affect only itself, so that user-created syslog messages no longer are confusingly combined in the host's syslog. "printk" itself always goes to the initial syslog_ns, and consoles belong only to the initial syslog_ns. However printks relating to a specific network namespace, for instance, can now be targeted to the syslog ns for the user ns which owns the network ns, aiding in debugging in a container.
This patch is on top of the user namespace enhanced kernel atgit://kernel.ubuntu.com/serge/quantal-userns. It is good enough to compile with stock ubuntu kernel options, boot, launch other syslog namespaces and exercise them. It will need help before it will compile with funky options like CONFIG_PRINTK=n. This is only being sent out to get feedback on the general idea.
Comments greatly appreciated.
(See https://wiki.ubuntu.com/LxcSyslogNs for background).
--- fs/proc/kmsg.c | 12 +- include/linux/printk.h | 1 - include/linux/syslog.h | 70 +++++- include/linux/user_namespace.h | 1 + kernel/printk.c | 530 +++++++++++++++++++++++----------------- kernel/sysctl.c | 3 +- kernel/user.c | 3 + kernel/user_namespace.c | 3 + 8 files changed, 392 insertions(+), 231 deletions(-)
fs/proc/kmsg.c +7 -5
@@ -13,6 +13,8 @@#include <linux/proc_fs.h> #include <linux/fs.h> #include <linux/syslog.h> +#include <linux/cred.h> +#include <linux/user_namespace.h> #include <asm/uaccess.h> #include <asm/io.h>
@@ -21,12 +23,12 @@ extern wait_queue_head_t log_wait;static int kmsg_open (struct inode * inode,struct file * file) { -return do_syslog (SYSLOG_ACTION_OPEN ,NULL ,0 ,SYSLOG_FROM_FILE ); +return do_syslog (file->f_cred->user_ns->syslog_ns,SYSLOG_ACTION_OPEN ,NULL ,0 ,SYSLOG_FROM_FILE ); }static int kmsg_release (struct inode * inode,struct file * file) { - (void )do_syslog (SYSLOG_ACTION_CLOSE ,NULL ,0 ,SYSLOG_FROM_FILE ); + (void )do_syslog (file->f_cred->user_ns->syslog_ns,SYSLOG_ACTION_CLOSE ,NULL ,0 ,SYSLOG_FROM_FILE );return 0 ; }
@@ -34,15 +36,15 @@ static ssize_t kmsg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) {if ((file->f_flags &O_NONBLOCK ) && - !do_syslog (SYSLOG_ACTION_SIZE_UNREAD ,NULL ,0 ,SYSLOG_FROM_FILE )) + !do_syslog (file->f_cred->user_ns->syslog_ns,SYSLOG_ACTION_SIZE_UNREAD ,NULL ,0 ,SYSLOG_FROM_FILE ))return -EAGAIN ; -return do_syslog (SYSLOG_ACTION_READ , buf, count,SYSLOG_FROM_FILE ); +return do_syslog (file->f_cred->user_ns->syslog_ns,SYSLOG_ACTION_READ , buf, count,SYSLOG_FROM_FILE ); }static unsigned int kmsg_poll (struct file *file,poll_table *wait) {poll_wait (file, &log_wait, wait); -if (do_syslog (SYSLOG_ACTION_SIZE_UNREAD ,NULL ,0 ,SYSLOG_FROM_FILE )) +if (do_syslog (file->f_cred->user_ns->syslog_ns,SYSLOG_ACTION_SIZE_UNREAD ,NULL ,0 ,SYSLOG_FROM_FILE ))return POLLIN |POLLRDNORM ;return 0 ; }
include/linux/printk.h +0 -1
@@ -134,7 +134,6 @@ extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, unsigned int interval_msec);extern int printk_delay_msec; -extern int dmesg_restrict;extern int kptr_restrict;void log_buf_kexec_setup (void );
include/linux/syslog.h +69 -1
78 lines not on this page · raw message
include/linux/user_namespace.h +1 -0
@@ -26,6 +26,7 @@ struct user_namespace {kuid_t owner;kgid_t group;unsigned int proc_inum; +struct syslog_ns *syslog_ns; };extern struct user_namespace init_user_ns;
kernel/printk.c +307 -223
1,117 lines not on this page · raw message
kernel/sysctl.c +2 -1
@@ -61,6 +61,7 @@#include <linux/kmod.h> #include <linux/capability.h> #include <linux/binfmts.h> +#include <linux/syslog.h> #include <asm/uaccess.h> #include <asm/processor.h>
@@ -712,7 +713,7 @@ static struct ctl_table kern_table[] = { }, { .procname = "dmesg_restrict", - .data = &dmesg_restrict, + .data = &init_syslog_ns.dmesg_restrict, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec_minmax_sysadmin,
kernel/user.c +3 -0
@@ -18,6 +18,8 @@#include <linux/user_namespace.h> #include <linux/proc_fs.h> +struct syslog_ns ; +extern struct syslog_ns init_syslog_ns;/* * userns count is 1 for root user, 1 for init_uts_ns, * and 1 for... ?
@@ -53,6 +55,7 @@ struct user_namespace init_user_ns = { .owner = GLOBAL_ROOT_UID, .group = GLOBAL_ROOT_GID, .proc_inum = PROC_USER_INIT_INO, + .syslog_ns = &init_syslog_ns, };EXPORT_SYMBOL_GPL (init_user_ns);
kernel/user_namespace.c +3 -0
@@ -21,6 +21,7 @@#include <linux/uaccess.h> #include <linux/ctype.h> #include <linux/projid.h> +#include <linux/syslog.h> static struct kmem_cache *user_ns_cachep__read_mostly ;
@@ -84,6 +85,7 @@ int create_user_ns(struct cred *new) ns->owner = owner; ns->group = group; + ns->syslog_ns =get_syslog_ns (parent_ns->syslog_ns);/* Leave the new user namespace reference ns on new */ set_cred_user_ns (new, ns);
@@ -111,6 +113,7 @@ void free_user_ns(struct kref *kref)struct user_namespace *parent, *ns = container_of(kref, struct user_namespace, kref); +put_syslog_ns (ns->syslog_ns); parent = ns->parent;proc_free_inum (ns->proc_inum);kmem_cache_free (user_ns_cachep, ns);
Signature · 1 line
1.7.10.4
Quoted 21 lines · Serge Hallyn
Introduce a system log namespace. The syslog ns is tied to a user namespace. You must create a new user namespace before you can create a new sylog ns. The syslog ns is created through a new command (11) to the
__NR_syslogsystem call.Once a task enters a new syslog ns, it's "dmesg", "dmesg -c" and
/dev/kmsgactions affect only itself, so that user-created syslog messages no longer are confusingly combined in the host's syslog. "printk" itself always goes to the initialsyslog_ns, and consoles belong only to the initialsyslog_ns. However printks relating to a specific network namespace, for instance, can now be targeted to the syslog ns for the user ns which owns the network ns, aiding in debugging in a container.This patch is on top of the user namespace enhanced kernel at
git://kernel.ubuntu.com/serge/quantal-userns. It is good enough to compile with stock ubuntu kernel options, boot, launch other syslog namespaces and exercise them. It will need help before it will compile with funky options likeCONFIG_PRINTK=n. This is only being sent out to get feedback on the general idea.
Quoted 3 lines
Comments greatly appreciated.
(See https://wiki.ubuntu.com/LxcSyslogNs for background).
Overall I would say the goal sounds well thought out.
I am not a fan of how this ties into the user namespace. I would prefer closer or looser ties. The recursive reference count loop where a userns refers to a syslogns and that syslogns refers to the same userns is unpleasant.
The important case as I understand it is to handle injection of messages into dmesg by userspace?
I would really like to see how messages from networking devices and netfilter would be handled. Right now one of the ugliest bits of lowering the permissions in the network namespace is what do about the commands that set the message loglevel.
In general unless we can safely and sanely direct kernel messages into this new dmesg I don't actually see the point of having another ring buffer in the kernel. If the only success is userspace having the syslog facility simply be unavailable seems more palatable.
Eric
A message that is not in the archive (sent off-list or not yet received): 87haoo3opt.fsf-aS9lmoZGLiVWk0Htik3J/[email protected]
Quoted 25 lines · Eric W. Biederman
Quoted 23 lines · Serge Hallyn
Introduce a system log namespace. The syslog ns is tied to a user namespace. You must create a new user namespace before you can create a new sylog ns. The syslog ns is created through a new command (11) to the
__NR_syslogsystem call.Once a task enters a new syslog ns, it's "dmesg", "dmesg -c" and
/dev/kmsgactions affect only itself, so that user-created syslog messages no longer are confusingly combined in the host's syslog. "printk" itself always goes to the initialsyslog_ns, and consoles belong only to the initialsyslog_ns. However printks relating to a specific network namespace, for instance, can now be targeted to the syslog ns for the user ns which owns the network ns, aiding in debugging in a container.This patch is on top of the user namespace enhanced kernel at
git://kernel.ubuntu.com/serge/quantal-userns. It is good enough to compile with stock ubuntu kernel options, boot, launch other syslog namespaces and exercise them. It will need help before it will compile with funky options likeCONFIG_PRINTK=n. This is only being sent out to get feedback on the general idea.Comments greatly appreciated.
Quoted 8 lines
Quoted 1 line
(See https://wiki.ubuntu.com/LxcSyslogNs for background).
Overall I would say the goal sounds well thought out.
I am not a fan of how this ties into the user namespace. I would prefer closer or looser ties. The recursive reference count loop where a userns refers to a syslogns and that syslogns refers to the same userns is unpleasant.
We could make the nsproxy point to the syslog_ns, but this seemed simpler. Note that the syslog_ns does not need to pin the user_ns, since by design the user_ns owning a syslog_ns can't go away if the syslog_ns is still alive.
But yes, the question of "what should point to the syslog_ns" is what has kept a syslog_ns from being seriously proposed since february 2010 :)
Hm, wait. A nagging feeling made me look back, and I see that I do in fact pin the user_ns from the syslog_ns. I didn't mean to (and I don't release it :) and we don't need to. When a syslog_ns is created, it can only be inherited by child user_ns's, and its owner, the parent user_ns, can never go away until the child user_ns's go away.
Quoted 2 lines
The important case as I understand it is to handle injection of messages into dmesg by userspace?
1. injection of messages into dmesg by userspace, 2. clearing of messages by userspace, but also 3. allowing appropriate kernel printks to be targeted to containers.
Quoted 2 lines
I would really like to see how messages from networking devices and netfilter would be handled. Right now one of the ugliest bits of
It would simply replace a
printk(KERN_NOTICE "doing something\n"); with nsprintk(net->user_ns->syslog_ns, KERN_NOTICE "doing something\n");
I'm not yet clear on whether we'd want nsprintk to print to both the init_syslog_ns (with a ns prefix) and the child ns.
Quoted 2 lines
lowering the permissions in the network namespace is what do about the commands that set the message loglevel.
Here I'm not sure what you mean.
Quoted 4 lines
In general unless we can safely and sanely direct kernel messages into this new dmesg I don't actually see the point of having another ring buffer in the kernel. If the only success is userspace having the syslog facility simply be unavailable seems more palatable.
No I didn't do any in this patch, but directing kernel messages into the new dmesg was definately a goal and should be trivial now.
-serge
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 40 lines · Serge E. Hallyn
Quoted 25 lines · Eric W. Biederman
Quoted 23 lines · Serge Hallyn
Introduce a system log namespace. The syslog ns is tied to a user namespace. You must create a new user namespace before you can create a new sylog ns. The syslog ns is created through a new command (11) to the
__NR_syslogsystem call.Once a task enters a new syslog ns, it's "dmesg", "dmesg -c" and
/dev/kmsgactions affect only itself, so that user-created syslog messages no longer are confusingly combined in the host's syslog. "printk" itself always goes to the initialsyslog_ns, and consoles belong only to the initialsyslog_ns. However printks relating to a specific network namespace, for instance, can now be targeted to the syslog ns for the user ns which owns the network ns, aiding in debugging in a container.This patch is on top of the user namespace enhanced kernel at
git://kernel.ubuntu.com/serge/quantal-userns. It is good enough to compile with stock ubuntu kernel options, boot, launch other syslog namespaces and exercise them. It will need help before it will compile with funky options likeCONFIG_PRINTK=n. This is only being sent out to get feedback on the general idea.Comments greatly appreciated.
Quoted 8 lines
Quoted 1 line
(See https://wiki.ubuntu.com/LxcSyslogNs for background).
Overall I would say the goal sounds well thought out.
I am not a fan of how this ties into the user namespace. I would prefer closer or looser ties. The recursive reference count loop where a userns refers to a syslogns and that syslogns refers to the same userns is unpleasant.
We could make the nsproxy point to the
syslog_ns, but this seemed simpler. Note that thesyslog_nsdoes not need to pin theuser_ns, since by design theuser_nsowning asyslog_nscan't go away if thesyslog_nsis still alive.
Quoted 8 lines
But yes, the question of "what should point to the
syslog_ns" is what has kept asyslog_nsfrom being seriously proposed since february 2010 :)Hm, wait. A nagging feeling made me look back, and I see that I do in fact pin the
user_nsfrom thesyslog_ns. I didn't mean to (and I don't release it :) and we don't need to. When asyslog_nsis created, it can only be inherited by child user_ns's, and its owner, the parentuser_ns, can never go away until the child user_ns's go away.
There is an argument to be made that syslog messages are the kind of security identifiers like uid, gids, and keys that should be part of a user namespace. I'm not fully convinced but there are some DOS attacks that would naturally prevent.
Quoted 10 lines
Quoted 2 lines
The important case as I understand it is to handle injection of messages into dmesg by userspace?
1. injection of messages into dmesg by userspace, 2. clearing of messages by userspace, but also 3. allowing appropriate kernel printks to be targeted to containers.
Quoted 2 lines
I would really like to see how messages from networking devices and netfilter would be handled. Right now one of the ugliest bits of
Quoted 7 lines
It would simply replace a
printk(KERN_NOTICE "doing something\n"); with nsprintk(net->user_ns->syslog_ns, KERN_NOTICE "doing something\n");I'm not yet clear on whether we'd want nsprintk to print to both the
init_syslog_ns(with a ns prefix) and the child ns.
There are some specialized forms of printk like dev_printk and in particular netdev_printk that it would be very interesting if they did the work behind the scenes. So that you could code the obvious thing and it would do the right thing automatically.
Quoted 4 lines
Quoted 2 lines
lowering the permissions in the network namespace is what do about the commands that set the message loglevel.
Here I'm not sure what you mean.
There is a possible DOS attack that by turning on debug messages in a user namespace you can overwhelm syslog.
Quoted 7 lines
Quoted 4 lines
In general unless we can safely and sanely direct kernel messages into this new dmesg I don't actually see the point of having another ring buffer in the kernel. If the only success is userspace having the syslog facility simply be unavailable seems more palatable.
No I didn't do any in this patch, but directing kernel messages into the new dmesg was definately a goal and should be trivial now.
Getting the semantics of which kernel messages should be directed at the new ring buffer and what that means seems to me to be a key factor in seeing how practical this is. Otherwise this seems to call out for a change in userspace.
Certainly inside a user namespace now you can't destructively touch the kernel's syslog at all.
Eric
A message that is not in the archive (sent off-list or not yet received): 87pq3c223i.fsf-aS9lmoZGLiVWk0Htik3J/[email protected]
Quoted 51 lines · Eric W. Biederman
Quoted 40 lines · Serge E. Hallyn
Quoted 25 lines · Eric W. Biederman
Quoted 23 lines · Serge Hallyn
Introduce a system log namespace. The syslog ns is tied to a user namespace. You must create a new user namespace before you can create a new sylog ns. The syslog ns is created through a new command (11) to the
__NR_syslogsystem call.Once a task enters a new syslog ns, it's "dmesg", "dmesg -c" and
/dev/kmsgactions affect only itself, so that user-created syslog messages no longer are confusingly combined in the host's syslog. "printk" itself always goes to the initialsyslog_ns, and consoles belong only to the initialsyslog_ns. However printks relating to a specific network namespace, for instance, can now be targeted to the syslog ns for the user ns which owns the network ns, aiding in debugging in a container.This patch is on top of the user namespace enhanced kernel at
git://kernel.ubuntu.com/serge/quantal-userns. It is good enough to compile with stock ubuntu kernel options, boot, launch other syslog namespaces and exercise them. It will need help before it will compile with funky options likeCONFIG_PRINTK=n. This is only being sent out to get feedback on the general idea.Comments greatly appreciated.
Quoted 8 lines
Quoted 1 line
(See https://wiki.ubuntu.com/LxcSyslogNs for background).
Overall I would say the goal sounds well thought out.
I am not a fan of how this ties into the user namespace. I would prefer closer or looser ties. The recursive reference count loop where a userns refers to a syslogns and that syslogns refers to the same userns is unpleasant.
We could make the nsproxy point to the
syslog_ns, but this seemed simpler. Note that thesyslog_nsdoes not need to pin theuser_ns, since by design theuser_nsowning asyslog_nscan't go away if thesyslog_nsis still alive.Quoted 8 lines
But yes, the question of "what should point to the
syslog_ns" is what has kept asyslog_nsfrom being seriously proposed since february 2010 :)Hm, wait. A nagging feeling made me look back, and I see that I do in fact pin the
user_nsfrom thesyslog_ns. I didn't mean to (and I don't release it :) and we don't need to. When asyslog_nsis created, it can only be inherited by child user_ns's, and its owner, the parentuser_ns, can never go away until the child user_ns's go away.
Quoted 4 lines
There is an argument to be made that syslog messages are the kind of security identifiers like uid, gids, and keys that should be part of a user namespace. I'm not fully convinced but there are some DOS attacks that would naturally prevent.
I can't really think of a good case for not putting the syslogns straight into the userns (i.e. not having a separate syslogns), so I'd say let's go that route.
There is a big locking bug (besides syslog_ns pinning user_ns) in my patch - something needs to be done with struct cont, which pins the syslog_ns. So either when a user_ns is freed we need to flush struct cont if it is pinning this user_ns, or the struct cont should explicitly pin the user_ns.
Quoted 15 lines
Quoted 15 lines
Quoted 2 lines
The important case as I understand it is to handle injection of messages into dmesg by userspace?
1. injection of messages into dmesg by userspace, 2. clearing of messages by userspace, but also 3. allowing appropriate kernel printks to be targeted to containers.
Quoted 2 lines
I would really like to see how messages from networking devices and netfilter would be handled. Right now one of the ugliest bits of
It would simply replace a
printk(KERN_NOTICE "doing something\n"); with nsprintk(net->user_ns->syslog_ns, KERN_NOTICE "doing something\n");
Quoted 7 lines
Quoted 2 lines
I'm not yet clear on whether we'd want nsprintk to print to both the
init_syslog_ns(with a ns prefix) and the child ns.There are some specialized forms of printk like
dev_printkand in particularnetdev_printkthat it would be very interesting if they did the work behind the scenes. So that you could code the obvious thing and it would do the right thing automatically.
Agreed.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
lowering the permissions in the network namespace is what do about the commands that set the message loglevel.
Here I'm not sure what you mean.
There is a possible DOS attack that by turning on debug messages in a user namespace you can overwhelm syslog.
Oh, I see.
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
In general unless we can safely and sanely direct kernel messages into this new dmesg I don't actually see the point of having another ring buffer in the kernel. If the only success is userspace having the syslog facility simply be unavailable seems more palatable.
Quoted 7 lines
Quoted 2 lines
No I didn't do any in this patch, but directing kernel messages into the new dmesg was definately a goal and should be trivial now.
Getting the semantics of which kernel messages should be directed at the new ring buffer and what that means seems to me to be a key factor in seeing how practical this is. Otherwise this seems to call out for a change in userspace.
Ok, I was hoping that once there was a trivial to use nsprintk the appopriate users would be converted by others :), but I can take a look at converting compelling users before I resend.
Quoted 2 lines
Certainly inside a user namespace now you can't destructively touch the kernel's syslog at all.
That should be true, yes.
thanks,
-serge