Commit 7058cb02ddab4bce70a46e519804fccb7ac0a060

Authored by Eric W. Biederman
Committed by Linus Torvalds
1 parent 8ada720d89

sysctl: deprecate sys_sysctl in a user space visible fashion.

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.

[lethal@linux-sh.org: sysctl: Fix syscall disabled build]
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 2 changed files with 76 additions and 23 deletions Side-by-side Diff

Documentation/feature-removal-schedule.txt
... ... @@ -82,6 +82,41 @@
82 82  
83 83 ---------------------------
84 84  
  85 +What: sys_sysctl
  86 +When: September 2010
  87 +Option: CONFIG_SYSCTL_SYSCALL
  88 +Why: The same information is available in a more convenient from
  89 + /proc/sys, and none of the sysctl variables appear to be
  90 + important performance wise.
  91 +
  92 + Binary sysctls are a long standing source of subtle kernel
  93 + bugs and security issues.
  94 +
  95 + When I looked several months ago all I could find after
  96 + searching several distributions were 5 user space programs and
  97 + glibc (which falls back to /proc/sys) using this syscall.
  98 +
  99 + The man page for sysctl(2) documents it as unusable for user
  100 + space programs.
  101 +
  102 + sysctl(2) is not generally ABI compatible to a 32bit user
  103 + space application on a 64bit and a 32bit kernel.
  104 +
  105 + For the last several months the policy has been no new binary
  106 + sysctls and no one has put forward an argument to use them.
  107 +
  108 + Binary sysctls issues seem to keep happening appearing so
  109 + properly deprecating them (with a warning to user space) and a
  110 + 2 year grace warning period will mean eventually we can kill
  111 + them and end the pain.
  112 +
  113 + In the mean time individual binary sysctls can be dealt with
  114 + in a piecewise fashion.
  115 +
  116 +Who: Eric Biederman <ebiederm@xmission.com>
  117 +
  118 +---------------------------
  119 +
85 120 What: a.out interpreter support for ELF executables
86 121 When: 2.6.25
87 122 Files: fs/binfmt_elf.c
... ... @@ -55,6 +55,8 @@
55 55 #include <asm/stacktrace.h>
56 56 #endif
57 57  
  58 +static int deprecated_sysctl_warning(struct __sysctl_args *args);
  59 +
58 60 #if defined(CONFIG_SYSCTL)
59 61  
60 62 /* External variables not in a header file. */
61 63  
... ... @@ -1347,10 +1349,15 @@
1347 1349 if (copy_from_user(&tmp, args, sizeof(tmp)))
1348 1350 return -EFAULT;
1349 1351  
  1352 + error = deprecated_sysctl_warning(&tmp);
  1353 + if (error)
  1354 + goto out;
  1355 +
1350 1356 lock_kernel();
1351 1357 error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp,
1352 1358 tmp.newval, tmp.newlen);
1353 1359 unlock_kernel();
  1360 +out:
1354 1361 return error;
1355 1362 }
1356 1363 #endif /* CONFIG_SYSCTL_SYSCALL */
1357 1364  
1358 1365  
1359 1366  
1360 1367  
1361 1368  
... ... @@ -2540,35 +2547,19 @@
2540 2547  
2541 2548 asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
2542 2549 {
2543   - static int msg_count;
2544 2550 struct __sysctl_args tmp;
2545   - int name[CTL_MAXNAME];
2546   - int i;
  2551 + int error;
2547 2552  
2548   - /* Read in the sysctl name for better debug message logging */
2549 2553 if (copy_from_user(&tmp, args, sizeof(tmp)))
2550 2554 return -EFAULT;
2551   - if (tmp.nlen <= 0 || tmp.nlen >= CTL_MAXNAME)
2552   - return -ENOTDIR;
2553   - for (i = 0; i < tmp.nlen; i++)
2554   - if (get_user(name[i], tmp.name + i))
2555   - return -EFAULT;
2556 2555  
2557   - /* Ignore accesses to kernel.version */
2558   - if ((tmp.nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION))
2559   - goto out;
  2556 + error = deprecated_sysctl_warning(&tmp);
2560 2557  
2561   - if (msg_count < 5) {
2562   - msg_count++;
2563   - printk(KERN_INFO
2564   - "warning: process `%s' used the removed sysctl "
2565   - "system call with ", current->comm);
2566   - for (i = 0; i < tmp.nlen; i++)
2567   - printk("%d.", name[i]);
2568   - printk("\n");
2569   - }
2570   -out:
2571   - return -ENOSYS;
  2558 + /* If no error reading the parameters then just -ENOSYS ... */
  2559 + if (!error)
  2560 + error = -ENOSYS;
  2561 +
  2562 + return error;
2572 2563 }
2573 2564  
2574 2565 int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
... ... @@ -2607,6 +2598,33 @@
2607 2598 }
2608 2599  
2609 2600 #endif /* CONFIG_SYSCTL_SYSCALL */
  2601 +
  2602 +static int deprecated_sysctl_warning(struct __sysctl_args *args)
  2603 +{
  2604 + static int msg_count;
  2605 + int name[CTL_MAXNAME];
  2606 + int i;
  2607 +
  2608 + /* Read in the sysctl name for better debug message logging */
  2609 + for (i = 0; i < args->nlen; i++)
  2610 + if (get_user(name[i], args->name + i))
  2611 + return -EFAULT;
  2612 +
  2613 + /* Ignore accesses to kernel.version */
  2614 + if ((args->nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION))
  2615 + return 0;
  2616 +
  2617 + if (msg_count < 5) {
  2618 + msg_count++;
  2619 + printk(KERN_INFO
  2620 + "warning: process `%s' used the deprecated sysctl "
  2621 + "system call with ", current->comm);
  2622 + for (i = 0; i < args->nlen; i++)
  2623 + printk("%d.", name[i]);
  2624 + printk("\n");
  2625 + }
  2626 + return 0;
  2627 +}
2610 2628  
2611 2629 /*
2612 2630 * No sense putting this after each symbol definition, twice,