Commit a5494dcd authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Linus Torvalds
Browse files

[PATCH] sysctl: move SYSV IPC sysctls to their own file



This is just a simple cleanup to keep kernel/sysctl.c from getting to crowded
with special cases, and by keeping all of the ipc logic to together it makes
the code a little more readable.

[gcoady.lk@gmail.com: build fix]
Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
Cc: Serge E. Hallyn <serue@us.ibm.com>
Cc: Herbert Poetzl <herbert@13thfloor.at>
Cc: Kirill Korotaev <dev@sw.ru>
Signed-off-by: default avatarGrant Coady <gcoady.lk@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 39732acd
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -125,6 +125,12 @@ config IPC_NS
	  environments, to use ipc namespaces to provide different ipc
	  environments, to use ipc namespaces to provide different ipc
	  objects for different servers.  If unsure, say N.
	  objects for different servers.  If unsure, say N.


config SYSVIPC_SYSCTL
	bool
	depends on SYSVIPC
	depends on SYSCTL
	default y

config POSIX_MQUEUE
config POSIX_MQUEUE
	bool "POSIX Message Queues"
	bool "POSIX Message Queues"
	depends on NET && EXPERIMENTAL
	depends on NET && EXPERIMENTAL
+1 −0
Original line number Original line Diff line number Diff line
@@ -4,6 +4,7 @@


obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o
obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o
obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o
obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o
obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o
obj_mq-$(CONFIG_COMPAT) += compat_mq.o
obj_mq-$(CONFIG_COMPAT) += compat_mq.o
obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y)
obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y)

ipc/ipc_sysctl.c

0 → 100644
+183 −0
Original line number Original line Diff line number Diff line
/*
 *  Copyright (C) 2007
 *
 *  Author: Eric Biederman <ebiederm@xmision.com>
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License as
 *  published by the Free Software Foundation, version 2 of the
 *  License.
 */

#include <linux/module.h>
#include <linux/ipc.h>
#include <linux/nsproxy.h>
#include <linux/sysctl.h>
#include <linux/uaccess.h>

#ifdef CONFIG_IPC_NS
static void *get_ipc(ctl_table *table)
{
	char *which = table->data;
	struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
	which = (which - (char *)&init_ipc_ns) + (char *)ipc_ns;
	return which;
}
#else
#define get_ipc(T) ((T)->data)
#endif

#ifdef CONFIG_PROC_FS
static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
	void __user *buffer, size_t *lenp, loff_t *ppos)
{
	struct ctl_table ipc_table;
	memcpy(&ipc_table, table, sizeof(ipc_table));
	ipc_table.data = get_ipc(table);

	return proc_dointvec(&ipc_table, write, filp, buffer, lenp, ppos);
}

static int proc_ipc_doulongvec_minmax(ctl_table *table, int write,
	struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
{
	struct ctl_table ipc_table;
	memcpy(&ipc_table, table, sizeof(ipc_table));
	ipc_table.data = get_ipc(table);

	return proc_doulongvec_minmax(&ipc_table, write, filp, buffer,
					lenp, ppos);
}

#else
#define proc_ipc_doulongvec_minmax NULL
#define proc_ipc_dointvec	   NULL
#endif

#ifdef CONFIG_SYSCTL_SYSCALL
/* The generic sysctl ipc data routine. */
static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen,
		void __user *oldval, size_t __user *oldlenp,
		void __user *newval, size_t newlen)
{
	size_t len;
	void *data;

	/* Get out of I don't have a variable */
	if (!table->data || !table->maxlen)
		return -ENOTDIR;

	data = get_ipc(table);
	if (!data)
		return -ENOTDIR;

	if (oldval && oldlenp) {
		if (get_user(len, oldlenp))
			return -EFAULT;
		if (len) {
			if (len > table->maxlen)
				len = table->maxlen;
			if (copy_to_user(oldval, data, len))
				return -EFAULT;
			if (put_user(len, oldlenp))
				return -EFAULT;
		}
	}

	if (newval && newlen) {
		if (newlen > table->maxlen)
			newlen = table->maxlen;

		if (copy_from_user(data, newval, newlen))
			return -EFAULT;
	}
	return 1;
}
#else
#define sysctl_ipc_data NULL
#endif

static struct ctl_table ipc_kern_table[] = {
	{
		.ctl_name	= KERN_SHMMAX,
		.procname	= "shmmax",
		.data		= &init_ipc_ns.shm_ctlmax,
		.maxlen		= sizeof (init_ipc_ns.shm_ctlmax),
		.mode		= 0644,
		.proc_handler	= proc_ipc_doulongvec_minmax,
		.strategy	= sysctl_ipc_data,
	},
	{
		.ctl_name	= KERN_SHMALL,
		.procname	= "shmall",
		.data		= &init_ipc_ns.shm_ctlall,
		.maxlen		= sizeof (init_ipc_ns.shm_ctlall),
		.mode		= 0644,
		.proc_handler	= proc_ipc_doulongvec_minmax,
		.strategy	= sysctl_ipc_data,
	},
	{
		.ctl_name	= KERN_SHMMNI,
		.procname	= "shmmni",
		.data		= &init_ipc_ns.shm_ctlmni,
		.maxlen		= sizeof (init_ipc_ns.shm_ctlmni),
		.mode		= 0644,
		.proc_handler	= proc_ipc_dointvec,
		.strategy	= sysctl_ipc_data,
	},
	{
		.ctl_name	= KERN_MSGMAX,
		.procname	= "msgmax",
		.data		= &init_ipc_ns.msg_ctlmax,
		.maxlen		= sizeof (init_ipc_ns.msg_ctlmax),
		.mode		= 0644,
		.proc_handler	= proc_ipc_dointvec,
		.strategy	= sysctl_ipc_data,
	},
	{
		.ctl_name	= KERN_MSGMNI,
		.procname	= "msgmni",
		.data		= &init_ipc_ns.msg_ctlmni,
		.maxlen		= sizeof (init_ipc_ns.msg_ctlmni),
		.mode		= 0644,
		.proc_handler	= proc_ipc_dointvec,
		.strategy	= sysctl_ipc_data,
	},
	{
		.ctl_name	= KERN_MSGMNB,
		.procname	=  "msgmnb",
		.data		= &init_ipc_ns.msg_ctlmnb,
		.maxlen		= sizeof (init_ipc_ns.msg_ctlmnb),
		.mode		= 0644,
		.proc_handler	= proc_ipc_dointvec,
		.strategy	= sysctl_ipc_data,
	},
	{
		.ctl_name	= KERN_SEM,
		.procname	= "sem",
		.data		= &init_ipc_ns.sem_ctls,
		.maxlen		= 4*sizeof (int),
		.mode		= 0644,
		.proc_handler	= proc_ipc_dointvec,
		.strategy	= sysctl_ipc_data,
	},
	{}
};

static struct ctl_table ipc_root_table[] = {
	{
		.ctl_name	= CTL_KERN,
		.procname	= "kernel",
		.mode		= 0555,
		.child		= ipc_kern_table,
	},
	{}
};

static int __init ipc_sysctl_init(void)
{
	register_sysctl_table(ipc_root_table, 0);
	return 0;
}

__initcall(ipc_sysctl_init);
+0 −176
Original line number Original line Diff line number Diff line
@@ -90,12 +90,6 @@ extern char modprobe_path[];
#ifdef CONFIG_CHR_DEV_SG
#ifdef CONFIG_CHR_DEV_SG
extern int sg_big_buff;
extern int sg_big_buff;
#endif
#endif
#ifdef CONFIG_SYSVIPC
static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
		void __user *buffer, size_t *lenp, loff_t *ppos);
static int proc_ipc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
		void __user *buffer, size_t *lenp, loff_t *ppos);
#endif


#ifdef __sparc__
#ifdef __sparc__
extern char reboot_command [];
extern char reboot_command [];
@@ -135,11 +129,6 @@ static int parse_table(int __user *, int, void __user *, size_t __user *,
		void __user *, size_t, ctl_table *);
		void __user *, size_t, ctl_table *);
#endif
#endif


#ifdef CONFIG_SYSVIPC
static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen,
		  void __user *oldval, size_t __user *oldlenp,
		  void __user *newval, size_t newlen);
#endif


#ifdef CONFIG_PROC_SYSCTL
#ifdef CONFIG_PROC_SYSCTL
static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
@@ -169,17 +158,6 @@ extern ctl_table inotify_table[];
int sysctl_legacy_va_layout;
int sysctl_legacy_va_layout;
#endif
#endif


#ifdef CONFIG_SYSVIPC
static void *get_ipc(ctl_table *table, int write)
{
	char *which = table->data;
	struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
	which = (which - (char *)&init_ipc_ns) + (char *)ipc_ns;
	return which;
}
#else
#define get_ipc(T,W) ((T)->data)
#endif


/* /proc declarations: */
/* /proc declarations: */


@@ -403,71 +381,6 @@ static ctl_table kern_table[] = {
		.proc_handler	= &proc_dointvec,
		.proc_handler	= &proc_dointvec,
	},
	},
#endif
#endif
#ifdef CONFIG_SYSVIPC
	{
		.ctl_name	= KERN_SHMMAX,
		.procname	= "shmmax",
		.data		= &init_ipc_ns.shm_ctlmax,
		.maxlen		= sizeof (init_ipc_ns.shm_ctlmax),
		.mode		= 0644,
		.proc_handler	= &proc_ipc_doulongvec_minmax,
		.strategy	= sysctl_ipc_data,
	},
	{
		.ctl_name	= KERN_SHMALL,
		.procname	= "shmall",
		.data		= &init_ipc_ns.shm_ctlall,
		.maxlen		= sizeof (init_ipc_ns.shm_ctlall),
		.mode		= 0644,
		.proc_handler	= &proc_ipc_doulongvec_minmax,
		.strategy	= sysctl_ipc_data,
	},
	{
		.ctl_name	= KERN_SHMMNI,
		.procname	= "shmmni",
		.data		= &init_ipc_ns.shm_ctlmni,
		.maxlen		= sizeof (init_ipc_ns.shm_ctlmni),
		.mode		= 0644,
		.proc_handler	= &proc_ipc_dointvec,
		.strategy	= sysctl_ipc_data,
	},
	{
		.ctl_name	= KERN_MSGMAX,
		.procname	= "msgmax",
		.data		= &init_ipc_ns.msg_ctlmax,
		.maxlen		= sizeof (init_ipc_ns.msg_ctlmax),
		.mode		= 0644,
		.proc_handler	= &proc_ipc_dointvec,
		.strategy	= sysctl_ipc_data,
	},
	{
		.ctl_name	= KERN_MSGMNI,
		.procname	= "msgmni",
		.data		= &init_ipc_ns.msg_ctlmni,
		.maxlen		= sizeof (init_ipc_ns.msg_ctlmni),
		.mode		= 0644,
		.proc_handler	= &proc_ipc_dointvec,
		.strategy	= sysctl_ipc_data,
	},
	{
		.ctl_name	= KERN_MSGMNB,
		.procname	=  "msgmnb",
		.data		= &init_ipc_ns.msg_ctlmnb,
		.maxlen		= sizeof (init_ipc_ns.msg_ctlmnb),
		.mode		= 0644,
		.proc_handler	= &proc_ipc_dointvec,
		.strategy	= sysctl_ipc_data,
	},
	{
		.ctl_name	= KERN_SEM,
		.procname	= "sem",
		.data		= &init_ipc_ns.sem_ctls,
		.maxlen		= 4*sizeof (int),
		.mode		= 0644,
		.proc_handler	= &proc_ipc_dointvec,
		.strategy	= sysctl_ipc_data,
	},
#endif
#ifdef CONFIG_MAGIC_SYSRQ
#ifdef CONFIG_MAGIC_SYSRQ
	{
	{
		.ctl_name	= KERN_SYSRQ,
		.ctl_name	= KERN_SYSRQ,
@@ -2269,27 +2182,6 @@ int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
				do_proc_dointvec_ms_jiffies_conv, NULL);
				do_proc_dointvec_ms_jiffies_conv, NULL);
}
}


#ifdef CONFIG_SYSVIPC
static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
	void __user *buffer, size_t *lenp, loff_t *ppos)
{
	void *which;
	which = get_ipc(table, write);
	return __do_proc_dointvec(which, table, write, filp, buffer,
			lenp, ppos, NULL, NULL);
}

static int proc_ipc_doulongvec_minmax(ctl_table *table, int write,
	struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
{
	void *which;
	which = get_ipc(table, write);
	return __do_proc_doulongvec_minmax(which, table, write, filp, buffer,
			lenp, ppos, 1l, 1l);
}

#endif

static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
			   void __user *buffer, size_t *lenp, loff_t *ppos)
			   void __user *buffer, size_t *lenp, loff_t *ppos)
{
{
@@ -2320,25 +2212,6 @@ int proc_dostring(ctl_table *table, int write, struct file *filp,
	return -ENOSYS;
	return -ENOSYS;
}
}


#ifdef CONFIG_SYSVIPC
static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp,
		void __user *buffer, size_t *lenp, loff_t *ppos)
{
	return -ENOSYS;
}
static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
		void __user *buffer, size_t *lenp, loff_t *ppos)
{
	return -ENOSYS;
}
static int proc_ipc_doulongvec_minmax(ctl_table *table, int write,
		struct file *filp, void __user *buffer,
		size_t *lenp, loff_t *ppos)
{
	return -ENOSYS;
}
#endif

int proc_dointvec(ctl_table *table, int write, struct file *filp,
int proc_dointvec(ctl_table *table, int write, struct file *filp,
		  void __user *buffer, size_t *lenp, loff_t *ppos)
		  void __user *buffer, size_t *lenp, loff_t *ppos)
{
{
@@ -2550,47 +2423,6 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,






#ifdef CONFIG_SYSVIPC
/* The generic sysctl ipc data routine. */
static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen,
		void __user *oldval, size_t __user *oldlenp,
		void __user *newval, size_t newlen)
{
	size_t len;
	void *data;

	/* Get out of I don't have a variable */
	if (!table->data || !table->maxlen)
		return -ENOTDIR;

	data = get_ipc(table, 1);
	if (!data)
		return -ENOTDIR;

	if (oldval && oldlenp) {
		if (get_user(len, oldlenp))
			return -EFAULT;
		if (len) {
			if (len > table->maxlen)
				len = table->maxlen;
			if (copy_to_user(oldval, data, len))
				return -EFAULT;
			if (put_user(len, oldlenp))
				return -EFAULT;
		}
	}

	if (newval && newlen) {
		if (newlen > table->maxlen)
			newlen = table->maxlen;

		if (copy_from_user(data, newval, newlen))
			return -EFAULT;
	}
	return 1;
}
#endif

#else /* CONFIG_SYSCTL_SYSCALL */
#else /* CONFIG_SYSCTL_SYSCALL */




@@ -2655,14 +2487,6 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
	return -ENOSYS;
	return -ENOSYS;
}
}


#ifdef CONFIG_SYSVIPC
static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen,
		void __user *oldval, size_t __user *oldlenp,
		void __user *newval, size_t newlen)
{
	return -ENOSYS;
}
#endif
#endif /* CONFIG_SYSCTL_SYSCALL */
#endif /* CONFIG_SYSCTL_SYSCALL */


/*
/*