[lkml]   [2005]   [Dec]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    Subject[PATCH] Fix user data corrupted by old value return of sysctl
    If the user reads a sysctl entry which is of string type
    by sysctl syscall, this call probably corrupts the user data
    right after the old value buffer, the issue lies in sysctl_string
    seting 0 to oldval[len], len is the available buffer size
    specified by the user, obviously, this will write to the first
    byte of the user memory place immediate after the old value buffer
    , the correct way is that sysctl_string doesn't set 0, the user
    should do it by self in the program.

    The following program verifies this point:

    #include <linux/unistd.h>
    #include <linux/types.h>
    #include <linux/sysctl.h>
    #include <errno.h>

    _syscall1(int, _sysctl, struct __sysctl_args *, args);
    int sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,
    void *newval, size_t newlen)
    struct __sysctl_args args
    = {name,nlen,oldval,oldlenp,newval,newlen};

    return _sysctl(&args);

    #define SIZE(x) sizeof(x)/sizeof(x[0])
    #define OSNAMESZ 4

    struct mystruct {
    char osname[OSNAMESZ];
    int target;
    int osnamelth;
    } myos;

    int name[] = { CTL_KERN, KERN_NODENAME };

    int main(int argc, char * argv[])
    { = 1;
    printf("target = %d\n",;
    myos.osnamelth = SIZE(myos.osname);
    if (sysctl(name, SIZE(name), myos.osname,
    &myos.osnamelth, 0, 0))
    else {
    printf("Current host name: %s\n", myos.osname);
    printf("target = %d\n",;
    return 0;

    Copy it to file sysctl-safe.c, then
    $ hostname
    $ gcc sysctl-safe.c
    $ ./a.out
    target = 1
    Current host name: mylo
    target = 0

    After apply this patch:
    $ hostname
    $ gcc sysctl-safe.c
    $ ./a.out
    target = 1
    Current host name: mylo
    target = 1

    Signed-off-by: Yi Yang <>

    --- a/kernel/sysctl.c.orig 2005-12-30 09:21:34.000000000 +0000
    +++ b/kernel/sysctl.c 2005-12-30 15:58:15.000000000 +0000
    @@ -2207,8 +2207,6 @@ int sysctl_string(ctl_table *table, int
    len = table->maxlen;
    if(copy_to_user(oldval, table->data, len))
    return -EFAULT;
    - if(put_user(0, ((char __user *) oldval) + len))
    - return -EFAULT;
    if(put_user(len, oldlenp))
    return -EFAULT;

    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to
    More majordomo info at
    Please read the FAQ at

     \ /
      Last update: 2005-12-30 09:43    [W:0.022 / U:24.120 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site