Files
Linux/kernel/sysctl_binary.c
T
Eric W. Biederman 61a47c1ad3 sysctl: Remove the sysctl system call
This system call has been deprecated almost since it was introduced, and
in a survey of the linux distributions I can no longer find any of them
that enable CONFIG_SYSCTL_SYSCALL.  The only indication that I can find
that anyone might care is that a few of the defconfigs in the kernel
enable CONFIG_SYSCTL_SYSCALL.  However this appears in only 31 of 414
defconfigs in the kernel, so I suspect this symbols presence is simply
because it is harmless to include rather than because it is necessary.

As there appear to be no users of the sysctl system call, remove the
code.  As this removes one of the few uses of the internal kernel mount
of proc I hope this allows for even more simplifications of the proc
filesystem.

Cc: Alex Smith <[email protected]>
Cc: Anders Berg <[email protected]>
Cc: Apelete Seketeli <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Chee Nouk Phoon <[email protected]>
Cc: Chris Zankel <[email protected]>
Cc: Christian Ruppert <[email protected]>
Cc: Greg Ungerer <[email protected]>
Cc: Harvey Hunt <[email protected]>
Cc: Helge Deller <[email protected]>
Cc: Hongliang Tao <[email protected]>
Cc: Hua Yan <[email protected]>
Cc: Huacai Chen <[email protected]>
Cc: John Crispin <[email protected]>
Cc: Jonas Jensen <[email protected]>
Cc: Josh Boyer <[email protected]>
Cc: Jun Nie <[email protected]>
Cc: Kevin Hilman <[email protected]>
Cc: Kevin Wells <[email protected]>
Cc: Kumar Gala <[email protected]>
Cc: Lars-Peter Clausen <[email protected]>
Cc: Ley Foon Tan <[email protected]>
Cc: Linus Walleij <[email protected]>
Cc: Markos Chandras <[email protected]>
Cc: Max Filippov <[email protected]>
Cc: Noam Camus <[email protected]>
Cc: Olof Johansson <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: Paul Mundt <[email protected]>
Cc: Phil Edworthy <[email protected]>
Cc: Pierrick Hascoet <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Roland Stigge <[email protected]>
Cc: Santosh Shilimkar <[email protected]>
Cc: Scott Telford <[email protected]>
Cc: Stephen Boyd <[email protected]>
Cc: Steven J. Hill <[email protected]>
Cc: Tanmay Inamdar <[email protected]>
Cc: Vineet Gupta <[email protected]>
Cc: Wolfram Sang <[email protected]>
Acked-by: Andi Kleen <[email protected]>
Reviewed-by: Kees Cook <[email protected]>
Signed-off-by: "Eric W. Biederman" <[email protected]>
2019-11-26 13:03:56 -06:00

172 lines
3.8 KiB
C

// SPDX-License-Identifier: GPL-2.0
#include <linux/stat.h>
#include <linux/sysctl.h>
#include "../fs/xfs/xfs_sysctl.h"
#include <linux/sunrpc/debug.h>
#include <linux/string.h>
#include <linux/syscalls.h>
#include <linux/namei.h>
#include <linux/mount.h>
#include <linux/fs.h>
#include <linux/nsproxy.h>
#include <linux/pid_namespace.h>
#include <linux/file.h>
#include <linux/ctype.h>
#include <linux/netdevice.h>
#include <linux/kernel.h>
#include <linux/uuid.h>
#include <linux/slab.h>
#include <linux/compat.h>
static ssize_t binary_sysctl(const int *name, int nlen,
void __user *oldval, size_t oldlen, void __user *newval, size_t newlen)
{
return -ENOSYS;
}
static void deprecated_sysctl_warning(const int *name, int nlen)
{
int i;
/*
* CTL_KERN/KERN_VERSION is used by older glibc and cannot
* ever go away.
*/
if (nlen >= 2 && name[0] == CTL_KERN && name[1] == KERN_VERSION)
return;
if (printk_ratelimit()) {
printk(KERN_INFO
"warning: process `%s' used the deprecated sysctl "
"system call with ", current->comm);
for (i = 0; i < nlen; i++)
printk(KERN_CONT "%d.", name[i]);
printk(KERN_CONT "\n");
}
return;
}
#define WARN_ONCE_HASH_BITS 8
#define WARN_ONCE_HASH_SIZE (1<<WARN_ONCE_HASH_BITS)
static DECLARE_BITMAP(warn_once_bitmap, WARN_ONCE_HASH_SIZE);
#define FNV32_OFFSET 2166136261U
#define FNV32_PRIME 0x01000193
/*
* Print each legacy sysctl (approximately) only once.
* To avoid making the tables non-const use a external
* hash-table instead.
* Worst case hash collision: 6, but very rarely.
* NOTE! We don't use the SMP-safe bit tests. We simply
* don't care enough.
*/
static void warn_on_bintable(const int *name, int nlen)
{
int i;
u32 hash = FNV32_OFFSET;
for (i = 0; i < nlen; i++)
hash = (hash ^ name[i]) * FNV32_PRIME;
hash %= WARN_ONCE_HASH_SIZE;
if (__test_and_set_bit(hash, warn_once_bitmap))
return;
deprecated_sysctl_warning(name, nlen);
}
static ssize_t do_sysctl(int __user *args_name, int nlen,
void __user *oldval, size_t oldlen, void __user *newval, size_t newlen)
{
int name[CTL_MAXNAME];
int i;
/* Check args->nlen. */
if (nlen < 0 || nlen > CTL_MAXNAME)
return -ENOTDIR;
/* Read in the sysctl name for simplicity */
for (i = 0; i < nlen; i++)
if (get_user(name[i], args_name + i))
return -EFAULT;
warn_on_bintable(name, nlen);
return binary_sysctl(name, nlen, oldval, oldlen, newval, newlen);
}
SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args)
{
struct __sysctl_args tmp;
size_t oldlen = 0;
ssize_t result;
if (copy_from_user(&tmp, args, sizeof(tmp)))
return -EFAULT;
if (tmp.oldval && !tmp.oldlenp)
return -EFAULT;
if (tmp.oldlenp && get_user(oldlen, tmp.oldlenp))
return -EFAULT;
result = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, oldlen,
tmp.newval, tmp.newlen);
if (result >= 0) {
oldlen = result;
result = 0;
}
if (tmp.oldlenp && put_user(oldlen, tmp.oldlenp))
return -EFAULT;
return result;
}
#ifdef CONFIG_COMPAT
struct compat_sysctl_args {
compat_uptr_t name;
int nlen;
compat_uptr_t oldval;
compat_uptr_t oldlenp;
compat_uptr_t newval;
compat_size_t newlen;
compat_ulong_t __unused[4];
};
COMPAT_SYSCALL_DEFINE1(sysctl, struct compat_sysctl_args __user *, args)
{
struct compat_sysctl_args tmp;
compat_size_t __user *compat_oldlenp;
size_t oldlen = 0;
ssize_t result;
if (copy_from_user(&tmp, args, sizeof(tmp)))
return -EFAULT;
if (tmp.oldval && !tmp.oldlenp)
return -EFAULT;
compat_oldlenp = compat_ptr(tmp.oldlenp);
if (compat_oldlenp && get_user(oldlen, compat_oldlenp))
return -EFAULT;
result = do_sysctl(compat_ptr(tmp.name), tmp.nlen,
compat_ptr(tmp.oldval), oldlen,
compat_ptr(tmp.newval), tmp.newlen);
if (result >= 0) {
oldlen = result;
result = 0;
}
if (compat_oldlenp && put_user(oldlen, compat_oldlenp))
return -EFAULT;
return result;
}
#endif /* CONFIG_COMPAT */