Skip to content

Commit

Permalink
sysctl: deprecate sys_sysctl in a user space visible fashion.
Browse files Browse the repository at this point in the history
After adding checking to register_sysctl_table and finding a whole new set
of bugs.  Missed by countless code reviews and testers I have finally lost
patience with the binary sysctl interface.

The binary sysctl interface has been sort of deprecated for years and
finding a user space program that uses the syscall is more difficult then
finding a needle in a haystack.  Problems continue to crop up, with the in
kernel implementation.  So since supporting something that no one uses is
silly, deprecate sys_sysctl with a sufficient grace period and notice that
the handful of user space applications that care can be fixed or replaced.

The /proc/sys sysctl interface that people use will continue to be
supported indefinitely.

This patch moves the tested warning about sysctls from the path where
sys_sysctl to a separate path called from both implementations of
sys_sysctl, and it adds a proper entry into
Documentation/feature-removal-schedule.

Allowing us to revisit this in a couple years time and actually kill
sys_sysctl.

[[email protected]: sysctl: Fix syscall disabled build]
Signed-off-by: Eric W. Biederman <[email protected]>
Signed-off-by: Paul Mundt <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
ebiederm authored and Linus Torvalds committed Oct 18, 2007
1 parent 8ada720 commit 7058cb0
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 23 deletions.
35 changes: 35 additions & 0 deletions Documentation/feature-removal-schedule.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,41 @@ Who: Dominik Brodowski <[email protected]>

---------------------------

What: sys_sysctl
When: September 2010
Option: CONFIG_SYSCTL_SYSCALL
Why: The same information is available in a more convenient from
/proc/sys, and none of the sysctl variables appear to be
important performance wise.

Binary sysctls are a long standing source of subtle kernel
bugs and security issues.

When I looked several months ago all I could find after
searching several distributions were 5 user space programs and
glibc (which falls back to /proc/sys) using this syscall.

The man page for sysctl(2) documents it as unusable for user
space programs.

sysctl(2) is not generally ABI compatible to a 32bit user
space application on a 64bit and a 32bit kernel.

For the last several months the policy has been no new binary
sysctls and no one has put forward an argument to use them.

Binary sysctls issues seem to keep happening appearing so
properly deprecating them (with a warning to user space) and a
2 year grace warning period will mean eventually we can kill
them and end the pain.

In the mean time individual binary sysctls can be dealt with
in a piecewise fashion.

Who: Eric Biederman <[email protected]>

---------------------------

What: a.out interpreter support for ELF executables
When: 2.6.25
Files: fs/binfmt_elf.c
Expand Down
64 changes: 41 additions & 23 deletions kernel/sysctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
#include <asm/stacktrace.h>
#endif

static int deprecated_sysctl_warning(struct __sysctl_args *args);

#if defined(CONFIG_SYSCTL)

/* External variables not in a header file. */
Expand Down Expand Up @@ -1347,10 +1349,15 @@ asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
if (copy_from_user(&tmp, args, sizeof(tmp)))
return -EFAULT;

error = deprecated_sysctl_warning(&tmp);
if (error)
goto out;

lock_kernel();
error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp,
tmp.newval, tmp.newlen);
unlock_kernel();
out:
return error;
}
#endif /* CONFIG_SYSCTL_SYSCALL */
Expand Down Expand Up @@ -2540,35 +2547,19 @@ int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen,

asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
{
static int msg_count;
struct __sysctl_args tmp;
int name[CTL_MAXNAME];
int i;
int error;

/* Read in the sysctl name for better debug message logging */
if (copy_from_user(&tmp, args, sizeof(tmp)))
return -EFAULT;
if (tmp.nlen <= 0 || tmp.nlen >= CTL_MAXNAME)
return -ENOTDIR;
for (i = 0; i < tmp.nlen; i++)
if (get_user(name[i], tmp.name + i))
return -EFAULT;

/* Ignore accesses to kernel.version */
if ((tmp.nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION))
goto out;
error = deprecated_sysctl_warning(&tmp);

if (msg_count < 5) {
msg_count++;
printk(KERN_INFO
"warning: process `%s' used the removed sysctl "
"system call with ", current->comm);
for (i = 0; i < tmp.nlen; i++)
printk("%d.", name[i]);
printk("\n");
}
out:
return -ENOSYS;
/* If no error reading the parameters then just -ENOSYS ... */
if (!error)
error = -ENOSYS;

return error;
}

int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
Expand Down Expand Up @@ -2608,6 +2599,33 @@ int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen,

#endif /* CONFIG_SYSCTL_SYSCALL */

static int deprecated_sysctl_warning(struct __sysctl_args *args)
{
static int msg_count;
int name[CTL_MAXNAME];
int i;

/* Read in the sysctl name for better debug message logging */
for (i = 0; i < args->nlen; i++)
if (get_user(name[i], args->name + i))
return -EFAULT;

/* Ignore accesses to kernel.version */
if ((args->nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION))
return 0;

if (msg_count < 5) {
msg_count++;
printk(KERN_INFO
"warning: process `%s' used the deprecated sysctl "
"system call with ", current->comm);
for (i = 0; i < args->nlen; i++)
printk("%d.", name[i]);
printk("\n");
}
return 0;
}

/*
* No sense putting this after each symbol definition, twice,
* exception granted :-)
Expand Down

0 comments on commit 7058cb0

Please sign in to comment.