diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2006-12-08 05:39:55 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-08 11:29:03 -0500 |
commit | cf9f151c7257683f489df85f94baf408d1d5694a (patch) | |
tree | 1b5db0f87d39bb7b83c86e0fb286a1f80f860922 /kernel/sysctl.c | |
parent | 6b1b60f41eef3ba7b188fd72f1d6de478aafd93c (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.c | 128 |
1 files changed, 26 insertions, 102 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 9846db93a595..c8bcbfb2e069 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -163,6 +163,28 @@ extern ctl_table inotify_table[]; | |||
163 | int sysctl_legacy_va_layout; | 163 | int sysctl_legacy_va_layout; |
164 | #endif | 164 | #endif |
165 | 165 | ||
166 | static 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 | |||
180 | static 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 | ||
231 | static ctl_table kern_table[] = { | 253 | static 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 | ||
1758 | static 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 */ | ||
1775 | static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, | 1730 | static 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 | ||
1817 | static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, | 1741 | static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, |
1818 | int *valp, | 1742 | int *valp, |