| | 3590 | |
| | 3591 | = 11/24 = |
| | 3592 | == improve read function of /proc == |
| | 3593 | * [http://wiki.bit-hive.com/tomizoo/pg/proc%20fs%20%A4%F2%BB%C8%A4%C3%A4%BF%A5%AB%A1%BC%A5%CD%A5%EB%BE%F0%CA%F3%A4%CE%C9%BD%BC%A8 proc fs を使ったカーネル情報の表示 - とみぞーノート] |
| | 3594 | * [http://wiki.bit-hive.com/tomizoo/pg/proc%20fs%20%A4%F2%BB%C8%A4%C3%A4%BF%A5%AB%A1%BC%A5%CD%A5%EB%BE%F0%CA%F3%A4%CE%C9%BD%BC%A8%20%A4%BD%A4%CE2 proc fs を使ったカーネル情報の表示 その2 - とみぞーノート] |
| | 3595 | |
| | 3596 | === check how stackmod_proc_read works === |
| | 3597 | * s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko |
| | 3598 | * s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.text |
| | 3599 | {{{ |
| | 3600 | 0xffffffffa005c000 |
| | 3601 | }}} |
| | 3602 | * s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.data |
| | 3603 | {{{ |
| | 3604 | 0xffffffffa005c738 |
| | 3605 | }}} |
| | 3606 | * s0711489@ubuntu-lucid64:~$ cat /sys/module/stackmod/sections/.bss |
| | 3607 | {{{ |
| | 3608 | 0xffffffffa005c970 |
| | 3609 | }}} |
| | 3610 | |
| | 3611 | * gdb |
| | 3612 | {{{ |
| | 3613 | (gdb) file vmlinux |
| | 3614 | Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done. |
| | 3615 | (gdb) add-symbol-file ../../04/stackmod/stackmod.o 0xffffffffa005c000 -s .data 0xffffffffa005c738 -s .bss 0xffffffffa005c970 |
| | 3616 | add symbol table from file "../../04/stackmod/stackmod.o" at |
| | 3617 | .text_addr = 0xffffffffa005c000 |
| | 3618 | .data_addr = 0xffffffffa005c738 |
| | 3619 | .bss_addr = 0xffffffffa005c970 |
| | 3620 | (y or n) y |
| | 3621 | Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.o...done. |
| | 3622 | (gdb) target remote localhost:8864 |
| | 3623 | Remote debugging using localhost:8864 |
| | 3624 | 0xffffffff810097a9 in native_safe_halt () |
| | 3625 | at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch |
| | 3626 | /x86/include/asm/irqflags.h:49 |
| | 3627 | 49 asm volatile("sti; hlt": : :"memory"); |
| | 3628 | (gdb) b |
| | 3629 | Breakpoint 1 at 0xffffffff810097a9: file /home/ugrad/07/s0711489/coursework/Kern |
| | 3630 | elHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h, line 49. |
| | 3631 | (gdb) d |
| | 3632 | Delete all breakpoints? (y or n) y |
| | 3633 | (gdb) b stackmod_proc_read |
| | 3634 | |
| | 3635 | Breakpoint 2 at 0xffffffffa005c1cd: file /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c, line 153. |
| | 3636 | (gdb) c |
| | 3637 | Continuing. |
| | 3638 | |
| | 3639 | Breakpoint 2, stackmod_proc_read (page=0xffff88001d90c000 "\300\300\220\035", |
| | 3640 | start=0xffff88001ad5fe90, off=0, count=3072, eof=0xffff88001ad5fe9c, |
| | 3641 | data=0x0) |
| | 3642 | at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153 |
| | 3643 | 153 ) { |
| | 3644 | (gdb) p *eof |
| | 3645 | $1 = 0 |
| | 3646 | (gdb) p *start |
| | 3647 | $2 = 0x0 |
| | 3648 | (gdb) n |
| | 3649 | 156 outlen = sprintf(page, "stack: %d\n", stack.depth); |
| | 3650 | (gdb) |
| | 3651 | 153 ) { |
| | 3652 | (gdb) |
| | 3653 | 156 outlen = sprintf(page, "stack: %d\n", stack.depth); |
| | 3654 | (gdb) |
| | 3655 | 157 *eof = 1; |
| | 3656 | (gdb) |
| | 3657 | 156 outlen = sprintf(page, "stack: %d\n", stack.depth); |
| | 3658 | (gdb) |
| | 3659 | 159 printk(KERN_DEBUG "/proc/" PROCNAME " is read\n"); |
| | 3660 | (gdb) |
| | 3661 | 162 } |
| | 3662 | (gdb) |
| | 3663 | __proc_file_read (file=<value optimized out>, |
| | 3664 | buf=0x1658000 <Address 0x1658000 out of bounds>, nbytes=32768, |
| | 3665 | ppos=0xffff88001ad5ff48) at fs/proc/generic.c:125 |
| | 3666 | 125 if (n == 0) /* end of file */ |
| | 3667 | (gdb) p *eof |
| | 3668 | Cannot access memory at address 0x1 |
| | 3669 | (gdb) bt |
| | 3670 | #0 __proc_file_read (file=<value optimized out>, |
| | 3671 | buf=0x1658000 <Address 0x1658000 out of bounds>, nbytes=32768, |
| | 3672 | ppos=0xffff88001ad5ff48) at fs/proc/generic.c:125 |
| | 3673 | #1 proc_file_read (file=<value optimized out>, |
| | 3674 | buf=0x1658000 <Address 0x1658000 out of bounds>, nbytes=32768, |
| | 3675 | ppos=0xffff88001ad5ff48) at fs/proc/generic.c:201 |
| | 3676 | #2 0xffffffff81124b07 in proc_reg_read (file=0xffff88001ad6dcc0, |
| | 3677 | buf=0x1658000 <Address 0x1658000 out of bounds>, count=32768, |
| | 3678 | ppos=0xffff88001ad5ff48) at fs/proc/inode.c:163 |
| | 3679 | #3 0xffffffff810df784 in vfs_read (file=0xffff88001ad6dcc0, |
| | 3680 | buf=0x1658000 <Address 0x1658000 out of bounds>, count=14135, |
| | 3681 | pos=0xffff88001ad5ff48) at fs/read_write.c:310 |
| | 3682 | #4 0xffffffff810dfa2b in sys_read (fd=<value optimized out>, |
| | 3683 | buf=0x1658000 <Address 0x1658000 out of bounds>, count=32768) |
| | 3684 | at fs/read_write.c:400 |
| | 3685 | #5 0xffffffff810029eb in ?? () |
| | 3686 | #6 0x0000000000000246 in ?? () |
| | 3687 | #7 0x00007fffbfae3c10 in ?? () |
| | 3688 | #8 0x0000000000000000 in ?? () |
| | 3689 | (gdb) p start |
| | 3690 | $3 = 0x0 |
| | 3691 | (gdb) p eof |
| | 3692 | $4 = 1 |
| | 3693 | (gdb) p n |
| | 3694 | $5 = <value optimized out> |
| | 3695 | (gdb) p count |
| | 3696 | $6 = <value optimized out> |
| | 3697 | (gdb) n |
| | 3698 | 120 n = dp->read_proc(page, &start, *ppos, |
| | 3699 | (gdb) |
| | 3700 | 127 if (n < 0) { /* error */ |
| | 3701 | (gdb) |
| | 3702 | 133 if (start == NULL) { |
| | 3703 | (gdb) |
| | 3704 | 134 if (n > PAGE_SIZE) { |
| | 3705 | (gdb) |
| | 3706 | 139 n -= *ppos; |
| | 3707 | (gdb) |
| | 3708 | 140 if (n <= 0) |
| | 3709 | (gdb) |
| | 3710 | 141 break; |
| | 3711 | (gdb) |
| | 3712 | 144 start = page + *ppos; |
| | 3713 | (gdb) |
| | 3714 | 170 might_sleep(); |
| | 3715 | (gdb) |
| | 3716 | 68 return _copy_to_user(dst, src, size); |
| | 3717 | (gdb) f |
| | 3718 | #0 __proc_file_read (file=<value optimized out>, |
| | 3719 | buf=0x1658000 <Address 0x1658000 out of bounds>, |
| | 3720 | nbytes=<value optimized out>, ppos=0xffff88001ad5ff48) |
| | 3721 | at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/uaccess_64.h:68 |
| | 3722 | 68 return _copy_to_user(dst, src, size); |
| | 3723 | (gdb) n |
| | 3724 | 171 if (n == 0) { |
| | 3725 | (gdb) p n |
| | 3726 | $7 = <value optimized out> |
| | 3727 | (gdb) n |
| | 3728 | 170 n -= copy_to_user(buf, start < page ? page : start, n); |
| | 3729 | (gdb) |
| | 3730 | 171 if (n == 0) { |
| | 3731 | (gdb) |
| | 3732 | 177 *ppos += start < page ? (unsigned long)start : n; |
| | 3733 | (gdb) |
| | 3734 | 178 nbytes -= n; |
| | 3735 | (gdb) |
| | 3736 | 179 buf += n; |
| | 3737 | (gdb) |
| | 3738 | 180 retval += n; |
| | 3739 | (gdb) |
| | 3740 | 68 while ((nbytes > 0) && !eof) { |
| | 3741 | (gdb) p eof |
| | 3742 | $8 = 1 |
| | 3743 | (gdb) |
| | 3744 | $9 = 1 |
| | 3745 | (gdb) n |
| | 3746 | 182 free_page((unsigned long) page); |
| | 3747 | (gdb) |
| | 3748 | proc_file_read (file=<value optimized out>, buf=0x1658009 "", nbytes=9, |
| | 3749 | ppos=0xffff88001ad5ff48) at fs/proc/generic.c:203 |
| | 3750 | 203 pde_users_dec(pde); |
| | 3751 | (gdb) bt |
| | 3752 | #0 proc_file_read (file=<value optimized out>, buf=0x1658009 "", nbytes=9, |
| | 3753 | ppos=0xffff88001ad5ff48) at fs/proc/generic.c:203 |
| | 3754 | #1 0xffffffff81124b07 in proc_reg_read (file=0xffff88001ad6dcc0, |
| | 3755 | buf=0x1658000 "stack: 0\n", count=32768, ppos=0xffff88001ad5ff48) |
| | 3756 | at fs/proc/inode.c:163 |
| | 3757 | #2 0xffffffff810df784 in vfs_read (file=0xffff88001ad6dcc0, |
| | 3758 | buf=0x1658000 "stack: 0\n", count=18446612132341573168, |
| | 3759 | pos=0xffff88001ad5ff48) at fs/read_write.c:310 |
| | 3760 | #3 0xffffffff810dfa2b in sys_read (fd=<value optimized out>, |
| | 3761 | buf=0x1658000 "stack: 0\n", count=32768) at fs/read_write.c:400 |
| | 3762 | #4 0xffffffff810029eb in ?? () |
| | 3763 | #5 0x0000000000000246 in ?? () |
| | 3764 | #6 0x00007fffbfae3c10 in ?? () |
| | 3765 | #7 0x0000000000000000 in ?? () |
| | 3766 | (gdb) n |
| | 3767 | 205 } |
| | 3768 | (gdb) |
| | 3769 | proc_reg_read (file=0xffff88001ad6dcc0, buf=0x1658000 "stack: 0\n", |
| | 3770 | count=32768, ppos=0xffff88001ad5ff48) at fs/proc/inode.c:165 |
| | 3771 | 165 pde_users_dec(pde); |
| | 3772 | (gdb) |
| | 3773 | 167 } |
| | 3774 | (gdb) c |
| | 3775 | Continuing. |
| | 3776 | |
| | 3777 | Breakpoint 2, stackmod_proc_read (page=0xffff88001d90c000 "stack: 0\n", |
| | 3778 | start=0xffff88001ad5fe90, off=9, count=3072, eof=0xffff88001ad5fe9c, |
| | 3779 | data=0x0) |
| | 3780 | at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153 |
| | 3781 | 153 ) { |
| | 3782 | (gdb) bt |
| | 3783 | #0 stackmod_proc_read (page=0xffff88001d90c000 "stack: 0\n", |
| | 3784 | start=0xffff88001ad5fe90, off=9, count=3072, eof=0xffff88001ad5fe9c, |
| | 3785 | data=0x0) |
| | 3786 | at /home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153 |
| | 3787 | #1 0xffffffff811291f4 in __proc_file_read (file=<value optimized out>, |
| | 3788 | buf=0x1658000 "stack: 0\n", nbytes=32768, ppos=0xffff88001ad5ff48) |
| | 3789 | at fs/proc/generic.c:120 |
| | 3790 | #2 proc_file_read (file=<value optimized out>, buf=0x1658000 "stack: 0\n", |
| | 3791 | nbytes=32768, ppos=0xffff88001ad5ff48) at fs/proc/generic.c:201 |
| | 3792 | #3 0xffffffff81124b07 in proc_reg_read (file=0xffff88001ad6dcc0, |
| | 3793 | buf=0x1658000 "stack: 0\n", count=32768, ppos=0xffff88001ad5ff48) |
| | 3794 | at fs/proc/inode.c:163 |
| | 3795 | #4 0xffffffff810df784 in vfs_read (file=0xffff88001ad6dcc0, |
| | 3796 | buf=0x1658000 "stack: 0\n", count=9, pos=0xffff88001ad5ff48) |
| | 3797 | at fs/read_write.c:310 |
| | 3798 | #5 0xffffffff810dfa2b in sys_read (fd=<value optimized out>, |
| | 3799 | buf=0x1658000 "stack: 0\n", count=32768) at fs/read_write.c:400 |
| | 3800 | #6 0xffffffff810029eb in ?? () |
| | 3801 | #7 0x0000000000000246 in ?? () |
| | 3802 | #8 0x00007fffbfae3be0 in ?? () |
| | 3803 | #9 0x0000000000000000 in ?? () |
| | 3804 | (gdb) p eof |
| | 3805 | $10 = (int *) 0xffff88001ad5fe9c |
| | 3806 | (gdb) p *eof |
| | 3807 | $11 = 0 |
| | 3808 | (gdb) info frame |
| | 3809 | Stack level 0, frame at 0xffff88001ad5fe68: |
| | 3810 | rip = 0xffffffffa005c1cd in stackmod_proc_read |
| | 3811 | (/home/ugrad/07/s0711489/coursework/KernelHack/04/stackmod/stackmod.c:153); saved rip 0xffffffff811291f4 |
| | 3812 | called by frame at 0xffff88001ad5fed8 |
| | 3813 | source language c. |
| | 3814 | Arglist at 0xffff88001ad5fe58, args: page=0xffff88001d90c000 "stack: 0\n", |
| | 3815 | start=0xffff88001ad5fe90, off=9, count=3072, eof=0xffff88001ad5fe9c, |
| | 3816 | data=0x0 |
| | 3817 | Locals at 0xffff88001ad5fe58, Previous frame's sp is 0xffff88001ad5fe68 |
| | 3818 | Saved registers: |
| | 3819 | rip at 0xffff88001ad5fe60 |
| | 3820 | (gdb) info local |
| | 3821 | No locals. |
| | 3822 | (gdb) info locals |
| | 3823 | No locals. |
| | 3824 | (gdb) n |
| | 3825 | 156 outlen = sprintf(page, "stack: %d\n", stack.depth); |
| | 3826 | (gdb) p outlen |
| | 3827 | $12 = <value optimized out> |
| | 3828 | (gdb) n |
| | 3829 | 153 ) { |
| | 3830 | (gdb) |
| | 3831 | 156 outlen = sprintf(page, "stack: %d\n", stack.depth); |
| | 3832 | (gdb) |
| | 3833 | 157 *eof = 1; |
| | 3834 | (gdb) |
| | 3835 | 156 outlen = sprintf(page, "stack: %d\n", stack.depth); |
| | 3836 | (gdb) |
| | 3837 | 159 printk(KERN_DEBUG "/proc/" PROCNAME " is read\n"); |
| | 3838 | (gdb) |
| | 3839 | 162 } |
| | 3840 | (gdb) p *eof |
| | 3841 | $13 = 1 |
| | 3842 | (gdb) n |
| | 3843 | __proc_file_read (file=<value optimized out>, buf=0x1658000 "stack: 0\n", |
| | 3844 | nbytes=32768, ppos=0xffff88001ad5ff48) at fs/proc/generic.c:125 |
| | 3845 | 125 if (n == 0) /* end of file */ |
| | 3846 | (gdb) c |
| | 3847 | Continuing. |
| | 3848 | }}} |
| | 3849 | |
| | 3850 | === read stack.data.length === |
| | 3851 | * s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko |
| | 3852 | * s0711489@ubuntu-lucid64:~$ cat /proc/stackmod |
| | 3853 | {{{ |
| | 3854 | stack: 0 |
| | 3855 | }}} |
| | 3856 | * s0711489@ubuntu-lucid64:~$ sudo mknod /dev/stack c 251 0 |
| | 3857 | * s0711489@ubuntu-lucid64:~$ sudo chmod 666 /dev/stack |
| | 3858 | * s0711489@ubuntu-lucid64:~$ ls -l |
| | 3859 | {{{ |
| | 3860 | -rw-r--r-- 1 s0711489 s0711489 128657 2011-11-24 01:30 stackmod.ko |
| | 3861 | }}} |
| | 3862 | * s0711489@ubuntu-lucid64:~$ cat stackmod.ko > /dev/stack |
| | 3863 | * s0711489@ubuntu-lucid64:~$ cat /proc/stackmod |
| | 3864 | {{{ |
| | 3865 | stack: 4 |
| | 3866 | stack.data[0].length: 32768 |
| | 3867 | stack.data[1].length: 32768 |
| | 3868 | stack.data[2].length: 32768 |
| | 3869 | stack.data[3].length: 30353 |
| | 3870 | }}} |
| | 3871 | |
| | 3872 | === read /proc causes buffer overflow with deep stack === |
| | 3873 | * s0711489@ubuntu-lucid64:~$ sudo rmmod stackmod |
| | 3874 | * s0711489@ubuntu-lucid64:~$ sudo insmod stackmod.ko entry=1000 |
| | 3875 | * s0711489@ubuntu-lucid64:~$ dd if=/dev/zero of=/dev/stack |
| | 3876 | {{{ |
| | 3877 | dd: writing to `/dev/stack': No space left on device |
| | 3878 | 1001+0 records in |
| | 3879 | 1000+0 records out |
| | 3880 | 512000 bytes (512 kB) copied, 0.0240922 s, 21.3 MB/s |
| | 3881 | }}} |
| | 3882 | * s0711489@ubuntu-lucid64:~$ cat /proc/stackmod |
| | 3883 | {{{ |
| | 3884 | stack: 1000 |
| | 3885 | stack.data[0].length: 512 |
| | 3886 | stack.data[1].length: 512 |
| | 3887 | stack.data[2].length: 512 |
| | 3888 | stack.data[3].length: 512 |
| | 3889 | stack.data[4].length: 512 |
| | 3890 | |
| | 3891 | (snip) |
| | 3892 | |
| | 3893 | stack.data[132].length: 512 |
| | 3894 | stack.data[133].length: 512 |
| | 3895 | stack.data[134].length: 512 |
| | 3896 | }}} |
| | 3897 | * s0711489@ubuntu-lucid64:~$ tailf /var/log/kern.log |
| | 3898 | {{{ |
| | 3899 | Nov 24 01:48:53 ubuntu-lucid64 kernel: [ 1509.351094] /proc/stackmod is read |
| | 3900 | Nov 24 01:48:53 ubuntu-lucid64 kernel: [ 1509.351673] proc_file_read: Apparent buffer overflow! |
| | 3901 | Nov 24 01:48:53 ubuntu-lucid64 kernel: [ 1509.351898] /proc/stackmod is read |
| | 3902 | Nov 24 01:48:53 ubuntu-lucid64 kernel: [ 1509.352482] proc_file_read: Apparent buffer overflow! |
| | 3903 | Nov 24 01:48:53 ubuntu-lucid64 kernel: [ 1509.353412] /proc/stackmod is read |
| | 3904 | Nov 24 01:48:53 ubuntu-lucid64 kernel: [ 1509.353971] proc_file_read: Apparent buffer overflow! |
| | 3905 | }}} |