1 #include <linux/stat.h>
2 #include <linux/sysctl.h>
3 #include "../fs/xfs/xfs_sysctl.h"
4 #include <linux/sunrpc/debug.h>
5 #include <linux/string.h>
14 #include <linux/ctype.h>
15 #include <linux/netdevice.h>
16 #include <linux/kernel.h>
17 #include <linux/slab.h>
19 #ifdef CONFIG_SYSCTL_SYSCALL
23 void __user *oldval,
size_t oldlen,
void __user *newval,
size_t newlen);
25 static bin_convert_t bin_dir;
26 static bin_convert_t bin_string;
27 static bin_convert_t bin_intvec;
28 static bin_convert_t bin_ulongvec;
29 static bin_convert_t bin_uuid;
30 static bin_convert_t bin_dn_node_address;
32 #define CTL_DIR bin_dir
33 #define CTL_STR bin_string
34 #define CTL_INT bin_intvec
35 #define CTL_ULONG bin_ulongvec
36 #define CTL_UUID bin_uuid
37 #define CTL_DNADR bin_dn_node_address
45 const struct bin_table *
child;
48 static const struct bin_table bin_random_table[] = {
58 static const struct bin_table bin_pty_table[] = {
64 static const struct bin_table bin_kern_table[] = {
100 { CTL_DIR,
KERN_RANDOM,
"random", bin_random_table },
126 { CTL_DIR,
KERN_PTY,
"pty", bin_pty_table },
143 static const struct bin_table bin_vm_table[] = {
175 static const struct bin_table bin_net_core_table[] = {
201 static const struct bin_table bin_net_unix_table[] = {
208 static const struct bin_table bin_net_ipv4_route_table[] = {
230 static const struct bin_table bin_net_ipv4_conf_vars_table[] = {
258 static const struct bin_table bin_net_ipv4_conf_table[] = {
261 { CTL_DIR, 0,
NULL, bin_net_ipv4_conf_vars_table },
265 static const struct bin_table bin_net_neigh_vars_table[] = {
287 static const struct bin_table bin_net_neigh_table[] = {
289 { CTL_DIR, 0,
NULL, bin_net_neigh_vars_table },
293 static const struct bin_table bin_net_ipv4_netfilter_table[] = {
330 static const struct bin_table bin_net_ipv4_table[] = {
418 { CTL_INT, 2088 ,
"ip_queue_maxlen" },
434 static const struct bin_table bin_net_ipx_table[] = {
440 static const struct bin_table bin_net_atalk_table[] = {
448 static const struct bin_table bin_net_netrom_table[] = {
464 static const struct bin_table bin_net_ax25_param_table[] = {
482 static const struct bin_table bin_net_ax25_table[] = {
483 { CTL_DIR, 0,
NULL, bin_net_ax25_param_table },
487 static const struct bin_table bin_net_rose_table[] = {
501 static const struct bin_table bin_net_ipv6_conf_var_table[] = {
529 static const struct bin_table bin_net_ipv6_conf_table[] = {
532 { CTL_DIR, 0,
NULL, bin_net_ipv6_conf_var_table },
536 static const struct bin_table bin_net_ipv6_route_table[] = {
550 static const struct bin_table bin_net_ipv6_icmp_table[] = {
555 static const struct bin_table bin_net_ipv6_table[] = {
566 { CTL_INT, 2088 ,
"ip6_queue_maxlen" },
570 static const struct bin_table bin_net_x25_table[] = {
580 static const struct bin_table bin_net_tr_table[] = {
586 static const struct bin_table bin_net_decnet_conf_vars[] = {
594 static const struct bin_table bin_net_decnet_conf[] = {
601 { CTL_DIR, 0,
NULL, bin_net_decnet_conf_vars },
605 static const struct bin_table bin_net_decnet_table[] = {
623 static const struct bin_table bin_net_sctp_table[] = {
644 static const struct bin_table bin_net_llc_llc2_timeout_table[] = {
652 static const struct bin_table bin_net_llc_station_table[] = {
657 static const struct bin_table bin_net_llc_llc2_table[] = {
658 { CTL_DIR,
NET_LLC2,
"timeout", bin_net_llc_llc2_timeout_table },
662 static const struct bin_table bin_net_llc_table[] = {
663 { CTL_DIR,
NET_LLC2,
"llc2", bin_net_llc_llc2_table },
668 static const struct bin_table bin_net_netfilter_table[] = {
705 static const struct bin_table bin_net_irda_table[] = {
723 static const struct bin_table bin_net_table[] = {
724 { CTL_DIR,
NET_CORE,
"core", bin_net_core_table },
727 { CTL_DIR,
NET_UNIX,
"unix", bin_net_unix_table },
728 { CTL_DIR,
NET_IPV4,
"ipv4", bin_net_ipv4_table },
729 { CTL_DIR,
NET_IPX,
"ipx", bin_net_ipx_table },
730 { CTL_DIR,
NET_ATALK,
"appletalk", bin_net_atalk_table },
731 { CTL_DIR,
NET_NETROM,
"netrom", bin_net_netrom_table },
732 { CTL_DIR,
NET_AX25,
"ax25", bin_net_ax25_table },
734 { CTL_DIR,
NET_ROSE,
"rose", bin_net_rose_table },
735 { CTL_DIR,
NET_IPV6,
"ipv6", bin_net_ipv6_table },
736 { CTL_DIR,
NET_X25,
"x25", bin_net_x25_table },
737 { CTL_DIR,
NET_TR,
"token-ring", bin_net_tr_table },
738 { CTL_DIR,
NET_DECNET,
"decnet", bin_net_decnet_table },
740 { CTL_DIR,
NET_SCTP,
"sctp", bin_net_sctp_table },
741 { CTL_DIR,
NET_LLC,
"llc", bin_net_llc_table },
742 { CTL_DIR,
NET_NETFILTER,
"netfilter", bin_net_netfilter_table },
744 { CTL_DIR,
NET_IRDA,
"irda", bin_net_irda_table },
745 { CTL_INT, 2089,
"nf_conntrack_max" },
749 static const struct bin_table bin_fs_quota_table[] = {
762 static const struct bin_table bin_fs_xfs_table[] = {
782 static const struct bin_table bin_fs_ocfs2_nm_table[] = {
783 { CTL_STR, 1,
"hb_ctl_path" },
787 static const struct bin_table bin_fs_ocfs2_table[] = {
788 { CTL_DIR, 1,
"nm", bin_fs_ocfs2_nm_table },
792 static const struct bin_table bin_inotify_table[] = {
799 static const struct bin_table bin_fs_table[] = {
815 { CTL_DIR,
FS_DQSTATS,
"quota", bin_fs_quota_table },
816 { CTL_DIR,
FS_XFS,
"xfs", bin_fs_xfs_table },
819 { CTL_DIR,
FS_INOTIFY,
"inotify", bin_inotify_table },
820 { CTL_DIR,
FS_OCFS2,
"ocfs2", bin_fs_ocfs2_table },
825 static const struct bin_table bin_ipmi_table[] = {
830 static const struct bin_table bin_mac_hid_files[] = {
840 static const struct bin_table bin_raid_table[] = {
846 static const struct bin_table bin_scsi_table[] = {
851 static const struct bin_table bin_dev_table[] = {
855 { CTL_DIR,
DEV_RAID,
"raid", bin_raid_table },
856 { CTL_DIR,
DEV_MAC_HID,
"mac_hid", bin_mac_hid_files },
857 { CTL_DIR,
DEV_SCSI,
"scsi", bin_scsi_table },
858 { CTL_DIR,
DEV_IPMI,
"ipmi", bin_ipmi_table },
862 static const struct bin_table bin_bus_isa_table[] = {
869 static const struct bin_table bin_bus_table[] = {
870 { CTL_DIR,
CTL_BUS_ISA,
"isa", bin_bus_isa_table },
875 static const struct bin_table bin_s390dbf_table[] = {
876 { CTL_INT, 5678 ,
"debug_stoppable" },
877 { CTL_INT, 5679 ,
"debug_active" },
881 static const struct bin_table bin_sunrpc_table[] = {
894 static const struct bin_table bin_pm_table[] = {
897 { CTL_INT, 2 ,
"cmode" },
898 { CTL_INT, 3 ,
"p0" },
899 { CTL_INT, 4 ,
"cm" },
903 static const struct bin_table bin_root_table[] = {
904 { CTL_DIR,
CTL_KERN,
"kernel", bin_kern_table },
905 { CTL_DIR,
CTL_VM,
"vm", bin_vm_table },
906 { CTL_DIR,
CTL_NET,
"net", bin_net_table },
908 { CTL_DIR,
CTL_FS,
"fs", bin_fs_table },
910 { CTL_DIR,
CTL_DEV,
"dev", bin_dev_table },
911 { CTL_DIR,
CTL_BUS,
"bus", bin_bus_table },
915 { CTL_DIR,
CTL_S390DBF,
"s390dbf", bin_s390dbf_table },
916 { CTL_DIR,
CTL_SUNRPC,
"sunrpc", bin_sunrpc_table },
917 { CTL_DIR,
CTL_PM,
"pm", bin_pm_table },
922 void __user *oldval,
size_t oldlen,
void __user *newval,
size_t newlen)
929 void __user *oldval,
size_t oldlen,
void __user *newval,
size_t newlen)
933 if (oldval && oldlen) {
938 result =
vfs_read(file, oldval, oldlen, &pos);
943 lastp = oldval + copied - 1;
958 if (newval && newlen) {
961 result =
vfs_write(file, newval, newlen, &pos);
971 static ssize_t bin_intvec(
struct file *file,
972 void __user *oldval,
size_t oldlen,
void __user *newval,
size_t newlen)
984 if (oldval && oldlen) {
985 unsigned __user *vec = oldval;
986 size_t length = oldlen /
sizeof(*vec);
1000 for (i = 0; i <
length; i++) {
1001 unsigned long value;
1011 copied +=
sizeof(*vec);
1017 if (newval && newlen) {
1018 unsigned __user *vec = newval;
1019 size_t length = newlen /
sizeof(*vec);
1026 for (i = 0; i <
length; i++) {
1027 unsigned long value;
1033 str +=
snprintf(str, end - str,
"%lu\t", value);
1037 result =
vfs_write(file, buffer, str - buffer, &pos);
1049 static ssize_t bin_ulongvec(
struct file *file,
1050 void __user *oldval,
size_t oldlen,
void __user *newval,
size_t newlen)
1062 if (oldval && oldlen) {
1063 unsigned long __user *vec = oldval;
1064 size_t length = oldlen /
sizeof(*vec);
1070 result =
vfs_read(file, buffer, BUFSZ - 1, &pos);
1078 for (i = 0; i <
length; i++) {
1079 unsigned long value;
1089 copied +=
sizeof(*vec);
1095 if (newval && newlen) {
1096 unsigned long __user *vec = newval;
1097 size_t length = newlen /
sizeof(*vec);
1104 for (i = 0; i <
length; i++) {
1105 unsigned long value;
1111 str +=
snprintf(str, end - str,
"%lu\t", value);
1115 result =
vfs_write(file, buffer, str - buffer, &pos);
1127 static ssize_t bin_uuid(
struct file *file,
1128 void __user *oldval,
size_t oldlen,
void __user *newval,
size_t newlen)
1134 if (oldval && oldlen) {
1136 char buf[40], *str =
buf;
1137 unsigned char uuid[16];
1141 result =
vfs_read(file, buf,
sizeof(buf) - 1, &pos);
1149 for (i = 0; i < 16; i++) {
1175 static ssize_t bin_dn_node_address(
struct file *file,
1176 void __user *oldval,
size_t oldlen,
void __user *newval,
size_t newlen)
1181 if (oldval && oldlen) {
1183 char buf[15], *nodep;
1184 unsigned long area,
node;
1188 result =
vfs_read(file, buf,
sizeof(buf) - 1, &pos);
1197 nodep =
strchr(buf,
'.') + 1;
1205 if ((area > 63)||(node > 1023))
1214 copied =
sizeof(dnaddr);
1217 if (newval && newlen) {
1224 if (newlen !=
sizeof(dnaddr))
1231 len =
snprintf(buf,
sizeof(buf),
"%hu.%hu",
1236 result =
vfs_write(file, buf, len, &pos);
1247 static const struct bin_table *get_sysctl(
const int *
name,
int nlen,
char *
path)
1249 const struct bin_table *
table = &bin_root_table[0];
1265 for ( ; table->convert; table++) {
1272 if (!table->ctl_name) {
1284 }
else if (ctl_name == table->ctl_name) {
1285 len =
strlen(table->procname);
1286 memcpy(path, table->procname, len);
1292 table = table->child;
1302 static char *sysctl_getname(
const int *name,
int nlen,
const struct bin_table **tablep)
1306 result = ERR_PTR(-
ENOMEM);
1309 const struct bin_table *table = get_sysctl(name, nlen, tmp);
1312 if (IS_ERR(table)) {
1314 result = ERR_CAST(table);
1320 static ssize_t binary_sysctl(
const int *name,
int nlen,
1321 void __user *oldval,
size_t oldlen,
void __user *newval,
size_t newlen)
1323 const struct bin_table *table =
NULL;
1330 pathname = sysctl_getname(name, nlen, &table);
1331 result = PTR_ERR(pathname);
1332 if (IS_ERR(pathname))
1336 if (oldval && oldlen && newval && newlen) {
1338 }
else if (newval && newlen) {
1340 }
else if (oldval && oldlen) {
1347 mnt =
current->nsproxy->pid_ns->proc_mnt;
1349 result = PTR_ERR(file);
1353 result = table->convert(file, oldval, oldlen, newval, newlen);
1365 static ssize_t binary_sysctl(
const int *name,
int nlen,
1366 void __user *oldval,
size_t oldlen,
void __user *newval,
size_t newlen)
1374 static void deprecated_sysctl_warning(
const int *name,
int nlen)
1385 if (printk_ratelimit()) {
1387 "warning: process `%s' used the deprecated sysctl "
1388 "system call with ",
current->comm);
1389 for (i = 0; i < nlen; i++)
1396 #define WARN_ONCE_HASH_BITS 8
1397 #define WARN_ONCE_HASH_SIZE (1<<WARN_ONCE_HASH_BITS)
1401 #define FNV32_OFFSET 2166136261U
1402 #define FNV32_PRIME 0x01000193
1412 static void warn_on_bintable(
const int *name,
int nlen)
1417 for (i = 0; i < nlen; i++)
1422 deprecated_sysctl_warning(name, nlen);
1425 static ssize_t do_sysctl(
int __user *args_name,
int nlen,
1426 void __user *oldval,
size_t oldlen,
void __user *newval,
size_t newlen)
1435 for (i = 0; i < nlen; i++)
1436 if (
get_user(name[i], args_name + i))
1439 warn_on_bintable(name, nlen);
1441 return binary_sysctl(name, nlen, oldval, oldlen, newval, newlen);
1474 #ifdef CONFIG_COMPAT
1475 #include <asm/compat.h>
1477 struct compat_sysctl_args {
1487 asmlinkage long compat_sys_sysctl(
struct compat_sysctl_args __user *args)
1489 struct compat_sysctl_args tmp;
1497 if (tmp.oldval && !tmp.oldlenp)
1500 compat_oldlenp = compat_ptr(tmp.oldlenp);
1501 if (compat_oldlenp &&
get_user(oldlen, compat_oldlenp))
1504 result = do_sysctl(compat_ptr(tmp.name), tmp.nlen,
1505 compat_ptr(tmp.oldval), oldlen,
1506 compat_ptr(tmp.newval), tmp.newlen);
1513 if (compat_oldlenp &&
put_user(oldlen, compat_oldlenp))