Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3ee75ac3c0f4904633322b7d9b111566fbc4a7d3
Commit:     3ee75ac3c0f4904633322b7d9b111566fbc4a7d3
Parent:     8b6312f4dcc1efe7975731b6c47dd134282bd9ac
Author:     Alexey Dobriyan <[EMAIL PROTECTED]>
AuthorDate: Sat Feb 10 01:44:39 2007 -0800
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Sun Feb 11 10:51:24 2007 -0800

    [PATCH] sysctl_{,ms_}jiffies: fix oldlen semantics
    
    currently it's
    1) if *oldlenp == 0,
        don't writeback anything
    
    2) if *oldlenp >= table->maxlen,
        don't writeback more than table->maxlen bytes and rewrite *oldlenp
        don't look at underlying type granularity
    
    3) if 0 < *oldlenp < table->maxlen,
                *cough*
        string sysctls don't writeback more than *oldlenp bytes.
        OK, that's because sizeof(char) == 1
    
        int sysctls writeback anything in (0, table->maxlen] range
        Though accept integers divisible by sizeof(int) for writing.
    
    sysctl_jiffies and sysctl_ms_jiffies don't writeback anything but
    sizeof(int), which violates 1) and 2).
    
    So, make sysctl_jiffies and sysctl_ms_jiffies accept
    a) *oldlenp == 0, not doing writeback
    b) *oldlenp >= sizeof(int), writing one integer.
    
    -EINVAL still returned for *oldlenp == 1, 2, 3.
    
    Signed-off-by: Alexey Dobriyan <[EMAIL PROTECTED]>
    Cc: "Eric W. Biederman" <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 kernel/sysctl.c |   44 ++++++++++++++++++++++++++++----------------
 1 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 41bbba1..16ef870 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -2553,17 +2553,23 @@ int sysctl_jiffies(ctl_table *table, int __user *name, 
int nlen,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
-       if (oldval) {
+       if (oldval && oldlenp) {
                size_t olen;
-               if (oldlenp) { 
-                       if (get_user(olen, oldlenp))
+
+               if (get_user(olen, oldlenp))
+                       return -EFAULT;
+               if (olen) {
+                       int val;
+
+                       if (olen < sizeof(int))
+                               return -EINVAL;
+
+                       val = *(int *)(table->data) / HZ;
+                       if (put_user(val, (int __user *)oldval))
+                               return -EFAULT;
+                       if (put_user(sizeof(int), oldlenp))
                                return -EFAULT;
-                       if (olen!=sizeof(int))
-                               return -EINVAL; 
                }
-               if (put_user(*(int *)(table->data)/HZ, (int __user *)oldval) ||
-                   (oldlenp && put_user(sizeof(int),oldlenp)))
-                       return -EFAULT;
        }
        if (newval && newlen) { 
                int new;
@@ -2581,17 +2587,23 @@ int sysctl_ms_jiffies(ctl_table *table, int __user 
*name, int nlen,
                void __user *oldval, size_t __user *oldlenp,
                void __user *newval, size_t newlen)
 {
-       if (oldval) {
+       if (oldval && oldlenp) {
                size_t olen;
-               if (oldlenp) { 
-                       if (get_user(olen, oldlenp))
+
+               if (get_user(olen, oldlenp))
+                       return -EFAULT;
+               if (olen) {
+                       int val;
+
+                       if (olen < sizeof(int))
+                               return -EINVAL;
+
+                       val = jiffies_to_msecs(*(int *)(table->data));
+                       if (put_user(val, (int __user *)oldval))
+                               return -EFAULT;
+                       if (put_user(sizeof(int), oldlenp))
                                return -EFAULT;
-                       if (olen!=sizeof(int))
-                               return -EINVAL; 
                }
-               if (put_user(jiffies_to_msecs(*(int *)(table->data)), (int 
__user *)oldval) ||
-                   (oldlenp && put_user(sizeof(int),oldlenp)))
-                       return -EFAULT;
        }
        if (newval && newlen) { 
                int new;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to