This is an old revision of the document!
Table of Contents
Linux Stack Overflow and Buffer Over
| Reference | Linux Kernel Stack |
kernel Stack
exception/hard IRQ/soft IRQ stack
hardware stack: hardirt_stack array softIRQ stack: softirt_stack array
kernel Stack OverFlow
Tools
checkstack.pl
checkstack.pl creates a listing of the size of the stack frame used by every function in the kernel (i.e. the total amount of local scratch space used by each function for local variables and whatnot).
The way it does this is by going through the disassembly of the kernel and looking for 2 things: function names and instructions which adjust the stack. It looks for function names by looking for lines that match $funcre (qr/^$x* <(.*)>:$/), and it looks for stack adjustment instructions that match $re or $dre; the latter two depend highly on what architecture the kernel was compiled for, which is what the first big block if if/else statements is checking for. $re searches for functions which adjust the stack by a fixed amount (the vast majority of functions), and $dre searches for functions which adjust the stack by a variable amount (rare).
$CROSS_COMPILE)objdump -d vmlinux | scripts/checkstack.pl [arch]
Example:
- mips-openwrt-linux-objdump -d vmlinux | scripts/checkstack.pl mips
Its output like below:
0x803feed4 match [vmlinux]: 3184 0x803fedc8 mangle_http_header.constprop.2 [vmlinux]: 2096 0x80045da8 mtsched_proc_write [vmlinux]: 1088 0x801119c0 do_sys_poll [vmlinux]: 952 0x802fa7ac pce_rule_write [vmlinux]: 848 0x8033daec of_get_dma_window [vmlinux]: 832 0x80110c78 do_select [vmlinux]: 752 0x802ed918 GSW_MulticastRouterPortRemove [vmlinux]: 664 0x802edd68 GSW_MulticastSnoopCfgSet [vmlinux]: 664 0x802f1cb4 GSW_PortRedirectSet [vmlinux]: 664 0x802ed610 GSW_MulticastRouterPortAdd [vmlinux]: 656 0x802f3908 GSW_8021X_EAPOL_RuleSet [vmlinux]: 632 0x802e6b30 GSW_STP_BPDU_RuleSet [vmlinux]: 624 0x8023a820 test_pcomp [vmlinux]: 600 0x8022a7d8 semctl_main [vmlinux]: 584 0x8023ade4 test_comp [vmlinux]: 584 0x8022b4e0 SyS_semtimedop [vmlinux]: 520 0x80038ff8 dma_build_device_chan_tbl [vmlinux]: 504 0x801298ac default_file_splice_read [vmlinux]: 496 0x8023b690 __test_skcipher [vmlinux]: 496 0x80163cd0 elf_kcore_store_hdr [vmlinux]: 464 0x801a5110 nlmsvc_mark_resources [vmlinux]: 432 0x802e2120 proc_write_directpath [vmlinux]: 432 0x80412190 copy_to_user_tmpl.part.33 [vmlinux]: 432 0x802a80bc loop_get_status_old [vmlinux]: 408 0x80197de0 nfs_dns_parse [vmlinux]: 400 0x802a7d58 loop_set_status_old [vmlinux]: 400 0x800d50b4 shmem_file_splice_read [vmlinux]: 368 0x80129268 __generic_file_splice_read [vmlinux]: 368 0x80129c08 vmsplice_to_pipe [vmlinux]: 368 0x801aabc8 autofs4_notify_daemon [vmlinux]: 368 0x8034c8b8 skb_splice_bits [vmlinux]: 352 0x800c2c3c show_free_areas [vmlinux]: 344 0x8037053c dev_seq_printf_stats [vmlinux]: 344 0x803b0e8c do_ip_setsockopt.isra.17 [vmlinux]: 344 0x80592c94 init_posix_timers [vmlinux]: 344 0x801111ac core_sys_select [vmlinux]: 336 0x8030adb4 tmu_proc_tmu_cascade_write [vmlinux]: 336 0x803b0214 do_ip_getsockopt.constprop.18 [vmlinux]: 328 0x80122c88 setxattr [vmlinux]: 320 0x80147660 elf_core_dump [vmlinux]: 320 0x8023d1c0 test_hash [vmlinux]: 320 0x803d8df0 __udp4_lib_mcast_deliver.isra.55 [vmlinux]: 320 0x800895e4 sched_domain_debug_one.constprop.66 [vmlinux]:312 0x8015f668 show_stat [vmlinux]: 312 0x801ac09c autofs4_expire_run [vmlinux]: 312 0x8027d7f4 store_mode [vmlinux]: 312 0x802b9aa4 mtdchar_ioctl [vmlinux]: 312 0x80122880 getxattr [vmlinux]: 304 0x8015f304 meminfo_proc_show [vmlinux]: 304 0x8019e460 exportfs_decode_fh [vmlinux]: 304 0x803696b8 rtnl_newlink [vmlinux]: 304 0x80396de0 conntrack_pptp_help [vmlinux]: 304
stack_size
Below are some results for static analysis of function stack depth in the Linux kernel, using 'stack_size'. (stack_size is a custom tool written by Tim Bird, before he found out about checkstack.pl.) https://lkml.org/lkml/2011/10/18/479
$ ./stack_size vmlinux-arm
============ RESULTS =============== number of functions = 14371 max function stack depth= 736 function with max depth = nlmclnt_reclaim Function Name Stack Depth ===================== =========== __generic_file_splice_read 352 do_select 376 loop_set_status_old 392 snd_ctl_elem_add_user 408 extract_buf 432 default_file_splice_read 472 sys_semtimedop 520 semctl_main.clone.7 560 do_sys_poll 568 nlmclnt_reclaim 736
CONFIG_DEBUG_STACK_USAGE / CONFIG_DEBUG_STACKOVERFLOW
# dmesg | grep greatest
kworker/u:0 used greatest stack depth: 10564 bytes left busybox used greatest stack depth: 9512 bytes left busybox used greatest stack depth: 9504 bytes left grep used greatest stack depth: 9372 bytes left init used greatest stack depth: 9028 bytes left
#echo t >/proc/sysrq-trigger #dmesg | grep -v [[]
task PC stack pid father init S 802af8b0 932 1 0 0x00000000 kthreadd S 802af8b0 2496 2 0 0x00000000 ksoftirqd/0 S 802af8b0 2840 3 2 0x00000000 kworker/0:0 S 802af8b0 2776 4 2 0x00000000 kworker/u:0 S 802af8b0 2548 5 2 0x00000000 migration/0 S 802af8b0 2704 6 2 0x00000000 migration/1 S 802af8b0 2704 7 2 0x00000000 kworker/1:0 S 802af8b0 2560 8 2 0x00000000 ksoftirqd/1 S 802af8b0 3024 9 2 0x00000000 khelper S 802af8b0 2824 10 2 0x00000000 sync_supers S 802af8b0 2872 11 2 0x00000000 bdi-default S 802af8b0 2584 12 2 0x00000000 kblockd S 802af8b0 2824 13 2 0x00000000 khubd S 802af8b0 2744 14 2 0x00000000


