lkml.org 
[lkml]   [2002]   [Dec]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    Subjectbug in sysctl
    There is a shar attached below that contains a script to reproduce
    this problem.

    1. One line summary:
    sysctl is returning bad data with multi-word arrays.

    2. full description:

    The bug is that the /proc/sys interface seems to write data incorrectly. I
    include a simple tsc (test sysctl) script, that writes a set of values. Notice
    that the last value, -62345678 gets shown as -6234567. In some tests, the
    missing digit 8 ends up in the next location.

    It could be a read problem, but I don't think so.
    Note that the errant data does print 32 items, not 33 (since it is "splitting"
    one of them).

    I think this bug is on the kernel side, because I am getting odd behavior
    whether I use /sbin/sysctl, or whether I write to /proc/sys with my own
    programs.

    3. keyword: kernel / sysctl

    4. version:

    Linux localhost.localdomain 2.4.18-w4l-rtl3.1 #2 Wed Jun 26 17:32:45 EDT 2002 i686 unknown

    also:
    Linux trb-rtl.imt 2.2.18-rtl3.0 #1 Tue Jan 30 14:23:47 CET 2001 i686 unknown

    I'm running with RTLinux patches on both these machines, they are
    otherwise common.

    5. no crash

    6. script that triggers problem:
    Also see shar attached below.

    scbug.o is an lkm that creates an array in /proc/sys/kernel/scbug/scratch
    (see associated shar file).

    tsc: a small test shell script

    <<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>

    # insmod scbug.o

    # cat tsc
    sysctl -w kernel/scbug/scratch="91 92 93 94 95 96 97 98 99"

    sysctl kernel/scbug/scratch

    sysctl -w kernel/scbug/scratch="11111111 -22222222 33333333 -44444444 55555555 -62345678"

    sysctl kernel/scbug/scratch

    # ./tsc
    kernel.scbug.scratch = 91 92 93 94 95 96 97 98 99
    kernel.scbug.scratch = 91 92 93 94 95 96 97 98 99 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0
    0 0 0 0
    kernel.scbug.scratch = 11111111 -22222222 33333333 -44444444 55555555 -62345678
    kernel.scbug.scratch = 11111111 -22222222 33333333 -44444444 55555555 -6234567 97 98 99 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0

    -- end of report --



    8<--cut here--

    #!/bin/sh
    # This is a shell archive (produced by GNU sharutils 4.2.1).
    # To extract the files from this archive, save it to some FILE, remove
    # everything before the `!/bin/sh' line above, then type `sh FILE'.
    #
    # Made on 2002-12-05 15:30 EST by <trb@trb-rtl.imt>.
    # Source directory was `/home/trb'.
    #
    # Existing files will *not* be overwritten unless `-c' is specified.
    #
    # This shar contains:
    # length mode name
    # ------ ---------- ------------------------------------------
    # 97 -rw-rw-r-- scbug/Makefile
    # 1134 -rw------- scbug/scbug.c
    # 209 -rwxr-xr-x scbug/tsc
    # 2171 -rw-r--r-- scbug/scbug.rpt
    # 402 -rw-rw-r-- scbug/make.out
    #
    save_IFS="${IFS}"
    IFS="${IFS}:"
    gettext_dir=FAILED
    locale_dir=FAILED
    first_param="$1"
    for dir in $PATH
    do
    if test "$gettext_dir" = FAILED && test -f $dir/gettext \
    && ($dir/gettext --version >/dev/null 2>&1)
    then
    set `$dir/gettext --version 2>&1`
    if test "$3" = GNU
    then
    gettext_dir=$dir
    fi
    fi
    if test "$locale_dir" = FAILED && test -f $dir/shar \
    && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
    then
    locale_dir=`$dir/shar --print-text-domain-dir`
    fi
    done
    IFS="$save_IFS"
    if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
    then
    echo=echo
    else
    TEXTDOMAINDIR=$locale_dir
    export TEXTDOMAINDIR
    TEXTDOMAIN=sharutils
    export TEXTDOMAIN
    echo="$gettext_dir/gettext -s"
    fi
    if touch -am -t 200112312359.59 $$.touch >/dev/null 2>&1 && test ! -f 200112312359.59 -a -f $$.touch; then
    shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'
    elif touch -am 123123592001.59 $$.touch >/dev/null 2>&1 && test ! -f 123123592001.59 -a ! -f 123123592001.5 -a -f $$.touch; then
    shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'
    elif touch -am 1231235901 $$.touch >/dev/null 2>&1 && test ! -f 1231235901 -a -f $$.touch; then
    shar_touch='touch -am $3$4$5$6$2 "$8"'
    else
    shar_touch=:
    echo
    $echo 'WARNING: not restoring timestamps. Consider getting and'
    $echo "installing GNU \`touch', distributed in GNU File Utilities..."
    echo
    fi
    rm -f 200112312359.59 123123592001.59 123123592001.5 1231235901 $$.touch
    #
    if mkdir _sh01217; then
    $echo 'x -' 'creating lock directory'
    else
    $echo 'failed to create lock directory'
    exit 1
    fi
    # ============= scbug/Makefile ==============
    if test ! -d 'scbug'; then
    $echo 'x -' 'creating directory' 'scbug'
    mkdir 'scbug'
    fi
    if test -f 'scbug/Makefile' && test "$first_param" != -c; then
    $echo 'x -' SKIPPING 'scbug/Makefile' '(file already exists)'
    else
    $echo 'x -' extracting 'scbug/Makefile' '(text)'
    sed 's/^X//' << 'SHAR_EOF' > 'scbug/Makefile' &&
    bug: scbug.o
    X insmod scbug.o
    X ./tsc
    X
    scbug.o:
    X gcc -c scbug.c -Wall
    X
    clean:
    X rmmod scbug
    X rm *.o
    SHAR_EOF
    (set 20 02 12 04 16 30 03 'scbug/Makefile'; eval "$shar_touch") &&
    chmod 0664 'scbug/Makefile' ||
    $echo 'restore of' 'scbug/Makefile' 'failed'
    if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
    && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'scbug/Makefile:' 'MD5 check failed'
    796e34bfe17a6cb88d7bd613aef34ec2 scbug/Makefile
    SHAR_EOF
    else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'scbug/Makefile'`"
    test 97 -eq "$shar_count" ||
    $echo 'scbug/Makefile:' 'original size' '97,' 'current size' "$shar_count!"
    fi
    fi
    # ============= scbug/scbug.c ==============
    if test -f 'scbug/scbug.c' && test "$first_param" != -c; then
    $echo 'x -' SKIPPING 'scbug/scbug.c' '(file already exists)'
    else
    $echo 'x -' extracting 'scbug/scbug.c' '(text)'
    sed 's/^X//' << 'SHAR_EOF' > 'scbug/scbug.c' &&
    /*
    X * sysctl bug prog
    X */
    X
    #define __KERNEL__
    #define MODULE
    #include <linux/module.h>
    X
    #include <linux/sched.h>
    #include <linux/kernel.h>
    #include <linux/sysctl.h>
    #include <linux/ctype.h>
    X
    #define __KERNEL_SYSCALLS__
    #include <linux/unistd.h>
    #include <asm/unistd.h>
    X
    #ifndef VERSION_CODE
    # define VERSION_CODE(vers,rel,seq) ( (vers<<16) | (rel<<8) | seq )
    #endif
    X
    int scratch[32];
    X
    #define KERN_SCBUG 434 /* a random number, high enough */
    enum {SCRATCH=1};
    X
    /* the scratch array */
    static ctl_table scbug_table[] = {
    X {SCRATCH, "scratch", &scratch, 32*sizeof(int), 0644,
    X NULL, &proc_dointvec, &sysctl_intvec, /* fill with 0's */},
    X {0}
    X };
    X
    /* a directory */
    static ctl_table scbug_kern_table[] = {
    X {KERN_SCBUG, "scbug", NULL, 0, 0555, scbug_table},
    X {0}
    X };
    X
    /* the kernel directory */
    static ctl_table scbug_root_table[] = {
    X {CTL_KERN, "kernel", NULL, 0, 0555, scbug_kern_table},
    X {0}
    X };
    X
    static struct ctl_table_header *scbug_table_header;
    X
    int init_module(void)
    {
    X scbug_table_header = register_sysctl_table(scbug_root_table, 0);
    X return 0;
    }
    X
    void cleanup_module(void)
    {
    X unregister_sysctl_table(scbug_table_header);
    }
    SHAR_EOF
    (set 20 02 12 04 13 21 59 'scbug/scbug.c'; eval "$shar_touch") &&
    chmod 0600 'scbug/scbug.c' ||
    $echo 'restore of' 'scbug/scbug.c' 'failed'
    if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
    && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'scbug/scbug.c:' 'MD5 check failed'
    13c9e91470b69730be09c9718bba008b scbug/scbug.c
    SHAR_EOF
    else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'scbug/scbug.c'`"
    test 1134 -eq "$shar_count" ||
    $echo 'scbug/scbug.c:' 'original size' '1134,' 'current size' "$shar_count!"
    fi
    fi
    # ============= scbug/tsc ==============
    if test -f 'scbug/tsc' && test "$first_param" != -c; then
    $echo 'x -' SKIPPING 'scbug/tsc' '(file already exists)'
    else
    $echo 'x -' extracting 'scbug/tsc' '(text)'
    sed 's/^X//' << 'SHAR_EOF' > 'scbug/tsc' &&
    sysctl -w kernel/scbug/scratch="91 92 93 94 95 96 97 98 99"
    X
    sysctl kernel/scbug/scratch
    X
    sysctl -w kernel/scbug/scratch="11111111 -22222222 33333333 -44444444 55555555 -62345678"
    X
    sysctl kernel/scbug/scratch
    SHAR_EOF
    (set 20 02 12 04 13 16 06 'scbug/tsc'; eval "$shar_touch") &&
    chmod 0755 'scbug/tsc' ||
    $echo 'restore of' 'scbug/tsc' 'failed'
    if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
    && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'scbug/tsc:' 'MD5 check failed'
    4078f361f00fc594865b9822b144fb91 scbug/tsc
    SHAR_EOF
    else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'scbug/tsc'`"
    test 209 -eq "$shar_count" ||
    $echo 'scbug/tsc:' 'original size' '209,' 'current size' "$shar_count!"
    fi
    fi
    # ============= scbug/scbug.rpt ==============
    if test -f 'scbug/scbug.rpt' && test "$first_param" != -c; then
    $echo 'x -' SKIPPING 'scbug/scbug.rpt' '(file already exists)'
    else
    $echo 'x -' extracting 'scbug/scbug.rpt' '(text)'
    sed 's/^X//' << 'SHAR_EOF' > 'scbug/scbug.rpt' &&
    1. One line summary:
    sysctl is returning bad data with multi-word arrays.
    X
    2. full description:
    X
    The bug is that the /proc/sys interface seems to write data incorrectly. I
    include a simple tsc (test sysctl) script, that writes a set of values. Notice
    that the last value, -62345678 gets written as -6234567. (In some tests, the
    missing 8 ends up in the next location.)
    X
    It could be a read problem, but I don't think so.
    Note that the errant data does print 32 items, not 33 (since it is "splitting"
    one of them).
    X
    I think this bug is on the kernel side, because I am getting odd behavior
    whether I use /sbin/sysctl, or whether I write to /proc/sys with my own
    programs.
    X
    3. keyword: kernel / sysctl
    X
    4. version:
    X
    # uname -a
    Linux localhost.localdomain 2.4.18-w4l-rtl3.1 #2 Wed Jun 26 17:32:45 EDT 2002 i686 unknown
    also:
    Linux trb-rtl.imt 2.2.18-rtl3.0 #1 Tue Jan 30 14:23:47 CET 2001 i686 unknown
    X
    5. no crash
    X
    6. script that triggers problem:
    This is shell output, split it up by hand, it's not too long.
    X
    scbug.o is an lkm that creates an array in /proc/sys/kernel/scbug/scratch
    (see associated shar file).
    X
    tsc: a small test shell script
    X
    <<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>
    X
    # insmod scbug.o
    X
    # cat tsc
    sysctl -w kernel/scbug/scratch="91 92 93 94 95 96 97 98 99"
    X
    sysctl kernel/scbug/scratch
    X
    sysctl -w kernel/scbug/scratch="11111111 -22222222 33333333 -44444444 55555555 -62345678"
    X
    sysctl kernel/scbug/scratch
    X
    # ./tsc
    kernel.scbug.scratch = 91 92 93 94 95 96 97 98 99
    kernel.scbug.scratch = 91 92 93 94 95 96 97 98 99 0 0 0 0 0 0 0 0 0
    X 0 0 0 0 0 0 0 0 0 0
    X 0 0 0 0
    kernel.scbug.scratch = 11111111 -22222222 33333333 -44444444 55555555 -62345678
    kernel.scbug.scratch = 11111111 -22222222 33333333 -44444444 55555555 -6234567 97 98 99 0 0 0 0 0
    X 0 0 0 0 0 0 0 0 0 0
    X 0 0 0 0 0 0 0 0
    X
    #
    SHAR_EOF
    (set 20 02 12 05 15 30 26 'scbug/scbug.rpt'; eval "$shar_touch") &&
    chmod 0644 'scbug/scbug.rpt' ||
    $echo 'restore of' 'scbug/scbug.rpt' 'failed'
    if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
    && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'scbug/scbug.rpt:' 'MD5 check failed'
    5cbb8ce9a2f7a248f131a2617e829618 scbug/scbug.rpt
    SHAR_EOF
    else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'scbug/scbug.rpt'`"
    test 2171 -eq "$shar_count" ||
    $echo 'scbug/scbug.rpt:' 'original size' '2171,' 'current size' "$shar_count!"
    fi
    fi
    # ============= scbug/make.out ==============
    if test -f 'scbug/make.out' && test "$first_param" != -c; then
    $echo 'x -' SKIPPING 'scbug/make.out' '(file already exists)'
    else
    $echo 'x -' extracting 'scbug/make.out' '(text)'
    sed 's/^X//' << 'SHAR_EOF' > 'scbug/make.out' &&
    gcc -c scbug.c -Wall
    insmod scbug.o
    X./tsc
    kernel.scbug.scratch = 91 92 93 94 95 96 97 98 99
    kernel.scbug.scratch = 91 92 93 94 95 96 97 98 99 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    kernel.scbug.scratch = 11111111 -22222222 33333333 -44444444 55555555 -62345678
    kernel.scbug.scratch = 11111111 -22222222 33333333 -44444444 55555555 -6234567 97 98 99 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    SHAR_EOF
    (set 20 02 12 04 15 44 25 'scbug/make.out'; eval "$shar_touch") &&
    chmod 0664 'scbug/make.out' ||
    $echo 'restore of' 'scbug/make.out' 'failed'
    if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
    && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'scbug/make.out:' 'MD5 check failed'
    2bcd64fa1bc631ec3f1bd07bad71cc16 scbug/make.out
    SHAR_EOF
    else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'scbug/make.out'`"
    test 402 -eq "$shar_count" ||
    $echo 'scbug/make.out:' 'original size' '402,' 'current size' "$shar_count!"
    fi
    fi
    rm -fr _sh01217
    exit 0

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:31    [W:0.040 / U:29.452 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site