aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sysctl.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2006-12-08 05:39:55 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-08 11:29:03 -0500
commitcf9f151c7257683f489df85f94baf408d1d5694a (patch)
tree1b5db0f87d39bb7b83c86e0fb286a1f80f860922 /kernel/sysctl.c
parent6b1b60f41eef3ba7b188fd72f1d6de478aafd93c (diff)
[PATCH] sysctl: simplify sysctl_uts_string
The binary interface to the namespace sysctls was never implemented resulting in some really weird things if you attempted to use sys_sysctl to read your hostname for example. This patch series simples the code a little and implements the binary sysctl interface. In testing this patch series I discovered that our 32bit compatibility for the binary sysctl interface is imperfect. In particular KERN_SHMMAX and KERN_SMMALL are size_t sized quantities and are returned as 8 bytes on to 32bit binaries using a x86_64 kernel. However this has existing for a long time so it is not a new regression with the namespace work. Gads the whole sysctl thing needs work before it stops being easy to shoot yourself in the foot. Looking forward a little bit we need a better way to handle sysctls and namespaces as our current technique will not work for the network namespace. I think something based on the current overlapping sysctl trees will work but the proc side needs to be redone before we can use it. This patch: Introduce get_uts() and put_uts() (used later) and remove most of the special cases for when UTS namespace is compiled in. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r--kernel/sysctl.c128
1 files changed, 26 insertions, 102 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 9846db93a59..c8bcbfb2e06 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -163,6 +163,28 @@ extern ctl_table inotify_table[];
163int sysctl_legacy_va_layout; 163int sysctl_legacy_va_layout;
164#endif 164#endif
165 165
166static void *get_uts(ctl_table *table, int write)
167{
168 char *which = table->data;
169#ifdef CONFIG_UTS_NS
170 struct uts_namespace *uts_ns = current->nsproxy->uts_ns;
171 which = (which - (char *)&init_uts_ns) + (char *)uts_ns;
172#endif
173 if (!write)
174 down_read(&uts_sem);
175 else
176 down_write(&uts_sem);
177 return which;
178}
179
180static void put_uts(ctl_table *table, int write, void *which)
181{
182 if (!write)
183 up_read(&uts_sem);
184 else
185 up_write(&uts_sem);
186}
187
166/* /proc declarations: */ 188/* /proc declarations: */
167 189
168#ifdef CONFIG_PROC_SYSCTL 190#ifdef CONFIG_PROC_SYSCTL
@@ -229,7 +251,6 @@ static ctl_table root_table[] = {
229}; 251};
230 252
231static ctl_table kern_table[] = { 253static ctl_table kern_table[] = {
232#ifndef CONFIG_UTS_NS
233 { 254 {
234 .ctl_name = KERN_OSTYPE, 255 .ctl_name = KERN_OSTYPE,
235 .procname = "ostype", 256 .procname = "ostype",
@@ -275,54 +296,6 @@ static ctl_table kern_table[] = {
275 .proc_handler = &proc_do_uts_string, 296 .proc_handler = &proc_do_uts_string,
276 .strategy = &sysctl_string, 297 .strategy = &sysctl_string,
277 }, 298 },
278#else /* !CONFIG_UTS_NS */
279 {
280 .ctl_name = KERN_OSTYPE,
281 .procname = "ostype",
282 .data = NULL,
283 /* could maybe use __NEW_UTS_LEN here? */
284 .maxlen = FIELD_SIZEOF(struct new_utsname, sysname),
285 .mode = 0444,
286 .proc_handler = &proc_do_uts_string,
287 .strategy = &sysctl_string,
288 },
289 {
290 .ctl_name = KERN_OSRELEASE,
291 .procname = "osrelease",
292 .data = NULL,
293 .maxlen = FIELD_SIZEOF(struct new_utsname, release),
294 .mode = 0444,
295 .proc_handler = &proc_do_uts_string,
296 .strategy = &sysctl_string,
297 },
298 {
299 .ctl_name = KERN_VERSION,
300 .procname = "version",
301 .data = NULL,
302 .maxlen = FIELD_SIZEOF(struct new_utsname, version),
303 .mode = 0444,
304 .proc_handler = &proc_do_uts_string,
305 .strategy = &sysctl_string,
306 },
307 {
308 .ctl_name = KERN_NODENAME,
309 .procname = "hostname",
310 .data = NULL,
311 .maxlen = FIELD_SIZEOF(struct new_utsname, nodename),
312 .mode = 0644,
313 .proc_handler = &proc_do_uts_string,
314 .strategy = &sysctl_string,
315 },
316 {
317 .ctl_name = KERN_DOMAINNAME,
318 .procname = "domainname",
319 .data = NULL,
320 .maxlen = FIELD_SIZEOF(struct new_utsname, domainname),
321 .mode = 0644,
322 .proc_handler = &proc_do_uts_string,
323 .strategy = &sysctl_string,
324 },
325#endif /* !CONFIG_UTS_NS */
326 { 299 {
327 .ctl_name = KERN_PANIC, 300 .ctl_name = KERN_PANIC,
328 .procname = "panic", 301 .procname = "panic",
@@ -1753,66 +1726,17 @@ int proc_dostring(ctl_table *table, int write, struct file *filp,
1753 * Special case of dostring for the UTS structure. This has locks 1726 * Special case of dostring for the UTS structure. This has locks
1754 * to observe. Should this be in kernel/sys.c ???? 1727 * to observe. Should this be in kernel/sys.c ????
1755 */ 1728 */
1756
1757#ifndef CONFIG_UTS_NS
1758static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
1759 void __user *buffer, size_t *lenp, loff_t *ppos)
1760{
1761 int r;
1762 1729
1763 if (!write) {
1764 down_read(&uts_sem);
1765 r=proc_dostring(table,0,filp,buffer,lenp, ppos);
1766 up_read(&uts_sem);
1767 } else {
1768 down_write(&uts_sem);
1769 r=proc_dostring(table,1,filp,buffer,lenp, ppos);
1770 up_write(&uts_sem);
1771 }
1772 return r;
1773}
1774#else /* !CONFIG_UTS_NS */
1775static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, 1730static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
1776 void __user *buffer, size_t *lenp, loff_t *ppos) 1731 void __user *buffer, size_t *lenp, loff_t *ppos)
1777{ 1732{
1778 int r; 1733 int r;
1779 struct uts_namespace* uts_ns = current->nsproxy->uts_ns; 1734 void *which;
1780 char* which; 1735 which = get_uts(table, write);
1781 1736 r = _proc_do_string(which, table->maxlen,write,filp,buffer,lenp, ppos);
1782 switch (table->ctl_name) { 1737 put_uts(table, write, which);
1783 case KERN_OSTYPE:
1784 which = uts_ns->name.sysname;
1785 break;
1786 case KERN_NODENAME:
1787 which = uts_ns->name.nodename;
1788 break;
1789 case KERN_OSRELEASE:
1790 which = uts_ns->name.release;
1791 break;
1792 case KERN_VERSION:
1793 which = uts_ns->name.version;
1794 break;
1795 case KERN_DOMAINNAME:
1796 which = uts_ns->name.domainname;
1797 break;
1798 default:
1799 r = -EINVAL;
1800 goto out;
1801 }
1802
1803 if (!write) {
1804 down_read(&uts_sem);
1805 r=_proc_do_string(which,table->maxlen,0,filp,buffer,lenp, ppos);
1806 up_read(&uts_sem);
1807 } else {
1808 down_write(&uts_sem);
1809 r=_proc_do_string(which,table->maxlen,1,filp,buffer,lenp, ppos);
1810 up_write(&uts_sem);
1811 }
1812 out:
1813 return r; 1738 return r;
1814} 1739}
1815#endif /* !CONFIG_UTS_NS */
1816 1740
1817static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, 1741static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
1818 int *valp, 1742 int *valp,