RFC: Containerized syslog (Take II)
Subsystems (3)
PATCH 1/1 RFC: Containerized syslog (Take II)
Containerized syslog is now part of nsproxy. A new flag CLONE_SYSLOG allow to unshare syslog area.
Main containerized syslog purpose is to allow full container not to leak or compromise hosts syslog data.
--- include/linux/init_task.h | 2 + include/linux/nsproxy.h | 2 + include/linux/sched.h | 1 + include/linux/syslog.h | 9 ++-- include/linux/user_namespace.h | 1 - kernel/fork.c | 2 +- kernel/nsproxy.c | 18 +++++++- kernel/printk.c | 14 +++--- kernel/syslog.c | 84 ++++++++++++++++++++++++++++++++-------- kernel/user.c | 3 - kernel/user_namespace.c | 5 -- 11 files changed, 101 insertions(+), 40 deletions(-)
include/linux/init_task.h +2 -0
@@ -11,6 +11,7 @@#include <linux/user_namespace.h> #include <linux/securebits.h> #include <net/net_namespace.h> +#include <linux/syslog.h> extern struct files_struct init_files;extern struct fs_struct init_fs;
@@ -37,6 +38,7 @@ extern struct nsproxy init_nsproxy; .count = ATOMIC_INIT(1), \ .uts_ns = &init_uts_ns, \ .mnt_ns = NULL, \ + .syslog_ns = &init_kernel_syslog_ns, \ INIT_NET_NS(net_ns) \ INIT_IPC_NS(ipc_ns) \ }
include/linux/nsproxy.h +2 -0
@@ -3,6 +3,7 @@#include <linux/spinlock.h> #include <linux/sched.h> +#include <linux/syslog.h> struct mnt_namespace ;struct uts_namespace ;
@@ -29,6 +30,7 @@ struct nsproxy {struct mnt_namespace *mnt_ns;struct pid_namespace *pid_ns;struct net *net_ns; +struct syslog_ns *syslog_ns; };extern struct nsproxy init_nsproxy;
include/linux/sched.h +1 -0
@@ -9,6 +9,7 @@#define CLONE_FS 0x00000200/* set if fs info shared between processes */ #define CLONE_FILES 0x00000400/* set if open files shared between processes */ #define CLONE_SIGHAND 0x00000800/* set if signal handlers and blocked signals shared */ +#define CLONE_SYSLOG 0x00001000/* set if we need private syslog (/proc/kmsg) */ #define CLONE_PTRACE 0x00002000/* set if we want to let tracing continue on the child too */ #define CLONE_VFORK 0x00004000/* set if the parent wants the child to wake it up on mm_release */ #define CLONE_PARENT 0x00008000/* set if we want to have the same parent as the cloner */
include/linux/syslog.h +5 -4
@@ -3,6 +3,7 @@#include <linux/spinlock_types.h> struct syslog_ns { +struct kref kref;/*syslog_ns reference count & control */ wait_queue_head_t wait;spinlock_t logbuf_lock;/* access conflict locker */ unsigned log_start;/* Index into log_buf: next char to be read by syslog() */
@@ -22,8 +23,8 @@ extern struct syslog_ns init_kernel_syslog_ns;* Syslog API * */ -extern struct syslog_ns *syslog_malloc (unsigned container_buf_len); -extern struct syslog_ns *syslog_realloc (struct syslog_ns *syslog_ns,unsigned container_buf_len); -extern struct syslog_ns *syslog_free (struct syslog_ns *syslog); -extern struct syslog_ns *syslog_get_current (void ); +extern struct syslog_ns *realloc_syslog_ns (struct syslog_ns *syslog_ns,unsigned container_buf_len); +extern struct syslog_ns *copy_syslog_ns (unsigned long flags,struct syslog_ns *current_syslog_ns); +extern struct syslog_ns *release_syslog_ns (struct syslog_ns *current_syslog_ns); +extern struct syslog_ns *get_current_syslog_ns (void );#endif /* _LINUX_SYSLOG_H */
include/linux/user_namespace.h +0 -1
@@ -14,7 +14,6 @@ struct user_namespace {struct hlist_head uidhash_table[UIDHASH_SZ ];struct user_struct *creator;struct work_struct destroyer; -struct syslog_ns *syslog; };extern struct user_namespace init_user_ns;
kernel/fork.c +1 -1
@@ -1647,7 +1647,7 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) err = -EINVAL ;if (unshare_flags & ~(CLONE_THREAD |CLONE_FS |CLONE_NEWNS |CLONE_SIGHAND |CLONE_VM |CLONE_FILES |CLONE_SYSVSEM | -CLONE_NEWUTS |CLONE_NEWIPC |CLONE_NEWNET )) +CLONE_NEWUTS |CLONE_NEWIPC |CLONE_NEWNET |CLONE_SYSLOG )) goto bad_unshare_out;/*
kernel/nsproxy.c +15 -3
@@ -44,6 +44,8 @@ static inline struct nsproxy *create_nsproxy(void)static struct nsproxy *create_new_namespaces (unsigned long flags,struct task_struct *tsk,struct fs_struct *new_fs) { +#define CONTAINER_BUF_LEN 4096/*should be enough for container syslog */ +struct nsproxy *new_nsp;int err;
@@ -80,9 +82,17 @@ static struct nsproxy *create_new_namespaces(unsigned long flags, err =PTR_ERR (new_nsp->net_ns); goto out_net; } - + new_nsp->syslog_ns =copy_syslog_ns (flags, tsk->nsproxy->syslog_ns); +if (IS_ERR (new_nsp->syslog_ns)) { + err =PTR_ERR (new_nsp->syslog_ns); + goto out_syslog; + } +return new_nsp; +out_syslog: +if (new_nsp->net_ns) +put_net (new_nsp->net_ns); out_net:if (new_nsp->pid_ns)put_pid_ns (new_nsp->pid_ns);
@@ -116,7 +126,7 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)get_nsproxy (old_ns);if (!(flags & (CLONE_NEWNS |CLONE_NEWUTS |CLONE_NEWIPC | -CLONE_NEWPID |CLONE_NEWNET ))) +CLONE_NEWPID |CLONE_NEWNET |CLONE_SYSLOG )))return 0 ;if (!capable (CAP_SYS_ADMIN )) {
@@ -151,6 +161,8 @@ out:void free_nsproxy (struct nsproxy *ns) { +if (ns->syslog_ns) + ns->syslog_ns=release_syslog_ns (ns->syslog_ns);if (ns->mnt_ns)put_mnt_ns (ns->mnt_ns);if (ns->uts_ns)
@@ -173,7 +185,7 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags,int err =0 ;if (!(unshare_flags & (CLONE_NEWNS |CLONE_NEWUTS |CLONE_NEWIPC | -CLONE_NEWNET ))) +CLONE_NEWNET |CLONE_SYSLOG )))return 0 ;if (!capable (CAP_SYS_ADMIN ))
kernel/printk.c +7 -7
@@ -148,7 +148,7 @@ static int saved_console_loglevel = -1;*/ void log_buf_kexec_setup (void ) { -struct syslog_ns *syslog_ns =syslog_get_current (); +struct syslog_ns *syslog_ns =get_current_syslog_ns ();VMCOREINFO_SYMBOL (sys_log_buf);VMCOREINFO_SYMBOL (sys_log_end);
@@ -163,7 +163,7 @@ static int __init log_buf_len_setup(char *str)if (size) { size =roundup_pow_of_two (size); - (void )syslog_realloc (&init_kernel_syslog_ns,size); + (void )realloc_syslog_ns (&init_kernel_syslog_ns,size); }return 1 ; }
@@ -244,7 +244,7 @@ int do_syslog(int type, char __user *buf, int len)int do_clear =0 ;char c;int error =0 ; -struct syslog_ns *syslog_ns =syslog_get_current (); +struct syslog_ns *syslog_ns =get_current_syslog_ns (); error =security_syslog (type);if (error)
@@ -638,7 +638,7 @@ asmlinkage int vprintk(const char *fmt, va_list args) {int printed_len =0 ;int current_log_level = default_message_loglevel; -struct syslog_ns *syslog_ns =syslog_get_current (); +struct syslog_ns *syslog_ns =get_current_syslog_ns ();unsigned long flags;int this_cpu;char *p;
@@ -1012,7 +1012,7 @@ void release_console_sem(void)unsigned long flags;unsigned _con_start, _log_end;unsigned wake_klogd =0 ; -struct syslog_ns *syslog_ns =syslog_get_current (); +struct syslog_ns *syslog_ns =get_current_syslog_ns ();for ( ; ; ) {spin_lock_irqsave (&sys_log_lock, flags);
@@ -1252,7 +1252,7 @@ void register_console(struct console *newcon)* for us. */ -struct syslog_ns *syslog_ns =syslog_get_current (); +struct syslog_ns *syslog_ns =get_current_syslog_ns ();spin_lock_irqsave (&sys_log_lock, flags); sys_log_con_start = sys_log_start;
@@ -1462,7 +1462,7 @@ void kmsg_dump(enum kmsg_dump_reason reason)const char *s1, *s2;unsigned long l1, l2;unsigned long flags; -struct syslog_ns *syslog_ns =syslog_get_current (); +struct syslog_ns *syslog_ns =get_current_syslog_ns ();/* Theoretically, the log could move on after we do this, but there's not a lot we can do about that. The new messages
kernel/syslog.c +68 -16
155 lines not on this page · raw message
kernel/user.c +0 -3
@@ -23,9 +23,6 @@ struct user_namespace init_user_ns = { .kref = { .refcount = ATOMIC_INIT(2), }, -#ifdef CONFIG_PRINTK - .syslog = &init_kernel_syslog_ns, -#endif .creator = &root_user };EXPORT_SYMBOL_GPL (init_user_ns);
kernel/user_namespace.c +0 -5
@@ -38,11 +38,6 @@ int create_user_ns(struct cred *new)INIT_HLIST_HEAD (ns->uidhash_table + n); - ns->syslog =syslog_malloc (CONTAINER_BUF_LEN ); -if (!ns->syslog) { -kfree (ns); -return -ENOMEM ; - }/* Alloc new root user. */ root_user =alloc_uid (ns,0 );if (!root_user) {
Signature · 1 line
1.6.6
A message that is not in the archive (sent off-list or not yet received): 201002161520.o1GFKC6Q013851-X4ZF2iejbABnc3BsFfMrZw@public.gmane.org
Quoted 6 lines · Jean-Marc Pigeon
Containerized syslog is now part of nsproxy. A new flag
CLONE_SYSLOGallow to unshare syslog area.
Main containerized syslog purpose is to allow full container not to leak or compromise hosts syslog data.
Hi Jean-Marc,
I think this last point deserves significant elaboration. What
does it mean to "not leak or compromise hosts syslog data"? Is it possible to guarantee that we don't leak or is this just a best-effort sort of thing? My hunch is it's the latter. You really must respond to Eric's question of why this is useful. I know it might seem obvious to you but it's not actualy clear. I've found that carefuly explaining my reasoning when it seemed obvious often uncovers hidden assumptions I made and may even suggest problems and/or alternate approaches.
Kernel patch guidelines suggests you should split the patch up so it's one change at a time. One possible way to divide this into a series of patches is:
patch to add krefs
patch to move syslog_ns from user_namespace to nsproxy patch to rename syslog_current_ns() (or whatever) patch to rename X to Y
(There may be better ways to break up the patches -- these just came to mind)
But the krefs patch probably deals with correctness so it should eventually be merged with the first patch (for clean bisectability). The name changes are nice right now, but should also be merged since introducing new code only to change the names later is often pointless. So you're left with:
<modified original patch>
patch to move syslog_ns from user_namespace to nsproxy
...
Each of these patches should have a clear description of why it's
necessary/good -- not just "this patch adds krefs" for example. What problem does adding the krefs solve?
Quoted 13 lines
include/linux/init_task.h +1
-0@@ -11,6 +11,7 @@#include <linux/user_namespace.h> #include <linux/securebits.h> #include <net/net_namespace.h> +#include <linux/syslog.h> extern struct files_struct init_files;extern struct fs_struct init_fs;
include/linux/init_task.h extern struct nsproxy init_nsproxy; · line 41
Quoted 4 lines
include/linux/init_task.h +1
-0@@ -37,6 +38,7 @@ extern struct nsproxy init_nsproxy; .count = ATOMIC_INIT(1), \ .uts_ns = &init_uts_ns, \ .mnt_ns = NULL, \ + .syslog_ns = &init_kernel_syslog_ns, \
s/_kernel_//
(We know it's kernel code..)
<snip>
include/linux/sched.h line 12
Quoted 9 lines
include/linux/sched.h +1
-0@@ -9,6 +9,7 @@#define CLONE_FS 0x00000200/* set if fs info shared between processes */ #define CLONE_FILES 0x00000400/* set if open files shared between processes */ #define CLONE_SIGHAND 0x00000800/* set if signal handlers and blocked signals shared */ +#define CLONE_SYSLOG 0x00001000/* set if we need private syslog (/proc/kmsg) */
Check with Suka on this one -- I seem to recall specific unused CLONE_ flags are, unfortunately, reserved. Otherwise yes, this is the right place and what Serge suggested.
<snip>
Quoted 17 lines
include/linux/user_namespace.h +0
-1@@ -14,7 +14,6 @@ struct user_namespace {struct hlist_head uidhash_table[UIDHASH_SZ ];struct user_struct *creator;struct work_struct destroyer; -struct syslog_ns *syslog; };extern struct user_namespace init_user_ns;kernel/fork.c +0
-0
kernel/fork.c SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) · line 1650
Quoted 5 lines
kernel/fork.c +1
-1@@ -1647,7 +1647,7 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) err = -EINVAL ;if (unshare_flags & ~(CLONE_THREAD |CLONE_FS |CLONE_NEWNS |CLONE_SIGHAND |CLONE_VM |CLONE_FILES |CLONE_SYSVSEM | -CLONE_NEWUTS |CLONE_NEWIPC |CLONE_NEWNET )) +CLONE_NEWUTS |CLONE_NEWIPC |CLONE_NEWNET |CLONE_SYSLOG ))
You shouldn't be able to unshare syslog -- I think it's a security concern. I think just keeping CLONE_SYSLOG out of this set is sufficient for sys_unshare. There's a corresponding check in clone/clone2/eclone which would be similar to how CLONE_NEWPID is privileged.
Quoted 45 lines
kernel/fork.c +0
-0goto bad_unshare_out;/* kernel/nsproxy.c +12
-2@@ -44,6 +44,8 @@ static inline struct nsproxy *create_nsproxy(void)static struct nsproxy *create_new_namespaces (unsigned long flags,struct task_struct *tsk,struct fs_struct *new_fs) { +#define CONTAINER_BUF_LEN 4096/*should be enough for container syslog */ +struct nsproxy *new_nsp;int err;@@ -80,9 +82,17 @@ static struct nsproxy *create_new_namespaces(unsigned long flags, err =PTR_ERR (new_nsp->net_ns); goto out_net; } - + new_nsp->syslog_ns =copy_syslog_ns (flags, tsk->nsproxy->syslog_ns); +if (IS_ERR (new_nsp->syslog_ns)) { + err =PTR_ERR (new_nsp->syslog_ns); + goto out_syslog; + } +return new_nsp; +out_syslog: +if (new_nsp->net_ns) +put_net (new_nsp->net_ns); out_net:if (new_nsp->pid_ns)put_pid_ns (new_nsp->pid_ns);@@ -116,7 +126,7 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)get_nsproxy (old_ns);if (!(flags & (CLONE_NEWNS |CLONE_NEWUTS |CLONE_NEWIPC | -CLONE_NEWPID |CLONE_NEWNET ))) +CLONE_NEWPID |CLONE_NEWNET |CLONE_SYSLOG )))return 0 ;if (!capable (CAP_SYS_ADMIN )) {
kernel/nsproxy.c out: · line 165
Quoted 5 lines
kernel/nsproxy.c +2
-0@@ -151,6 +161,8 @@ out:void free_nsproxy (struct nsproxy *ns) { +if (ns->syslog_ns) + ns->syslog_ns=release_syslog_ns (ns->syslog_ns);
style: space around the assignment operator.
See the kernel Documentation on contributing patches and the style of kernel code -- those are our standards too. scripts/checkpatch.pl will also find many of these things for you.
kernel/nsproxy.c int unshare_nsproxy_namespaces(unsigned long unshare_flags, · line 188
Quoted 9 lines
kernel/nsproxy.c +1
-1if (ns->mnt_ns)put_mnt_ns (ns->mnt_ns);if (ns->uts_ns)@@ -173,7 +185,7 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags,int err =0 ;if (!(unshare_flags & (CLONE_NEWNS |CLONE_NEWUTS |CLONE_NEWIPC | -CLONE_NEWNET ))) +CLONE_NEWNET |CLONE_SYSLOG )))
You shouldn't be able to unshare syslog. It should require using a privileged clone() call like CLONE_NEWPID. So CLONE_SYSLOG doesn't belong here I think.
Quoted 17 lines
kernel/nsproxy.c +0
-0return 0 ;if (!capable (CAP_SYS_ADMIN ))kernel/printk.c +1
-1@@ -148,7 +148,7 @@ static int saved_console_loglevel = -1;*/ void log_buf_kexec_setup (void ) { -struct syslog_ns *syslog_ns =syslog_get_current (); +struct syslog_ns *syslog_ns =get_current_syslog_ns ();VMCOREINFO_SYMBOL (sys_log_buf);VMCOREINFO_SYMBOL (sys_log_end);
kernel/printk.c static int __init log_buf_len_setup(char *str) · line 166
Quoted 5 lines
kernel/printk.c +1
-1@@ -163,7 +163,7 @@ static int __init log_buf_len_setup(char *str)if (size) { size =roundup_pow_of_two (size); - (void )syslog_realloc (&init_kernel_syslog_ns,size); + (void )realloc_syslog_ns (&init_kernel_syslog_ns,size);
style: The namechange looks fine. The (void) cast does not.
Quoted 22 lines
kernel/printk.c +2
-2}return 1 ; }@@ -244,7 +244,7 @@ int do_syslog(int type, char __user *buf, int len)int do_clear =0 ;char c;int error =0 ; -struct syslog_ns *syslog_ns =syslog_get_current (); +struct syslog_ns *syslog_ns =get_current_syslog_ns (); error =security_syslog (type);if (error)@@ -638,7 +638,7 @@ asmlinkage int vprintk(const char *fmt, va_list args) {int printed_len =0 ;int current_log_level = default_message_loglevel; -struct syslog_ns *syslog_ns =syslog_get_current (); +struct syslog_ns *syslog_ns =get_current_syslog_ns ();unsigned long flags;int this_cpu;char *p;
kernel/printk.c void release_console_sem(void) · line 1015
Quoted 5 lines
kernel/printk.c +1
-1@@ -1012,7 +1012,7 @@ void release_console_sem(void)unsigned long flags;unsigned _con_start, _log_end;unsigned wake_klogd =0 ; -struct syslog_ns *syslog_ns =syslog_get_current (); +struct syslog_ns *syslog_ns =get_current_syslog_ns ();
In kernel code, especially namespaces, "get" implies taking an extra reference. So get_current_syslog_ns() needs a different name. I'd name it like the pid
namespace: anything without _ns on the end uses "current".
kernel/printk.c void register_console(struct console *newcon) · line 1255
Quoted 9 lines
kernel/printk.c +1
-1for ( ; ; ) {spin_lock_irqsave (&sys_log_lock, flags);@@ -1252,7 +1252,7 @@ void register_console(struct console *newcon)* for us. */ -struct syslog_ns *syslog_ns =syslog_get_current (); +struct syslog_ns *syslog_ns =get_current_syslog_ns ();
I don't think current necessarily has the relevant syslog_ns here. Current will probably be the tasks involved in device coldplugging -- not the tasks that will be using the console for output. Console/tty code is especially tricky as I recall. This needs more review from someone more familiar with that area I think.
Quoted 19 lines
kernel/printk.c +1
-1spin_lock_irqsave (&sys_log_lock, flags); sys_log_con_start = sys_log_start;@@ -1462,7 +1462,7 @@ void kmsg_dump(enum kmsg_dump_reason reason)const char *s1, *s2;unsigned long l1, l2;unsigned long flags; -struct syslog_ns *syslog_ns =syslog_get_current (); +struct syslog_ns *syslog_ns =get_current_syslog_ns ();/* Theoretically, the log could move on after we do this, but there's not a lot we can do about that. The new messages kernel/syslog.c +0
-0@@ -22,35 +22,66 @@* */
kernel/syslog.c line 33
Quoted 10 lines
kernel/syslog.c +3
-0+#include <linux/module.h> #include <linux/bootmem.h> #include <linux/slab.h> #include <linux/cred.h> +#include <linux/kref.h> #include <linux/user_namespace.h> #include <linux/syslog.h> +#ifdef CONFIG_PRINTK
Shouldn't syslog.c only be compiled if CONFIG_PRINTK is defined? That's a patch to the kernel/Makefile:
obj-$(CONFIG_PRINTK) += syslog.o
Then I think you can avoid this #ifdef entirely.
kernel/syslog.c line 37
Quoted 7 lines
kernel/syslog.c +0
-2/* * Static memory definition, used to assign a syslog * to the kernel itself * */ - -#ifdef CONFIG_PRINTK
I suppose. Again, not a substantial change. To me the comment is unnecessary. This init_foo_ns pattern is quite recognizable to anyone familiar with how things are initialized in the kernel.
Quoted 16 lines
kernel/syslog.c +6
-0#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)static char __log_buf[__LOG_BUF_LEN];struct syslog_ns init_kernel_syslog_ns = { + .kref = { + .refcount =ATOMIC_INIT (2 ), + }, .wait =__WAIT_QUEUE_HEAD_INITIALIZER (init_kernel_syslog_ns.wait), .buf_len = __LOG_BUF_LEN, .buf = __log_buf }; +EXPORT_SYMBOL_GPL (init_kernel_syslog_ns);#endif +/* +* Procedure to free all ressources tied to syslog
kernel/syslog.c line 64
Quoted 10 lines
kernel/syslog.c +10
-0+* +*/ +struct syslog_ns *syslog_free (struct syslog_ns *syslog) + +{ +if (syslog != (struct syslog_ns *)0 ) { + (void )kfree (syslog->buf); + (void )kfree (syslog); + syslog = (struct syslog_ns *)0 ; + }
Ugh. Please run your stuff through checkpatch before the next posting.
Quoted 11 lines
kernel/syslog.c +9
-0+return syslog; +}/* +* Procedure to interface kref _put with syslog_free +* +*/ +static void syslog_out (struct kref *kref) + +{ +struct syslog_ns *sl;
kernel/syslog.c line 84
Quoted 10 lines
kernel/syslog.c +6
-1+ + sl=container_of(kref, struct syslog_ns, kref); + sl=syslog_free (sl); +} +/* * Procedure to assign memory for syslog area * */ -struct syslog_ns *syslog_malloc (unsigned container_buf_len) +static struct syslog_ns *malloc_syslog_ns (unsigned container_buf_len)
For namespaces we've been using "create" rather than foo_[m]alloc. create_pid_namespace, create_user_ns, create_uts_ns, etc.
Quoted 13 lines
kernel/syslog.c +2
-0{struct syslog_ns *ns;@@ -61,6 +92,8 @@ struct syslog_ns * syslog_malloc(unsigned container_buf_len)if (!ns)return ERR_PTR (-ENOMEM ); + (void )kref_init (&(ns->kref)); + ns->buf_len = container_buf_len; ns->buf =kzalloc (container_buf_len,GFP_KERNEL );if (!ns->buf) {
kernel/syslog.c struct syslog_ns * syslog_malloc(unsigned container_buf_len) · line 113
Quoted 5 lines
kernel/syslog.c +1
-1@@ -77,7 +110,7 @@ struct syslog_ns * syslog_malloc(unsigned container_buf_len)* If syslog_ns is NULL, assign a brand new syslog_ns * */ -struct syslog_ns *syslog_realloc (struct syslog_ns *syslog_ns,unsigned container_buf_len) +struct syslog_ns *realloc_syslog_ns (struct syslog_ns *syslog_ns,unsigned container_buf_len)
Does this change the syslog_ns pointer, or just the buffer size? If the latter then resize might be a better word.
Quoted 58 lines
kernel/syslog.c +27
-9{if ((syslog_ns == &init_kernel_syslog_ns ) && (container_buf_len > syslog_ns->buf_len)) {@@ -102,7 +135,7 @@ struct syslog_ns * syslog_realloc(struct syslog_ns *syslog_ns, unsigned containe (void )free_bootmem ((unsigned long )old_buf, old_buf_len); }if (!syslog_ns) -return syslog_malloc (container_buf_len); +return malloc_syslog_ns (container_buf_len);if (syslog_ns->buf_len > container_buf_len) { (void )printk (KERN_WARNING "log_buf_len: Not allowed to decrease syslog buffer\n" );return ERR_PTR (-EINVAL );@@ -126,32 +159,51 @@ struct syslog_ns * syslog_realloc(struct syslog_ns *syslog_ns, unsigned containe (void )printk (KERN_NOTICE "log_buf_len: %u\n" , syslog_ns->buf_len);return syslog_ns; } +/* -* Procedure to free all ressources tied to syslog +* Procedure to use current syslog unless a CLONE_SYSLOG is set +* such a new syslog area is defined and used * */ -struct syslog_ns *syslog_free (struct syslog_ns *syslog) +struct syslog_ns *copy_syslog_ns (unsigned long flags,struct syslog_ns *current_syslog_ns) { -if (syslog != (struct syslog_ns *)0 ) { - (void )kfree (syslog->buf); - (void )kfree (syslog); - syslog = (struct syslog_ns *)0 ; - } -return syslog; +#define CONTAINER_BUF_LEN 4096/*should be enough for container syslog */ + +BUG_ON (!current_syslog_ns); +if ((flags &CLONE_SYSLOG ) ==0 )/*incrementing usage reference count */ + (void )kref_get (&(current_syslog_ns->kref)); +else + current_syslog_ns=malloc_syslog_ns (CONTAINER_BUF_LEN ); +return current_syslog_ns; + +} + +/* +* Procedure to decrement syslog usage count and free memory +* if syslog usage count reach zero. +* +*/ +struct syslog_ns *release_syslog_ns (struct syslog_ns *current_syslog_ns) + +{ +if (kref_put (&(current_syslog_ns->kref), syslog_out)==0 ) + current_syslog_ns=(struct syslog_ns *)0 ; +return current_syslog_ns; }/*
kernel/syslog.c struct syslog_ns * syslog_realloc(struct syslog_ns *syslog_ns, unsigned containe · line 203
Quoted 10 lines
kernel/syslog.c +3
-2-* Procedure to get the current syslog area linked to a container (by CLONE_USER) +* Procedure to get the current syslog area linked to a container (by CLONE_SYSLOG) * if trouble, pin down the problem before it propagate. * */ -struct syslog_ns *syslog_get_current (void ) +struct syslog_ns *get_current_syslog_ns (void ) { +
Whitespace changes mixed with other changes are also frowned upon. This one is totally unnecessary.
So please read up on kernel style and patch submission. Please use checkpatch.pl Please break up your patch where it's logical to do so.
Cheers,
-Matt Helsley
A message that is not in the archive (sent off-list or not yet received): 20100216235909.GB3604-52DBMbEzqgQ/wnmkkaCWp/[email protected]
Bonjour Matt,
Thanks for comments. your time is really appreciated.
Quoted 8 lines · Matt Helsley
I think this last point deserves significant elaboration. What
does it mean to "not leak or compromise hosts syslog data"? Is it possible to guarantee that we don't leak or is this just a best-effort sort of thing? My hunch is it's the latter. You really must respond to Eric's question of why this is useful. I know it might seem obvious to you but it's not actualy clear. I've found that carefuly explaining my reasoning when it seemed obvious often uncovers hidden assumptions I made and may even suggest problems and/or alternate approaches.
You are right, I'll try to give a better rational when posting patches next time.
Quoted 11 lines
Kernel patch guidelines suggests you should split the patch up so it's one change at a time. One possible way to divide this into a series of patches is:
patch to add krefs
patch to movesyslog_nsfromuser_namespaceto nsproxy patch to renamesyslog_current_ns()(or whatever) patch to rename X to Y(There may be better ways to break up the patches -- these just came to mind)
In this case I disagree.
First patch posted is patch to previous (working set) to try to follow Serge suggestion, I should have send both part instead only the last one (not very confortable yet with git).
Patch proposed is a complet set needed to reach a working stage, there is nothing achieved if cut patch in slice, nobody can say it is (not)working without the full patch set...
Quoted 5 lines
Check with Suka on this one -- I seem to recall specific unused
CLONE_flags are, unfortunately, reserved. Otherwise yes, this is the right place and what Serge suggested.
This very CLONE_SYSLOG 0x0001000 flag was suggested by Serge too.
Quoted 1 line
[...]
Quoted 5 lines
You shouldn't be able to unshare syslog -- I think it's a security concern. I think just keeping
CLONE_SYSLOGout of this set is sufficient forsys_unshare. There's a corresponding check in clone/clone2/eclone which would be similar to howCLONE_NEWPIDis privileged.
We must be able to unshare syslog, this the whole point of the exercice. (to make sure about understanding, unshare means "I, process xyz, want to replace current syslog buffer with
my own".
My personal feeling it shouldn't be a CLONE_SYSLOG, but rather going with a more generic as CLONE_NEWPID.
[...]
Quoted 6 lines
kernel/nsproxy.c out: · line 165
Quoted 1 line
kernel/nsproxy.c +1
-0+ ns->syslog_ns=release_syslog_ns (ns->syslog_ns);style: space around the assignment operator.
See the kernel Documentation on contributing patches and the style of kernel code -- those are our standards too.scripts/checkpatch.plwill also find many of these things for you.
Tried to keep local standard, seems my personal way to write code find their way....
Thanks for the pointer scripts/checkpatch.pl
[..[ CLONE_NEWNET | CLONE_SYSLOG )))
Quoted 3 lines
You shouldn't be able to unshare syslog. It should require using a privileged
clone()call likeCLONE_NEWPID. SoCLONE_SYSLOGdoesn't belong here I think.
If you mean we shouldn't be able to unshare syslog in specific, but link unsharing to another CLONE flag I agree. NEWPID seems to be an excellent candidate....
But question... what is the best way to reach consensus on this project??? seems everybody is not in pace with the other.
Quoted 4 lines
In kernel code, especially namespaces, "get" implies taking an extra reference. So
get_current_syslog_ns()needs a different name. I'd name it like the pid
namespace: anything without_nson the end uses "current".
OK, point taken about "get", I'll check about pid_namespace.
Quoted 4 lines
obj-$(CONFIG_PRINTK) += syslog.o
Then I think you can avoid this #ifdef entirely.
Interesting, I was not satisfied with my #ifdef, that should clean the code, Thanks.
Quoted 12 lines
kernel/syslog.c line 37
Quoted 8 lines
/*
* Static memory definition, used to assign a syslog
* to the kernel itself
*
*/kernel/syslog.c +0
-2- -#ifdef CONFIG_PRINTK I suppose. Again, not a substantial change. To me the comment is unnecessary. This
init_foo_nspattern is quite recognizable to anyone familiar with how things are initialized in the kernel.
Well, just notice, for a guy looking at the kernel, I won't call it "cristal clear" (I know it is now an old code), a little bit of help is not that bad. I understand it is not good to write 100 lines of explanation for 10 lines of code, but data pointer are not that bad.
syslog need to be unshared is crystal clear for VZ real user, but you need some data pointer to figure it out (no offense :-}}}).
Quoted 5 lines
kernel/syslog.c line 84
Quoted 2 lines
kernel/syslog.c +1
-1-struct syslog_ns *syslog_malloc (unsigned container_buf_len) +static struct syslog_ns *malloc_syslog_ns (unsigned container_buf_len)For namespaces we've been using "create" rather than foo_[m]alloc.
create_pid_namespace,create_user_ns,create_uts_ns, etc.
My understanding of "create" it doesn't assign memory space each time....syslog_malloc does and I was keeping myself here to the malloc standard library routine. (and malloc_syslog_ns is static, which should give me
a little bit of freedom).
{..]
Quoted 4 lines
Quoted 1 line
+struct
syslog_ns*realloc_syslog_ns(struct syslog_ns *syslog_ns, unsigned container_buf_len)Does this change the
syslog_nspointer, or just the buffer size? If the latter then resize might be a better word.
good idea.
Signature · 14 lines
A bientôt ========================================================================== Jean-Marc Pigeon Internet: [email protected] SAFE Inc. Phone: (514) 493-4280 Fax: (514) 493-1946 Clement, 'a kiss solution' to get rid of SPAM (at last) Clement' Home base <"http://www.clement.safe.ca"> ========================================================================== _______________________________________________ Containers mailing list [email protected] https://lists.linux-foundation.org/mailman/listinfo/containers