wiki:Dev/KernelHack/COINS/worklog/201111

11/02

informative system calls

  • kernel/sys.c
    • sethostname, gethostname
    • about copy_to_user/copy_from_user
  • kernel/hrtimer.c
    • nanosleep
    • about timespec
  • kernel/posix-timers.c
    • clock_gettime
    • about timespec
  • kernel/module.c
    • delete_module
    • about strncpy_from_user
  • kernel/printk.c
    • about __LOG_BUF_LEN/access_ok

testing new_debug syscall

  • windell57:i386 s0711489$ make -j2
    Kernel: arch/x86/boot/bzImage is ready  (#3)
    
  • s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh
  • s0711489@ubuntu-lucid:~$ sudo reboot
  • s0711489@ubuntu-lucid:~$ cat > new_debug-sys.c
  • s0711489@ubuntu-lucid:~$ gcc -I /lib/modules/2.6.35.14/build/arch/x86/include/ new_debug-sys.c
  • s0711489@ubuntu-lucid:~$ ./a.out
    new_debug()
    
  • s0711489@ubuntu-lucid:~$ dmesg | tail -n 2
    [    6.833440] dhclient3 used greatest stack depth: 5560 bytes left
    [  579.378377] new_debug()
    
  • s0711489@ubuntu-lucid:~$ ./a.out hoge fuga piyo
    [-570566464.-1216585740] hoge
    [0.000000000] fuga
    [0.000000000] piyo
    
  • s0711489@ubuntu-lucid:~$ dmesg | tail -n 5
    [    6.833440] dhclient3 used greatest stack depth: 5560 bytes left
    [  579.378377] new_debug()
    [  596.785236] hoge
    [  596.785274] fuga
    [  596.785282] piyo
    

maybe useful

11/04

  • define as static char __log_buf[__LOG_BUF_LEN] in printk.c
  • sys_clock_gettime uses copy_to_user in its code

11/08

  • new_debug() が正常に動作したりしなかったりする
    • 結論 -> staticで確保していなかったのが良くない

char message[__LOG_BUF_LEN];

  • windell46:i386 s0711489$ ./build
    press enter key to make with i386 kernel
    
    Kernel: arch/x86/boot/bzImage is ready  (#6)
    
  • windell46:i386 s0711489$ make modules
  • s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh
  • s0711489@ubuntu-lucid:~$ sudo reboot
    Linux ubuntu-lucid 2.6.35.14 #6 SMP Tue Nov 8 17:26:43 JST 2011 i686 GNU/Linux
    
  • windell46:~ s0711489$ scp -r .subversion/ 172.16.237.130:~
  • s0711489@ubuntu-lucid:~/03$ gcc -I /lib/modules/2.6.35.14/build/arch/x86/include/ new_debug-sys.c
  • s0711489@ubuntu-lucid:~/03$ ./a.out
    new_debug with argv[i]: Bad address
    
  • s0711489@ubuntu-lucid:~/03$ ./a.out 1 2
    new_debug with argv[i]: Bad address
    new_debug with argv[i]: Bad address
    

gdb

  • viola06:i386 s0711489$ gdb
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/vmlinux...(no debugging symbols found)...done.
    (gdb) b sys_new_debug
    Breakpoint 1 at 0xc101d89f: file arch/x86/kernel/new_debug.c, line 9.
    (gdb) target remote windell46:8832
    Remote debugging using windell46:8832
    0xc1007cdf in native_safe_halt () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid:~/03$ ./a.out 1 2
    Breakpoint 1, sys_new_debug (message_user=0xbfc6499e "1", tp_user=0xbfc63804) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) l
    4       #include <linux/time.h>
    5
    6       /* from kernel/printk.c */
    7       #define __LOG_BUF_LEN   (1 << CONFIG_LOG_BUF_SHIFT)
    8
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    10              int errno;
    11              char message[__LOG_BUF_LEN];
    12              struct timespec ts;
    13
    (gdb)
    14              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    15                      errno = -EFAULT;
    16                      goto out;
    17              }
    18
    19              if (message == NULL) {
    20                      errno = -EINVAL;
    21                      goto out;
    22              }
    23              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    (gdb)
    24                      errno = -EFAULT;
    25                      goto out;
    26              }
    27              message[sizeof(message) - 1] = '\0';
    28
    29              printk(KERN_DEBUG "%s\n", message);
    30
    31              if (tp_user != NULL) {
    32                      sys_clock_gettime(CLOCK_REALTIME, &ts);
    33                      if (copy_to_user(tp_user, &ts, sizeof(ts)) != 0) {
    (gdb)
    34                              errno = -EFAULT;
    35                              goto out;
    36                      }
    37              }
    38
    39              errno = 0;
    40
    41      out:
    42              return errno;
    43      }
    (gdb)
    Line number 44 out of range; arch/x86/kernel/new_debug.c has 43 lines.
    (gdb) s
    14              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    41      out:
    (gdb)
    43      }
    (gdb) p errno
    $1 = -14
    (gdb) finish
    Run till exit from #0  sys_new_debug (message_user=0xbfc6499e "1", tp_user=0xbfc63804) at arch/x86/kernel/new_debug.c:43
    0xc100288c in ?? ()
    Value returned is $2 = -14
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0xbfc649a0 "2", tp_user=0xbfc63804) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) s
    14              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    41      out:
    (gdb) finish
    Run till exit from #0  sys_new_debug (message_user=0xbfc649a0 "2", tp_user=0xbfc63804) at arch/x86/kernel/new_debug.c:41
    0xc100288c in ?? ()
    Value returned is $3 = -14
    (gdb) c
    Continuing.
    
    • s0711489@ubuntu-lucid:~/03$ ./a.out 1 2
      new_debug with argv[i]: Bad address
      new_debug with argv[i]: Bad address
      
  • s0711489@ubuntu-lucid:~/03$ ./a.out
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/vmlinux...(no debugging symbols found)...done.
    (gdb) b sys_new_debug
    Breakpoint 1 at 0xc101d89f: file arch/x86/kernel/new_debug.c, line 9.
    (gdb) target remote windell46:8832
    Remote debugging using windell46:8832
    0xc1007cdf in native_safe_halt () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0x8048646 "new_debug()", tp_user=0x0) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) l
    4       #include <linux/time.h>
    5
    6       /* from kernel/printk.c */
    7       #define __LOG_BUF_LEN   (1 << CONFIG_LOG_BUF_SHIFT)
    8
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    10              int errno;
    11              char message[__LOG_BUF_LEN];
    12              struct timespec ts;
    13
    (gdb)
    14              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    15                      errno = -EFAULT;
    16                      goto out;
    17              }
    18
    19              if (message == NULL) {
    20                      errno = -EINVAL;
    21                      goto out;
    22              }
    23              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    (gdb)
    24                      errno = -EFAULT;
    25                      goto out;
    26              }
    27              message[sizeof(message) - 1] = '\0';
    28
    29              printk(KERN_DEBUG "%s\n", message);
    30
    31              if (tp_user != NULL) {
    32                      sys_clock_gettime(CLOCK_REALTIME, &ts);
    33                      if (copy_to_user(tp_user, &ts, sizeof(ts)) != 0) {
    (gdb) s
    14              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    23              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    (gdb)
    strncpy_from_user (dst=0xdf275f9c "", src=0x8048646 "new_debug()", count=262143) at arch/x86/lib/usercopy_32.c:114
    114     {
    (gdb) l
    109      * If @count is smaller than the length of the string, copies @count bytes
    110      * and returns @count.
    111      */
    112     long
    113     strncpy_from_user(char *dst, const char __user *src, long count)
    114     {
    115             long res = -EFAULT;
    116             if (access_ok(VERIFY_READ, src, 1))
    117                     __do_strncpy_from_user(dst, src, count, res);
    118             return res;
    (gdb)
    119     }
    120     EXPORT_SYMBOL(strncpy_from_user);
    121
    122     /*
    123      * Zero Userspace
    124      */
    125
    126     #define __do_clear_user(addr,size)                                      \
    127     do {                                                                    \
    128             int __d0;                                                       \
    (gdb)
    129             might_fault();                                                  \
    130             __asm__ __volatile__(                                           \
    131                     "0:     rep; stosl\n"                                   \
    132                     "       movl %2,%0\n"                                   \
    133                     "1:     rep; stosb\n"                                   \
    134                     "2:\n"                                                  \
    135                     ".section .fixup,\"ax\"\n"                              \
    136                     "3:     lea 0(%2,%0,4),%0\n"                            \
    137                     "       jmp 2b\n"                                       \
    138                     ".previous\n"                                           \
    (gdb)
    139                     _ASM_EXTABLE(0b,3b)                                     \
    140                     _ASM_EXTABLE(1b,2b)                                     \
    141                     : "=&c"(size), "=&D" (__d0)                             \
    142                     : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0));     \
    143     } while (0)
    144
    145     /**
    146      * clear_user: - Zero a block of memory in user space.
    147      * @to:   Destination address, in user space.
    148      * @n:    Number of bytes to zero.
    (gdb) s
    116             if (access_ok(VERIFY_READ, src, 1))
    (gdb)
    119     }
    (gdb) p src
    $1 = 0x8048646 "new_debug()"
    (gdb) p dst
    $2 = 0xdf275f9c ""
    (gdb) p count
    $3 = 262143
    (gdb) p res
    $4 = -14
    (gdb) finish
    Run till exit from #0  strncpy_from_user (dst=0xdf275f9c "", src=0x8048646 "new_debug()", count=262143) at arch/x86/lib/usercopy_32.c:119
    0xc101d8d3 in sys_new_debug (message_user=0x8048646 "new_debug()", tp_user=0x0) at arch/x86/kernel/new_debug.c:23
    23              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    Value returned is $5 = -14
    (gdb) s
    41      out:
    (gdb)
    43      }
    (gdb) finish
    Run till exit from #0  sys_new_debug (message_user=0x8048646 "new_debug()", tp_user=0x0) at arch/x86/kernel/new_debug.c:43
    0xc100288c in ?? ()
    Value returned is $6 = -14
    (gdb) s
    Cannot find bounds of current function
    (gdb) c
    Continuing.
    
    • s0711489@ubuntu-lucid:~/03$ ./a.out
      new_debug with argv[i]: Bad address
      
  • s0711489@ubuntu-lucid:~/03$ ./a.out
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/vmlinux...(no debugging symbols found)...done.
    (gdb) b sys_new_debug
    Breakpoint 1 at 0xc101d89f: file arch/x86/kernel/new_debug.c, line 9.
    (gdb) target remote windell46:8832
    Remote debugging using windell46:8832
    0xc1007cdf in native_safe_halt () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0x8048646 "new_debug()", tp_user=0x0) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) s
    14              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    23              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    (gdb)
    strncpy_from_user (
        dst=0xdc3d9f9c "\210\035i\b\250\035i\b\330\035i\b\250\270L\b\b\036i\b\030\036i\b\350\343O\b8\036i\bX\036i\bx\036i\b\270\036i\b\350\036i\b\330\036i\b\370\036i\b\b\037i\b\350\036i\b(\037i\b8\037i\bH\037i\bh\037i\b\210\037i\b\250\037i\b\350\037i\bX\021W\b\310\037i\bp\200h\b", src=0x8048646 "new_debug()",
        count=262143) at arch/x86/lib/usercopy_32.c:114
    114     {
    (gdb)
    116             if (access_ok(VERIFY_READ, src, 1))
    (gdb)
    119     }
    (gdb) finish
    Run till exit from #0  strncpy_from_user (
        dst=0xdc3d9f9c "\210\035i\b\250\035i\b\330\035i\b\250\270L\b\b\036i\b\030\036i\b\350\343O\b8\036i\bX\036i\bx\036i\b\270\036i\b\350\036i\b\330\036i\b\370\036i\b\b\037i\b\350\036i\b(\037i\b8\037i\bH\037i\bh\037i\b\210\037i\b\250\037i\b\350\037i\bX\021W\b\310\037i\bp\200h\b", src=0x8048646 "new_debug()",
        count=262143) at arch/x86/lib/usercopy_32.c:119
    0xc101d8d3 in sys_new_debug (message_user=0x8048646 "new_debug()", tp_user=0x0) at arch/x86/kernel/new_debug.c:23
    23              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    Value returned is $1 = -14
    (gdb)
    Run till exit from #0  0xc101d8d3 in sys_new_debug (message_user=0x8048646 "new_debug()", tp_user=0x0) at arch/x86/kernel/new_debug.c:23
    0xc100288c in ?? ()
    Value returned is $2 = -14
    (gdb)
    Run till exit from #0  0xc100288c in ?? ()
    
  • gdbでステップ実行していると、finishで関数から抜けようとした際に、以下のようにkernel panicを起こすことが多々あった
  • まれにうまく動作した場合、message[]はstaticでは無いのに前のデータが残っていることがある模様
    • guest
      s0711489@ubuntu-lucid:~/03$ ./a.out
      new_debug()
      s0711489@ubuntu-lucid:~/03$ ./a.out
      
    • gdb
      Breakpoint 1, sys_new_debug (message_user=0x8048646 "new_debug()", tp_user=0x0) at arch/x86/kernel/new_debug.c:9
      9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
      (gdb) s
      14              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
      (gdb)
      23              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
      (gdb)
      strncpy_from_user (dst=0xdc569f9c "new_debug()", src=0x8048646 "new_debug()", count=262143) at arch/x86/lib/usercopy_32.c:114
      114     {
      (gdb) finish
      Run till exit from #0  strncpy_from_user (dst=0xdc569f9c "new_debug()", src=0x8048646 "new_debug()", count=262143) at arch/x86/lib/usercopy_32.c:114
      

len = strnlen_user

  • vim arch/x86/kernel/new_debug.c
    • arch/x86/kernel/new_debug.c

       
      1010        int errno; 
      1111        char message[__LOG_BUF_LEN]; 
      1212        struct timespec ts; 
       13        long len = 0; 
      1314         
      1415        if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) { 
      1516                errno = -EFAULT; 
      1617                goto out; 
      1718        } 
      1819         
      19         if (message == NULL) { 
       20        if (message_user == NULL) { 
      2021                errno = -EINVAL; 
      2122                goto out; 
      2223        } 
       24        len = strnlen_user(message_user, __LOG_BUF_LEN); 
       25        if (len == 0 || len > __LOG_BUF_LEN) { 
       26                errno = -EINVAL; 
       27                goto out; 
       28        } 
      2329        if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) { 
      2430                errno = -EFAULT; 
      2531                goto out; 
  • windell46:i386 s0711489$ ./build
    Kernel: arch/x86/boot/bzImage is ready  (#7)
    
  • s0711489@ubuntu-lucid:~$ sudo reboot
  • s0711489@ubuntu-lucid:~/03$ ./a.out
    new_debug with argv[i]: Invalid argument
    
  • s0711489@ubuntu-lucid:~/03$ ./a.out
    Breakpoint 1, sys_new_debug (message_user=0x8048646 "new_debug()", tp_user=0x0) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) s
    15              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    20              if (message_user == NULL) {
    (gdb)
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    (gdb)
    strnlen_user (s=0x8048646 "new_debug()", n=262144) at arch/x86/lib/usercopy_32.c:196
    196     {
    (gdb)
    197             unsigned long mask = -__addr_ok(s);
    (gdb) finish
    Run till exit from #0  strnlen_user (s=0x8048646 "new_debug()", n=262144) at arch/x86/lib/usercopy_32.c:197
    
    Program received signal SIGINT, Interrupt.
    0xc1332240 in __ticket_spin_lock () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/arch/x86/include/asm/spinlock.h:65
    65              asm volatile (
    (gdb) detach
    Ending remote debugging.
    

__LOG_BUF_LEN 1024

  • vim arch/x86/kernel/new_debug.c
    • arch/x86/kernel/new_debug.c

       
      44#include <linux/time.h> 
      55 
      66/* from kernel/printk.c */ 
      7 #define __LOG_BUF_LEN   (1 << CONFIG_LOG_BUF_SHIFT) 
       7#define __LOG_BUF_LEN   1024 
      88 
      99SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) { 
      1010        int errno; 
  • windell46:i386 s0711489$ ./build
    Kernel: arch/x86/boot/bzImage is ready  (#8)
    
  • windell46:i386 s0711489$ make modules
  • s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh
  • gdb
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/vmlinux...(no debugging symbols found)...done.
    (gdb) b sys_new_debug
    Breakpoint 1 at 0xc101d8a0: file arch/x86/kernel/new_debug.c, line 9.
    (gdb) target remote windell46:8832
    Remote debugging using windell46:8832
    0xc1007cdf in native_safe_halt () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0x8048646 "new_debug()", tp_user=0x0) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) l
    4       #include <linux/time.h>
    5
    6       /* from kernel/printk.c */
    7       #define __LOG_BUF_LEN   1024
    8
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    10              int errno;
    11              char message[__LOG_BUF_LEN];
    12              struct timespec ts;
    13              long len = 0;
    (gdb)
    14
    15              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    16                      errno = -EFAULT;
    17                      goto out;
    18              }
    19
    20              if (message_user == NULL) {
    21                      errno = -EINVAL;
    22                      goto out;
    23              }
    (gdb)
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    25              if (len == 0 || len > __LOG_BUF_LEN) {
    26                      errno = -EINVAL;
    27                      goto out;
    28              }
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    30                      errno = -EFAULT;
    31                      goto out;
    32              }
    33              message[sizeof(message) - 1] = '\0';
    (gdb)
    34
    35              printk(KERN_DEBUG "%s\n", message);
    36
    37              if (tp_user != NULL) {
    38                      sys_clock_gettime(CLOCK_REALTIME, &ts);
    39                      if (copy_to_user(tp_user, &ts, sizeof(ts)) != 0) {
    40                              errno = -EFAULT;
    41                              goto out;
    42                      }
    43              }
    (gdb)
    44
    45              errno = 0;
    46
    47      out:
    48              return errno;
    49      }
    (gdb) s
    15              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    20              if (message_user == NULL) {
    (gdb)
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    (gdb)
    strnlen_user (s=0x8048646 "new_debug()", n=1024) at arch/x86/lib/usercopy_32.c:196
    196     {
    (gdb)
    197             unsigned long mask = -__addr_ok(s);
    (gdb) finish
    Run till exit from #0  strnlen_user (s=0x8048646 "new_debug()", n=1024) at arch/x86/lib/usercopy_32.c:197
    sys_new_debug (message_user=0x8048646 "new_debug()", tp_user=0x0) at arch/x86/kernel/new_debug.c:25
    25              if (len == 0 || len > __LOG_BUF_LEN) {
    Value returned is $1 = 12
    (gdb) s
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    (gdb) p message
    $2 = '\000' <repeats 176 times>, "\022\002\000\000[\356U鬜\354\335,\236\354\335\060\236\354\335\064\236\354\335\070\236\354\335<\236\354\335\220\216NN\224O\377\206\002\222\374\302[\356U\351\203\002a\033\336\314}\350\002\222\374\302\b\301\261\215P\000\000\000\000\000\000\000 \000\000\000,\236\354\335L\236\354\335;^\035\301\354\235\354\335,\236\354\335b\236\354\335\250\026\367\337\331\377\377\377\000\000\000\000\000\177\300\301\000\000\000\000Ȝ\354\335\037p\000\301\020\235\354\335\223\206\004\301\254a\a\371F\000\000\000\374`\a\371F\000\000\000\374`\a\371F\000\000\000@\204\300\301@\177\300\301C\224)*\017H\017\000\000\000\000\000\034T\215\337\017H\017\000\070\235\354݄c\002\301t\235\354\335,b\004\301F\000\000\000\360S\215\337\017H\017\000\000\000\000\000R\334\070*\003\000\000\000\300\344\063\301@B\017\000\000\000\000\000@>\300\301\200\235\354\335|v\004\301@B\017\000\000\000\000\000@`\374\370F\000\000\000t\235\354\335X\235\354\335d\235\354\335\250d\001\301l\235\354\335\304f\001\301\220\235\354\335\063\352\004\301\063`\016\001\000\000\000\000\v\026\341\226w\004\000\000\200\242\v\371F\000\000\000\002\000\000\000\230"...
    (gdb) p message_user
    $3 = 0x8048646 "new_debug()"
    (gdb) s
    strncpy_from_user (dst=0xddec9b98 "", src=0x8048646 "new_debug()", count=1023) at arch/x86/lib/usercopy_32.c:114
    114     {
    (gdb) finish
    Run till exit from #0  strncpy_from_user (dst=0xddec9b98 "", src=0x8048646 "new_debug()", count=1023) at arch/x86/lib/usercopy_32.c:114
    0xc101d8f1 in sys_new_debug (message_user=0x8048646 "new_debug()", tp_user=0x0) at arch/x86/kernel/new_debug.c:29
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    Value returned is $4 = 11
    (gdb) p message_user
    $5 = 0x8048646 "new_debug()"
    (gdb) p message
    $6 = "new_debug()", '\000' <repeats 165 times>, "\022\002\000\000[\356U鬜\354\335,\236\354\335\060\236\354\335\064\236\354\335\070\236\354\335<\236\354\335\220\216NN\224O\377\206\002\222\374\302[\356U\351\203\002a\033\336\314}\350\002\222\374\302\b\301\261\215P\000\000\000\000\000\000\000 \000\000\000,\236\354\335L\236\354\335;^\035\301\354\235\354\335,\236\354\335b\236\354\335\250\026\367\337\331\377\377\377\000\000\000\000\000\177\300\301\000\000\000\000Ȝ\354\335\037p\000\301\020\235\354\335\223\206\004\301\254a\a\371F\000\000\000\374`\a\371F\000\000\000\374`\a\371F\000\000\000@\204\300\301@\177\300\301C\224)*\017H\017\000\000\000\000\000\034T\215\337\017H\017\000\070\235\354݄c\002\301t\235\354\335,b\004\301F\000\000\000\360S\215\337\017H\017\000\000\000\000\000R\334\070*\003\000\000\000\300\344\063\301@B\017\000\000\000\000\000@>\300\301\200\235\354\335|v\004\301@B\017\000\000\000\000\000@`\374\370F\000\000\000t\235\354\335X\235\354\335d\235\354\335\250d\001\301l\235\354\335\304f\001\301\220\235\354\335\063\352\004\301\063`\016\001\000\000\000\000\v\026\341\226w"...
    (gdb) s
    35              printk(KERN_DEBUG "%s\n", message);
    (gdb)
    33              message[sizeof(message) - 1] = '\0';
    (gdb)
    35              printk(KERN_DEBUG "%s\n", message);
    (gdb) n
    37              if (tp_user != NULL) {
    (gdb) s
    49      }
    (gdb) finish
    Run till exit from #0  sys_new_debug (message_user=0x8048646 "new_debug()", tp_user=0x0) at arch/x86/kernel/new_debug.c:49
    0xc100288c in ?? ()
    Value returned is $7 = 0
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid:~/03$ ./a.out
    new_debug()
    
  • 期待通りの挙動を示した

static char message []

  • vim arch/x86/kernel/new_debug.c
    • arch/x86/kernel/new_debug.c

       
      88 
      99SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) { 
      1010        int errno; 
      11         char message[__LOG_BUF_LEN]; 
       11        static char message[__LOG_BUF_LEN]; 
      1212        struct timespec ts; 
      1313        long len = 0; 
      1414         
  • windell46:i386 s0711489$ ./build
    Kernel: arch/x86/boot/bzImage is ready  (#9)
    
  • windell46:i386 s0711489$ make modules
  • s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh
  • gdb
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/vmlinux...(no debugging symbols found)...done.
    (gdb) b sys_new_debug
    Breakpoint 1 at 0xc101d89c: file arch/x86/kernel/new_debug.c, line 9.
    (gdb) target remote windell46:8832
    Remote debugging using windell46:8832
    0xc1007cdf in native_safe_halt () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0xbf8b099c "1", tp_user=0xbf8af014) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) l
    4       #include <linux/time.h>
    5
    6       /* from kernel/printk.c */
    7       #define __LOG_BUF_LEN   (1 << CONFIG_LOG_BUF_SHIFT)
    8
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    10              int errno;
    11              static char message[__LOG_BUF_LEN];
    12              struct timespec ts;
    13              long len = 0;
    (gdb)
    14
    15              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    16                      errno = -EFAULT;
    17                      goto out;
    18              }
    19
    20              if (message_user == NULL) {
    21                      errno = -EINVAL;
    22                      goto out;
    23              }
    (gdb)
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    25              if (len == 0 || len > __LOG_BUF_LEN) {
    26                      errno = -EINVAL;
    27                      goto out;
    28              }
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    30                      errno = -EFAULT;
    31                      goto out;
    32              }
    33              message[sizeof(message) - 1] = '\0';
    (gdb)
    34
    35              printk(KERN_DEBUG "%s\n", message);
    36
    37              if (tp_user != NULL) {
    38                      sys_clock_gettime(CLOCK_REALTIME, &ts);
    39                      if (copy_to_user(tp_user, &ts, sizeof(ts)) != 0) {
    40                              errno = -EFAULT;
    41                              goto out;
    42                      }
    43              }
    (gdb)
    44
    45              errno = 0;
    46
    47      out:
    48              return errno;
    49      }
    (gdb) s
    15              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    20              if (message_user == NULL) {
    (gdb)
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    (gdb)
    strnlen_user (s=0xbf8b099c "1", n=262144) at arch/x86/lib/usercopy_32.c:196
    196     {
    (gdb) finish
    Run till exit from #0  strnlen_user (s=0xbf8b099c "1", n=262144) at arch/x86/lib/usercopy_32.c:196
    sys_new_debug (message_user=0xbf8b099c "1", tp_user=0xbf8af014) at arch/x86/kernel/new_debug.c:25
    25              if (len == 0 || len > __LOG_BUF_LEN) {
    Value returned is $1 = 2
    (gdb) s
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    (gdb)
    strncpy_from_user (dst=0xc158da00 "fuga", src=0xbf8b099c "1", count=262143) at arch/x86/lib/usercopy_32.c:114
    114     {
    (gdb) finish
    Run till exit from #0  strncpy_from_user (dst=0xc158da00 "fuga", src=0xbf8b099c "1", count=262143) at arch/x86/lib/usercopy_32.c:114
    0xc101d8ea in sys_new_debug (message_user=0xbf8b099c "1", tp_user=0xbf8af014) at arch/x86/kernel/new_debug.c:29
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    Value returned is $2 = 1
    (gdb) s
    35              printk(KERN_DEBUG "%s\n", message);
    (gdb)
    33              message[sizeof(message) - 1] = '\0';
    (gdb)
    35              printk(KERN_DEBUG "%s\n", message);
    (gdb) p message
    $3 = "1\000ga\000ebug()", '\000' <repeats 262132 times>
    (gdb) n
    37              if (tp_user != NULL) {
    (gdb) s
    38                      sys_clock_gettime(CLOCK_REALTIME, &ts);
    (gdb) p ts
    $4 = {tv_sec = -598564864, tv_nsec = -1217056780}
    (gdb) n
    39                      if (copy_to_user(tp_user, &ts, sizeof(ts)) != 0) {
    (gdb) p ts
    $5 = {tv_sec = -598564864, tv_nsec = -1217056780}
    (gdb) n
    49      }
    (gdb) p ts_user
    No symbol "ts_user" in current context.
    (gdb) p tp_
    tp_event               tp_perf_event_destroy  tp_probes              tp_user
    (gdb) p tp_user
    $6 = (struct timespec *) 0xbf8af014
    (gdb) p errno
    $7 = 0
    (gdb) finish
    Run till exit from #0  sys_new_debug (message_user=0xbf8b099c "1", tp_user=0xbf8af014) at arch/x86/kernel/new_debug.c:49
    0xc100288c in ?? ()
    Value returned is $8 = 0
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0xbf8b099e "2", tp_user=0xbf8af014) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0xbf8b09a0 "3", tp_user=0xbf8af014) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0xbfc1e99c "1", tp_user=0xbfc1d654) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0xbfc1e99e "2", tp_user=0xbfc1d654) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) s
    15              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    20              if (message_user == NULL) {
    (gdb) n
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    (gdb)
    25              if (len == 0 || len > __LOG_BUF_LEN) {
    (gdb)
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    (gdb)
    35              printk(KERN_DEBUG "%s\n", message);
    (gdb)
    33              message[sizeof(message) - 1] = '\0';
    (gdb)
    35              printk(KERN_DEBUG "%s\n", message);
    (gdb)
    37              if (tp_user != NULL) {
    (gdb) p tp_user
    $9 = (struct timespec *) 0xbfc1d654
    (gdb) p ts
    $10 = {tv_sec = 0, tv_nsec = 0}
    (gdb) n
    38                      sys_clock_gettime(CLOCK_REALTIME, &ts);
    (gdb)
    39                      if (copy_to_user(tp_user, &ts, sizeof(ts)) != 0) {
    (gdb)
    49      }
    (gdb) finish
    Run till exit from #0  sys_new_debug (message_user=0xbfc1e99e "2", tp_user=0xbfc1d654) at arch/x86/kernel/new_debug.c:49
    0xc100288c in ?? ()
    Value returned is $11 = 0
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0xbfc1e9a0 "3", tp_user=0xbfc1d654) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid:~/03$ ./a.out hoge fuga
    [-598562624.-1216589836] hoge
    [0.000000000] fuga
    
  • s0711489@ubuntu-lucid:~/03$ ./a.out 1 2 3
    [-598564864.-1217056780] 1
    [0.000000000] 2
    [0.000000000] 3
    
  • s0711489@ubuntu-lucid:~/03$ ./a.out 1 2 3
    [-598564864.-1215885324] 1
    [0.000000000] 2
    [0.000000000] 3
    
  • こちらも問題無く動作した

very long argument

  • gdb
    (gdb) target remote windell46:8832
    Remote debugging using windell46:8832
    0xc1007cdf in native_safe_halt () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0xbfcf7619 '0' <repeats 97 times>, "1", '0' <repeats 99 times>, "200"..., tp_user=0xbfcf62d4)
        at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) s
    15              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    20              if (message_user == NULL) {
    (gdb) p message
    $12 = '\000' <repeats 262143 times>
    (gdb) p message_user
    $13 = 0xbfcf7619 '0' <repeats 97 times>, "1", '0' <repeats 99 times>, "200"...
    (gdb) p tp_user
    $14 = (struct timespec *) 0xbfcf62d4
    (gdb) s
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    (gdb) p len
    $15 = <value optimized out>
    (gdb) n
    25              if (len == 0 || len > __LOG_BUF_LEN) {
    (gdb) s
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    (gdb)
    strncpy_from_user (dst=0xc158da00 "", src=0xbfcf7619 '0' <repeats 97 times>, "1", '0' <repeats 99 times>, "200"..., count=262143)
        at arch/x86/lib/usercopy_32.c:114
    114     {
    (gdb) finish
    Run till exit from #0  strncpy_from_user (dst=0xc158da00 "", src=0xbfcf7619 '0' <repeats 97 times>, "1", '0' <repeats 99 times>, "200"..., count=262143)
        at arch/x86/lib/usercopy_32.c:114
    0xc101d8ea in sys_new_debug (message_user=0xbfcf7619 '0' <repeats 97 times>, "1", '0' <repeats 99 times>, "200"..., tp_user=0xbfcf62d4)
        at arch/x86/kernel/new_debug.c:29
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    Value returned is $16 = 5000
    (gdb) p message
    $17 = '0' <repeats 97 times>, "1", '0' <repeats 99 times>, "2", '0' <repeats 99 times>, "3", '0' <repeats 99 times>, "4", '0' <repeats 99 times>, "5", '0' <repeats 99 times>, "6", '0' <repeats 99 times>, "7", '0' <repeats 99 times>, "8", '0' <repeats 99 times>, "9", '0' <repeats 98 times>, "1", '0' <repeats 99 times>, "11", '0' <repeats 98 times>, "12", '0' <repeats 98 times>, "13", '0' <repeats 98 times>, "14", '0' <repeats 98 times>, "15", '0' <repeats 98 times>, "16", '0' <repeats 98 times>, "17", '0' <repeats 98 times>...
    (gdb) s
    35              printk(KERN_DEBUG "%s\n", message);
    (gdb) n
    33              message[sizeof(message) - 1] = '\0';
    (gdb) p sizeof(message)
    $18 = 262144
    (gdb) n
    35              printk(KERN_DEBUG "%s\n", message);
    (gdb)
    37              if (tp_user != NULL) {
    (gdb)
    38                      sys_clock_gettime(CLOCK_REALTIME, &ts);
    (gdb) p ts
    $19 = {tv_sec = -598614528, tv_nsec = -1216688140}
    (gdb) n
    39                      if (copy_to_user(tp_user, &ts, sizeof(ts)) != 0) {
    (gdb)
    49      }
    (gdb) finish
    Run till exit from #0  sys_new_debug (message_user=0xbfcf7619 '0' <repeats 97 times>, "1", '0' <repeats 99 times>, "200"..., tp_user=0xbfcf62d4)
        at arch/x86/kernel/new_debug.c:49
    0xc100288c in ?? ()
    Value returned is $20 = 0
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid:~/03$ ./a.out 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000150000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000270000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000
    [-598614528.-1216688140] 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000150000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000270000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000
    
  • s0711489@ubuntu-lucid:~/03$ dmesg | tail -n 2
    [    6.197442] vmblock: version magic '2.6.32-33-generic SMP mod_unload modversions 586 ' should be '2.6.35.14 SMP mod_unload 686 '
    [  276.962399] 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000
    
  • printk()
    Breakpoint 1, sys_new_debug (message_user=0xbfee1619 '0' <repeats 97 times>, "1", '0' <repeats 99 times>, "200"..., tp_user=0xbfedfda4)
        at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) n
    15              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    20              if (message_user == NULL) {
    (gdb)
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    (gdb)
    25              if (len == 0 || len > __LOG_BUF_LEN) {
    (gdb)
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    (gdb)
    35              printk(KERN_DEBUG "%s\n", message);
    (gdb) s
    33              message[sizeof(message) - 1] = '\0';
    (gdb)
    35              printk(KERN_DEBUG "%s\n", message);
    (gdb)
    printk (fmt=0xc1449542 "<7>%s\n") at kernel/printk.c:614
    614             va_start(args, fmt);
    (gdb) finish
    Run till exit from #0  printk (fmt=0xc1449542 "<7>%s\n") at kernel/printk.c:614
    sys_new_debug (message_user=0xbfee1619 '0' <repeats 97 times>, "1", '0' <repeats 99 times>, "200"..., tp_user=0xbfedfda4)
        at arch/x86/kernel/new_debug.c:37
    37              if (tp_user != NULL) {
    Value returned is $21 = 1041
    (gdb)
    Run till exit from #0  sys_new_debug (message_user=0xbfee1619 '0' <repeats 97 times>, "1", '0' <repeats 99 times>, "200"..., tp_user=0xbfedfda4)
        at arch/x86/kernel/new_debug.c:37
    0xc100288c in ?? ()
    Value returned is $22 = 0
    (gdb) c
    Continuing.
    

shorten message[]

  • printk()は1020文字程度しか出力してくれない(Ubuntu 10.04 i386)ので、バッファイサイズをずっと短くする
  • vim arch/x86/kernel/new_debug.c
    • arch/x86/kernel/new_debug.c

       
      44#include <linux/time.h> 
      55 
      66/* from kernel/printk.c */ 
      7 #define __LOG_BUF_LEN   (1 << CONFIG_LOG_BUF_SHIFT) 
       7#define __LOG_BUF_LEN 1024 
      88 
      99SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) { 
      1010        int errno; 
  • windell46:i386 s0711489$ ./build
    Kernel: arch/x86/boot/bzImage is ready  (#11)
    
  • windell46:i386 s0711489$ make modules
  • s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh
  • s0711489@ubuntu-lucid:~/03$ ./a.out
    new_debug()
    
  • s0711489@ubuntu-lucid:~/03$ ./a.out 1 2 3 4
    [-572681344.-1217335308] 1
    [0.000000000] 2
    [0.000000000] 3
    [0.000000000] 4
    
  • s0711489@ubuntu-lucid:~/03$ ./a.out 1 2 3 4 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000020 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000020123 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000201234 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000002012345
    [-572680448.-1215909900] 1
    [0.000000000] 2
    [0.000000000] 3
    [0.000000000] 4
    [0.000000000] 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000
    [0.000000000] 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000020
    [0.000000000] 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000020123
    new_debug with argv[i]: Invalid argument
    new_debug with argv[i]: Invalid argument
    
  • gdb
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/vmlinux...(no debugging symbols found)...done.
    b sys_new_debug
    (gdb) b sys_new_debug
    Breakpoint 1 at 0xc101d89c: file arch/x86/kernel/new_debug.c, line 9.
    (gdb) target remote windell46:8832
    Remote debugging using windell46:8832
    0xc1007cdf in native_safe_halt () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0xbfa735b9 '0' <repeats 200 times>..., tp_user=0xbfa716a4) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) n
    15              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    20              if (message_user == NULL) {
    (gdb)
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    (gdb) s
    strnlen_user (s=0xbfa735b9 '0' <repeats 200 times>..., n=1024) at arch/x86/lib/usercopy_32.c:196
    196     {
    (gdb) finish
    Run till exit from #0  strnlen_user (s=0xbfa735b9 '0' <repeats 200 times>..., n=1024) at arch/x86/lib/usercopy_32.c:196
    sys_new_debug (message_user=0xbfa735b9 '0' <repeats 200 times>..., tp_user=0xbfa716a4) at arch/x86/kernel/new_debug.c:25
    25              if (len == 0 || len > __LOG_BUF_LEN) {
    Value returned is $1 = 1001
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0xbfa739a2 '0' <repeats 200 times>..., tp_user=0xbfa716a4) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) n
    15              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    20              if (message_user == NULL) {
    (gdb)
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    (gdb) s
    strnlen_user (s=0xbfa739a2 '0' <repeats 200 times>..., n=1024) at arch/x86/lib/usercopy_32.c:196
    196     {
    (gdb) finish
    Run till exit from #0  strnlen_user (s=0xbfa739a2 '0' <repeats 200 times>..., n=1024) at arch/x86/lib/usercopy_32.c:196
    sys_new_debug (message_user=0xbfa739a2 '0' <repeats 200 times>..., tp_user=0xbfa716a4) at arch/x86/kernel/new_debug.c:25
    25              if (len == 0 || len > __LOG_BUF_LEN) {
    Value returned is $2 = 1021
    (gdb) s
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    (gdb)
    strncpy_from_user (dst=0xc158da00 '0' <repeats 200 times>..., src=0xbfa739a2 '0' <repeats 200 times>..., count=1023) at arch/x86/lib/usercopy_32.c:114
    114     {
    (gdb) finish
    Run till exit from #0  strncpy_from_user (dst=0xc158da00 '0' <repeats 200 times>..., src=0xbfa739a2 '0' <repeats 200 times>..., count=1023)
        at arch/x86/lib/usercopy_32.c:114
    0xc101d8ea in sys_new_debug (message_user=0xbfa739a2 '0' <repeats 200 times>..., tp_user=0xbfa716a4) at arch/x86/kernel/new_debug.c:29
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    Value returned is $3 = 1020
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0xbfa73d9f '0' <repeats 200 times>..., tp_user=0xbfa716a4) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) n
    15              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    20              if (message_user == NULL) {
    (gdb)
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    (gdb) s
    strnlen_user (s=0xbfa73d9f '0' <repeats 200 times>..., n=1024) at arch/x86/lib/usercopy_32.c:196
    196     {
    (gdb) finish
    Run till exit from #0  strnlen_user (s=0xbfa73d9f '0' <repeats 200 times>..., n=1024) at arch/x86/lib/usercopy_32.c:196
    sys_new_debug (message_user=0xbfa73d9f '0' <repeats 200 times>..., tp_user=0xbfa716a4) at arch/x86/kernel/new_debug.c:25
    25              if (len == 0 || len > __LOG_BUF_LEN) {
    Value returned is $4 = 1024
    (gdb) s
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    (gdb)
    strncpy_from_user (dst=0xc158da00 '0' <repeats 200 times>..., src=0xbfa73d9f '0' <repeats 200 times>..., count=1023) at arch/x86/lib/usercopy_32.c:114
    114     {
    (gdb) finish
    Run till exit from #0  strncpy_from_user (dst=0xc158da00 '0' <repeats 200 times>..., src=0xbfa73d9f '0' <repeats 200 times>..., count=1023)
        at arch/x86/lib/usercopy_32.c:114
    0xc101d8ea in sys_new_debug (message_user=0xbfa73d9f '0' <repeats 200 times>..., tp_user=0xbfa716a4) at arch/x86/kernel/new_debug.c:29
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    Value returned is $5 = 1023
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0xbfa7419f '0' <repeats 200 times>..., tp_user=0xbfa716a4) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) n
    15              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    20              if (message_user == NULL) {
    (gdb)
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    (gdb) s
    strnlen_user (s=0xbfa7419f '0' <repeats 200 times>..., n=1024) at arch/x86/lib/usercopy_32.c:196
    196     {
    (gdb) finish
    Run till exit from #0  strnlen_user (s=0xbfa7419f '0' <repeats 200 times>..., n=1024) at arch/x86/lib/usercopy_32.c:196
    sys_new_debug (message_user=0xbfa7419f '0' <repeats 200 times>..., tp_user=0xbfa716a4) at arch/x86/kernel/new_debug.c:25
    25              if (len == 0 || len > __LOG_BUF_LEN) {
    Value returned is $6 = 1025
    (gdb) s
    49      }
    (gdb) l 25
    20              if (message_user == NULL) {
    21                      errno = -EINVAL;
    22                      goto out;
    23              }
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    25              if (len == 0 || len > __LOG_BUF_LEN) {
    26                      errno = -EINVAL;
    27                      goto out;
    28              }
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    (gdb) p errno
    $7 = -22
    (gdb) finish
    Run till exit from #0  sys_new_debug (message_user=0xbfa7419f '0' <repeats 200 times>..., tp_user=0xbfa716a4) at arch/x86/kernel/new_debug.c:49
    0xc100288c in ?? ()
    Value returned is $8 = -22
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0xbfa745a0 '0' <repeats 200 times>..., tp_user=0xbfa716a4) at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) n
    15              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    20              if (message_user == NULL) {
    (gdb)
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    (gdb) s
    strnlen_user (s=0xbfa745a0 '0' <repeats 200 times>..., n=1024) at arch/x86/lib/usercopy_32.c:196
    196     {
    (gdb) finish
    Run till exit from #0  strnlen_user (s=0xbfa745a0 '0' <repeats 200 times>..., n=1024) at arch/x86/lib/usercopy_32.c:196
    sys_new_debug (message_user=0xbfa745a0 '0' <repeats 200 times>..., tp_user=0xbfa716a4) at arch/x86/kernel/new_debug.c:25
    25              if (len == 0 || len > __LOG_BUF_LEN) {
    Value returned is $9 = 1025
    (gdb) s
    49      }
    (gdb) p errno
    $10 = -22
    (gdb) finish
    Run till exit from #0  sys_new_debug (message_user=0xbfa745a0 '0' <repeats 200 times>..., tp_user=0xbfa716a4) at arch/x86/kernel/new_debug.c:49
    0xc100288c in ?? ()
    Value returned is $11 = -22
    (gdb) c
    Continuing.
    
    • s0711489@ubuntu-lucid:~/03$ ./a.out 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000020 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000020123 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000201234 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000002012345
      [-593455808.-1216405516] 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000
      [0.000000000] 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000020
      [0.000000000] 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000020123
      new_debug with argv[i]: Invalid argument
      new_debug with argv[i]: Invalid argument
      

11/09

change sys_clock_gettime to getnstimeofday

  • vim arch/x86/kernel/new_debug.c
    • arch/x86/kernel/new_debug.c

       
      3535        printk(KERN_DEBUG "%s\n", message); 
      3636         
      3737        if (tp_user != NULL) { 
      38                 sys_clock_gettime(CLOCK_REALTIME, &ts); 
       38                getnstimeofday(&ts); 
      3939                if (copy_to_user(tp_user, &ts, sizeof(ts)) != 0) { 
      4040                        errno = -EFAULT; 
      4141                        goto out; 
  • windell46:i386 s0711489$ ./build
    Kernel: arch/x86/boot/bzImage is ready  (#12)
    
  • s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh
  • gdb
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/vmlinux...(no debugging symbols found)...done.
    (gdb) b sys_new_debug
    Breakpoint 1 at 0xc101d89c: file arch/x86/kernel/new_debug.c, line 9.
    (gdb) target remote windell46:8832
    Remote debugging using windell46:8832
    0xc1007cdf in native_safe_halt ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/i386/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) c
    Continuing.
    
    Breakpoint 1, sys_new_debug (message_user=0x8048646 "new_debug()", tp_user=0x0)
        at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) l
    4       #include <linux/time.h>
    5
    6       /* from kernel/printk.c */
    7       #define __LOG_BUF_LEN 1024
    8
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    10              int errno;
    11              static char message[__LOG_BUF_LEN];
    12              struct timespec ts;
    13              long len = 0;
    (gdb)
    14
    15              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    16                      errno = -EFAULT;
    17                      goto out;
    18              }
    19
    20              if (message_user == NULL) {
    21                      errno = -EINVAL;
    22                      goto out;
    23              }
    (gdb)
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    25              if (len == 0 || len > __LOG_BUF_LEN) {
    26                      errno = -EINVAL;
    27                      goto out;
    28              }
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    30                      errno = -EFAULT;
    31                      goto out;
    32              }
    33              message[sizeof(message) - 1] = '\0';
    (gdb)
    34
    35              printk(KERN_DEBUG "%s\n", message);
    36
    37              if (tp_user != NULL) {
    38                      getnstimeofday(&ts);
    39                      if (copy_to_user(tp_user, &ts, sizeof(ts)) != 0) {
    40                              errno = -EFAULT;
    41                              goto out;
    42                      }
    43              }
    (gdb)
    44
    45              errno = 0;
    46
    47      out:
    48              return errno;
    49      }
    (gdb) s
    15              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    20              if (message_user == NULL) {
    (gdb)
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    (gdb)
    strnlen_user (s=0x8048646 "new_debug()", n=1024)
        at arch/x86/lib/usercopy_32.c:196
    196     {
    (gdb) finish
    Run till exit from #0  strnlen_user (s=0x8048646 "new_debug()", n=1024)
        at arch/x86/lib/usercopy_32.c:196
    sys_new_debug (message_user=0x8048646 "new_debug()", tp_user=0x0)
        at arch/x86/kernel/new_debug.c:25
    25              if (len == 0 || len > __LOG_BUF_LEN) {
    Value returned is $1 = 12
    (gdb) s
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    (gdb)
    strncpy_from_user (dst=0xc158da00 "", src=0x8048646 "new_debug()", count=1023)
        at arch/x86/lib/usercopy_32.c:114
    114     {
    (gdb) finish
    Run till exit from #0  strncpy_from_user (dst=0xc158da00 "",
        src=0x8048646 "new_debug()", count=1023) at arch/x86/lib/usercopy_32.c:114
    0xc101d8ea in sys_new_debug (message_user=0x8048646 "new_debug()", tp_user=0x0)
        at arch/x86/kernel/new_debug.c:29
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    Value returned is $2 = 11
    (gdb) s
    35              printk(KERN_DEBUG "%s\n", message);
    (gdb)
    33              message[sizeof(message) - 1] = '\0';
    (gdb)
    35              printk(KERN_DEBUG "%s\n", message);
    (gdb)
    printk (fmt=0xc1449542 "<7>%s\n") at kernel/printk.c:614
    614             va_start(args, fmt);
    (gdb) finish
    Run till exit from #0  printk (fmt=0xc1449542 "<7>%s\n") at kernel/printk.c:614
    sys_new_debug (message_user=0x8048646 "new_debug()", tp_user=0x0)
        at arch/x86/kernel/new_debug.c:37
    37              if (tp_user != NULL) {
    Value returned is $3 = 33
    (gdb) s
    49      }
    (gdb) finish
    Run till exit from #0  sys_new_debug (message_user=0x8048646 "new_debug()",
        tp_user=0x0) at arch/x86/kernel/new_debug.c:49
    0xc100288c in ?? ()
    Value returned is $4 = 0
    (gdb) c
    Continuing.
    
    • s0711489@ubuntu-lucid:~$ ./a.out
      new_debug()
      
  • gdb
    Breakpoint 1, sys_new_debug (message_user=0xbfb1b9b9 "1", tp_user=0xbfb1b324)
        at arch/x86/kernel/new_debug.c:9
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    (gdb) l
    4       #include <linux/time.h>
    5
    6       /* from kernel/printk.c */
    7       #define __LOG_BUF_LEN 1024
    8
    9       SYSCALL_DEFINE2(new_debug, const char *, message_user, struct timespec*, tp_user) {
    10              int errno;
    11              static char message[__LOG_BUF_LEN];
    12              struct timespec ts;
    13              long len = 0;
    (gdb) p message
    $5 = "new_debug()", '\000' <repeats 1012 times>
    (gdb) p message_user
    $6 = 0xbfb1b9b9 "1"
    (gdb) p tp_user
    $7 = (struct timespec *) 0xbfb1b324
    (gdb) p ts
    $8 = {tv_sec = -570499584, tv_nsec = -1216356364}
    (gdb) n
    15              if(tp_user != NULL && ! access_ok(VERIFY_WRITE, tp_user, sizeof(*tp_user)) ) {
    (gdb)
    20              if (message_user == NULL) {
    (gdb)
    24              len = strnlen_user(message_user, __LOG_BUF_LEN);
    (gdb)
    25              if (len == 0 || len > __LOG_BUF_LEN) {
    (gdb)
    29              if (strncpy_from_user(message, message_user, sizeof(message) - 1) < 0) {
    (gdb)
    35              printk(KERN_DEBUG "%s\n", message);
    (gdb)
    33              message[sizeof(message) - 1] = '\0';
    (gdb)
    35              printk(KERN_DEBUG "%s\n", message);
    (gdb)
    37              if (tp_user != NULL) {
    (gdb)
    38                      getnstimeofday(&ts);
    (gdb)
    39                      if (copy_to_user(tp_user, &ts, sizeof(ts)) != 0) {
    (gdb) p ts
    $9 = {tv_sec = 1320815780, tv_nsec = 601392214}
    (gdb) p tp_user
    $10 = (struct timespec *) 0xbfb1b324
    (gdb) n
    49      }
    (gdb) p tp_user
    $11 = (struct timespec *) 0xbfb1b324
    (gdb) finish
    Run till exit from #0  sys_new_debug (message_user=0xbfb1b9b9 "1",
        tp_user=0xbfb1b324) at arch/x86/kernel/new_debug.c:49
    0xc100288c in ?? ()
    Value returned is $12 = 0
    (gdb) c
    Continuing.
    
    • s0711489@ubuntu-lucid:~$ ./a.out 1
      [1320815780.601392214] 1
      
  • s0711489@ubuntu-lucid:~$ ./a.out 1 2 3 4
    [1320815837.554212464] 1
    [1320815837.554367435] 2
    [1320815837.554373628] 3
    [1320815837.554378429] 4
    
  • s0711489@ubuntu-lucid:~$ ./a.out 1 2 3 4
    [1320815846.036561542] 1
    [1320815846.036726240] 2
    [1320815846.036732514] 3
    [1320815846.036737329] 4
    
  • s0711489@ubuntu-lucid:~$ tail /var/log/debug
    Nov  9 14:14:21 ubuntu-lucid kernel: [  187.486803] new_debug()
    Nov  9 14:16:38 ubuntu-lucid kernel: [  364.616724] 1
    Nov  9 14:17:17 ubuntu-lucid kernel: [  425.607587] 1
    Nov  9 14:17:17 ubuntu-lucid kernel: [  425.607744] 2
    Nov  9 14:17:17 ubuntu-lucid kernel: [  425.607750] 3
    Nov  9 14:17:17 ubuntu-lucid kernel: [  425.607755] 4
    Nov  9 14:17:26 ubuntu-lucid kernel: [  434.089936] 1
    Nov  9 14:17:26 ubuntu-lucid kernel: [  434.090102] 2
    Nov  9 14:17:26 ubuntu-lucid kernel: [  434.090109] 3
    Nov  9 14:17:26 ubuntu-lucid kernel: [  434.090114] 4
    

fix macro for new_debug

  • vim arch/x86/include/asm/new_debug.h
    • arch/x86/include/asm/new_debug.h

       
      22#define _ASM_X86_NEW_DEBUG_H 
      33 
      44#include <asm/unistd.h> 
      5 #define new_debug(x) syscall(__NR_new_debug, x) 
       5#define new_debug(x,y) syscall(__NR_new_debug, x, y) 
      66 
      77#endif /* _ASM_X86_NEW_DEBUG_H */ 
  • windell46:i386 s0711489$ ./build
    Kernel: arch/x86/boot/bzImage is ready  (#12)
    

add new_debug to x86_64

  • vim arch/x86/include/asm/unistd_64.h
    • arch/x86/include/asm/unistd_64.h

       
      665665__SYSCALL(__NR_recvmmsg, sys_recvmmsg) 
      666666#define __NR_new_hello              300 
      667667__SYSCALL(__NR_new_hello, sys_new_hello) 
       668#define __NR_new_debug              301 
       669__SYSCALL(__NR_new_debug, sys_new_debug) 
      668670 
      669671#ifndef __NO_STUBS 
      670672#define __ARCH_WANT_OLD_READDIR 
  • viola06:x86_64 s0711489$ ./build
    Kernel: arch/x86/boot/bzImage is ready  (#5)
    
  • s0711489@ubuntu-lucid64:~$ sudo /mnt/hgfs/tools/install.sh
  • s0711489@ubuntu-lucid64:~$ gcc -I /lib/modules/2.6.35.14/build/arch/x86/include/ 03/new_debug-sys.c
  • s0711489@ubuntu-lucid64:~$ ./a.out
    new_debug()
    
  • s0711489@ubuntu-lucid64:~$ ./a.out 1 2 3 4 5 6 7 8
    [1320819346.718424802] 1
    [1320819346.718761534] 2
    [1320819346.718767685] 3
    [1320819346.718772404] 4
    [1320819346.718776934] 5
    [1320819346.718781608] 6
    [1320819346.718786123] 7
    [1320819346.718790631] 8
    
  • s0711489@ubuntu-lucid64:~$ tail /var/log/kern.log
    Nov  9 15:15:24 ubuntu-lucid64 kernel: [   27.316107] cc1 used greatest stack depth: 4368 bytes left
    Nov  9 15:15:36 ubuntu-lucid64 kernel: [   39.137213] new_debug()
    Nov  9 15:15:46 ubuntu-lucid64 kernel: [   49.629638] 1
    Nov  9 15:15:46 ubuntu-lucid64 kernel: [   49.629978] 2
    Nov  9 15:15:46 ubuntu-lucid64 kernel: [   49.629985] 3
    Nov  9 15:15:46 ubuntu-lucid64 kernel: [   49.629990] 4
    Nov  9 15:15:46 ubuntu-lucid64 kernel: [   49.629994] 5
    Nov  9 15:15:46 ubuntu-lucid64 kernel: [   49.629999] 6
    Nov  9 15:15:46 ubuntu-lucid64 kernel: [   49.630004] 7
    Nov  9 15:15:46 ubuntu-lucid64 kernel: [   49.630008] 8
    

11/11

stackmod

  • 適当な深さのスタックデバイス
  • writeするとpushされる
  • readするとpopされる

modtest

  • windell46:04 s0711489$ touch Makefile
  • windell46:04 s0711489$ touch modtest.c

11/15

test module

  • s0711489@ubuntu-lucid:~$ sudo insmod modtest.ko
  • s0711489@ubuntu-lucid:~$ lsmod | grep test
    modtest                  511  0
    
  • s0711489@ubuntu-lucid:~$ sudo rmmod modtest
  • s0711489@ubuntu-lucid:~$ tailf /var/log/kern.log
    Nov 16 12:57:12 ubuntu-lucid kernel: [  184.191269] modtest is loaded
    Nov 16 12:57:49 ubuntu-lucid kernel: [  221.183851] modtest is unloaded
    

accept parameter

  • s0711489@ubuntu-lucid:~$ sudo insmod modtest.ko
  • s0711489@ubuntu-lucid:~$ sudo rmmod modtest
  • s0711489@ubuntu-lucid:~$ sudo insmod modtest.ko entry=1024
  • s0711489@ubuntu-lucid:~$ sudo rmmod modtest
  • s0711489@ubuntu-lucid:~$ tail /var/log/kern.log
    Nov 16 13:55:37 ubuntu-lucid kernel: [ 3688.894628] modtest is loaded with 128 entry
    Nov 16 13:55:42 ubuntu-lucid kernel: [ 3694.171780] modtest is unloaded
    Nov 16 13:55:49 ubuntu-lucid kernel: [ 3700.375278] modtest is loaded with 1024 entry
    Nov 16 13:55:52 ubuntu-lucid kernel: [ 3704.198557] modtest is unloaded
    
  • s0711489@ubuntu-lucid:~$ sudo insmod modtest.ko entry=1024
  • s0711489@ubuntu-lucid:~$ cat /sys/module/modtest/parameters/entry
    1024
    

stack module (copy from modtest)

  • s0711489@ubuntu-lucid:~$ sudo insmod stackmod.ko
  • s0711489@ubuntu-lucid:~$ sudo rmmod stackmod
  • s0711489@ubuntu-lucid:~$ tail /var/log/kern.log
    Nov 16 14:56:16 ubuntu-lucid kernel: [ 7326.677171] stackmod is loaded
    Nov 16 14:56:16 ubuntu-lucid kernel: [ 7326.677175] stackmod: 128 entry, major is 251, minor is 0
    Nov 16 14:56:24 ubuntu-lucid kernel: [ 7335.090496] stackmod is unloaded
    

11/20

fs/char_dev.c

  • struct cdev *cdev_alloc(void)
     * cdev_alloc() - allocate a cdev structure
     *
     * Allocates and returns a cdev structure, or NULL on failure.
    
  • void cdev_init(struct cdev *cdev, const struct file_operations *fops)
     * cdev_init() - initialize a cdev structure
     * @cdev: the structure to initialize
     * @fops: the file_operations for this device
     *
     * Initializes @cdev, remembering @fops, making it ready to add to the
     * system with cdev_add().
    
  • int cdev_add(struct cdev *p, dev_t dev, unsigned count)
     * cdev_add() - add a char device to the system
     * @p: the cdev structure for the device
     * @dev: the first device number for which this device is responsible
     * @count: the number of consecutive minor numbers corresponding to this
     *         device
     *
     * cdev_add() adds the device represented by @p to the system, making it
     * live immediately.  A negative error code is returned on failure.
    
  • void cdev_del(struct cdev *p)
     * cdev_del() - remove a cdev from the system
     * @p: the cdev structure to be removed
     *
     * cdev_del() removes @p from the system, possibly freeing the structure
     * itself.
    

stackmod with open/close/read/write skeleton

  • 参考
    • drivers/char/raw.c -> register_chrdev_region, cdev_init
    • include/linux/cdev.h -> struct cdev
    • include/linux/fs.h -> struct file_operations
  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko
    Nov 20 17:47:12 ubuntu-lucid64 kernel: [ 4074.120567] stackmod is loaded
    Nov 20 17:47:12 ubuntu-lucid64 kernel: [ 4074.120571] stackmod: 128 entry, major is 251, minor is 0
    Nov 20 17:47:12 ubuntu-lucid64 kernel: [ 4074.120576] stackmod is added successfully
    
  • s0711489@ubuntu-lucid64:~$ grep stack /proc/devices
    251 stackmod
    
  • s0711489@ubuntu-lucid64:~$ sudo mknod /dev/stack c 251 0
  • s0711489@ubuntu-lucid64:~$ ls -l /dev/stack
    crw-r--r-- 1 root root 251, 0 2011-11-20 17:50 /dev/stack
    
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack
    Nov 20 17:50:56 ubuntu-lucid64 kernel: [ 4297.683404] stackmod is opened
    Nov 20 17:50:56 ubuntu-lucid64 kernel: [ 4297.683424] stackmod is read
    Nov 20 17:50:56 ubuntu-lucid64 kernel: [ 4297.683428] stackmod is released
    
  • s0711489@ubuntu-lucid64:~$ sudo sh -c "echo 1 > /dev/stack"
    ^C
    
    (snip)
    
    Nov 20 17:51:43 ubuntu-lucid64 kernel: [ 4343.961818] stackmod is written
    Nov 20 17:51:43 ubuntu-lucid64 kernel: [ 4343.961818] stackmod is written
    Nov 20 17:51:43 ubuntu-lucid64 kernel: [ 4343.965238] stackmod is released
    
  • s0711489@ubuntu-lucid64:~$ sudo dd if=/dev/null of=/dev/stack
    0+0 records in
    0+0 records out
    0 bytes (0 B) copied, 2.3001e-05 s, 0.0 kB/s
    
    Nov 20 17:52:58 ubuntu-lucid64 kernel: [ 4419.365245] stackmod is opened
    Nov 20 17:52:58 ubuntu-lucid64 kernel: [ 4419.365281] stackmod is released
    

/proc read skeleton

  • 参考
    • sound/core/info.c -> create_proc_entry
    • arch/h8300/kernel/gpio.c -> create_proc_entry
    • arch/arm/mach-bcmring/dma.c -> create_proc_read_entry
    • drivers/nubus/nubus.c -> create_proc_read_entry
    • include/linux/proc_fs.h -> static inline struct proc_dir_entry *create_proc_read_entry
  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko
    Nov 21 00:33:28 ubuntu-lucid64 kernel: [   41.547601] stackmod is loaded
    Nov 21 00:33:28 ubuntu-lucid64 kernel: [   41.547606] stackmod: 128 entry, major is 251, minor is 0
    Nov 21 00:33:28 ubuntu-lucid64 kernel: [   41.547615] stackmod: create /proc/stackmod
    Nov 21 00:33:28 ubuntu-lucid64 kernel: [   41.547617] stackmod is added successfully
    
  • s0711489@ubuntu-lucid64:~$ ls -l /proc/ | grep stack
    -r--r--r--  1 root     root                   0 2011-11-21 00:34 stackmod
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    Nov 21 00:34:21 ubuntu-lucid64 kernel: [   94.446963] /proc/stackmod is read
    
  • s0711489@ubuntu-lucid64:~$ sudo rmmod stackmod.ko
    Nov 21 00:35:43 ubuntu-lucid64 kernel: [  177.060782] stackmod is unloaded
    

implement stackmod_proc_read as proc_dir_entry->read_proc

  • fs/proc/generic.c -> proc_file_read
     * How to be a proc read function
    
  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    0 stacks
    
    Nov 21 02:30:23 ubuntu-lucid64 kernel: [ 7055.042732] /proc/stackmod is read
    Nov 21 02:30:23 ubuntu-lucid64 kernel: [ 7055.042747] /proc/stackmod is read
    

kmalloc/kfree -> stack.buffer

without memset

  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.text
    0xffffffffa0056000
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.data
    0xffffffffa0056458
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.bss
    0xffffffffa0056690
    
  • gdb
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done.
    (gdb) add-symbol-file ../../04/stackmod/stackmod.o 0xffffffffa0056000 -s .data 0xffffffffa0056458 -s .bss 0xffffffffa0056690
    add symbol table from file "../../04/stackmod/stackmod.o" at
            .text_addr = 0xffffffffa0056000
            .data_addr = 0xffffffffa0056458
            .bss_addr = 0xffffffffa0056690
    (y or n) y
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.o...done.
    (gdb) l stackmod.c:145
    
    140             stack.buffer = (char **) kmalloc(entry * sizeof(char *), GFP_KERNEL);
    141             if (stack.buffer == NULL) {
    142                     printk(KERN_WARNING MODNAME ": (char **) kmalloc failed\n");
    143                     ret = -ENOMEM;
    144                     goto error_cdev;
    145             }
    146     //        memset(stack.buffer, NULL, entry * sizeof(char *));
    147
    148             printk(KERN_INFO MODNAME " is added successfully\n");
    149
    (gdb) p stack
    Cannot access memory at address 0xffffffffa0056690
    (gdb) target remote localhost:8864
    Remote debugging using localhost:8864
    0xffffffff810097a9 in native_safe_halt ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) p stack
    $1 = {buffer = 0xffff88001b740800, depth = 0, errno = 0}
    (gdb) ptype stack
    type = struct kernel_module_stack {
        char **buffer;
        int depth;
        int errno;
    }
    (gdb) p stack.buffer
    $2 = (char **) 0xffff88001b740800
    (gdb) p stack.buffer[0]
    $3 = 0xffff88001b744c00 ""
    (gdb) p stack.buffer[1]
    $4 = 0x1000 <Address 0x1000 out of bounds>
    (gdb) p stack.buffer[2]
    $5 = 0xffffea00005f0148 ","
    (gdb) p stack.buffer[3]
    $6 = 0x1000 <Address 0x1000 out of bounds>
    (gdb) p stack.buffer[4]
    $7 = 0xffffea00005f0110 ","
    (gdb) p stack.buffer[5]
    $8 = 0x1000 <Address 0x1000 out of bounds>
    (gdb) p stack.buffer[6]
    $9 = 0xffffea00005f4048 ","
    (gdb) p stack.depth
    $10 = 0
    (gdb) p/c stack.depth
    $11 = 0 '\000'
    (gdb) p stack.buffer
    $12 = (char **) 0xffff88001b740800
    (gdb) p/x stack.buffer
    $13 = 0xffff88001b740800
    (gdb) p/x stack.buffer[0]
    $14 = 0xffff88001b744c00
    (gdb) p/x stack.buffer[1]
    $15 = 0x1000
    (gdb) p/x stack.buffer[2]
    $16 = 0xffffea00005f0148
    (gdb) p/x stack.buffer[3]
    $17 = 0x1000
    (gdb) p/x stack.buffer[4]
    $18 = 0xffffea00005f0110
    

with memset

  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.text
    0xffffffffa0056000
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.data
    0xffffffffa0056458
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.bss
    0xffffffffa0056690
    
  • gdb
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done.
    (gdb) add-symbol-file ../../04/stackmod/stackmod.o 0xffffffffa0056000 -s .data 0xffffffffa0056458 -s .bss 0xffffffffa0056690
    add symbol table from file "../../04/stackmod/stackmod.o" at
            .text_addr = 0xffffffffa0056000
            .data_addr = 0xffffffffa0056458
            .bss_addr = 0xffffffffa0056690
    (y or n) y
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.o...done.
    (gdb) l stackmod.c:145
    
    140             stack.buffer = (char **) kmalloc(entry * sizeof(char *), GFP_KERNEL);
    141             if (stack.buffer == NULL) {
    142                     printk(KERN_WARNING MODNAME ": (char **) kmalloc failed\n");
    143                     ret = -ENOMEM;
    144                     goto error_cdev;
    145             }
    146             memset(stack.buffer, (int) NULL, entry * sizeof(char *));
    147
    148             printk(KERN_INFO MODNAME " is added successfully\n");
    149
    (gdb) target remote localhost:8864
    Remote debugging using localhost:8864
    0xffffffff810097a9 in native_safe_halt ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) p stack
    $1 = {buffer = 0xffff88001b5cb400, depth = 0, errno = 0}
    (gdb) p stack.buffer
    $2 = (char **) 0xffff88001b5cb400
    (gdb) p/c stack.buffer
    $3 = 0 '\000'
    (gdb) p/x stack.buffer
    $4 = 0xffff88001b5cb400
    (gdb) p/x stack.buffer[0]
    $5 = 0x0
    (gdb) p/x stack.buffer[1]
    $6 = 0x0
    (gdb) p/x stack.buffer[2]
    $7 = 0x0
    (gdb) p/x stack.buffer[3]
    $8 = 0x0
    (gdb) p/x stack.buffer[4]
    $9 = 0x0
    (gdb) p/x stack.buffer[5]
    $10 = 0x0
    (gdb) p/x stack.buffer[127]
    $11 = 0x0
    (gdb) p/x stack.buffer[128]
    $12 = 0xffff88001b5cb000
    (gdb) p/x stack.buffer[129]
    $13 = 0x0
    (gdb) p/x stack.buffer[130]
    $14 = 0xffffffff00000000
    (gdb) p/x stack.buffer[126]
    $15 = 0x0
    (gdb) p/x stack.buffer[125]
    $16 = 0x0
    

much more entry with memset

  • s0711489@ubuntu-lucid64:~$ sudo rmmod stackmod.ko
  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko entry=1024
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.text
    0xffffffffa005c000
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.data
    0xffffffffa005c458
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.bss
    0xffffffffa005c690
    
  • gdb
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done.
    (gdb) add-symbol-file ../../04/stackmod/stackmod.o 0xffffffffa005c000 -s .data 0xffffffffa005c458 -s .bss 0xffffffffa005c690
    add symbol table from file "../../04/stackmod/stackmod.o" at
            .text_addr = 0xffffffffa005c000
            .data_addr = 0xffffffffa005c458
            .bss_addr = 0xffffffffa005c690
    (y or n) y
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.o...done.
    (gdb) target remote localhost:8864
    Remote debugging using localhost:8864
    0xffffffff810097a9 in native_safe_halt ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) p stack
    $1 = {buffer = 0xffff88001af16000, depth = 0, errno = 0}
    (gdb) p entry
    $2 = 1024
    (gdb) p stack.buffer
    $3 = (char **) 0xffff88001af16000
    (gdb) p/x stack.buffer
    $4 = 0xffff88001af16000
    (gdb) p/x stack.buffer[0]
    $5 = 0x0
    (gdb) p/x stack.buffer[127]
    $6 = 0x0
    (gdb) p/x stack.buffer[128]
    $7 = 0x0
    (gdb) p/x stack.buffer[1020]
    $8 = 0x0
    (gdb) p/x stack.buffer[1021]
    $9 = 0x0
    (gdb) p/x stack.buffer[1022]
    $10 = 0x0
    (gdb) p/x stack.buffer[1023]
    $11 = 0x0
    (gdb) p/x stack.buffer[1024]
    $12 = 0xc7c7485500c3c9a0
    (gdb) p/x stack.buffer[1025]
    $13 = 0xe8e58948a001a000
    (gdb) p/x stack.buffer[1026]
    $14 = 0x4855c3c9e11ca49c
    

11/21

check backtrace to stackmod_read

  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko
  • s0711489@ubuntu-lucid64:~$ sudo mknod /dev/stack c 251 0
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack
  • s0711489@ubuntu-lucid64:~$ tail /var/log/kern.log
    Nov 21 06:41:49 ubuntu-lucid64 kernel: [ 5352.251306] stackmod is loaded
    Nov 21 06:41:49 ubuntu-lucid64 kernel: [ 5352.251310] stackmod: 128 entry, major is 251, minor is 0
    Nov 21 06:41:49 ubuntu-lucid64 kernel: [ 5352.251323] stackmod: create /proc/stackmod
    Nov 21 06:41:49 ubuntu-lucid64 kernel: [ 5352.251325] stackmod is added successfully
    Nov 21 06:42:03 ubuntu-lucid64 kernel: [ 5366.796334] stackmod is opened
    Nov 21 06:42:03 ubuntu-lucid64 kernel: [ 5366.796353] stackmod is read
    Nov 21 06:42:03 ubuntu-lucid64 kernel: [ 5366.796357] stackmod is released
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.text
    0xffffffffa0062000
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.data
    0xffffffffa0062478
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.bss
    0xffffffffa00626b0
    
  • gdb
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done.
    (gdb) add-symbol-file ../../04/stackmod/stackmod.o 0xffffffffa0062000 -s .data 0xffffffffa0062478 -s .bss 0xffffffffa00626b0
    add symbol table from file "../../04/stackmod/stackmod.o" at
            .text_addr = 0xffffffffa0062000
            .data_addr = 0xffffffffa0062478
            .bss_addr = 0xffffffffa00626b0
    (y or n) y
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.o...done.
    (gdb) target remote localhost:8864
    Remote debugging using localhost:8864
    0xffffffff810097a9 in native_safe_halt ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) b stackmod_read
    Breakpoint 1 at 0xffffffffa0062016: file /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c, line 56.
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack
    Breakpoint 1, stackmod_read (filep=0xffff88001efcf900,
        buf_user=0xde9000 <Address 0xde9000 out of bounds>, size=32768,
        offset=0xffff88001aecdf48)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:56
    56      ) {
    (gdb) bt
    #0  stackmod_read (filep=0xffff88001efcf900,
        buf_user=0xde9000 <Address 0xde9000 out of bounds>, size=32768,
        offset=0xffff88001aecdf48)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:56
    #1  0xffffffff810df784 in vfs_read (file=0xffff88001efcf900,
        buf=0xde9000 <Address 0xde9000 out of bounds>, count=32768,
        pos=0xffff88001aecdf48) at fs/read_write.c:310
    #2  0xffffffff810dfa2b in sys_read (fd=<value optimized out>,
        buf=0xde9000 <Address 0xde9000 out of bounds>, count=32768)
        at fs/read_write.c:400
    #3  0xffffffff810029eb in ?? ()
    #4  0x0000000000000246 in stackmod_exit ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:175
    Backtrace stopped: previous frame inner to this frame (corrupt stack?)
    

implement read/write for char dev

  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko
    Nov 21 17:33:19 ubuntu-lucid64 kernel: [   53.780695] stackmod is loaded
    Nov 21 17:33:19 ubuntu-lucid64 kernel: [   53.780699] stackmod: 128 entry, major is 251, minor is 0
    Nov 21 17:33:19 ubuntu-lucid64 kernel: [   53.780707] stackmod: create /proc/stackmod
    Nov 21 17:33:19 ubuntu-lucid64 kernel: [   53.780709] stackmod is added successfully
    
  • s0711489@ubuntu-lucid64:~$ sudo mknod /dev/stack c 251 0
  • s0711489@ubuntu-lucid64:~$ ls -l /dev/stack
  • s0711489@ubuntu-lucid64:~$ sudo chmod 666 /dev/stack
  • s0711489@ubuntu-lucid64:~$ echo hoge > /dev/stack
    Nov 21 17:34:37 ubuntu-lucid64 kernel: [  131.432249] stackmod is opened
    Nov 21 17:34:37 ubuntu-lucid64 kernel: [  131.432286] stackmod is written
    Nov 21 17:34:37 ubuntu-lucid64 kernel: [  131.432292] stackmod is released
    
  • s0711489@ubuntu-lucid64:~$ echo fuga > /dev/stack
    Nov 21 17:34:50 ubuntu-lucid64 kernel: [  144.556110] stackmod is opened
    Nov 21 17:34:50 ubuntu-lucid64 kernel: [  144.556125] stackmod is written
    Nov 21 17:34:50 ubuntu-lucid64 kernel: [  144.556136] stackmod is released
    
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack
    fuga
    ���hoge
    ���s0711489@ubuntu-lucid64:~$
    
    Nov 21 17:35:16 ubuntu-lucid64 kernel: [  170.887727] stackmod is opened
    Nov 21 17:35:16 ubuntu-lucid64 kernel: [  170.887745] stackmod is read
    Nov 21 17:35:16 ubuntu-lucid64 kernel: [  170.887758] stackmod is read
    Nov 21 17:35:16 ubuntu-lucid64 kernel: [  170.887763] stackmod is read
    Nov 21 17:35:16 ubuntu-lucid64 kernel: [  170.887766] stackmod is released
    
    • buggy
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 0
    
  • s0711489@ubuntu-lucid64:~$ echo hoge > /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 1
    
  • s0711489@ubuntu-lucid64:~$ echo fuga > /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 2
    
  • s0711489@ubuntu-lucid64:~$ echo piyo > /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 3
    
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack
    piyo
    ���fuga
    ���hoge
    ���s0711489@ubuntu-lucid64:~$
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 0
    

check what is bug with gdb

  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko
  • s0711489@ubuntu-lucid64:~$ sudo mknod /dev/stack c 251 0
  • s0711489@ubuntu-lucid64:~$ sudo chmod 666 /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.text
    0xffffffffa0056000
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.data
    0xffffffffa0056738
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.bss
    0xffffffffa0056970
    
  • gdb
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done.
    (gdb) add-symbol-file ../../04/stackmod/stackmod.o 0xffffffffa0056000 -s .data 0xffffffffa0056738 -s .bss 0xffffffffa0056970
    add symbol table from file "../../04/stackmod/stackmod.o" at
            .text_addr = 0xffffffffa0056000
            .data_addr = 0xffffffffa0056738
            .bss_addr = 0xffffffffa0056970
    (y or n) y
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.o...done.
    (gdb) b stackmod_proc_read
    Cannot access memory at address 0xffffffffa00561e0
    (gdb) target remote localhost:8864
    Remote debugging using localhost:8864
    0xffffffff810097a9 in native_safe_halt ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) b stackmod_proc_read
    Breakpoint 1 at 0xffffffffa00561e0: file /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c, line 137.
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 0
    
    Breakpoint 1, stackmod_proc_read (page=0xffff88001f792000 "0\"y\037",
        start=0xffff88001b6d1e90, off=0, count=3072, eof=0xffff88001b6d1e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:137
    137     ) {
    (gdb) p stack
    $1 = {buffer = 0xffff88001b6e5000, depth = 0, errno = 0}
    (gdb) p/x stack.buffer
    $2 = 0xffff88001b6e5000
    (gdb) p/x stack.buffer[0]
    $3 = 0x0
    (gdb) p/x stack.buffer[1]
    $4 = 0x0
    (gdb) c
    Continuing.
    
    Breakpoint 1, stackmod_proc_read (page=0xffff88001f792000 "stack: 0\n",
        start=0xffff88001b6d1e90, off=9, count=3072, eof=0xffff88001b6d1e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:137
    137     ) {
    (gdb) p/x stack.buffer
    $5 = 0xffff88001b6e5000
    (gdb) p stack
    $6 = {buffer = 0xffff88001b6e5000, depth = 0, errno = 0}
    (gdb) p/x stack.buffer[0]
    $7 = 0x0
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ echo hoge > /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 1
    
    Breakpoint 1, stackmod_proc_read (page=0xffff88001f7a3000 "@5z\037",
        start=0xffff88001b6d1e90, off=0, count=3072, eof=0xffff88001b6d1e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:137
    137     ) {
    (gdb) p stack
    $8 = {buffer = 0xffff88001b6e5000, depth = 1, errno = 0}
    (gdb) p/x stack.buffer
    $9 = 0xffff88001b6e5000
    (gdb) p/x stack.buffer[0]
    $10 = 0xffff880017ea1340
    (gdb) p stack.buffer[0]
    $11 = 0xffff880017ea1340 "hoge\n\210\377\377"
    (gdb) p stack.buffer[1]
    $12 = 0x0
    (gdb) bt
    #0  stackmod_proc_read (page=0xffff88001f7a3000 "@5z\037",
        start=0xffff88001b6d1e90, off=0, count=3072, eof=0xffff88001b6d1e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:137
    #1  0xffffffff811291f4 in __proc_file_read (file=<value optimized out>,
        buf=0x2398000 <Address 0x2398000 out of bounds>, nbytes=32768,
        ppos=0xffff88001b6d1f48) at fs/proc/generic.c:120
    #2  proc_file_read (file=<value optimized out>,
        buf=0x2398000 <Address 0x2398000 out of bounds>, nbytes=32768,
        ppos=0xffff88001b6d1f48) at fs/proc/generic.c:201
    #3  0xffffffff81124b07 in proc_reg_read (file=0xffff88001aeda840,
        buf=0x2398000 <Address 0x2398000 out of bounds>, count=32768,
        ppos=0xffff88001b6d1f48) at fs/proc/inode.c:163
    #4  0xffffffff810df784 in vfs_read (file=0xffff88001aeda840,
        buf=0x2398000 <Address 0x2398000 out of bounds>, count=0,
        pos=0xffff88001b6d1f48) at fs/read_write.c:310
    #5  0xffffffff810dfa2b in sys_read (fd=<value optimized out>,
        buf=0x2398000 <Address 0x2398000 out of bounds>, count=32768)
        at fs/read_write.c:400
    #6  0xffffffff810029eb in ?? ()
    #7  0x0000000000000246 in ?? ()
    #8  0x00007fffe2db44d0 in ?? ()
    #9  0x0000000000000000 in ?? ()
    (gdb) c
    Continuing.
    
    Breakpoint 1, stackmod_proc_read (page=0xffff88001f7a3000 "stack: 1\n",
        start=0xffff88001b6d1e90, off=9, count=3072, eof=0xffff88001b6d1e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:137
    137     ) {
    (gdb) bt
    #0  stackmod_proc_read (page=0xffff88001f7a3000 "stack: 1\n",
        start=0xffff88001b6d1e90, off=9, count=3072, eof=0xffff88001b6d1e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:137
    #1  0xffffffff811291f4 in __proc_file_read (file=<value optimized out>,
        buf=0x2398000 "stack: 1\n", nbytes=32768, ppos=0xffff88001b6d1f48)
        at fs/proc/generic.c:120
    #2  proc_file_read (file=<value optimized out>, buf=0x2398000 "stack: 1\n",
        nbytes=32768, ppos=0xffff88001b6d1f48) at fs/proc/generic.c:201
    #3  0xffffffff81124b07 in proc_reg_read (file=0xffff88001aeda840,
        buf=0x2398000 "stack: 1\n", count=32768, ppos=0xffff88001b6d1f48)
        at fs/proc/inode.c:163
    #4  0xffffffff810df784 in vfs_read (file=0xffff88001aeda840,
        buf=0x2398000 "stack: 1\n", count=9, pos=0xffff88001b6d1f48)
        at fs/read_write.c:310
    #5  0xffffffff810dfa2b in sys_read (fd=<value optimized out>,
        buf=0x2398000 "stack: 1\n", count=32768) at fs/read_write.c:400
    #6  0xffffffff810029eb in ?? ()
    #7  0x0000000000000246 in ?? ()
    #8  0x00007fffe2db44a0 in ?? ()
    #9  0x0000000000000000 in ?? ()
    (gdb) c
    Continuing.
    
    (gdb) d
    Delete all breakpoints? (y or n) y
    (gdb) b stackmod.c:144
    
    Breakpoint 2 at 0xffffffffa0056216: file /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c, line 144.
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ echo hoge > /dev/stack
  • s0711489@ubuntu-lucid64:~$ echo hoge > /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 3
    
    Breakpoint 2, stackmod_proc_read (page=<value optimized out>,
        start=<value optimized out>, off=<value optimized out>,
        count=<value optimized out>, eof=0xffff88001ee0de9c,
        data=<value optimized out>)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:146
    146     }
    (gdb) p len
    No symbol "len" in current context.
    (gdb) p outlen
    $13 = <value optimized out>
    (gdb) p page
    $14 = <value optimized out>
    (gdb) finish
    Run till exit from #0  stackmod_proc_read (page=<value optimized out>,
        start=<value optimized out>, off=<value optimized out>,
        count=<value optimized out>, eof=0xffff88001ee0de9c,
        data=<value optimized out>)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:146
    __proc_file_read (file=<value optimized out>,
        buf=0x659000 <Address 0x659000 out of bounds>, nbytes=32768,
        ppos=0xffff88001ee0df48) at fs/proc/generic.c:125
    125                     if (n == 0)   /* end of file */
    Could not fetch register "orig_rax"; remote failure reply 'E00'
    (gdb) c
    Continuing.
    
    Breakpoint 2, stackmod_proc_read (page=<value optimized out>,
        start=<value optimized out>, off=<value optimized out>,
        count=<value optimized out>, eof=0xffff88001ee0de9c,
        data=<value optimized out>)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:146
    146     }
    (gdb) c
    Continuing.
    
    (gdb) d
    Delete all breakpoints? (y or n) y
    (gdb) b stackmod_proc_read
    
    Breakpoint 3 at 0xffffffffa00561e0: file /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c, line 137.
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 3
    
    Breakpoint 3, stackmod_proc_read (page=0xffff88001f792000 "stack: 3\n",
        start=0xffff88001b669e90, off=0, count=3072, eof=0xffff88001b669e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:137
    137     ) {
    (gdb) p outlen
    $15 = <value optimized out>
    (gdb) ret
    Make stackmod_proc_read return now? (y or n) y
    Could not fetch register "orig_rax"; remote failure reply 'E00'
    (gdb) c
    Continuing.
    
    Breakpoint 3, stackmod_proc_read (page=0xffff88001f792000 "stack: 3\n",
        start=0xffff88001b669e90, off=9, count=3072, eof=0xffff88001b669e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:137
    137     ) {
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ echo hoge > /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 4
    
    Breakpoint 3, stackmod_proc_read (page=0xffff88001f792000 "stack: 3\n",
        start=0xffff88001b669e90, off=0, count=3072, eof=0xffff88001b669e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:137
    137     ) {
    (gdb) p stack
    $16 = {buffer = 0xffff88001b6e5000, depth = 4, errno = 0}
    (gdb) p/x stack.buffer
    $17 = 0xffff88001b6e5000
    (gdb) p/x stack.buffer[0]
    $18 = 0xffff880017ea1340
    (gdb) p/x stack.buffer[4]
    $19 = 0x0
    (gdb) p stack.buffer[0]
    $20 = 0xffff880017ea1340 "hoge\n\210\377\377"
    (gdb) p stack.buffer[1]
    $21 = 0xffff880017ea1640 "hoge\n\210\377\377"
    (gdb) p stack.buffer[2]
    $22 = 0xffff880017ea1200 "hoge\n\210\377\377"
    (gdb) p stack.buffer[3]
    $23 = 0xffff88001ef2cd80 "hoge\n\210\377\377\210\315\362\036"
    (gdb) p stack.buffer[4]
    $24 = 0x0
    (gdb) c
    Continuing.
    
    Breakpoint 3, stackmod_proc_read (page=0xffff88001f792000 "stack: 4\n",
        start=0xffff88001b669e90, off=9, count=3072, eof=0xffff88001b669e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:137
    137     ) {
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack
    hoge
    ������hoge
    ���hoge
    ���hoge
    ���s0711489@ubuntu-lucid64:~$
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 0
    
    Breakpoint 3, stackmod_proc_read (page=0xffff88001f792000 "stack: 4\n",
        start=0xffff88001afd5e90, off=0, count=3072, eof=0xffff88001afd5e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:137
    137     ) {
    (gdb) p stack
    $25 = {buffer = 0xffff88001b6e5000, depth = 0, errno = 0}
    (gdb) p stack.buffer[0]
    $26 = 0x0
    (gdb) p stack.buffer[3]
    $27 = 0x0
    (gdb) c
    Continuing.
    
    Breakpoint 3, stackmod_proc_read (page=0xffff88001f792000 "stack: 0\n",
        start=0xffff88001afd5e90, off=9, count=3072, eof=0xffff88001afd5e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:137
    137     ) {
    (gdb) c
    Continuing.
    

11/23

instead of char*, use typedef struct DATA

  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko
    Nov 23 01:54:02 ubuntu-lucid64 kernel: [  242.821597] stackmod is loaded
    Nov 23 01:54:02 ubuntu-lucid64 kernel: [  242.821601] stackmod: 128 entry, major is 251, minor is 0
    Nov 23 01:54:02 ubuntu-lucid64 kernel: [  242.821616] stackmod: create /proc/stackmod
    Nov 23 01:54:02 ubuntu-lucid64 kernel: [  242.821618] stackmod is added successfully
    
  • s0711489@ubuntu-lucid64:~$ sudo mknod /dev/stack c 251 0
  • s0711489@ubuntu-lucid64:~$ sudo chmod 666 /dev/stack
  • s0711489@ubuntu-lucid64:~$ echo hoge > /dev/stack
    Nov 23 01:55:26 ubuntu-lucid64 kernel: [  327.080724] stackmod is opened
    Nov 23 01:55:26 ubuntu-lucid64 kernel: [  327.080773] stackmod is written
    Nov 23 01:55:26 ubuntu-lucid64 kernel: [  327.080784] stackmod is released
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 1
    
    Nov 23 01:55:44 ubuntu-lucid64 kernel: [  344.897310] /proc/stackmod is read
    Nov 23 01:55:44 ubuntu-lucid64 kernel: [  344.897328] /proc/stackmod is read
    
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack
    cat: /dev/stack: Bad address
    
    Nov 23 01:56:09 ubuntu-lucid64 kernel: [  370.036240] stackmod is opened
    Nov 23 01:56:09 ubuntu-lucid64 kernel: [  370.036253] stackmod is read
    Nov 23 01:56:09 ubuntu-lucid64 kernel: [  370.036346] stackmod: copy_to_user failed
    Nov 23 01:56:09 ubuntu-lucid64 kernel: [  370.036471] stackmod is released
    
    • buggy
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 1
    

check what is bug with gdb

  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko entry=4
  • s0711489@ubuntu-lucid64:~$ sudo mknod /dev/stack c 251 0
  • s0711489@ubuntu-lucid64:~$ sudo chmod 666 /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.text
    0xffffffffa0056000
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.data
    0xffffffffa00566b8
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.bss
    0xffffffffa00568f0
    
  • gdb
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done.
    (gdb) add-symbol-file ../../04/stackmod/stackmod.o 0xffffffffa0056000 -s .data 0xffffffffa00566b8 -s .bss 0xffffffffa00568f0
    add symbol table from file "../../04/stackmod/stackmod.o" at
            .text_addr = 0xffffffffa0056000
            .data_addr = 0xffffffffa00566b8
            .bss_addr = 0xffffffffa00568f0
    (y or n) y
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.o...done.
    (gdb) target remote localhost:8864
    Remote debugging using localhost:8864
    0xffffffff810097a9 in native_safe_halt ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) b stackmod_read
    Breakpoint 1 at 0xffffffffa00560b4: file /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c, line 62.
    (gdb) b stackmod_write
    Breakpoint 2 at 0xffffffffa00561e0: file /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c, line 105.
    (gdb) b stackmod_proc_read
    Breakpoint 3 at 0xffffffffa00561a3: file /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c, line 153.
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 0
    
    Breakpoint 3, stackmod_proc_read (page=0xffff88001d9a9000 "p\227\232\035",
        start=0xffff88001b95fe90, off=0, count=3072, eof=0xffff88001b95fe9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153     ) {
    (gdb) p stack
    $1 = {data = 0xffff88001b7c7940, depth = 0, errno = 0}
    (gdb) p stack.data
    $2 = (DATA *) 0xffff88001b7c7940
    (gdb) ptype stack.data
    type = struct kernel_module_stack_data {
        int length;
        char *content;
    } *
    (gdb) ptype stack.data[0]
    type = struct kernel_module_stack_data {
        int length;
        char *content;
    }
    (gdb) p stack.data[0]
    $3 = {length = 461142784, content = 0xffff88001b7c7988 "\210y|\033"}
    (gdb) p stack.data[1]
    $4 = {length = 0, content = 0x0}
    (gdb) p stack.data[2]
    $5 = {length = 0,
      content = 0x2e2e02020010e071 <Address 0x2e2e02020010e071 out of bounds>}
    (gdb) c
    Continuing.
    
    Breakpoint 3, stackmod_proc_read (page=0xffff88001d9a9000 "stack: 0\n",
        start=0xffff88001b95fe90, off=9, count=3072, eof=0xffff88001b95fe9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153     ) {
    (gdb) finish
    Run till exit from #0  stackmod_proc_read (
        page=0xffff88001d9a9000 "stack: 0\n", start=0xffff88001b95fe90, off=9,
        count=3072, eof=0xffff88001b95fe9c, data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    __proc_file_read (file=<value optimized out>, buf=0x1420000 "stack: 0\n",
        nbytes=32768, ppos=0xffff88001b95ff48) at fs/proc/generic.c:125
    125                     if (n == 0)   /* end of file */
    Could not fetch register "orig_rax"; remote failure reply 'E00'
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack
    Nov 23 02:43:46 ubuntu-lucid64 kernel: [ 2449.923317] stackmod is opened
    Nov 23 02:43:46 ubuntu-lucid64 kernel: [ 2514.778526] stackmod is read
    Nov 23 02:43:46 ubuntu-lucid64 kernel: [ 2538.311203] stackmod is released
    
    Breakpoint 1, stackmod_read (filep=0xffff88001b90a240,
        buf_user=0x189a000 <Address 0x189a000 out of bounds>, size=32768,
        offset=0xffff88001bb19f48)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:62
    62      ) {
    (gdb) p p
    $6 = <value optimized out>
    (gdb) p stack.depth
    $7 = 0
    
    (snip)
    
    (gdb) n
    66              printk(KERN_DEBUG MODNAME " is read\n");
    (gdb)
    62      ) {
    (gdb)
    66              printk(KERN_DEBUG MODNAME " is read\n");
    (gdb)
    68              if (size == 0) {
    (gdb)
    71              if (stack.depth == 0) {
    (gdb)
    101     }
    (gdb)
    vfs_read (file=0xffff88001b90a240,
        buf=0x189a000 <Address 0x189a000 out of bounds>,
        count=<value optimized out>, pos=0xffff88001bb19f48) at fs/read_write.c:313
    313                     if (ret > 0) {
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ echo depth=0 > /dev/stack
    Nov 23 02:47:16 ubuntu-lucid64 kernel: [ 2651.841249] stackmod is opened
    Nov 23 02:47:41 ubuntu-lucid64 kernel: [ 2724.502176] stackmod is written
    Nov 23 02:50:07 ubuntu-lucid64 kernel: [ 2916.725803] stackmod is released
    
    Breakpoint 2, stackmod_write (filep=0xffff88001b984240,
        buf_user=0x126ac08 "depth=0\n /usr/bin/xzdec\nusr/sbin/update-alternatives\n\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337", <incomplete sequence \337>..., size=8,
        offset=0xffff88001b8dff48)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:105
    105     ) {
    (gdb) p p
    $8 = <value optimized out>
    (gdb) p stack
    $9 = {data = 0xffff88001b7c7940, depth = 0, errno = 0}
    (gdb) p stack.data[0]
    $10 = {length = 461142784, content = 0xffff88001b7c7988 "\210y|\033"}
    (gdb) n
    108             printk(KERN_DEBUG MODNAME " is written\n");
    (gdb)
    105     ) {
    (gdb)
    108             printk(KERN_DEBUG MODNAME " is written\n");
    (gdb)
    110             if (size == 0) {
    (gdb)
    113             if (stack.depth >= entry) {
    (gdb)
    117             if (buf_user == NULL) {
    (gdb)
    122             p.content = (char *) kmalloc(size * sizeof(char), GFP_KERNEL);
    (gdb)
    123             if (p.content == NULL) {
    (gdb)
    122             p.content = (char *) kmalloc(size * sizeof(char), GFP_KERNEL);
    (gdb)
    123             if (p.content == NULL) {
    (gdb)
    129             if (copy_from_user(p.content, buf_user, size) != 0) {
    (gdb) p stack.data[0]
    $11 = {length = 461142784, content = 0xffff88001b7c7988 "\210y|\033"}
    (gdb) n
    136             stack.depth++;
    (gdb) p stack.data[0]
    $12 = {length = 461142784, content = 0xffff88001b7c7988 "\210y|\033"}
    (gdb) p stack.data[0].content
    $13 = 0xffff88001b7c7988 "\210y|\033"
    (gdb) p size
    $14 = 0
    (gdb) p buf_user
    $15 = 0x126ac08 "depth=0\n /usr/bin/xzdec\nusr/sbin/update-alternatives\n\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337", <incomplete sequence \337>...
    (gdb) n
    140             return size;
    (gdb) p stack
    $16 = {data = 0xffff88001b7c7940, depth = 1, errno = 0}
    (gdb) p stack.data[0]
    $17 = {length = 461142784, content = 0xffff88001b7c7988 "\210y|\033"}
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ echo depth=1 > /dev/stack
    Nov 23 02:51:53 ubuntu-lucid64 kernel: [ 2955.599055] stackmod is opened
    Nov 23 02:51:53 ubuntu-lucid64 kernel: [ 2986.156722] stackmod is written
    Nov 23 02:53:51 ubuntu-lucid64 kernel: [ 3139.258180] stackmod is released
    
    Breakpoint 2, stackmod_write (filep=0xffff88001b80e9c0,
        buf_user=0x126ac08 "depth=1\n /usr/bin/xzdec\nusr/sbin/update-alternatives\n\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337", <incomplete sequence \337>..., size=8,
        offset=0xffff88001b8dff48)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:105
    105     ) {
    (gdb) p size
    $18 = 8
    (gdb) n
    108             printk(KERN_DEBUG MODNAME " is written\n");
    (gdb)
    105     ) {
    (gdb)
    108             printk(KERN_DEBUG MODNAME " is written\n");
    (gdb)
    110             if (size == 0) {
    (gdb)
    113             if (stack.depth >= entry) {
    (gdb)
    117             if (buf_user == NULL) {
    (gdb)
    122             p.content = (char *) kmalloc(size * sizeof(char), GFP_KERNEL);
    (gdb) l
    117             if (buf_user == NULL) {
    118                     return -EINVAL;
    119             }
    120
    121             p = stack.data[stack.depth];
    122             p.content = (char *) kmalloc(size * sizeof(char), GFP_KERNEL);
    123             if (p.content == NULL) {
    124                     printk(KERN_WARNING MODNAME ": (char *) kmalloc failed\n");
    125                     return -ENOMEM;
    126             }
    (gdb) n
    123             if (p.content == NULL) {
    (gdb) p p.content
    $19 = 0x0
    (gdb) n
    122             p.content = (char *) kmalloc(size * sizeof(char), GFP_KERNEL);
    (gdb)
    123             if (p.content == NULL) {
    (gdb) p p.content
    $20 = 0x0
    (gdb) n
    129             if (copy_from_user(p.content, buf_user, size) != 0) {
    (gdb)
    136             stack.depth++;
    (gdb) p p.content
    $21 = 0x0
    (gdb) p size
    $22 = 0
    (gdb) p p
    $23 = <value optimized out>
    (gdb) p stack.data
    $24 = (DATA *) 0xffff88001b7c7940
    (gdb) p stack
    $25 = {data = 0xffff88001b7c7940, depth = 1, errno = 0}
    (gdb) p stack[1]
    Structure has no component named operator[].
    (gdb) p stack.data[1]
    $26 = {length = 0, content = 0x0}
    (gdb) n
    140             return size;
    (gdb) p size
    $27 = 0
    (gdb) finish
    Run till exit from #0  stackmod_write (filep=<value optimized out>,
        buf_user=0x126ac08 "depth=1\n /usr/bin/xzdec\nusr/sbin/update-alternatives\n\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337", <incomplete sequence \337>..., size=0,
        offset=0xffff88001b8dff48)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:140
    0xffffffff810df5a3 in vfs_write (file=0xffff88001b80e9c0,
        buf=0x126ac08 "depth=1\n /usr/bin/xzdec\nusr/sbin/update-alternatives\n\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337", <incomplete sequence \337>...,
        count=<value optimized out>, pos=0xffff88001b8dff48) at fs/read_write.c:366
    366                             ret = file->f_op->write(file, buf, count, pos);
    Could not fetch register "orig_rax"; remote failure reply 'E00'
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 2
    
    Breakpoint 3, stackmod_proc_read (page=0xffff88001d9a9000 "stack: 0\n",
        start=0xffff88001b8ade90, off=0, count=3072, eof=0xffff88001b8ade9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153     ) {
    (gdb) p stack
    $28 = {data = 0xffff88001b7c7940, depth = 2, errno = 0}
    (gdb) p stack.data[0]
    $29 = {length = 461142784, content = 0xffff88001b7c7988 "\210y|\033"}
    (gdb) p stack.data[1]
    $30 = {length = 0, content = 0x0}
    (gdb) p stack.data[2]
    $31 = {length = 0,
      content = 0x2e2e02020010e071 <Address 0x2e2e02020010e071 out of bounds>}
    (gdb) ptype stack
    type = struct kernel_module_stack {
        DATA *data;
        int depth;
        int errno;
    }
    (gdb) ptype stack.data
    type = struct kernel_module_stack_data {
        int length;
        char *content;
    } *
    (gdb) ptype stack.data[0]
    type = struct kernel_module_stack_data {
        int length;
        char *content;
    }
    (gdb) ptype stack.data[0].content
    type = char *
    (gdb) c
    Continuing.
    
    Breakpoint 3, stackmod_proc_read (page=0xffff88001d9a9000 "stack: 2\n",
        start=0xffff88001b8ade90, off=9, count=3072, eof=0xffff88001b8ade9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153     ) {
    (gdb) c
    Continuing.
    

use pointer of DATA

  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko entry=4
  • s0711489@ubuntu-lucid64:~$ sudo mknod /dev/stack c 251 0
  • s0711489@ubuntu-lucid64:~$ sudo chmod 666 /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.text
    0xffffffffa0056000
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.data
    0xffffffffa0056718
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.bss
    0xffffffffa0056950
    
  • gdb
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done.
    (gdb) add-symbol-file ../../04/stackmod/stackmod.o 0xffffffffa0056000 -s .data 0xffffffffa0056718 -s .bss 0xffffffffa0056950
    add symbol table from file "../../04/stackmod/stackmod.o" at
            .text_addr = 0xffffffffa0056000
            .data_addr = 0xffffffffa0056718
            .bss_addr = 0xffffffffa0056950
    (y or n) y
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.o...done.
    (gdb) target remote localhost:8864
    Remote debugging using localhost:8864
    0xffffffff810097a9 in native_safe_halt ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) b stackmod_read
    Breakpoint 1 at 0xffffffffa00560b4: file /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c, line 62.
    (gdb) b stackmod_write
    Breakpoint 2 at 0xffffffffa0056207: file /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c, line 105.
    (gdb) b stackmod_proc_read
    Breakpoint 3 at 0xffffffffa00561ca: file /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c, line 153.
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 0
    
    Breakpoint 3, stackmod_proc_read (page=0xffff880019958000 "`\204\225\031",
        start=0xffff88001ac77e90, off=0, count=3072, eof=0xffff88001ac77e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153     ) {
    (gdb) p stack
    $1 = {data = 0xffff88001aca6d40, depth = 0, errno = 0}
    (gdb) p stack p
    A syntax error in expression, near `p'.
    (gdb) p p
    No symbol "p" in current context.
    (gdb) p stack.data
    $2 = (DATA *) 0xffff88001aca6d40
    (gdb) p stack.data[0]
    $3 = {length = 449474496, content = 0xffff88001aca6c88 "\210l\312\032"}
    (gdb) p stack.data[1]
    $4 = {length = 0, content = 0x0}
    (gdb) p stack.data[2]
    $5 = {length = 0,
      content = 0x2e2e02020010e071 <Address 0x2e2e02020010e071 out of bounds>}
    (gdb) p stack.data[3]
    $6 = {length = 0, content = 0x0}
    (gdb) p stack.data[4]
    $7 = {length = 0, content = 0xffff88001dfc94b0 "h\n\235\037"}
    (gdb) c
    Continuing.
    
    Breakpoint 3, stackmod_proc_read (page=0xffff880019958000 "stack: 0\n",
        start=0xffff88001ac77e90, off=9, count=3072, eof=0xffff88001ac77e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153     ) {
    (gdb) p eof
    $8 = (int *) 0xffff88001ac77e9c
    (gdb) p *eof
    $9 = 0
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ echo depth0 > /dev/stack
    Breakpoint 2, stackmod_write (filep=0xffff88001b793900,
        buf_user=0x2262c08 "depth0\ne -o filenames -F _insmod insmod\nalternatives\n\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337", <incomplete sequence \337>..., size=7,
        offset=0xffff88001ac19f48)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:105
    105     ) {
    (gdb) p p
    $10 = <value optimized out>
    (gdb) n
    108             printk(KERN_DEBUG MODNAME " is written\n");
    (gdb)
    105     ) {
    (gdb)
    108             printk(KERN_DEBUG MODNAME " is written\n");
    (gdb)
    110             if (size == 0) {
    (gdb)
    113             if (stack.depth >= entry) {
    (gdb)
    117             if (buf_user == NULL) {
    (gdb)
    121             p = stack.data + stack.depth;
    (gdb) p stack
    $11 = {data = 0xffff88001aca6d40, depth = 0, errno = 0}
    (gdb) p stack.data
    $12 = (DATA *) 0xffff88001aca6d40
    (gdb) p stack.data[0]
    $13 = {length = 449474496, content = 0xffff88001aca6c88 "\210l\312\032"}
    (gdb) p stack.data[1]
    $14 = {length = 0, content = 0x0}
    (gdb) n
    122             p->content = (char *) kmalloc(size * sizeof(char), GFP_KERNEL);
    (gdb)
    121             p = stack.data + stack.depth;
    (gdb)
    122             p->content = (char *) kmalloc(size * sizeof(char), GFP_KERNEL);
    (gdb) p p
    $15 = (DATA *) 0xffff88001aca6d40
    (gdb) ptype p
    type = struct kernel_module_stack_data {
        int length;
        char *content;
    } *
    (gdb) p *p
    $16 = {length = 449474496, content = 0xffff88001aca6c88 "\210l\312\032"}
    (gdb) n
    123             if (p->content == NULL) {
    (gdb) n
    122             p->content = (char *) kmalloc(size * sizeof(char), GFP_KERNEL);
    (gdb) p *p
    $17 = {length = 449474496, content = 0xffff88001aca6c88 "\210l\312\032"}
    (gdb) n
    123             if (p->content == NULL) {
    (gdb)
    127             p->length = size;
    (gdb) p *p
    $18 = {length = 449474496, content = 0xffff88001dfc94c8 "\030\225\374\035"}
    (gdb) p size
    $19 = 7
    (gdb) n
    129             if (copy_from_user(p->content, buf_user, size) != 0) {
    (gdb) p *p
    $20 = {length = 7, content = 0xffff88001dfc94c8 "\030\225\374\035"}
    (gdb) n
    136             stack.depth++;
    (gdb) p *p
    $21 = {length = 7, content = 0xffff88001dfc94c8 "depth0\n\377holders"}
    (gdb) p stack
    $22 = {data = 0xffff88001aca6d40, depth = 0, errno = 0}
    (gdb) n
    140             return size;
    (gdb) p size
    $23 = 0
    (gdb) n
    138             *offset += size;
    (gdb)
    141     }
    (gdb) p size
    $24 = <value optimized out>
    (gdb) n
    vfs_write (file=0xffff88001b793900,
        buf=0x2262c08 "depth0\ne -o filenames -F _insmod insmod\nalternatives\n\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337", <incomplete sequence \337>...,
        count=<value optimized out>, pos=0xffff88001ac19f48) at fs/read_write.c:369
    369                     if (ret > 0) {
    (gdb) finish
    Run till exit from #0  vfs_write (file=0xffff88001b793900,
        buf=0x2262c08 "depth0\ne -o filenames -F _insmod insmod\nalternatives\n\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337", <incomplete sequence \337>...,
        count=<value optimized out>, pos=0xffff88001ac19f48) at fs/read_write.c:369
    0xffffffff810df6b7 in sys_write (fd=<value optimized out>,
        buf=0x2262c08 "depth0\ne -o filenames -F _insmod insmod\nalternatives\n\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337", <incomplete sequence \337>..., count=7)
        at fs/read_write.c:418
    418                     ret = vfs_write(file, buf, count, &pos);
    Could not fetch register "orig_rax"; remote failure reply 'E00'
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ echo depth1 > /dev/stack
    Breakpoint 2, stackmod_write (filep=0xffff88001b906480,
        buf_user=0x2262c08 "depth1\ne -o filenames -F _insmod insmod\nalternatives\n\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337", <incomplete sequence \337>..., size=7,
        offset=0xffff88001ac19f48)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:105
    105     ) {
    (gdb) n
    108             printk(KERN_DEBUG MODNAME " is written\n");
    (gdb)
    105     ) {
    (gdb)
    108             printk(KERN_DEBUG MODNAME " is written\n");
    (gdb)
    110             if (size == 0) {
    (gdb)
    113             if (stack.depth >= entry) {
    (gdb)
    117             if (buf_user == NULL) {
    (gdb)
    121             p = stack.data + stack.depth;
    (gdb)
    122             p->content = (char *) kmalloc(size * sizeof(char), GFP_KERNEL);
    (gdb)
    121             p = stack.data + stack.depth;
    (gdb)
    122             p->content = (char *) kmalloc(size * sizeof(char), GFP_KERNEL);
    (gdb)
    123             if (p->content == NULL) {
    (gdb)
    122             p->content = (char *) kmalloc(size * sizeof(char), GFP_KERNEL);
    (gdb)
    123             if (p->content == NULL) {
    (gdb)
    127             p->length = size;
    (gdb)
    129             if (copy_from_user(p->content, buf_user, size) != 0) {
    (gdb) p size
    $25 = 7
    (gdb) p p
    $26 = (DATA *) 0xffff88001aca6d50
    (gdb) p *p
    $27 = {length = 7, content = 0xffff88001dfc9518 " \225\374\035"}
    (gdb) p stack
    $28 = {data = 0xffff88001aca6d40, depth = 1, errno = 0}
    (gdb) s
    copy_from_user (filep=<value optimized out>,
        buf_user=0x2262c08 "depth1\ne -o filenames -F _insmod insmod\nalternatives\n\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337", <incomplete sequence \337>..., size=7,
        offset=0xffff88001ac19f48)
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/uaccess_64.h:53
    53              might_fault();
    (gdb) finish
    Run till exit from #0  copy_from_user (filep=<value optimized out>,
        buf_user=0x2262c08 "depth1\ne -o filenames -F _insmod insmod\nalternatives\n\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337", <incomplete sequence \337>..., size=7,
        offset=0xffff88001ac19f48)
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/uaccess_64.h:53
    129             if (copy_from_user(p->content, buf_user, size) != 0) {
    (gdb) p size
    $29 = 7
    (gdb) n
    136             stack.depth++;
    (gdb)
    140             return size;
    (gdb) p size
    $30 = 0
    (gdb) n
    138             *offset += size;
    (gdb) p *offset
    $31 = 0
    (gdb) n
    141     }
    (gdb) p *offset
    $32 = 7
    (gdb) p size
    $33 = <value optimized out>
    (gdb) finish
    Run till exit from #0  stackmod_write (filep=<value optimized out>,
        buf_user=0x2262c08 "depth1\ne -o filenames -F _insmod insmod\nalternatives\n\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337", <incomplete sequence \337>...,
        size=<value optimized out>, offset=0xffff88001ac19f48)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:141
    0xffffffff810df5a3 in vfs_write (file=0xffff88001b906480,
        buf=0x2262c08 "depth1\ne -o filenames -F _insmod insmod\nalternatives\n\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337\337", <incomplete sequence \337>...,
        count=<value optimized out>, pos=0xffff88001ac19f48) at fs/read_write.c:366
    366                             ret = file->f_op->write(file, buf, count, pos);
    Could not fetch register "orig_rax"; remote failure reply 'E00'
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 2
    
    Breakpoint 3, stackmod_proc_read (page=0xffff880019958000 "stack: 0\n",
        start=0xffff88001b885e90, off=0, count=3072, eof=0xffff88001b885e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153     ) {
    (gdb) p stack
    $34 = {data = 0xffff88001aca6d40, depth = 2, errno = 0}
    (gdb) p stack.data
    $35 = (DATA *) 0xffff88001aca6d40
    (gdb) p stack.data[0]
    $36 = {length = 7, content = 0xffff88001dfc94c8 "depth0\n\377holders"}
    (gdb) p stack.data[1]
    $37 = {length = 7, content = 0xffff88001dfc9518 "depth1\n\377(\225\374\035"}
    (gdb) p stack.data[2]
    $38 = {length = 0,
      content = 0x2e2e02020010e071 <Address 0x2e2e02020010e071 out of bounds>}
    (gdb) p stack.data[3]
    $39 = {length = 0, content = 0x0}
    (gdb) p stack.data[4]
    $40 = {length = 0, content = 0xffff88001dfc94b0 "h\n\235\037"}
    (gdb) p stack.data[5]
    $41 = {length = 1, content = 0x0}
    (gdb) n
    156             outlen = sprintf(page, "stack: %d\n", stack.depth);
    (gdb)
    153     ) {
    (gdb)
    156             outlen = sprintf(page, "stack: %d\n", stack.depth);
    (gdb) p outlen
    $42 = <value optimized out>
    (gdb) n
    157             *eof = 1;
    (gdb) p outlen
    $43 = <value optimized out>
    (gdb) n
    156             outlen = sprintf(page, "stack: %d\n", stack.depth);
    (gdb)
    159             printk(KERN_DEBUG "/proc/" PROCNAME " is read\n");
    (gdb) p outlen
    $44 = <value optimized out>
    (gdb) n
    162     }
    (gdb) p outlen
    $45 = <value optimized out>
    (gdb) finish
    Run till exit from #0  stackmod_proc_read (page=<value optimized out>,
        start=<value optimized out>, off=<value optimized out>,
        count=<value optimized out>, eof=0xffff88001b885e9c,
        data=<value optimized out>)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:162
    __proc_file_read (file=<value optimized out>,
        buf=0xfb6000 <Address 0xfb6000 out of bounds>, nbytes=32768,
        ppos=0xffff88001b885f48) at fs/proc/generic.c:125
    125                     if (n == 0)   /* end of file */
    Could not fetch register "orig_rax"; remote failure reply 'E00'
    (gdb) c
    Continuing.
    
    Breakpoint 3, stackmod_proc_read (page=0xffff880019958000 "stack: 2\n",
        start=0xffff88001b885e90, off=9, count=3072, eof=0xffff88001b885e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153     ) {
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack
    depth1
    depth0
    
    Breakpoint 1, stackmod_read (filep=0xffff88001b591180,
        buf_user=0xcec000 <Address 0xcec000 out of bounds>, size=32768,
        offset=0xffff88001ba91f48)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:62
    62      ) {
    (gdb) p stack
    $46 = {data = 0xffff88001aca6d40, depth = 2, errno = 0}
    (gdb) n
    66              printk(KERN_DEBUG MODNAME " is read\n");
    (gdb)
    62      ) {
    (gdb)
    66              printk(KERN_DEBUG MODNAME " is read\n");
    (gdb)
    68              if (size == 0) {
    (gdb)
    71              if (stack.depth == 0) {
    (gdb)
    75              if (buf_user == NULL) {
    (gdb)
    78              if (! access_ok(VERIFY_WRITE, buf_user, size) ) {
    (gdb)
    82              stack.depth--;
    (gdb)
    83              p = stack.data + stack.depth;
    (gdb)
    82              stack.depth--;
    (gdb)
    83              p = stack.data + stack.depth;
    (gdb)
    85              len = p->length;
    (gdb) p p
    $47 = (DATA *) 0xffff88001aca6d50
    (gdb) p stack.data
    $48 = (DATA *) 0xffff88001aca6d40
    (gdb) p stack.data[0]
    $49 = {length = 7, content = 0xffff88001dfc94c8 "depth0\n\377holders"}
    (gdb) p stack.data[1]
    $50 = {length = 7, content = 0xffff88001dfc9518 "depth1\n\377(\225\374\035"}
    (gdb) n
    86              if (size < len) {
    (gdb) p len
    $51 = 7
    (gdb) n
    87                      len = size;
    (gdb)
    89              if (len > 0 && copy_to_user(buf_user, p->content, len) != 0) {
    (gdb) p len
    $52 = 7
    (gdb) n
    94              kfree(p->content);
    (gdb) p p
    $53 = (DATA *) 0xffff88001aca6d50
    (gdb) p *p
    $54 = {length = 7, content = 0xffff88001dfc9518 "depth1\n\377(\225\374\035"}
    (gdb) n
    98              *offset += len;
    (gdb) p *p
    $55 = {length = 7, content = 0xffff88001dfc9518 " \225\374\035"}
    (gdb) n
    95              p->content = NULL;
    (gdb)
    96              p->length = 0;
    (gdb)
    98              *offset += len;
    (gdb) p len
    $56 = 7
    (gdb) p *p
    $57 = {length = 0, content = 0x0}
    (gdb) n
    100             return len;
    (gdb)
    101     }
    (gdb) c
    Continuing.
    
    Breakpoint 1, stackmod_read (filep=0xffff88001b591180,
        buf_user=0xcec000 "depth1\n", size=32768, offset=0xffff88001ba91f48)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:62
    62      ) {
    (gdb) n
    66              printk(KERN_DEBUG MODNAME " is read\n");
    (gdb)
    62      ) {
    (gdb)
    66              printk(KERN_DEBUG MODNAME " is read\n");
    (gdb)
    68              if (size == 0) {
    (gdb)
    71              if (stack.depth == 0) {
    (gdb) p stack
    $58 = {data = 0xffff88001aca6d40, depth = 1, errno = 0}
    (gdb) n
    75              if (buf_user == NULL) {
    (gdb)
    78              if (! access_ok(VERIFY_WRITE, buf_user, size) ) {
    (gdb)
    82              stack.depth--;
    (gdb)
    83              p = stack.data + stack.depth;
    (gdb)
    82              stack.depth--;
    (gdb)
    83              p = stack.data + stack.depth;
    (gdb)
    85              len = p->length;
    (gdb) p *p
    $59 = {length = 7, content = 0xffff88001dfc94c8 "depth0\n\377holders"}
    (gdb) n
    86              if (size < len) {
    (gdb)
    87                      len = size;
    (gdb)
    89              if (len > 0 && copy_to_user(buf_user, p->content, len) != 0) {
    (gdb) p len
    $60 = 7
    (gdb) n
    94              kfree(p->content);
    (gdb) n
    98              *offset += len;
    (gdb)
    95              p->content = NULL;
    (gdb)
    96              p->length = 0;
    (gdb)
    98              *offset += len;
    (gdb) p *p
    $61 = {length = 0, content = 0x0}
    (gdb) n
    100             return len;
    (gdb) p buf_user
    $62 = 0xcec000 "depth0\n"
    (gdb) n
    101     }
    (gdb) c
    Continuing.
    
    Breakpoint 1, stackmod_read (filep=0xffff88001b591180,
        buf_user=0xcec000 "depth0\n", size=32768, offset=0xffff88001ba91f48)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:62
    62      ) {
    (gdb) n
    66              printk(KERN_DEBUG MODNAME " is read\n");
    (gdb)
    62      ) {
    (gdb)
    66              printk(KERN_DEBUG MODNAME " is read\n");
    (gdb)
    68              if (size == 0) {
    (gdb) p stack
    $63 = {data = 0xffff88001aca6d40, depth = 0, errno = 0}
    (gdb) p stack.data[0]
    $64 = {length = 0, content = 0x0}
    (gdb) n
    71              if (stack.depth == 0) {
    (gdb)
    101     }
    (gdb) c
    Continuing.
    

stackmod seems to work as expected

  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko entry=4
  • s0711489@ubuntu-lucid64:~$ sudo mknod /dev/stack c 251 0
  • s0711489@ubuntu-lucid64:~$ sudo chmod 666 /dev/stack
  • s0711489@ubuntu-lucid64:~$ echo 0 > /dev/stack
  • s0711489@ubuntu-lucid64:~$ echo 1 > /dev/stack
  • s0711489@ubuntu-lucid64:~$ echo 2 > /dev/stack
  • s0711489@ubuntu-lucid64:~$ echo 3 > /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 4
    
  • s0711489@ubuntu-lucid64:~$ echo 4 > /dev/stack
    -bash: echo: write error: No space left on device
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 4
    
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack
    3
    2
    1
    0
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 0
    
  • s0711489@ubuntu-lucid64:~$ tailf /var/log/kern.log
    Nov 23 20:03:55 ubuntu-lucid64 kernel: [   34.772987] stackmod is loaded
    Nov 23 20:03:55 ubuntu-lucid64 kernel: [   34.772992] stackmod: 4 entry, major is 251, minor is 0
    Nov 23 20:03:55 ubuntu-lucid64 kernel: [   34.773002] stackmod: create /proc/stackmod
    Nov 23 20:03:55 ubuntu-lucid64 kernel: [   34.773004] stackmod is added successfully
    Nov 23 20:05:02 ubuntu-lucid64 kernel: [  101.487336] stackmod is opened
    Nov 23 20:05:02 ubuntu-lucid64 kernel: [  101.487361] stackmod is written (2)
    Nov 23 20:05:02 ubuntu-lucid64 kernel: [  101.487367] stackmod is released
    Nov 23 20:05:05 ubuntu-lucid64 kernel: [  104.420526] stackmod is opened
    Nov 23 20:05:05 ubuntu-lucid64 kernel: [  104.420537] stackmod is written (2)
    Nov 23 20:05:05 ubuntu-lucid64 kernel: [  104.420542] stackmod is released
    Nov 23 20:05:08 ubuntu-lucid64 kernel: [  107.535829] stackmod is opened
    Nov 23 20:05:08 ubuntu-lucid64 kernel: [  107.535844] stackmod is written (2)
    Nov 23 20:05:08 ubuntu-lucid64 kernel: [  107.535849] stackmod is released
    Nov 23 20:05:11 ubuntu-lucid64 kernel: [  110.279177] stackmod is opened
    Nov 23 20:05:11 ubuntu-lucid64 kernel: [  110.279192] stackmod is written (2)
    Nov 23 20:05:11 ubuntu-lucid64 kernel: [  110.279198] stackmod is released
    Nov 23 20:05:16 ubuntu-lucid64 kernel: [  115.426012] /proc/stackmod is read
    Nov 23 20:05:16 ubuntu-lucid64 kernel: [  115.426026] /proc/stackmod is read
    Nov 23 20:05:21 ubuntu-lucid64 kernel: [  120.354789] stackmod is opened
    Nov 23 20:05:21 ubuntu-lucid64 kernel: [  120.354804] stackmod is written (2)
    Nov 23 20:05:21 ubuntu-lucid64 kernel: [  120.354989] stackmod is released
    Nov 23 20:05:25 ubuntu-lucid64 kernel: [  124.989666] /proc/stackmod is read
    Nov 23 20:05:25 ubuntu-lucid64 kernel: [  124.989681] /proc/stackmod is read
    Nov 23 20:05:34 ubuntu-lucid64 kernel: [  133.278525] stackmod is opened
    Nov 23 20:05:34 ubuntu-lucid64 kernel: [  133.278792] stackmod is read (32768)
    Nov 23 20:05:34 ubuntu-lucid64 kernel: [  133.278802] stackmod is read (32768)
    Nov 23 20:05:34 ubuntu-lucid64 kernel: [  133.278806] stackmod is read (32768)
    Nov 23 20:05:34 ubuntu-lucid64 kernel: [  133.278810] stackmod is read (32768)
    Nov 23 20:05:34 ubuntu-lucid64 kernel: [  133.278813] stackmod is read (32768)
    Nov 23 20:05:34 ubuntu-lucid64 kernel: [  133.278817] stackmod is released
    Nov 23 20:05:37 ubuntu-lucid64 kernel: [  136.451935] /proc/stackmod is read
    Nov 23 20:05:37 ubuntu-lucid64 kernel: [  136.451949] /proc/stackmod is read
    

test with binary data

within 1 stack

  • s0711489@ubuntu-lucid64:~$ dd if=/dev/urandom of=10kb count=10 bs=1024
  • s0711489@ubuntu-lucid64:~$ cat 10kb > /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack > 10kb.st
  • s0711489@ubuntu-lucid64:~$ ls -l
    total 156
    -rw-r--r-- 1 s0711489 s0711489  10240 2011-11-23 20:13 10kb
    -rw-r--r-- 1 s0711489 s0711489  10240 2011-11-23 20:15 10kb.st
    -rw-r--r-- 1 s0711489 s0711489 128105 2011-11-23 20:03 stackmod.ko
    
  • s0711489@ubuntu-lucid64:~$ sha1sum -b 10kb*
    8cc43464af331cd5d56f1db7d44b59530e038ec8 *10kb
    8cc43464af331cd5d56f1db7d44b59530e038ec8 *10kb.st
    
  • s0711489@ubuntu-lucid64:~$ tailf /var/log/kern.log
    Nov 23 20:14:18 ubuntu-lucid64 kernel: [  657.018652] stackmod is opened
    Nov 23 20:14:18 ubuntu-lucid64 kernel: [  657.020744] stackmod is written (10240)
    Nov 23 20:14:18 ubuntu-lucid64 kernel: [  657.020767] stackmod is released
    Nov 23 20:15:05 ubuntu-lucid64 kernel: [  704.792196] stackmod is opened
    Nov 23 20:15:05 ubuntu-lucid64 kernel: [  704.792212] stackmod is read (32768)
    Nov 23 20:15:05 ubuntu-lucid64 kernel: [  704.792275] stackmod is read (32768)
    Nov 23 20:15:05 ubuntu-lucid64 kernel: [  704.792279] stackmod is released
    

more than one stack

  • s0711489@ubuntu-lucid64:~$ dd if=/dev/urandom of=blob count=10 bs=32768
  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko entry=10
  • s0711489@ubuntu-lucid64:~$ cat blob > /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack > blob.rev
  • s0711489@ubuntu-lucid64:~$ cat blob.rev > /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack > blob.st
  • s0711489@ubuntu-lucid64:~$ sha1sum -b blob*
    d72eb4053f12de4c3c436663dd61679b20c156ac *blob
    2366d2d5b3c62a647c7eb28ae6708caf064470f4 *blob.rev
    d72eb4053f12de4c3c436663dd61679b20c156ac *blob.st
    

memset DATA

  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.text
    0xffffffffa0068000
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.data
    0xffffffffa0068738
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.bss
    0xffffffffa0068970
    
  • gdb
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done.
    (gdb) add-symbol-file ../../04/stackmod/stackmod.o 0xffffffffa0068000 -s .data 0xffffffffa0068738 -s .bss 0xffffffffa0068970
    add symbol table from file "../../04/stackmod/stackmod.o" at
            .text_addr = 0xffffffffa0068000
            .data_addr = 0xffffffffa0068738
            .bss_addr = 0xffffffffa0068970
    (y or n) y
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.o...done.
    (gdb) target remote localhost:8864
    Remote debugging using localhost:8864
    0xffffffff810097a9 in native_safe_halt ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) b stackmod_proc_read
    Breakpoint 1 at 0xffffffffa00681cd: file /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c, line 153.
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 0
    
    Breakpoint 1, stackmod_proc_read (page=0xffff88001d9bd000 "",
        start=0xffff88001adbbe90, off=0, count=3072, eof=0xffff88001adbbe9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153     ) {
    (gdb) p stack
    $1 = {data = 0xffff88001b5fa000, depth = 0, errno = 0}
    (gdb) p entry
    $2 = 128
    (gdb) p stack.data[0]
    $3 = {length = 0, content = 0x0}
    (gdb) p stack.data[127]
    $4 = {length = 0, content = 0x0}
    (gdb) p stack.data[128]
    $5 = {length = 459255808, content = 0x0}
    (gdb) c
    Continuing.
    
    Breakpoint 1, stackmod_proc_read (page=0xffff88001d9bd000 "stack: 0\n",
        start=0xffff88001adbbe90, off=9, count=3072, eof=0xffff88001adbbe9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153     ) {
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ cat blob > /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 10
    
    Breakpoint 1, stackmod_proc_read (page=0xffff88001d9bd000 "stack: 0\n",
        start=0xffff88001adbbe90, off=0, count=3072, eof=0xffff88001adbbe9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153     ) {
    (gdb) p stack
    $6 = {data = 0xffff88001b5fa000, depth = 10, errno = 0}
    (gdb) p stack.data[0]
    $7 = {length = 32768,
      content = 0xffff88001b9e0000 "\315̦[\371t\021\252Ď\230\311\003\240f\222\206}\363oyy\\$\276\205\271l3\033;\215\215\231m\375B\005\027|]$\375-x\374@\227\205\262\320\371z\022\342Z\351\273/\234\214\034\331\020z C\345\004\023J\024?\232\262ë\357\266xa\274l%H\264ʿ,uZ\025\373\373@^q\226z\326k\276\a6\227\r\322B\035X\303Y\364\205#β\325\342\222\301%\311]\301TR\277e\242s\276m]>\346\001\327\027J]\325\065<\212\332\037\200QFtUԴ\223q;.Y/\017ٻj\313\264\246$\254v`\241بz!`i\255Ћ\245\360\346\065\252\343\315ĤN\034\364!\324'\002\001\321P"...}
    (gdb) p stack.data[8]
    $8 = {length = 32768,
      content = 0xffff88001ac70000 "\377\352<e\275\025\343\"j\bc\021V\016\272\027h\244DYpo\347\215s\216\353\326\307\\\033\017\230:i}\024<n\342P\355\371\\\374\337j8\334M=m\276e\300\277dm\270SQ\\M\376\003\301\025&\203\325\034\r\361\355v\201o\303\034;M\206i\217\017w\365R\373\003+\242EN\037\327\375\353\004[\024.\f\255\234cb)\314qnR6\021\374\312\351b\252\035\232?OY\025Ǖ\347\ft\276\360\304g", <incomplete sequence \342>}
    (gdb) p stack.data[9]
    $9 = {length = 32768,
      content = 0xffff88001ac68000 "\266,\361\t\361\366\345\352=\247k&Ce"}
    (gdb) p stack.data[10]
    $10 = {length = 0, content = 0x0}
    (gdb) p stack.data[11]
    $11 = {length = 0, content = 0x0}
    (gdb) c
    Continuing.
    
    Breakpoint 1, stackmod_proc_read (page=0xffff88001d9bd000 "stack: 10\n",
        start=0xffff88001adbbe90, off=10, count=3072, eof=0xffff88001adbbe9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153     ) {
    (gdb) c
    Continuing.
    
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack > /dev/null
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 0
    
    Breakpoint 1, stackmod_proc_read (page=0xffff88001d9bd000 "stack: 10\n",
        start=0xffff88001b587e90, off=0, count=3072, eof=0xffff88001b587e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153     ) {
    (gdb) p stack
    $12 = {data = 0xffff88001b5fa000, depth = 0, errno = 0}
    (gdb) p stack.data[0]
    $13 = {length = 0, content = 0x0}
    (gdb) p stack.data[9]
    $14 = {length = 0, content = 0x0}
    (gdb) p stack.data[10]
    $15 = {length = 0, content = 0x0}
    (gdb) c
    Continuing.
    
    Breakpoint 1, stackmod_proc_read (page=0xffff88001d9bd000 "stack: 0\n",
        start=0xffff88001b587e90, off=9, count=3072, eof=0xffff88001b587e9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153     ) {
    (gdb)
    Continuing.
    

11/24

improve read function of /proc

check how stackmod_proc_read works

  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.text
    0xffffffffa005c000
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.data
    0xffffffffa005c738
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.bss
    0xffffffffa005c970
    
  • gdb
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done.
    (gdb) add-symbol-file ../../04/stackmod/stackmod.o 0xffffffffa005c000 -s .data 0xffffffffa005c738 -s .bss 0xffffffffa005c970
    add symbol table from file "../../04/stackmod/stackmod.o" at
            .text_addr = 0xffffffffa005c000
            .data_addr = 0xffffffffa005c738
            .bss_addr = 0xffffffffa005c970
    (y or n) y
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.o...done.
    (gdb) target remote localhost:8864
    Remote debugging using localhost:8864
    0xffffffff810097a9 in native_safe_halt ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch
    /x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) b
    Breakpoint 1 at 0xffffffff810097a9: file /home/ugrad/07/s0711489/coursework/Kern
    elHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h, line 49.
    (gdb) d
    Delete all breakpoints? (y or n) y
    (gdb) b stackmod_proc_read
    
    Breakpoint 2 at 0xffffffffa005c1cd: file /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c, line 153.
    (gdb) c
    Continuing.
    
    Breakpoint 2, stackmod_proc_read (page=0xffff88001d90c000 "\300\300\220\035",
        start=0xffff88001ad5fe90, off=0, count=3072, eof=0xffff88001ad5fe9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153     ) {
    (gdb) p *eof
    $1 = 0
    (gdb) p *start
    $2 = 0x0
    (gdb) n
    156             outlen = sprintf(page, "stack: %d\n", stack.depth);
    (gdb)
    153     ) {
    (gdb)
    156             outlen = sprintf(page, "stack: %d\n", stack.depth);
    (gdb)
    157             *eof = 1;
    (gdb)
    156             outlen = sprintf(page, "stack: %d\n", stack.depth);
    (gdb)
    159             printk(KERN_DEBUG "/proc/" PROCNAME " is read\n");
    (gdb)
    162     }
    (gdb)
    __proc_file_read (file=<value optimized out>,
        buf=0x1658000 <Address 0x1658000 out of bounds>, nbytes=32768,
        ppos=0xffff88001ad5ff48) at fs/proc/generic.c:125
    125                     if (n == 0)   /* end of file */
    (gdb) p *eof
    Cannot access memory at address 0x1
    (gdb) bt
    #0  __proc_file_read (file=<value optimized out>,
        buf=0x1658000 <Address 0x1658000 out of bounds>, nbytes=32768,
        ppos=0xffff88001ad5ff48) at fs/proc/generic.c:125
    #1  proc_file_read (file=<value optimized out>,
        buf=0x1658000 <Address 0x1658000 out of bounds>, nbytes=32768,
        ppos=0xffff88001ad5ff48) at fs/proc/generic.c:201
    #2  0xffffffff81124b07 in proc_reg_read (file=0xffff88001ad6dcc0,
        buf=0x1658000 <Address 0x1658000 out of bounds>, count=32768,
        ppos=0xffff88001ad5ff48) at fs/proc/inode.c:163
    #3  0xffffffff810df784 in vfs_read (file=0xffff88001ad6dcc0,
        buf=0x1658000 <Address 0x1658000 out of bounds>, count=14135,
        pos=0xffff88001ad5ff48) at fs/read_write.c:310
    #4  0xffffffff810dfa2b in sys_read (fd=<value optimized out>,
        buf=0x1658000 <Address 0x1658000 out of bounds>, count=32768)
        at fs/read_write.c:400
    #5  0xffffffff810029eb in ?? ()
    #6  0x0000000000000246 in ?? ()
    #7  0x00007fffbfae3c10 in ?? ()
    #8  0x0000000000000000 in ?? ()
    (gdb) p start
    $3 = 0x0
    (gdb) p eof
    $4 = 1
    (gdb) p n
    $5 = <value optimized out>
    (gdb) p count
    $6 = <value optimized out>
    (gdb) n
    120                             n = dp->read_proc(page, &start, *ppos,
    (gdb)
    127                     if (n < 0) {  /* error */
    (gdb)
    133                     if (start == NULL) {
    (gdb)
    134                             if (n > PAGE_SIZE) {
    (gdb)
    139                             n -= *ppos;
    (gdb)
    140                             if (n <= 0)
    (gdb)
    141                                     break;
    (gdb)
    144                             start = page + *ppos;
    (gdb)
    170             might_sleep();
    (gdb)
    68              return _copy_to_user(dst, src, size);
    (gdb) f
    #0  __proc_file_read (file=<value optimized out>,
        buf=0x1658000 <Address 0x1658000 out of bounds>,
        nbytes=<value optimized out>, ppos=0xffff88001ad5ff48)
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/uaccess_64.h:68
    68              return _copy_to_user(dst, src, size);
    (gdb) n
    171                     if (n == 0) {
    (gdb) p n
    $7 = <value optimized out>
    (gdb) n
    170                     n -= copy_to_user(buf, start < page ? page : start, n);
    (gdb)
    171                     if (n == 0) {
    (gdb)
    177                     *ppos += start < page ? (unsigned long)start : n;
    (gdb)
    178                     nbytes -= n;
    (gdb)
    179                     buf += n;
    (gdb)
    180                     retval += n;
    (gdb)
    68              while ((nbytes > 0) && !eof) {
    (gdb) p eof
    $8 = 1
    (gdb)
    $9 = 1
    (gdb) n
    182             free_page((unsigned long) page);
    (gdb)
    proc_file_read (file=<value optimized out>, buf=0x1658009 "", nbytes=9,
        ppos=0xffff88001ad5ff48) at fs/proc/generic.c:203
    203             pde_users_dec(pde);
    (gdb) bt
    #0  proc_file_read (file=<value optimized out>, buf=0x1658009 "", nbytes=9,
        ppos=0xffff88001ad5ff48) at fs/proc/generic.c:203
    #1  0xffffffff81124b07 in proc_reg_read (file=0xffff88001ad6dcc0,
        buf=0x1658000 "stack: 0\n", count=32768, ppos=0xffff88001ad5ff48)
        at fs/proc/inode.c:163
    #2  0xffffffff810df784 in vfs_read (file=0xffff88001ad6dcc0,
        buf=0x1658000 "stack: 0\n", count=18446612132341573168,
        pos=0xffff88001ad5ff48) at fs/read_write.c:310
    #3  0xffffffff810dfa2b in sys_read (fd=<value optimized out>,
        buf=0x1658000 "stack: 0\n", count=32768) at fs/read_write.c:400
    #4  0xffffffff810029eb in ?? ()
    #5  0x0000000000000246 in ?? ()
    #6  0x00007fffbfae3c10 in ?? ()
    #7  0x0000000000000000 in ?? ()
    (gdb) n
    205     }
    (gdb)
    proc_reg_read (file=0xffff88001ad6dcc0, buf=0x1658000 "stack: 0\n",
        count=32768, ppos=0xffff88001ad5ff48) at fs/proc/inode.c:165
    165             pde_users_dec(pde);
    (gdb)
    167     }
    (gdb) c
    Continuing.
    
    Breakpoint 2, stackmod_proc_read (page=0xffff88001d90c000 "stack: 0\n",
        start=0xffff88001ad5fe90, off=9, count=3072, eof=0xffff88001ad5fe9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153     ) {
    (gdb) bt
    #0  stackmod_proc_read (page=0xffff88001d90c000 "stack: 0\n",
        start=0xffff88001ad5fe90, off=9, count=3072, eof=0xffff88001ad5fe9c,
        data=0x0)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    #1  0xffffffff811291f4 in __proc_file_read (file=<value optimized out>,
        buf=0x1658000 "stack: 0\n", nbytes=32768, ppos=0xffff88001ad5ff48)
        at fs/proc/generic.c:120
    #2  proc_file_read (file=<value optimized out>, buf=0x1658000 "stack: 0\n",
        nbytes=32768, ppos=0xffff88001ad5ff48) at fs/proc/generic.c:201
    #3  0xffffffff81124b07 in proc_reg_read (file=0xffff88001ad6dcc0,
        buf=0x1658000 "stack: 0\n", count=32768, ppos=0xffff88001ad5ff48)
        at fs/proc/inode.c:163
    #4  0xffffffff810df784 in vfs_read (file=0xffff88001ad6dcc0,
        buf=0x1658000 "stack: 0\n", count=9, pos=0xffff88001ad5ff48)
        at fs/read_write.c:310
    #5  0xffffffff810dfa2b in sys_read (fd=<value optimized out>,
        buf=0x1658000 "stack: 0\n", count=32768) at fs/read_write.c:400
    #6  0xffffffff810029eb in ?? ()
    #7  0x0000000000000246 in ?? ()
    #8  0x00007fffbfae3be0 in ?? ()
    #9  0x0000000000000000 in ?? ()
    (gdb) p eof
    $10 = (int *) 0xffff88001ad5fe9c
    (gdb) p *eof
    $11 = 0
    (gdb) info frame
    Stack level 0, frame at 0xffff88001ad5fe68:
     rip = 0xffffffffa005c1cd in stackmod_proc_read
        (/home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153); saved rip 0xffffffff811291f4
     called by frame at 0xffff88001ad5fed8
     source language c.
     Arglist at 0xffff88001ad5fe58, args: page=0xffff88001d90c000 "stack: 0\n",
        start=0xffff88001ad5fe90, off=9, count=3072, eof=0xffff88001ad5fe9c,
        data=0x0
     Locals at 0xffff88001ad5fe58, Previous frame's sp is 0xffff88001ad5fe68
     Saved registers:
      rip at 0xffff88001ad5fe60
    (gdb) info local
    No locals.
    (gdb) info locals
    No locals.
    (gdb) n
    156             outlen = sprintf(page, "stack: %d\n", stack.depth);
    (gdb) p outlen
    $12 = <value optimized out>
    (gdb) n
    153     ) {
    (gdb)
    156             outlen = sprintf(page, "stack: %d\n", stack.depth);
    (gdb)
    157             *eof = 1;
    (gdb)
    156             outlen = sprintf(page, "stack: %d\n", stack.depth);
    (gdb)
    159             printk(KERN_DEBUG "/proc/" PROCNAME " is read\n");
    (gdb)
    162     }
    (gdb) p *eof
    $13 = 1
    (gdb) n
    __proc_file_read (file=<value optimized out>, buf=0x1658000 "stack: 0\n",
        nbytes=32768, ppos=0xffff88001ad5ff48) at fs/proc/generic.c:125
    125                     if (n == 0)   /* end of file */
    (gdb) c
    Continuing.
    

read stack.data.length

  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 0
    
  • s0711489@ubuntu-lucid64:~$ sudo mknod /dev/stack c 251 0
  • s0711489@ubuntu-lucid64:~$ sudo chmod 666 /dev/stack
  • s0711489@ubuntu-lucid64:~$ ls -l
    -rw-r--r-- 1 s0711489 s0711489 128657 2011-11-24 01:30 stackmod.ko
    
  • s0711489@ubuntu-lucid64:~$ cat stackmod.ko > /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 4
    stack.data[0].length:  32768
    stack.data[1].length:  32768
    stack.data[2].length:  32768
    stack.data[3].length:  30353
    

read /proc causes buffer overflow with deep stack

  • s0711489@ubuntu-lucid64:~$ sudo rmmod stackmod
  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko entry=1000
  • s0711489@ubuntu-lucid64:~$ dd if=/dev/zero of=/dev/stack
    dd: writing to `/dev/stack': No space left on device
    1001+0 records in
    1000+0 records out
    512000 bytes (512 kB) copied, 0.0240922 s, 21.3 MB/s
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 1000
    stack.data[0].length:    512
    stack.data[1].length:    512
    stack.data[2].length:    512
    stack.data[3].length:    512
    stack.data[4].length:    512
    
    (snip)
    
    stack.data[132].length:    512
    stack.data[133].length:    512
    stack.data[134].length:    512
    
  • s0711489@ubuntu-lucid64:~$ tailf /var/log/kern.log
    Nov 24 01:48:53 ubuntu-lucid64 kernel: [ 1509.351094] /proc/stackmod is read
    Nov 24 01:48:53 ubuntu-lucid64 kernel: [ 1509.351673] proc_file_read: Apparent buffer overflow!
    Nov 24 01:48:53 ubuntu-lucid64 kernel: [ 1509.351898] /proc/stackmod is read
    Nov 24 01:48:53 ubuntu-lucid64 kernel: [ 1509.352482] proc_file_read: Apparent buffer overflow!
    Nov 24 01:48:53 ubuntu-lucid64 kernel: [ 1509.353412] /proc/stackmod is read
    Nov 24 01:48:53 ubuntu-lucid64 kernel: [ 1509.353971] proc_file_read: Apparent buffer overflow!
    

/proc fs with seq_file

  • 参考
    • fs/proc/loadavg.c
      • single_open
    • fs/proc/devices.c
      • seq_open
  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko entry=1000
  • s0711489@ubuntu-lucid64:~$ sudo mknod /dev/stack c 251 0
  • s0711489@ubuntu-lucid64:~$ sudo chmod 666 /dev/stack
  • s0711489@ubuntu-lucid64:~$ dd if=/dev/zero of=/dev/stack
    dd: writing to `/dev/stack': No space left on device
    1001+0 records in
    1000+0 records out
    512000 bytes (512 kB) copied, 0.0338233 s, 15.1 MB/s
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 1000
    stack.data[0].length:    512
    stack.data[1].length:    512
    
    (snip)
    
    stack.data[997].length:    512
    stack.data[998].length:    512
    stack.data[999].length:    512
    
  • s0711489@ubuntu-lucid64:~$ tailf /var/log/kern.log
    Nov 24 03:26:17 ubuntu-lucid64 kernel: [ 4468.813821] /proc/stackmod is opened
    

no stack, no /proc output

  • s0711489@ubuntu-lucid64:~$ echo hoge > /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 1
    stack.data[0].length:      5
    
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack
    hoge
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod

debug with gdb

  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.text
    0xffffffffa0056000
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.data
    0xffffffffa00568e8
    
  • s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.bss
    0xffffffffa0056b30
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    (gdb) file vmlinux
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done.
    (gdb) add-symbol-file ../../04/stackmod/stackmod.o 0xffffffffa0056000 -s .data 0xffffffffa00568e8 -s .bss 0xffffffffa0056b30
    add symbol table from file "../../04/stackmod/stackmod.o" at
            .text_addr = 0xffffffffa0056000
            .data_addr = 0xffffffffa00568e8
            .bss_addr = 0xffffffffa0056b30
    (y or n) y
    Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.o...done.
    (gdb) target remote localhost:8864
    Remote debugging using localhost:8864
    0xffffffff810097a9 in native_safe_halt ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h:49
    49              asm volatile("sti; hlt": : :"memory");
    (gdb) b proc_seq_start
    Breakpoint 1 at 0xffffffffa00560cb: file /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c, line 153.
    (gdb) c
    Continuing.
    
    Breakpoint 1, proc_seq_start (m=0xffff880017e3a180, pos=0xffff88001b737e98)
        at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153
    153             if (*pos == 0) {
    (gdb) p *pos
    $1 = 0
    (gdb) n
    154                     seq_printf(m, "stack: %d\n", stack.depth);
    (gdb)
    157             if (*pos < stack.depth) {
    (gdb)
    162     }
    (gdb)
    157             if (*pos < stack.depth) {
    (gdb)
    162     }
    (gdb)
    seq_read (file=0xffff88001b66c240,
        buf=0xc8a000 <Address 0xc8a000 out of bounds>, size=32768,
        ppos=0xffff88001b737f48) at fs/seq_file.c:197
    197                     if (!p || IS_ERR(p))
    (gdb) bt
    #0  seq_read (file=0xffff88001b66c240,
        buf=0xc8a000 <Address 0xc8a000 out of bounds>, size=32768,
        ppos=0xffff88001b737f48) at fs/seq_file.c:197
    #1  0xffffffff81124b07 in proc_reg_read (file=0xffff88001b66c240,
        buf=0xc8a000 <Address 0xc8a000 out of bounds>, count=32768,
        ppos=0xffff88001b737f48) at fs/proc/inode.c:163
    #2  0xffffffff810df784 in vfs_read (file=0xffff88001b66c240,
        buf=0xc8a000 <Address 0xc8a000 out of bounds>, count=0,
        pos=0xffff88001b737f48) at fs/read_write.c:310
    #3  0xffffffff810dfa2b in sys_read (fd=<value optimized out>,
        buf=0xc8a000 <Address 0xc8a000 out of bounds>, count=32768)
        at fs/read_write.c:400
    #4  0xffffffff810029eb in ?? ()
    #5  0x0000000000000246 in ?? ()
    #6  0x00007fffced80000 in ?? ()
    #7  0x0000000000000000 in ?? ()
    (gdb) c
    Continuing.
    

fix it to read /proc correctly

  • s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 0
    
  • s0711489@ubuntu-lucid64:~$ sudo mknod /dev/stack c 251 0
  • s0711489@ubuntu-lucid64:~$ sudo chmod 666 /dev/stack
  • s0711489@ubuntu-lucid64:~$ echo hoge > /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 1
    stack.data[0].length:      5
    
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack
    hoge
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 0
    
  • s0711489@ubuntu-lucid64:~$ dd if=/dev/zero of=/dev/stack bs=10
    dd: writing `/dev/stack': No space left on device
    129+0 records in
    128+0 records out
    1280 bytes (1.3 kB) copied, 0.00669531 s, 191 kB/s
    
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 128
    stack.data[0].length:     10
    stack.data[1].length:     10
    
    (snip)
    
    stack.data[125].length:     10
    stack.data[126].length:     10
    stack.data[127].length:     10
    
  • s0711489@ubuntu-lucid64:~$ cat /dev/stack
  • s0711489@ubuntu-lucid64:~$ cat /proc/stackmod
    stack: 0
    

test with i386

  • s0711489@ubuntu-lucid:~$ sudo insmod stackmod.ko
  • s0711489@ubuntu-lucid:~$ cat /proc/stackmod
    stack: 0
    
  • s0711489@ubuntu-lucid:~$ sudo mknod /dev/stack c 251 0
  • s0711489@ubuntu-lucid:~$ sudo chmod 666 /dev/stack
  • s0711489@ubuntu-lucid:~$ echo hoge > /dev/stack
  • s0711489@ubuntu-lucid:~$ echo fuga > /dev/stack
  • s0711489@ubuntu-lucid:~$ cat /proc/stackmod
    stack: 2
    stack.data[0].length:      5
    stack.data[1].length:      5
    
  • s0711489@ubuntu-lucid:~$ cat /dev/stack
    fuga
    hoge
    
  • s0711489@ubuntu-lucid:~$ dd if=/dev/zero of=/dev/stack bs=10
    dd: writing `/dev/stack': No space left on device
    129+0 records in
    128+0 records out
    1280 bytes (1.3 kB) copied, 0.00711637 s, 180 kB/s
    
  • s0711489@ubuntu-lucid:~$ cat /proc/stackmod | tail
    stack.data[118].length:     10
    stack.data[119].length:     10
    stack.data[120].length:     10
    stack.data[121].length:     10
    stack.data[122].length:     10
    stack.data[123].length:     10
    stack.data[124].length:     10
    stack.data[125].length:     10
    stack.data[126].length:     10
    stack.data[127].length:     10
    
  • s0711489@ubuntu-lucid:~$ cat /dev/stack
  • s0711489@ubuntu-lucid:~$ cat /proc/stackmod
    stack: 0
    

add author/description

  • s0711489@ubuntu-lucid:~$ modinfo stackmod.ko
    filename:       stackmod.ko
    license:        Dual BSD/GPL
    author:         Ken-ichi Mito, @mittyorz
    description:    Kernel Stack Module
    depends:
    vermagic:       2.6.35.14 SMP mod_unload 686
    parm:           entry:max entry number (int)
    

11/25

userland test for new_debug

  • viola06:03 s0711489$ gcc new_debug.c -lrt
  • viola06:03 s0711489$ ./a.out
    DEBUG: new_debug()
    new_debug()
    
  • viola06:03 s0711489$ ./a.out 1
    DEBUG: 1
    [1322200781.086185000] 1
    
  • viola06:03 s0711489$ ./a.out 2 3 4 5
    DEBUG: 2
    [1322200793.130088000] 2
    DEBUG: 3
    [1322200793.130106000] 3
    DEBUG: 4
    [1322200793.130115000] 4
    DEBUG: 5
    [1322200793.130125000] 5
    

additional test for new_debug syscall

  • new_debug-err.c
    #include <stdio.h>
    #include <time.h>
    #include <asm/new_debug.h>
    
    int main (int argc, char *argv[]) {
            int i;
            const struct timespec *ts = "";
            
            if (new_debug(NULL, NULL)) {
                    perror("");
            }
            if (new_debug("", ts)) {
                    perror("");
            }
            
            return 0;
    }
    
  • s0711489@ubuntu-lucid64:~$ gcc -I /lib/modules/2.6.35.14/build/arch/x86/include/ new_debug-err.c
    new_debug-err.c: In function ‘main’:
    new_debug-err.c:7: warning: initialization from incompatible pointer type
    
  • s0711489@ubuntu-lucid64:~$ ./a.out
    Invalid argument
    Bad address
    
Last modified 6 years ago Last modified on Nov 25, 2011 3:02:02 PM

Attachments (4)

Download all attachments as: .zip