| 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 | }}} |