Linux Container Development
 help / color / mirror / Atom feed
From: Kirill Korotaev <dev-3ImXcnM4P+0@public.gmane.org>
To: Cedric Le Goater <clg-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Cc: containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
Subject: Re: [patch -mm 1/5] mqueue namespace : add struct mq_namespace
Date: Tue, 02 Oct 2007 13:06:49 +0400	[thread overview]
Message-ID: <47020A29.9060403@sw.ru> (raw)
In-Reply-To: <20071002084906.477406083-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>>

Cedric,

how safe does it intersect with netlinks from network namespace?
I see mqueues can send netlink messages, have you checked how safe it is?

Thanks,
Kirill

Cedric Le Goater wrote:
> From: Cedric Le Goater <clg-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
> 
> This patch adds a struct mq_namespace holding the common attributes 
> of the mqueue namespace. 
> 
> The current code is modified to use the default mqueue namespace 
> object 'init_mq_ns' and to prepare the ground for futur dynamic 
> objects.
> 
> Todo:
> 	- use CONFIG_NAMESPACE when next -mm is released
> 
> Signed-off-by: Cedric Le Goater <clg-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
> ---
>  include/linux/mq_namespace.h |   60 +++++++++++++++++++++++
>  ipc/mqueue.c                 |  111 +++++++++++++++++++++++++++----------------
>  2 files changed, 130 insertions(+), 41 deletions(-)
> 
> Index: 2.6.23-rc8-mm2/include/linux/mq_namespace.h
> ===================================================================
> --- /dev/null
> +++ 2.6.23-rc8-mm2/include/linux/mq_namespace.h
> @@ -0,0 +1,60 @@
> +#ifndef _LINUX_MQ_NAMESPACE_H
> +#define _LINUX_MQ_NAMESPACE_H
> +
> +#include <linux/kref.h>
> +
> +struct vfsmount;
> +
> +struct mq_namespace {
> +	struct kref	kref;
> +	struct vfsmount *mnt;
> +
> +	unsigned int	queues_count;
> +	unsigned int	queues_max;
> +	unsigned int	msg_max;
> +	unsigned int	msgsize_max;
> +};
> +
> +extern struct mq_namespace init_mq_ns;
> +
> +#ifdef CONFIG_POSIX_MQUEUE
> +
> +#define INIT_MQ_NS(ns)		.ns		= &init_mq_ns,
> +
> +static inline struct mq_namespace *get_mq_ns(struct mq_namespace *ns)
> +{
> +	if (ns)
> +		kref_get(&ns->kref);
> +	return ns;
> +}
> +
> +extern struct mq_namespace *copy_mq_ns(unsigned long flags,
> +				struct mq_namespace *old_ns);
> +extern void free_mq_ns(struct kref *kref);
> +
> +static inline void put_mq_ns(struct mq_namespace *ns)
> +{
> +	if (ns)
> +		kref_put(&ns->kref, free_mq_ns);
> +}
> +
> +#else
> +
> +#define INIT_MQ_NS(ns)
> +
> +static inline struct mq_namespace *get_mq_ns(struct mq_namespace *ns)
> +{
> +	return ns;
> +}
> +
> +static inline struct mq_namespace *copy_mq_ns(unsigned long flags,
> +					struct mq_namespace *old_ns)
> +{
> +	return old_ns;
> +}
> +
> +static inline void put_mq_ns(struct mq_namespace *ns) { }
> +
> +#endif /* CONFIG_POSIX_MQUEUE */
> +
> +#endif /* _LINUX_MQ_H */
> Index: 2.6.23-rc8-mm2/ipc/mqueue.c
> ===================================================================
> --- 2.6.23-rc8-mm2.orig/ipc/mqueue.c
> +++ 2.6.23-rc8-mm2/ipc/mqueue.c
> @@ -31,6 +31,7 @@
>  #include <linux/mutex.h>
>  #include <linux/nsproxy.h>
>  #include <linux/pid.h>
> +#include <linux/mq_namespace.h>
>  
>  #include <net/sock.h>
>  #include "util.h"
> @@ -87,12 +88,18 @@ static void remove_notification(struct m
>  
>  static spinlock_t mq_lock;
>  static struct kmem_cache *mqueue_inode_cachep;
> -static struct vfsmount *mqueue_mnt;
>  
> -static unsigned int queues_count;
> -static unsigned int queues_max 	= DFLT_QUEUESMAX;
> -static unsigned int msg_max 	= DFLT_MSGMAX;
> -static unsigned int msgsize_max = DFLT_MSGSIZEMAX;
> +struct mq_namespace init_mq_ns = {
> +	.kref = {
> +		.refcount = ATOMIC_INIT(2),
> +	},
> +	.mnt		= NULL,
> +	.queues_count	= 0,
> +	.queues_max 	= DFLT_QUEUESMAX,
> +	.msg_max 	= DFLT_MSGMAX,
> +	.msgsize_max	= DFLT_MSGSIZEMAX,
> +};
> +
>  
>  static struct ctl_table_header * mq_sysctl_table;
>  
> @@ -101,6 +108,21 @@ static inline struct mqueue_inode_info *
>  	return container_of(inode, struct mqueue_inode_info, vfs_inode);
>  }
>  
> +struct mq_namespace *copy_mq_ns(unsigned long flags,
> +				struct mq_namespace *old_ns)
> +{
> +	BUG_ON(!old_ns);
> +	return get_mq_ns(old_ns);
> +}
> +
> +void free_mq_ns(struct kref *kref)
> +{
> +	struct mq_namespace *mq_ns;
> +
> +	mq_ns = container_of(kref, struct mq_namespace, kref);
> +	kfree(mq_ns);
> +}
> +
>  static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
>  							struct mq_attr *attr)
>  {
> @@ -235,6 +257,7 @@ static void mqueue_delete_inode(struct i
>  	struct user_struct *user;
>  	unsigned long mq_bytes;
>  	int i;
> +	struct mq_namespace *mq_ns = &init_mq_ns;
>  
>  	if (S_ISDIR(inode->i_mode)) {
>  		clear_inode(inode);
> @@ -255,7 +278,7 @@ static void mqueue_delete_inode(struct i
>  	if (user) {
>  		spin_lock(&mq_lock);
>  		user->mq_bytes -= mq_bytes;
> -		queues_count--;
> +		mq_ns->queues_count--;
>  		spin_unlock(&mq_lock);
>  		free_uid(user);
>  	}
> @@ -267,20 +290,22 @@ static int mqueue_create(struct inode *d
>  	struct inode *inode;
>  	struct mq_attr *attr = dentry->d_fsdata;
>  	int error;
> +	struct mq_namespace *mq_ns = &init_mq_ns;
>  
>  	spin_lock(&mq_lock);
> -	if (queues_count >= queues_max && !capable(CAP_SYS_RESOURCE)) {
> +	if (mq_ns->queues_count >= mq_ns->queues_max &&
> +		!capable(CAP_SYS_RESOURCE)) {
>  		error = -ENOSPC;
>  		goto out_lock;
>  	}
> -	queues_count++;
> +	mq_ns->queues_count++;
>  	spin_unlock(&mq_lock);
>  
>  	inode = mqueue_get_inode(dir->i_sb, mode, attr);
>  	if (!inode) {
>  		error = -ENOMEM;
>  		spin_lock(&mq_lock);
> -		queues_count--;
> +		mq_ns->queues_count--;
>  		goto out_lock;
>  	}
>  
> @@ -571,7 +596,7 @@ static void remove_notification(struct m
>  	info->notify_owner = NULL;
>  }
>  
> -static int mq_attr_ok(struct mq_attr *attr)
> +static int mq_attr_ok(struct mq_namespace *mq_ns, struct mq_attr *attr)
>  {
>  	if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0)
>  		return 0;
> @@ -579,8 +604,8 @@ static int mq_attr_ok(struct mq_attr *at
>  		if (attr->mq_maxmsg > HARD_MSGMAX)
>  			return 0;
>  	} else {
> -		if (attr->mq_maxmsg > msg_max ||
> -				attr->mq_msgsize > msgsize_max)
> +		if (attr->mq_maxmsg > mq_ns->msg_max ||
> +				attr->mq_msgsize > mq_ns->msgsize_max)
>  			return 0;
>  	}
>  	/* check for overflow */
> @@ -596,8 +621,9 @@ static int mq_attr_ok(struct mq_attr *at
>  /*
>   * Invoked when creating a new queue via sys_mq_open
>   */
> -static struct file *do_create(struct dentry *dir, struct dentry *dentry,
> -			int oflag, mode_t mode, struct mq_attr __user *u_attr)
> +static struct file *do_create(struct mq_namespace *mq_ns, struct dentry *dir,
> +			struct dentry *dentry, int oflag, mode_t mode,
> +			struct mq_attr __user *u_attr)
>  {
>  	struct mq_attr attr;
>  	int ret;
> @@ -607,7 +633,7 @@ static struct file *do_create(struct den
>  		if (copy_from_user(&attr, u_attr, sizeof(attr)))
>  			goto out;
>  		ret = -EINVAL;
> -		if (!mq_attr_ok(&attr))
> +		if (!mq_attr_ok(mq_ns, &attr))
>  			goto out;
>  		/* store for use during create */
>  		dentry->d_fsdata = &attr;
> @@ -619,33 +645,34 @@ static struct file *do_create(struct den
>  	if (ret)
>  		goto out;
>  
> -	return dentry_open(dentry, mqueue_mnt, oflag);
> +	return dentry_open(dentry, mq_ns->mnt, oflag);
>  
>  out:
>  	dput(dentry);
> -	mntput(mqueue_mnt);
> +	mntput(mq_ns->mnt);
>  	return ERR_PTR(ret);
>  }
>  
>  /* Opens existing queue */
> -static struct file *do_open(struct dentry *dentry, int oflag)
> +static struct file *do_open(struct mq_namespace *mq_ns, struct dentry *dentry,
> +			int oflag)
>  {
>  static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
>  					MAY_READ | MAY_WRITE };
>  
>  	if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) {
>  		dput(dentry);
> -		mntput(mqueue_mnt);
> +		mntput(mq_ns->mnt);
>  		return ERR_PTR(-EINVAL);
>  	}
>  
>  	if (permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE], NULL)) {
>  		dput(dentry);
> -		mntput(mqueue_mnt);
> +		mntput(mq_ns->mnt);
>  		return ERR_PTR(-EACCES);
>  	}
>  
> -	return dentry_open(dentry, mqueue_mnt, oflag);
> +	return dentry_open(dentry, mq_ns->mnt, oflag);
>  }
>  
>  asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
> @@ -655,6 +682,7 @@ asmlinkage long sys_mq_open(const char _
>  	struct file *filp;
>  	char *name;
>  	int fd, error;
> +	struct mq_namespace *mq_ns = &init_mq_ns;
>  
>  	error = audit_mq_open(oflag, mode, u_attr);
>  	if (error != 0)
> @@ -667,13 +695,13 @@ asmlinkage long sys_mq_open(const char _
>  	if (fd < 0)
>  		goto out_putname;
>  
> -	mutex_lock(&mqueue_mnt->mnt_root->d_inode->i_mutex);
> -	dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name));
> +	mutex_lock(&mq_ns->mnt->mnt_root->d_inode->i_mutex);
> +	dentry = lookup_one_len(name, mq_ns->mnt->mnt_root, strlen(name));
>  	if (IS_ERR(dentry)) {
>  		error = PTR_ERR(dentry);
>  		goto out_err;
>  	}
> -	mntget(mqueue_mnt);
> +	mntget(mq_ns->mnt);
>  
>  	if (oflag & O_CREAT) {
>  		if (dentry->d_inode) {	/* entry already exists */
> @@ -681,12 +709,12 @@ asmlinkage long sys_mq_open(const char _
>  			error = -EEXIST;
>  			if (oflag & O_EXCL)
>  				goto out;
> -			filp = do_open(dentry, oflag);
> +			filp = do_open(mq_ns, dentry, oflag);
>  		} else {
> -			error = mnt_want_write(mqueue_mnt);
> +			error = mnt_want_write(mq_ns->mnt);
>  			if (error)
>  				goto out;
> -			filp = do_create(mqueue_mnt->mnt_root, dentry,
> +			filp = do_create(mq_ns, mq_ns->mnt->mnt_root, dentry,
>  						oflag, mode, u_attr);
>  		}
>  	} else {
> @@ -694,7 +722,7 @@ asmlinkage long sys_mq_open(const char _
>  		if (!dentry->d_inode)
>  			goto out;
>  		audit_inode(name, dentry);
> -		filp = do_open(dentry, oflag);
> +		filp = do_open(mq_ns, dentry, oflag);
>  	}
>  
>  	if (IS_ERR(filp)) {
> @@ -708,13 +736,13 @@ asmlinkage long sys_mq_open(const char _
>  
>  out:
>  	dput(dentry);
> -	mntput(mqueue_mnt);
> +	mntput(mq_ns->mnt);
>  out_putfd:
>  	put_unused_fd(fd);
>  out_err:
>  	fd = error;
>  out_upsem:
> -	mutex_unlock(&mqueue_mnt->mnt_root->d_inode->i_mutex);
> +	mutex_unlock(&mq_ns->mnt->mnt_root->d_inode->i_mutex);
>  out_putname:
>  	putname(name);
>  	return fd;
> @@ -726,14 +754,15 @@ asmlinkage long sys_mq_unlink(const char
>  	char *name;
>  	struct dentry *dentry;
>  	struct inode *inode = NULL;
> +	struct mq_namespace *mq_ns = &init_mq_ns;
>  
>  	name = getname(u_name);
>  	if (IS_ERR(name))
>  		return PTR_ERR(name);
>  
> -	mutex_lock_nested(&mqueue_mnt->mnt_root->d_inode->i_mutex,
> +	mutex_lock_nested(&mq_ns->mnt->mnt_root->d_inode->i_mutex,
>  			I_MUTEX_PARENT);
> -	dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name));
> +	dentry = lookup_one_len(name, mq_ns->mnt->mnt_root, strlen(name));
>  	if (IS_ERR(dentry)) {
>  		err = PTR_ERR(dentry);
>  		goto out_unlock;
> @@ -747,16 +776,16 @@ asmlinkage long sys_mq_unlink(const char
>  	inode = dentry->d_inode;
>  	if (inode)
>  		atomic_inc(&inode->i_count);
> -	err = mnt_want_write(mqueue_mnt);
> +	err = mnt_want_write(mq_ns->mnt);
>  	if (err)
>  		goto out_err;
>  	err = vfs_unlink(dentry->d_parent->d_inode, dentry);
> -	mnt_drop_write(mqueue_mnt);
> +	mnt_drop_write(mq_ns->mnt);
>  out_err:
>  	dput(dentry);
>  
>  out_unlock:
> -	mutex_unlock(&mqueue_mnt->mnt_root->d_inode->i_mutex);
> +	mutex_unlock(&mq_ns->mnt->mnt_root->d_inode->i_mutex);
>  	putname(name);
>  	if (inode)
>  		iput(inode);
> @@ -1201,14 +1230,14 @@ static int msg_maxsize_limit_max = INT_M
>  static ctl_table mq_sysctls[] = {
>  	{
>  		.procname	= "queues_max",
> -		.data		= &queues_max,
> +		.data		= &init_mq_ns.queues_max,
>  		.maxlen		= sizeof(int),
>  		.mode		= 0644,
>  		.proc_handler	= &proc_dointvec,
>  	},
>  	{
>  		.procname	= "msg_max",
> -		.data		= &msg_max,
> +		.data		= &init_mq_ns.msg_max,
>  		.maxlen		= sizeof(int),
>  		.mode		= 0644,
>  		.proc_handler	= &proc_dointvec_minmax,
> @@ -1217,7 +1246,7 @@ static ctl_table mq_sysctls[] = {
>  	},
>  	{
>  		.procname	= "msgsize_max",
> -		.data		= &msgsize_max,
> +		.data		= &init_mq_ns.msgsize_max,
>  		.maxlen		= sizeof(int),
>  		.mode		= 0644,
>  		.proc_handler	= &proc_dointvec_minmax,
> @@ -1263,13 +1292,13 @@ static int __init init_mqueue_fs(void)
>  	if (error)
>  		goto out_sysctl;
>  
> -	if (IS_ERR(mqueue_mnt = kern_mount(&mqueue_fs_type))) {
> -		error = PTR_ERR(mqueue_mnt);
> +	init_mq_ns.mnt = kern_mount(&mqueue_fs_type);
> +	if (IS_ERR(init_mq_ns.mnt)) {
> +		error = PTR_ERR(init_mq_ns.mnt);
>  		goto out_filesystem;
>  	}
>  
>  	/* internal initialization - not common for vfs */
> -	queues_count = 0;
>  	spin_lock_init(&mq_lock);
>  
>  	return 0;
> 

  parent reply	other threads:[~2007-10-02  9:06 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20071002084608.149781400@fr.ibm.com>
2007-10-02  8:46 ` [patch -mm 1/5] mqueue namespace : add struct mq_namespace Cedric Le Goater
2007-10-02  8:46 ` [patch -mm 2/5] mqueue namespace : add unshare support Cedric Le Goater
2007-10-02  8:46 ` [patch -mm 3/5] mqueue namespace : add get_sb_single_per_data() Cedric Le Goater
2007-10-02  8:46 ` [patch -mm 4/5] mqueue namespace : enable the namespace Cedric Le Goater
2007-10-02  8:46 ` [patch -mm 5/5] mqueue namespace : make sysctl work per namespace Cedric Le Goater
     [not found] ` <20071002084906.477406083@fr.ibm.com>
     [not found]   ` <20071002084906.477406083-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
2007-10-02  9:06     ` Kirill Korotaev [this message]
     [not found]       ` <47020A29.9060403-3ImXcnM4P+0@public.gmane.org>
2007-10-02 10:13         ` [patch -mm 1/5] mqueue namespace : add struct mq_namespace Cedric Le Goater
     [not found]           ` <470219BC.3050702-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
2007-10-02 10:59             ` Eric W. Biederman
     [not found]               ` <m1ir5plr3c.fsf-T1Yj925okcoyDheHMi7gv2pdwda3JcWeAL8bYrjMMd8@public.gmane.org>
2007-10-02 12:21                 ` Cedric Le Goater
     [not found]                   ` <470237C7.5000902-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
2007-10-02 16:30                     ` sukadev-r/Jw6+rmf7HQT0dZR+AlfA
     [not found]                       ` <20071002163020.GA11207-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2007-10-02 17:16                         ` Eric W. Biederman
     [not found]                           ` <m1k5q5jv29.fsf-T1Yj925okcoyDheHMi7gv2pdwda3JcWeAL8bYrjMMd8@public.gmane.org>
2007-10-03  7:12                             ` Cedric Le Goater
     [not found]                               ` <470340F8.50806-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
2007-10-03  7:38                                 ` Cedric Le Goater
     [not found]                                   ` <47034712.9060101-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
2007-10-03 14:32                                     ` Eric W. Biederman
2007-10-03  7:44                         ` Cedric Le Goater
     [not found]                           ` <47034868.5010505-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
2007-10-03 13:59                             ` Serge E. Hallyn
     [not found]                               ` <20071003135955.GA7934-6s5zFf/epYLPQpwDFJZrxKsjOiXwFzmk@public.gmane.org>
2007-10-03 14:11                                 ` Cedric Le Goater
     [not found]                                   ` <4703A30F.2010007-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
2007-10-03 16:56                                     ` sukadev-r/Jw6+rmf7HQT0dZR+AlfA
     [not found]                                       ` <20071003165644.GA338-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2007-10-03 17:03                                         ` Eric W. Biederman
     [not found]                                           ` <m1myv0ceqp.fsf-T1Yj925okcoyDheHMi7gv2pdwda3JcWeAL8bYrjMMd8@public.gmane.org>
2007-10-03 17:09                                             ` sukadev-r/Jw6+rmf7HQT0dZR+AlfA
     [not found]                                               ` <20071003170930.GB338-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2007-10-04 13:12                                                 ` Cedric Le Goater
     [not found]                                                   ` <4704E6C7.5010908-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
2007-10-04 13:32                                                     ` Serge E. Hallyn
2007-10-02 17:02                     ` Eric W. Biederman
     [not found] ` <20071002084608.149781400-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
2007-10-02 10:50   ` [patch -mm 0/5] mqueue namespace Eric W. Biederman
     [not found]     ` <m1przxlrim.fsf-T1Yj925okcoyDheHMi7gv2pdwda3JcWeAL8bYrjMMd8@public.gmane.org>
2007-10-02 11:06       ` Cedric Le Goater
2007-10-02 11:01   ` Eric W. Biederman
     [not found]     ` <m1ejgdlr0a.fsf-T1Yj925okcoyDheHMi7gv2pdwda3JcWeAL8bYrjMMd8@public.gmane.org>
2007-10-02 11:41       ` Cedric Le Goater

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=47020A29.9060403@sw.ru \
    --to=dev-3imxcnm4p+0@public.gmane.org \
    --cc=clg-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org \
    --cc=containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox