xref: /openbmc/linux/kernel/utsname_sysctl.c (revision 39fe5434cb9de5da40510028b17b96bc4eb312b3)
1 /*
2  *  Copyright (C) 2007
3  *
4  *  Author: Eric Biederman <ebiederm@xmision.com>
5  *
6  *  This program is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU General Public License as
8  *  published by the Free Software Foundation, version 2 of the
9  *  License.
10  */
11 
12 #include <linux/module.h>
13 #include <linux/uts.h>
14 #include <linux/utsname.h>
15 #include <linux/version.h>
16 #include <linux/sysctl.h>
17 
18 static void *get_uts(ctl_table *table, int write)
19 {
20 	char *which = table->data;
21 
22 	if (!write)
23 		down_read(&uts_sem);
24 	else
25 		down_write(&uts_sem);
26 	return which;
27 }
28 
29 static void put_uts(ctl_table *table, int write, void *which)
30 {
31 	if (!write)
32 		up_read(&uts_sem);
33 	else
34 		up_write(&uts_sem);
35 }
36 
37 #ifdef CONFIG_PROC_FS
38 /*
39  *	Special case of dostring for the UTS structure. This has locks
40  *	to observe. Should this be in kernel/sys.c ????
41  */
42 static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
43 		  void __user *buffer, size_t *lenp, loff_t *ppos)
44 {
45 	struct ctl_table uts_table;
46 	int r;
47 	memcpy(&uts_table, table, sizeof(uts_table));
48 	uts_table.data = get_uts(table, write);
49 	r = proc_dostring(&uts_table,write,filp,buffer,lenp, ppos);
50 	put_uts(table, write, uts_table.data);
51 	return r;
52 }
53 #else
54 #define proc_do_uts_string NULL
55 #endif
56 
57 
58 #ifdef CONFIG_SYSCTL_SYSCALL
59 /* The generic string strategy routine: */
60 static int sysctl_uts_string(ctl_table *table, int __user *name, int nlen,
61 		  void __user *oldval, size_t __user *oldlenp,
62 		  void __user *newval, size_t newlen)
63 {
64 	struct ctl_table uts_table;
65 	int r, write;
66 	write = newval && newlen;
67 	memcpy(&uts_table, table, sizeof(uts_table));
68 	uts_table.data = get_uts(table, write);
69 	r = sysctl_string(&uts_table, name, nlen,
70 		oldval, oldlenp, newval, newlen);
71 	put_uts(table, write, uts_table.data);
72 	return r;
73 }
74 #else
75 #define sysctl_uts_string NULL
76 #endif
77 
78 static struct ctl_table uts_kern_table[] = {
79 	{
80 		.ctl_name	= KERN_OSTYPE,
81 		.procname	= "ostype",
82 		.data		= init_uts_ns.name.sysname,
83 		.maxlen		= sizeof(init_uts_ns.name.sysname),
84 		.mode		= 0444,
85 		.proc_handler	= proc_do_uts_string,
86 		.strategy	= sysctl_uts_string,
87 	},
88 	{
89 		.ctl_name	= KERN_OSRELEASE,
90 		.procname	= "osrelease",
91 		.data		= init_uts_ns.name.release,
92 		.maxlen		= sizeof(init_uts_ns.name.release),
93 		.mode		= 0444,
94 		.proc_handler	= proc_do_uts_string,
95 		.strategy	= sysctl_uts_string,
96 	},
97 	{
98 		.ctl_name	= KERN_VERSION,
99 		.procname	= "version",
100 		.data		= init_uts_ns.name.version,
101 		.maxlen		= sizeof(init_uts_ns.name.version),
102 		.mode		= 0444,
103 		.proc_handler	= proc_do_uts_string,
104 		.strategy	= sysctl_uts_string,
105 	},
106 	{
107 		.ctl_name	= KERN_NODENAME,
108 		.procname	= "hostname",
109 		.data		= init_uts_ns.name.nodename,
110 		.maxlen		= sizeof(init_uts_ns.name.nodename),
111 		.mode		= 0644,
112 		.proc_handler	= proc_do_uts_string,
113 		.strategy	= sysctl_uts_string,
114 	},
115 	{
116 		.ctl_name	= KERN_DOMAINNAME,
117 		.procname	= "domainname",
118 		.data		= init_uts_ns.name.domainname,
119 		.maxlen		= sizeof(init_uts_ns.name.domainname),
120 		.mode		= 0644,
121 		.proc_handler	= proc_do_uts_string,
122 		.strategy	= sysctl_uts_string,
123 	},
124 	{}
125 };
126 
127 static struct ctl_table uts_root_table[] = {
128 	{
129 		.ctl_name	= CTL_KERN,
130 		.procname	= "kernel",
131 		.mode		= 0555,
132 		.child		= uts_kern_table,
133 	},
134 	{}
135 };
136 
137 static int __init utsname_sysctl_init(void)
138 {
139 	register_sysctl_table(uts_root_table);
140 	return 0;
141 }
142 
143 __initcall(utsname_sysctl_init);
144