wiki:Dev/KernelHack/COINS/worklog/201110

Version 4 (modified by mitty, 8 years ago) (diff)

--

10/05

trace getpid() syscall with GDB

  • windell57:x86_64 s0711489$ gdb
    (gdb) set logging file gdb.getpid.log
    (gdb) set logging on
    Copying output to gdb.getpid.log.
    (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) b sys_getpid
    Breakpoint 1 at 0xffffffff81048ce4: file kernel/timer.c, line 1344.
    (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) c
    Continuing.
    
    Breakpoint 1, sys_getpid () at kernel/timer.c:1344
    
  • => attachment:gdb.getpid.log
  • on VM guest
    • s0711489@ubuntu-lucid64:~/coursework/KernelHack/02$ ./getpid
      getpid() -> 2143
      

trace log with source list and print data

  • windell57:x86_64 s0711489$ 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) b sys_getpid
    Breakpoint 1 at 0xffffffff81048ce4: file kernel/timer.c, line 1344.
    (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) c
    Continuing.
    
    Breakpoint 1, sys_getpid () at kernel/timer.c:1344
    1344    {
    (gdb) bt
    #0  sys_getpid () at kernel/timer.c:1344
    #1  0xffffffff810029eb in ?? ()
    #2  0x0000000000000246 in ?? ()
    #3  0x00007fff70d418e0 in ?? ()
    #4  0x00007f6c11b19210 in ?? ()
    #5  0x00007f6c11b05300 in ?? ()
    #6  0x0000000000000027 in ?? ()
    #7  0x0000000000000000 in ?? ()
    (gdb) l
    1339     * which case the tgid is the same in all threads of the same group.
    1340     *
    1341     * This is SMP safe as current->tgid does not change.
    1342     */
    1343    SYSCALL_DEFINE0(getpid)
    1344    {
    1345            return task_tgid_vnr(current);
    1346    }
    1347
    1348    /*
    (gdb) s
    1345            return task_tgid_vnr(current);
    (gdb)
    get_current ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:14
    14              return percpu_read_stable(current_task);
    (gdb) l
    9
    10      DECLARE_PER_CPU(struct task_struct *, current_task);
    11
    12      static __always_inline struct task_struct *get_current(void)
    13      {
    14              return percpu_read_stable(current_task);
    15      }
    16
    17      #define current get_current()
    18
    (gdb) bt
    #0  get_current ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:14
    #1  sys_getpid () at kernel/timer.c:1345
    #2  0xffffffff810029eb in ?? ()
    #3  0x0000000000000246 in ?? ()
    #4  0x00007fff63204890 in ?? ()
    #5  0x00007fc615a98210 in ?? ()
    #6  0x00007fc615a84300 in ?? ()
    #7  0x0000000000000027 in ?? ()
    #8  0x0000000000000000 in ?? ()
    (gdb) p current_task
    Cannot access memory at address 0xb540
    (gdb) ptype current_task
    type = struct task_struct {
    
    (snip)
    
    (gdb) s
    sys_getpid () at kernel/timer.c:1344
    1344    {
    (gdb) l
    1339     * which case the tgid is the same in all threads of the same group.
    1340     *
    1341     * This is SMP safe as current->tgid does not change.
    1342     */
    1343    SYSCALL_DEFINE0(getpid)
    1344    {
    1345            return task_tgid_vnr(current);
    1346    }
    1347
    1348    /*
    (gdb) bt
    #0  sys_getpid () at kernel/timer.c:1344
    #1  0xffffffff810029eb in ?? ()
    #2  0x0000000000000246 in ?? ()
    #3  0x00007fff63204890 in ?? ()
    #4  0x00007fc615a98210 in ?? ()
    #5  0x00007fc615a84300 in ?? ()
    #6  0x0000000000000027 in ?? ()
    #7  0x0000000000000000 in ?? ()
    (gdb) s
    1345            return task_tgid_vnr(current);
    (gdb) s
    task_tgid_vnr (tsk=0xffff88001bbe5880) at include/linux/sched.h:1606
    1606    {
    (gdb) l
    1601    }
    1602
    1603    pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
    1604
    1605    static inline pid_t task_tgid_vnr(struct task_struct *tsk)
    1606    {
    1607            return pid_vnr(task_tgid(tsk));
    1608    }
    1609
    1610
    (gdb) bt
    #0  task_tgid_vnr (tsk=0xffff88001bbe5880) at include/linux/sched.h:1606
    #1  0xffffffff81048cf6 in sys_getpid () at kernel/timer.c:1345
    #2  0xffffffff810029eb in ?? ()
    #3  0x0000000000000246 in ?? ()
    #4  0x00007fff63204890 in ?? ()
    #5  0x00007fc615a98210 in ?? ()
    #6  0x00007fc615a84300 in ?? ()
    #7  0x0000000000000027 in ?? ()
    #8  0x0000000000000000 in ?? ()
    (gdb) p tsk
    $2 = (struct task_struct *) 0xffff88001bbe5880
    (gdb) ptype tsk
    type = struct task_struct {
    
    (snip)
    
        pid_t pid;
        pid_t tgid;
    
    (snip)
    
        struct task_struct *group_leader;
        struct list_head ptraced;
        struct list_head ptrace_entry;
        struct pid_link pids[3];
    
    (snip)
    
    (gdb) ptype tsk->group_leader->pids
    type = struct pid_link {
        struct hlist_node node;
        struct pid *pid;
    } [3]
    
    (snip)
    
    (gdb) s
    1607            return pid_vnr(task_tgid(tsk));
    (gdb)
    1606    {
    (gdb)
    1607            return pid_vnr(task_tgid(tsk));
    (gdb)
    pid_vnr (pid=0xffff88001fb55400) at kernel/pid.c:444
    444     {
    (gdb) bt
    #0  pid_vnr (pid=0xffff88001fb55400) at kernel/pid.c:444
    #1  0xffffffff81048783 in task_tgid_vnr (tsk=<value optimized out>)
        at include/linux/sched.h:1607
    #2  0xffffffff81048cf6 in sys_getpid () at kernel/timer.c:1345
    #3  0xffffffff810029eb in ?? ()
    #4  0x0000000000000246 in ?? ()
    #5  0x00007fff63204890 in ?? ()
    #6  0x00007fc615a98210 in ?? ()
    #7  0x00007fc615a84300 in ?? ()
    #8  0x0000000000000027 in ?? ()
    #9  0x0000000000000000 in ?? ()
    (gdb) l
    439             }
    440             return nr;
    441     }
    442
    443     pid_t pid_vnr(struct pid *pid)
    444     {
    445             return pid_nr_ns(pid, current->nsproxy->pid_ns);
    446     }
    447     EXPORT_SYMBOL_GPL(pid_vnr);
    448
    (gdb) ptype pid
    type = struct pid {
        atomic_t count;
        unsigned int level;
        struct hlist_head tasks[3];
        struct rcu_head rcu;
        struct upid numbers[1];
    } *
    (gdb) up
    #1  0xffffffff81048783 in task_tgid_vnr (tsk=<value optimized out>)
        at include/linux/sched.h:1607
    1607            return pid_vnr(task_tgid(tsk));
    (gdb) ptype tsk->nsproxy->pid_ns
    type = struct pid_namespace {
        struct kref kref;
        struct pidmap pidmap[128];
        int last_pid;
        struct task_struct *child_reaper;
        struct kmem_cache *pid_cachep;
        unsigned int level;
        struct pid_namespace *parent;
        struct vfsmount *proc_mnt;
        struct bsd_acct_struct *bacct;
    } *
    (gdb) down
    #0  pid_vnr (pid=0xffff88001fb55400) at kernel/pid.c:444
    444     {
    (gdb) s
    445             return pid_nr_ns(pid, current->nsproxy->pid_ns);
    (gdb)
    get_current (pid=0xffff88001fb55400)
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:14
    14              return percpu_read_stable(current_task);
    (gdb) p current_task
    Cannot access memory at address 0xb540
    (gdb) s
    pid_vnr (pid=0xffff88001fb55400) at kernel/pid.c:445
    445             return pid_nr_ns(pid, current->nsproxy->pid_ns);
    (gdb) s
    444     {
    (gdb)
    445             return pid_nr_ns(pid, current->nsproxy->pid_ns);
    (gdb)
    pid_nr_ns (pid=0xffff88001fb55400, ns=0xffffffff8181bfe0) at kernel/pid.c:431
    431     {
    (gdb) bt
    #0  pid_nr_ns (pid=0xffff88001fb55400, ns=0xffffffff8181bfe0)
        at kernel/pid.c:431
    #1  0xffffffff81052db6 in pid_vnr (pid=0xffff88001fb55400) at kernel/pid.c:445
    #2  0xffffffff81048783 in task_tgid_vnr (tsk=<value optimized out>)
        at include/linux/sched.h:1607
    #3  0xffffffff81048cf6 in sys_getpid () at kernel/timer.c:1345
    #4  0xffffffff810029eb in ?? ()
    #5  0x0000000000000246 in ?? ()
    #6  0x00007fff63204890 in ?? ()
    #7  0x00007fc615a98210 in ?? ()
    #8  0x00007fc615a84300 in ?? ()
    #9  0x0000000000000027 in ?? ()
    #10 0x0000000000000000 in ?? ()
    (gdb) l
    426             return pid;
    427     }
    428     EXPORT_SYMBOL_GPL(find_get_pid);
    429
    430     pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
    431     {
    432             struct upid *upid;
    433             pid_t nr = 0;
    434
    435             if (pid && ns->level <= pid->level) {
    (gdb) l
    436                     upid = &pid->numbers[ns->level];
    437                     if (upid->ns == ns)
    438                             nr = upid->nr;
    439             }
    440             return nr;
    441     }
    442
    443     pid_t pid_vnr(struct pid *pid)
    444     {
    445             return pid_nr_ns(pid, current->nsproxy->pid_ns);
    (gdb) ptype pid
    type = struct pid {
        atomic_t count;
        unsigned int level;
        struct hlist_head tasks[3];
        struct rcu_head rcu;
        struct upid numbers[1];
    } *
    (gdb) ptype ns
    type = struct pid_namespace {
        struct kref kref;
        struct pidmap pidmap[128];
        int last_pid;
        struct task_struct *child_reaper;
        struct kmem_cache *pid_cachep;
        unsigned int level;
        struct pid_namespace *parent;
        struct vfsmount *proc_mnt;
        struct bsd_acct_struct *bacct;
    } *
    type = struct upid {
        int nr;
        struct pid_namespace *ns;
        struct hlist_node pid_chain;
    } *
    (gdb) ptype pid_t
    type = int
    (gdb) p ns->level
    $5 = 0
    (gdb) p pid->level
    $6 = 0
    (gdb) p ns->level <= pid->level
    $7 = 1
    (gdb) p ns
    $8 = (struct pid_namespace *) 0xffffffff8181bfe0
    (gdb) p &pid->numbers[ns->level]
    $9 = (struct upid *) 0xffff88001fb55430
    (gdb) p (&pid->numbers[ns->level])->ns
    $10 = (struct pid_namespace *) 0xffffffff8181bfe0
    (gdb) info locals
    upid = <value optimized out>
    nr = <value optimized out>
    (gdb) p nr
    $11 = <value optimized out>
    (gdb) p (&pid->numbers[ns->level])->nr
    $12 = 2225
    (gdb) s
    435             if (pid && ns->level <= pid->level) {
    (gdb)
    431     {
    (gdb)
    435             if (pid && ns->level <= pid->level) {
    (gdb)
    436                     upid = &pid->numbers[ns->level];
    (gdb)
    437                     if (upid->ns == ns)
    (gdb) p upid
    $13 = (struct upid *) 0xffff88001fb55430
    (gdb) s
    438                             nr = upid->nr;
    (gdb) p upid->ns == ns
    $14 = 1
    (gdb) p nr
    $15 = <value optimized out>
    (gdb) p upid->nr
    $16 = 2225
    (gdb) s
    441     }
    (gdb)
    pid_vnr (pid=<value optimized out>) at kernel/pid.c:446
    446     }
    (gdb) s
    task_tgid_vnr (tsk=<value optimized out>) at include/linux/sched.h:1608
    1608    }
    (gdb)
    sys_getpid () at kernel/timer.c:1346
    1346    }
    (gdb)
    sys_getpid () at kernel/timer.c:1345
    1345            return task_tgid_vnr(current);
    (gdb)
    sys_getpid () at kernel/timer.c:1346
    1346    }
    (gdb)
    
  • on VM guest
    • s0711489@ubuntu-lucid64:~/coursework/KernelHack/02$ ./getpid
      getpid() -> 2225
      

location of functions on source file

  • windell57:x86_64 s0711489$ grep percpu_read_stable -r .
    (snip)
    
    ./arch/x86/include/asm/percpu.h:#define percpu_read_stable(var)         percpu_from_op("mov", var, "p" (&(var)))
    
    (snip)
    
  • windell57:x86_64 s0711489$ grep task_tgid -r .
    (snip)
    
    ./include/linux/sched.h:static inline struct pid *task_tgid(struct task_struct *task)
    
    (snip)
    
  • include/linux/sched.h
    static inline struct pid *task_tgid(struct task_struct *task)
    {
    	return task->group_leader->pids[PIDTYPE_PID].pid;
    }
    

get_current function

  • windell57:02 s0711489$ gcc -E ../linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h -I ~/coursework/KernelHack/linux-2.6.35.14/x86_64/include -I ~/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/ > current.h
    In file included from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/percpu.h:44,
                     from ../linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:5:
    /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/include/linux/kernel.h:733:2: warning: #warning Attempt to use kernel headers from user space, see http:
    
  • pre-processed arch/x86/include/asm/current.h
    static __always_inline struct task_struct *get_current(void)
    {
     return ({ typeof(current_task) pfo_ret__; switch (sizeof(current_task)) { case 1: asm("mov" "b ""%P" "1"",%0" : "=q" (pfo_ret__) : "p" (&(current_task))); break; case 2: asm("mov" "w ""%P" "1"",%0" : "=r" (pfo_ret__) : "p" (&(current_task))); break; case 4: asm("mov" "l ""%P" "1"",%0" : "=r" (pfo_ret__) : "p" (&(current_task))); break; case 8: asm("mov" "q ""%P" "1"",%0" : "=r" (pfo_ret__) : "p" (&(current_task))); break; default: __bad_percpu_size(); } pfo_ret__; });
    }
    

10/12

tee system call

  • http://linuxjm.sourceforge.jp/html/LDP_man-pages/man2/tee.2.html
    #define _GNU_SOURCE
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <limits.h>
    
    int
    main(int argc, char *argv[])
    {
        int fd;
        int len, slen;
    
        if (argc != 2) {
            fprintf(stderr, "Usage: %s <file>\n", argv[0]);
            exit(EXIT_FAILURE);
        }
    
        fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
        if (fd == -1) {
            perror("open");
            exit(EXIT_FAILURE);
        }
    
        do {
            /*
             * tee stdin to stdout.
             */
            len = tee(STDIN_FILENO, STDOUT_FILENO,
                      INT_MAX, SPLICE_F_NONBLOCK);
    
            if (len < 0) {
                if (errno == EAGAIN)
                    continue;
                perror("tee");
                exit(EXIT_FAILURE);
            } else
                if (len == 0)
                    break;
    
            /*
             * Consume stdin by splicing it to a file.
             */
            while (len > 0) {
                slen = splice(STDIN_FILENO, NULL, fd, NULL,
                              len, SPLICE_F_MOVE);
                if (slen < 0) {
                    perror("splice");
                    break;
                }
                len -= slen;
            }
        } while (1);
    
        close(fd);
        exit(EXIT_SUCCESS);
    }
    
  • Ubuntu lucid(2.6.32-33-generic)やvanilla 2.6.35.14ではサンプルコードのまま正常に使える
    • mitty@ubuntu64:~/coursework/KernelHack/02$ cat tee.c | ./tee hoge | wc
           58     130    1217
      
  • CentOS 5.7(2.6.18-238.19.1.el5.centos.plusPAE or 2.6.18-274.3.1.el5)ではspliceがエラーになる
    • viola01:02 s0711489$ cat tee.c | ./tee hoge | wc
      viola01:02 s0711489$ cat tee.c | ./tee hoge | wc
      splice: Invalid argument
      splice: Invalid argument
      splice: Invalid argument
      splice: Invalid argument
      splice: Invalid argument
      splice: Invalid argument
      splice: Invalid argument
      splice: Invalid argument
      splice: Invalid argument
      
      ....
      
  • Ubuntu上でも、strace出来ない
    • mitty@ubuntu64:~/coursework/KernelHack/02$ strace -f -o sh.log sh -c 'cat tee.c | ./tee hoge | wc'
    • mitty@ubuntu64:~/coursework/KernelHack/02$ less sh.log
      (snip)
      
      1611  <... tee resumed> )               = -1 EAGAIN (Resource temporarily unavailable)
      1611  tee(0, 0x1, 0x7fffffff, 0x2)      = -1 EAGAIN (Resource temporarily unavailable)
      1611  tee(0, 0x1, 0x7fffffff, 0x2)      = -1 EAGAIN (Resource temporarily unavailable)
      1611  tee(0, 0x1, 0x7fffffff, 0x2)      = -1 EAGAIN (Resource temporarily unavailable)
      1611  tee(0, 0x1, 0x7fffffff, 0x2)      = -1 EAGAIN (Resource temporarily unavailable)
      1611  tee(0, 0x1, 0x7fffffff, 0x2)      = -1 EAGAIN (Resource temporarily unavailable)
      1611  tee(0, 0x1, 0x7fffffff, 0x2)      = -1 EAGAIN (Resource temporarily unavailable)
      
      (snip)
      
  • GDBによるステップ実行は、3000行ほど実行してみたがguest側で結果が出力されないので、断念

10/14

getcpu system call

  • getcpu system callはには存在しない
    • arch/x86/include/asm/unistd_64.h
      #define __IGNORE_getcpu     /* implemented as a vsyscall */
      
  • s0711489@ubuntu-lucid64:~/coursework/KernelHack/02$ cat > getcpu.c
    #define _GNU_SOURCE         /* See feature_test_macros(7) */
    #include <linux/getcpu.h>
    #include <stdio.h>
    
    int main (void) {
            int c, s;
            s = getcpu(&c, NULL, NULL);
            printf ("getcpu() -> %d\n", (s == -1) ? s : c);
    }
    
  • s0711489@ubuntu-lucid64:~/coursework/KernelHack/02$ gcc getcpu.c -o getcpu
    getcpu.c:1:26: error: linux/getcpu.h: No such file or directory
    

i386

  • s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh
    + cat /mnt/hgfs/linux-2.6.35.14/include/config/kernel.release
    + VERSION=2.6.35.14
    + echo Install Linux Kernel version 2.6.35.14
    Install Linux Kernel version 2.6.35.14
    + cd /mnt/hgfs/linux-2.6.35.14/
    + make install
    sh /mnt/hgfs/linux-2.6.35.14/arch/x86/boot/install.sh 2.6.35.14 arch/x86/boot/bzImage \
                    System.map "/boot"
    + make modules_install
      INSTALL arch/x86/kernel/test_nx.ko
      INSTALL drivers/scsi/scsi_wait_scan.ko
      INSTALL net/netfilter/xt_mark.ko
      DEPMOD  2.6.35.14
    + mkinitramfs -o /boot/initrd.img-2.6.35.14 2.6.35.14
    + update-grub
    Generating grub.cfg ...
    Found linux image: /boot/vmlinuz-2.6.35.14
    Found initrd image: /boot/initrd.img-2.6.35.14
    Found linux image: /boot/vmlinuz-2.6.32-33-generic
    Found initrd image: /boot/initrd.img-2.6.32-33-generic
    Found memtest86+ image: /boot/memtest86+.bin
    done
    + echo Install Kernel Headers to /lib/modules/2.6.35.14/build
    Install Kernel Headers to /lib/modules/2.6.35.14/build
    + date +%Y%m%d
    + mv /lib/modules/2.6.35.14/build /lib/modules/2.6.35.14/build-20111014
    + cd /mnt/hgfs/
    + tar c --files-from -
    + tar x -C /lib/modules/2.6.35.14/
    + egrep -v vmlinu
    + egrep -v .o$
    + find linux-2.6.35.14 -type f
    + mv /lib/modules/2.6.35.14/linux-2.6.35.14 /lib/modules/2.6.35.14/build
    + uname -a
    Linux ubuntu-lucid 2.6.32-33-generic #72-Ubuntu SMP Fri Jul 29 21:08:37 UTC 2011 i686 GNU/Linux
    
  • s0711489@ubuntu-lucid:~$ sudo vmware-config-tools.pl --default
  • s0711489@ubuntu-lucid:~$ cat > getcpu.c
    #define _GNU_SOURCE
    
    #include <stdio.h>
    #include <sys/syscall.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    
    int main( void )
    {
            int cpu = syscall(SYS_getcpu);
            if (cpu < 0)
            {
                    printf( "Error: errno = %d\n", errno ); fflush(stdout);
                    printf( "Error: errno: %s\n", strerror(errno) ); fflush(stdout);
                    return -1;
            }
            printf( "cpu = %d\n", cpu );
    
            return 0;
    }
    
  • s0711489@ubuntu-lucid:~$ gcc getcpu.c -o getcpu
  • s0711489@ubuntu-lucid:~$ ./getcpu
    Error: errno = 14
    Error: errno: Bad address
    
  • うまく動かない

getuid system call

  • windell57:x86_64 s0711489$ gdb
    (gdb) set logging file gdb.getuid.log
    (gdb) set logging on
    Copying output to gdb.getuid.log.
    (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) b sys_getuid
    Breakpoint 1 at 0xffffffff81048d17: file kernel/timer.c, line 1366.
    (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) c
    Continuing.
    
    Breakpoint 1, sys_getuid () at kernel/timer.c:1366
    1366    {
    (gdb) s
    1368            return current_uid();
    (gdb)
    get_current ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:14
    14              return percpu_read_stable(current_task);
    (gdb)
    1368            return current_uid();
    (gdb)
    sys_getuid () at kernel/timer.c:1366
    1366    {
    (gdb)
    1368            return current_uid();
    (gdb)
    get_current () at kernel/timer.c:1368
    1368            return current_uid();
    (gdb)
    sys_getuid () at kernel/timer.c:1369
    1369    }
    (gdb)
    
    Program received signal SIGINT, Interrupt.
    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) detach
    Ending remote debugging.
    (gdb) quit
    
  • s0711489@ubuntu-lucid64:~/coursework/KernelHack/02$ ./getuid
    getuid() -> 1000
    

trace log with source list and print data

  • windell57:x86_64 s0711489$ 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) b sys_getuid
    Breakpoint 1 at 0xffffffff81048d17: file kernel/timer.c, line 1366.
    (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) c
    Continuing.
    
    Breakpoint 1, sys_getuid () at kernel/timer.c:1366
    1366    {
    (gdb) bt
    #0  sys_getuid () at kernel/timer.c:1366
    #1  0xffffffff810029eb in ?? ()
    #2  0x0000000000000206 in ?? ()
    #3  0x00007ffff56d6ad0 in ?? ()
    #4  0x00007f8671347210 in ?? ()
    #5  0x00007f8671333300 in ?? ()
    #6  0x0000000000000066 in ?? ()
    #7  0x0000000000000000 in ?? ()
    (gdb) l
    1361
    1362            return pid;
    1363    }
    1364
    1365    SYSCALL_DEFINE0(getuid)
    1366    {
    1367            /* Only we change this so SMP safe */
    1368            return current_uid();
    1369    }
    1370
    (gdb) s
    1368            return current_uid();
    (gdb)
    get_current ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:14
    14              return percpu_read_stable(current_task);
    (gdb) bt
    #0  get_current ()
        at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:14
    #1  sys_getuid () at kernel/timer.c:1368
    #2  0xffffffff810029eb in ?? ()
    #3  0x0000000000000206 in ?? ()
    #4  0x00007ffff56d6ad0 in ?? ()
    #5  0x00007f8671347210 in ?? ()
    #6  0x00007f8671333300 in ?? ()
    #7  0x0000000000000066 in ?? ()
    #8  0x0000000000000000 in ?? ()
    (gdb) l
    9
    10      DECLARE_PER_CPU(struct task_struct *, current_task);
    11
    12      static __always_inline struct task_struct *get_current(void)
    13      {
    14              return percpu_read_stable(current_task);
    15      }
    16
    17      #define current get_current()
    18
    (gdb) p current_task
    Cannot access memory at address 0xb540
    (gdb) ptype current_task
    type = struct task_struct {
    
    (snip
    
    ---Type <return> to continue, or q <return> to quit---q
    Quit
    (gdb) s
    1368            return current_uid();
    (gdb)
    sys_getuid () at kernel/timer.c:1366
    1366    {
    (gdb) bt
    #0  sys_getuid () at kernel/timer.c:1366
    #1  0xffffffff810029eb in ?? ()
    #2  0x0000000000000206 in ?? ()
    #3  0x00007ffff56d6ad0 in ?? ()
    #4  0x00007f8671347210 in ?? ()
    #5  0x00007f8671333300 in ?? ()
    #6  0x0000000000000066 in ?? ()
    #7  0x0000000000000000 in ?? ()
    (gdb) s
    1368            return current_uid();
    (gdb)
    get_current () at kernel/timer.c:1368
    1368            return current_uid();
    (gdb) bt
    #0  get_current () at kernel/timer.c:1368
    #1  sys_getuid () at kernel/timer.c:1368
    #2  0xffffffff810029eb in ?? ()
    #3  0x0000000000000206 in ?? ()
    #4  0x00007ffff56d6ad0 in ?? ()
    #5  0x00007f8671347210 in ?? ()
    #6  0x00007f8671333300 in ?? ()
    #7  0x0000000000000066 in ?? ()
    #8  0x0000000000000000 in ?? ()
    (gdb) l
    1363    }
    1364
    1365    SYSCALL_DEFINE0(getuid)
    1366    {
    1367            /* Only we change this so SMP safe */
    1368            return current_uid();
    1369    }
    1370
    1371    SYSCALL_DEFINE0(geteuid)
    1372    {
    (gdb) s
    sys_getuid () at kernel/timer.c:1369
    1369    }
    (gdb) bt
    #0  sys_getuid () at kernel/timer.c:1369
    #1  0xffffffff810029eb in ?? ()
    #2  0x0000000000000206 in ?? ()
    #3  0x00007ffff56d6ad0 in ?? ()
    #4  0x00007f8671347210 in ?? ()
    #5  0x00007f8671333300 in ?? ()
    #6  0x0000000000000066 in ?? ()
    #7  0x0000000000000000 in ?? ()
    (gdb) l
    1364
    1365    SYSCALL_DEFINE0(getuid)
    1366    {
    1367            /* Only we change this so SMP safe */
    1368            return current_uid();
    1369    }
    1370
    1371    SYSCALL_DEFINE0(geteuid)
    1372    {
    1373            /* Only we change this so SMP safe */
    (gdb) p current_uid
    No symbol "current_uid" in current context.
    (gdb) ptype current_uid
    No symbol "current_uid" in current context.
    (gdb) s
    
    Breakpoint 1, sys_getuid () at kernel/timer.c:1366
    1366    {
    (gdb) detach
    Ending remote debugging.
    
  • include/linux/cred.h
    #define current_cred_xxx(xxx)           \
    ({                      \
        current->cred->xxx;         \
    })
    
    #define current_uid()       (current_cred_xxx(uid))
    #define current_gid()       (current_cred_xxx(gid))
    
    (snip)
    
  • ptype of current_task->cred
    (gdb) ptype current_task->cred
    type = const struct cred {
        atomic_t usage;
        uid_t uid;
        gid_t gid;
        uid_t suid;
        gid_t sgid;
        uid_t euid;
        gid_t egid;
        uid_t fsuid;
        gid_t fsgid;
        unsigned int securebits;
        kernel_cap_t cap_inheritable;
        kernel_cap_t cap_permitted;
        kernel_cap_t cap_effective;
        kernel_cap_t cap_bset;
        unsigned char jit_keyring;
        struct key *thread_keyring;
        struct key *request_key_auth;
        struct thread_group_cred *tgcred;
        void *security;
        struct user_struct *user;
        struct group_info *group_info;
        struct rcu_head rcu;
    } *
    (gdb) ptype current_task->cred->uid
    type = unsigned int
    

10/19

add new system call (i386)

  • windell57:i386 s0711489$ vim arch/x86/include/asm/unistd_32.h
  • windell57:i386 s0711489$ vim arch/x86/kernel/syscall_table_32.S
  • windell57:i386 s0711489$ vim arch/x86/include/asm/new_hello.h
  • windell57:i386 s0711489$ vim arch/x86/kernel/new_hello.c

10/21

add new system call (i386) (cont)

  • windell57:i386 s0711489$ vim arch/x86/kernel/new_hello.c
  • windell57:i386 s0711489$ vim arch/x86/kernel/Makefile
    • arch/x86/kernel/syscall_table_32.S

       
      337337    .long sys_rt_tgsigqueueinfo /* 335 */ 
      338338    .long sys_perf_event_open 
      339339    .long sys_recvmmsg 
       340    .long sys_new_hello 
    • arch/x86/kernel/Makefile

       
      131131    obj-$(CONFIG_PCI_MMCONFIG)  += mmconf-fam10h_64.o 
      132132    obj-y               += vsmp_64.o 
      133133endif 
       134 
       135obj-y               += new_hello.o 
    • arch/x86/kernel/new_hello.c

       
       1#include <linux/kernel.h> 
       2#include <linux/syscalls.h> 
       3 
       4SYSCALL_DEFINE1(new_hello, int, i) { 
       5        printk(KERN_DEBUG "new_hello() syscall with %d", i); 
       6        return i; 
       7} 
    • arch/x86/include/asm/unistd_32.h

       
      343343#define __NR_rt_tgsigqueueinfo  335 
      344344#define __NR_perf_event_open    336 
      345345#define __NR_recvmmsg       337 
       346#define __NR_new_hello      338 
      346347 
      347348#ifdef __KERNEL__ 
      348349 
      349 #define NR_syscalls 338 
       350#define NR_syscalls 339 
      350351 
      351352#define __ARCH_WANT_IPC_PARSE_VERSION 
      352353#define __ARCH_WANT_OLD_READDIR 
    • arch/x86/include/asm/new_hello.h

       
       1#ifndef _ASM_X86_NEW_HELLO_H 
       2#define _ASM_X86_NEW_HELLO_H 
       3 
       4#include <asm/unistd.h> 
       5#define new_hello(x) syscall(__NR_new_hello, x) 
       6 
       7#endif /* _ASM_X86_NEW_HELLO_H */ 
  • windell57:i386 s0711489$ make
    Kernel: arch/x86/boot/bzImage is ready  (#2)
    
  • windell57: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 #2 SMP Fri Oct 21 14:25:51 JST 2011 i686 GNU/Linux
    Ubuntu 10.04.3 LTS
    
  • s0711489@ubuntu-lucid:~$ cat > new_hello.c
    #include <unistd.h>
    #include <syscall.h>
    #include <stdio.h>
    
    int main (void) {
            printf ("new_helloc(1) -> %d\n",
                    syscall(__NR_new_hello, 1)
            );
    }
    
  • s0711489@ubuntu-lucid:~$ gcc -I /lib/modules/2.6.35.14/build/arch/x86/include/ new_hello.c
    new_hello.c: In function ‘main’:
    new_hello.c:8: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long int’
    
  • dmesgにしか出なかったので、KERN_DEBUGを消す
  • windell57:i386 s0711489$ make
    Kernel: arch/x86/boot/bzImage is ready  (#3)
    
  • windell57:i386 s0711489$ make modules
  • s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh
  • s0711489@ubuntu-lucid:~$ sudo reboot
  • s0711489@ubuntu-lucid:~$ cat > new_hello.c
  • s0711489@ubuntu-lucid:~$ gcc -I /lib/modules/2.6.35.14/build/arch/x86/include/ new_hello.c
  • s0711489@ubuntu-lucid:~$ ./a.out
    new_helloc(1) -> 1
    
  • s0711489@ubuntu-lucid:~$ dmesg | tail -n 1
    [  116.986628] new_hello() syscall with 1
    
  • KERN_DEBUGを消したが、結局dmesgにしか出ない
    • \nの追加
      • arch/x86/kernel/new_hello.c

         
        22#include <linux/syscalls.h> 
        33 
        44SYSCALL_DEFINE1(new_hello, int, i) { 
        5         printk(KERN_DEBUG "new_hello() syscall with %d", i); 
         5        printk("new_hello() syscall with %d\n", i); 
        66        return i; 
        77} 
  • windell57:i386 s0711489$ make
    Kernel: arch/x86/boot/bzImage is ready  (#4)
    
  • windell57:i386 s0711489$ make modules
  • s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh
  • s0711489@ubuntu-lucid:~$ cat > new_hello.c
  • s0711489@ubuntu-lucid:~$ gcc -I /lib/modules/2.6.35.14/build/arch/x86/include/ new_hello.c
  • s0711489@ubuntu-lucid:~$ ./a.out
    new_helloc(1) -> 1
    
  • s0711489@ubuntu-lucid:~$ ./a.out 1
    new_helloc(2) -> 2
    
  • s0711489@ubuntu-lucid:~$ ./a.out 2
    new_helloc(2) -> 2
    
  • s0711489@ubuntu-lucid:~$ ./a.out 3
    new_helloc(2) -> 2
    
  • s0711489@ubuntu-lucid:~$ ./a.out 1 2 3 4 5
    new_helloc(6) -> 6
    
  • s0711489@ubuntu-lucid:~$ dmesg | tail
    [   62.656820] new_hello() syscall with 1
    [   66.271703] new_hello() syscall with 2
    [   68.411791] new_hello() syscall with 2
    [   70.395934] new_hello() syscall with 2
    [   77.010426] new_hello() syscall with 6
    
  • /var/log/messages /var/log/kern.log /var/log/syslog にも出るようになった
    Oct 21 15:29:00 ubuntu-lucid kernel: [   62.656820] new_hello() syscall with 1
    Oct 21 15:29:04 ubuntu-lucid kernel: [   66.271703] new_hello() syscall with 2
    Oct 21 15:29:06 ubuntu-lucid kernel: [   68.411791] new_hello() syscall with 2
    Oct 21 15:29:08 ubuntu-lucid kernel: [   70.395934] new_hello() syscall with 2
    Oct 21 15:29:14 ubuntu-lucid kernel: [   77.010426] new_hello() syscall with 6
    
  • KERN_DEBUGを戻す
    • arch/x86/kernel/new_hello.c

       
      22#include <linux/syscalls.h> 
      33 
      44SYSCALL_DEFINE1(new_hello, int, i) { 
      5         printk("new_hello() syscall with %d\n", i); 
       5        printk(KERN_DEBUG "new_hello() syscall with %d\n", i); 
      66        return i; 
      77} 
  • windell57:i386 s0711489$ make
    Kernel: arch/x86/boot/bzImage is ready  (#5)
    
  • windell57:i386 s0711489$ make modules
  • s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh
  • s0711489@ubuntu-lucid:~$ ./a.out
    new_helloc(1) -> 1
    
  • s0711489@ubuntu-lucid:~$ ./a.out 2
    new_helloc(2) -> 2
    
  • s0711489@ubuntu-lucid:~$ ./a.out 2 4
    new_helloc(3) -> 3
    
  • s0711489@ubuntu-lucid:~$ ./a.out 2 3 4
    new_helloc(4) -> 4
    
  • s0711489@ubuntu-lucid:~$ tailf /var/log/syslog
    Oct 21 15:39:29 ubuntu-lucid kernel: [   55.626892] new_hello() syscall with 1
    Oct 21 15:40:18 ubuntu-lucid kernel: [  104.990720] new_hello() syscall with 2
    Oct 21 15:40:20 ubuntu-lucid kernel: [  106.772709] new_hello() syscall with 3
    Oct 21 15:40:23 ubuntu-lucid kernel: [  109.867051] new_hello() syscall with 4
    
  • /var/log/messages には出なくなる

trace sys_new_hello with GDB

  • windell57: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_hello
    Breakpoint 1 at 0xc101d87c: file arch/x86/kernel/new_hello.c, line 4.
    (gdb) target remote localhost:8832
    Remote debugging using localhost: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_hello (i=1) at arch/x86/kernel/new_hello.c:4
    4       SYSCALL_DEFINE1(new_hello, int, i) {
    (gdb) n
    5               printk(KERN_DEBUG "new_hello() syscall with %d\n", i);
    (gdb) l
    1       #include <linux/kernel.h>
    2       #include <linux/syscalls.h>
    3
    4       SYSCALL_DEFINE1(new_hello, int, i) {
    5               printk(KERN_DEBUG "new_hello() syscall with %d\n", i);
    6               return i;
    7       }
    (gdb) s
    printk (fmt=0xc1449502 "<7>new_hello() syscall with %d\n")
        at kernel/printk.c:614
    614             va_start(args, fmt);
    (gdb) l
    609                     r = vkdb_printf(fmt, args);
    610                     va_end(args);
    611                     return r;
    612             }
    613     #endif
    614             va_start(args, fmt);
    615             r = vprintk(fmt, args);
    616             va_end(args);
    617
    618             return r;
    (gdb) n
    615             r = vprintk(fmt, args);
    (gdb)
    614             va_start(args, fmt);
    (gdb)
    615             r = vprintk(fmt, args);
    (gdb)
    619     }
    (gdb)
    sys_new_hello (i=1) at arch/x86/kernel/new_hello.c:7
    7       }
    (gdb) l
    2       #include <linux/syscalls.h>
    3
    4       SYSCALL_DEFINE1(new_hello, int, i) {
    5               printk(KERN_DEBUG "new_hello() syscall with %d\n", i);
    6               return i;
    7       }
    (gdb) s
    
  • s0711489@ubuntu-lucid:~$ ./a.out
    new_helloc(1) -> 1
    

add sys_new_hello entry

  • windell57:i386 s0711489$ vim include/linux/syscalls.h
    • include/linux/syscalls.h

       
      826826            unsigned long fd, unsigned long pgoff); 
      827827asmlinkage long sys_old_mmap(struct mmap_arg_struct __user *arg); 
      828828 
       829asmlinkage long sys_new_hello(int i); 
       830 
      829831#endif 
  • windell57:i386 s0711489$ make
    Kernel: arch/x86/boot/bzImage is ready  (#6)
    
  • windell57:i386 s0711489$ make modules
  • s0711489@ubuntu-lucid:~$ sudo /mnt/hgfs/tools/install.sh
  • s0711489@ubuntu-lucid:~$ ./a.out
    new_helloc(1) -> 1
    
  • s0711489@ubuntu-lucid:~$ ./a.out 2
    new_helloc(2) -> 2
    
  • s0711489@ubuntu-lucid:~$ ./a.out 2 3
    new_helloc(3) -> 3
    
  • s0711489@ubuntu-lucid:~$ tailf /var/log/kern.log
    Oct 21 16:16:20 ubuntu-lucid kernel: [   59.045533] new_hello() syscall with 1
    Oct 21 16:16:22 ubuntu-lucid kernel: [   61.043321] new_hello() syscall with 2
    Oct 21 16:16:24 ubuntu-lucid kernel: [   63.470397] new_hello() syscall with 3
    

add new system call (x86_64)

  • viola04:linux-2.6.35.14 s0711489$ svn cp i386/arch/x86/include/asm/new_hello.h x86_64/arch/x86/include/asm/new_hello.h
  • viola04:linux-2.6.35.14 s0711489$ svn cp i386/arch/x86/kernel/new_hello.c x86_64/arch/x86/kernel/
  • viola04:linux-2.6.35.14 s0711489$ svn merge i386/include/linux/syscalls.h x86_64/include/linux/syscalls.h -r 1358:1359

Attachments (1)

Download all attachments as: .zip