⑴ 怎麼解決 linux 堆棧溢出內存的問題
【緩沖區溢出的處理】
你屋子裡的門和窗戶越少,入侵者進入的方式就越少……
由於緩沖區溢出是一個編程問題,所以只能通過修復被破壞的程序的代碼而解決問題。州隱如果你沒有源代碼,從上面「堆棧溢出攻擊」的原理可以看出,要防止此類攻擊,我們可以:
① 開放程序時仔細檢查溢出情況,不允許數據溢出緩沖區。由於編程和編程語言的原因,這非常困難,而且不適合大量已經在使用的程序;
② 使用檢查堆棧溢出的編譯器或者在程序中加入某些記號,以便程序運行時確認禁止黑客有意造成的溢出。問題是無法針對已有程序,對新程序來講,需要修改編譯器;
③ 經常檢查你的操作系統和應用程序提供商的站點,一旦發現他們提供的補丁程序,就馬上下載並且應用在系統上,這是最好的方法。但是系統管理員總要比攻擊者慢 一步,如果這個有問題的軟體是可選的,甚團頃至是臨時的,把它從你的系統中刪除。舉另外一個例 子,你屋子裡的門和窗戶越少,入侵者進入的方式就越少。
----------------------------------------------------------------------------------------------------------------------------------------
char buf[3];
memset(buf,0x55,10);
這個程序就存在溢出
對數據塊的訪問超出該數據塊的地址范圍
===================================================================================
【一個檢測工具】
Valgrind 是一款 Linux下(支持 x86、x86_64和ppc32)程序的內存調試工具,它可以對編譯後的二進製程序進行內存使用監測(C語言中的 malloc 和 free,以及 C++ 中的 new 和 delete),找出內存泄漏問題。
Valgrind 中包含的冊或廳 Memcheck 工具可以檢查以下的程序錯誤:
使用未初始化的內存 (Use of uninitialised memory)
使用已經釋放了的內存 (Reading/writing memory after it has been free』d)
使用超過 malloc 分配的內存空間(Reading/writing off the end of malloc』d blocks)
對堆棧的非法訪問(Reading/writing inappropriate areas on the stack)
申請的空間是否有釋放(Memory leaks – where pointers to malloc』d blocks are lost forever)
malloc/free/new/delete 申請和釋放內存的匹配(Mismatched use of malloc/new/new [] vs free/delete/delete [])
src 和 dst 的重疊(Overlapping src and dst pointers in memcpy() and related functions)
重復 free
① 編譯安裝 Valgrind:
# wget http://valgrind.org/downloads/valgrind-3.4.1.tar.bz2
# tar xvf valgrind-3.4.1.tar.bz2
# cd valgrind-3.4.1/
# ./configure
…………
Primary build target: X86_LINUX
Secondary build target:
Default supp files: exp-ptrcheck.supp xfree-3.supp xfree-4.supp glibc-2.X-drd.supp glibc-2.34567-NPTL-helgrind.supp glibc-2.5.supp
# make
# make install
# whereis valgrind
valgrind:
/usr/bin/valgrind
/usr/lib/valgrind
/usr/local/bin/valgrind
/usr/local/lib/valgrind
/usr/include/valgrind
/usr/share/man/man1/valgrind.1.gz
運行程序
使用示例:對「ls」程序進程檢查,返回結果中的「definitely lost: 0 bytes in 0 blocks.」表示沒有內存泄漏。
# /usr/local/bin/valgrind --tool=memcheck --leak-check=full ls /
==29801== Memcheck, a memory error detector.
==29801== Copyright (C) 2002-2008, and GNU GPL'd, by Julian Seward et al.
==29801== Using LibVEX rev 1884, a library for dynamic binary translation.
==29801== Copyright (C) 2004-2008, and GNU GPL'd, by OpenWorks LLP.
==29801== Using valgrind-3.4.1, a dynamic binary instrumentation framework.
==29801== Copyright (C) 2000-2008, and GNU GPL'd, by Julian Seward et al.
==29801== For more details, rerun with: -v
==29801==
bin etc lost+found mnt proc selinux sys usr
boot home media net root smokeping tftpboot var
dev lib misc opt sbin srv tmp
==29801==
==29801== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 21 from 1)
==29801== malloc/free: in use at exit: 14,744 bytes in 32 blocks.
==29801== malloc/free: 162 allocs, 130 frees, 33,758 bytes allocated.
==29801== For counts of detected errors, rerun with: -v
==29801== searching for pointers to 32 not-freed blocks.
==29801== checked 139,012 bytes.
==29801==
==29801== LEAK SUMMARY:
==29801== definitely lost: 0 bytes in 0 blocks.
==29801== possibly lost: 0 bytes in 0 blocks.
==29801== still reachable: 14,744 bytes in 32 blocks.
==29801== suppressed: 0 bytes in 0 blocks.
==29801== Reachable blocks (those to which a pointer was found) are not shown.
==29801== To see them, rerun with: --leak-check=full --show-reachable=yes
----------------------------------------------------------------------------------------------------------------------------------------
# /usr/local/bin/valgrind --tool=memcheck --leak-check=full ps /
==29898== Memcheck, a memory error detector.
==29898== Copyright (C) 2002-2008, and GNU GPL'd, by Julian Seward et al.
==29898== Using LibVEX rev 1884, a library for dynamic binary translation.
==29898== Copyright (C) 2004-2008, and GNU GPL'd, by OpenWorks LLP.
==29898== Using valgrind-3.4.1, a dynamic binary instrumentation framework.
==29898== Copyright (C) 2000-2008, and GNU GPL'd, by Julian Seward et al.
==29898== For more details, rerun with: -v
==29898==
ERROR: Garbage option.
********* simple selection ********* ********* selection by list *********
-A all processes -C by command name
-N negate selection -G by real group ID (supports names)
-a all w/ tty except session leaders -U by real user ID (supports names)
-d all except session leaders -g by session OR by effective group name
-e all processes -p by process ID
T all processes on this terminal -s processes in the sessions given
a all w/ tty, including other users -t by tty
g OBSOLETE -- DO NOT USE -u by effective user ID (supports names)
r only running processes U processes for specified users
x processes w/o controlling ttys t by tty
*********** output format ********** *********** long options ***********
-o,o user-defined -f full --Group --User --pid --cols --ppid
-j,j job control s signal --group --user --sid --rows --info
-O,O preloaded -o v virtual memory --cumulative --format --deselect
-l,l long u user-oriented --sort --tty --forest --version
-F extra full X registers --heading --no-heading --context
********* misc options *********
-V,V show version L list format codes f ASCII art forest
-m,m,-L,-T,H threads S children in sum -y change -l format
-M,Z security data c true command name -c scheling class
-w,w wide output n numeric WCHAN,UID -H process hierarchy
==29898==
==29898== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 14 from 1)
==29898== malloc/free: in use at exit: 16 bytes in 2 blocks.
==29898== malloc/free: 20 allocs, 18 frees, 2,344 bytes allocated.
==29898== For counts of detected errors, rerun with: -v
==29898== searching for pointers to 2 not-freed blocks.
==29898== checked 263,972 bytes.
==29898==
==29898== 8 bytes in 1 blocks are definitely lost in loss record 2 of 2
==29898== at 0x4005A88: malloc (vg_replace_malloc.c:207)
==29898== by 0xBFF6DF: strp (in /lib/libc-2.5.so)
==29898== by 0x804A464: (within /bin/ps)
==29898== by 0x804A802: (within /bin/ps)
==29898== by 0x804964D: (within /bin/ps)
==29898== by 0xBA5E8B: (below main) (in /lib/libc-2.5.so)
==29898==
==29898== LEAK SUMMARY:
==29898== definitely lost: 8 bytes in 1 blocks.
==29898== possibly lost: 0 bytes in 0 blocks.
==29898== still reachable: 8 bytes in 1 blocks.
==29898== suppressed: 0 bytes in 0 blocks.
==29898== Reachable blocks (those to which a pointer was found) are not shown.
==29898== To see them, rerun with: --leak-check=full --show-reachable=yes
⑵ Linux 怎麼查看一個進程的堆棧
方法一:pstack pid
NAME
pstack - print a stack trace of a running process
SYNOPSIS
pstack pid
DESCRIPTION
pstack attaches to the active process named by the pid on the command line, and prints out an execution stack trace. If ELF symbols exist in the binary (usually the case
unless you have run strip(1)), then symbolic addresses are printed as well.
If the process is part of a thread group, then pstack will print out a stack trace for each of the threads in the group.
SEE ALSO
nm(1), ptrace(2), gdb(1)
方法二:gstack pid
NAME
gstack - print a stack trace of a running process
SYNOPSIS
gstack pid
DESCRIPTION
gstack attaches to the active process named by the pid on the command line, and prints out an execution stack trace. If ELF symbols exist in the binary (usually the case
unless you have run strip(1)), then symbolic addresses are printed as well.
If the process is part of a thread group, then gstack will print out a stack trace for each of the threads in the group.
SEE ALSO
nm(1), ptrace(2), gdb(1)
方胡敬升法三:
使用gdb 然後attach 進程ID,然後再使用命令 thread apply all bt。
方法一和褲老方法二一樣,方法三可以查看更多稿拿的信息。
⑶ 在linux系統下使用內存技術,檢測堆越界錯誤
一般使用c或cpp編程時,堆棧越界訪問(read/write)往往會引起很多意想不到的錯誤,比如延後的進程崩潰等。因此,如果有一種方法,可以讓越界訪問立即觸發系統錯誤(讓進程拋出異常而終止,再生成coremp文件),就可以立即檢測出內存越界行為,並將對這種隱藏的錯誤,及時作出反應,以免在生產環境下造成更大粗唯沖的損失。
我們知道,在windows系統下面,我們可以使用VirtualAlloc系列函數,通過申請2頁內存,並設置某頁的保護參數(比如,可讀,可寫等),就可以實現類似的保護機制。這樣,當我們對新增加的類(數據結構),就可以重載operator new/delete,將類的邊界設置到一頁的邊緣,再將相鄰頁設置為不可讀不可寫。這樣就能有效監測堆越界讀寫問題。而且可以,設置某個編譯宏,比如PROTECT_CLASSX。演示代碼如下:
在linux下,則需要藉助mmap和mprotect來實現這個機制。具體步驟如下,首先用mmap使用PROT_NONE映射一個特殊文件,比如/岩殲dev/zero(或者使用MAP_ANONYMOUS),然後再用mprotect提交內存。上面的例子,可以繼續使用,但是只列出來核心的代碼,什麼重載操作符就不寫了,另外,內存映射文件j句柄最好用內存山族池來hold,最後在close掉。演示代碼只說明大致用法,並不能直接拿來用。
下面補充mprotect的用法:
再把mmap函數的用法示例如下:
⑷ Redhat Linux中怎樣自動設置線程堆棧大小
不是可以直接用線程屬性進行設置嗎?
我寫了一個小程序。如下:
#include <pthread.h>
#include <limits.h>#define Thread_NUM 5void *MultiThread_soap_serve(){ sleep(5); printf("new pthread!!\n");}//PTHREAD_STACK_MIN 經過計算是16K。//64*16K = 1M,線程堆棧應該是夠用的。#define MICHAEL_SET_PTHREAD_STACK_SIZE 64int main(){ pthread_attr_t attr; pthread_attr_init(&attr); size_t stacksize = MICHAEL_SET_PTHREAD_STACK_SIZE*PTHREAD_STACK_MIN; //stacksize =PTHREAD_STACK_MIN; //stackaddr=(void*)malloc((N+1)*PTHREAD_STACK_MIN); //pthread_attr_getstack(&attr,&statckattr,&stacksize); //pthread_attr_setstack(&attr,stackaddr,); pthread_attr_setstacksize(&attr,stacksize); int iThreadNum = 0; pthread_t PSoapThread[Thread_NUM]; for ( ; iThreadNum < Thread_NUM ; iThreadNum++ ) { pthread_create(&PSoapThread[iThreadNum],&attr,MultiThread_soap_serve,(void *)NULL); } pthread_attr_destroy(&attr); while(1) { sleep(10); printf("main!!\n"); }}
⑸ linux16g內存分配多少java堆內存
linux16g內存分配 -Xmxjava堆內存
以WAS為例:
[tmp]$ ps -ef | grep jav
root 9787 1 0 Sep17 ? 00:02:48 /opt/IBM/WebSphere/AppServer/java/bin/java Xms50m -Xmx256m-Xms 和 -Xmx 分別代表分配JVM的最小內存和最大內存。堆棧信息你可以用 kill -3 後斗稿簡面跟上java進程的pid,這樣就能生成 thread mp 了。
具體如下:
簡介C語言是一門通用計算機編程語言,應用廣泛。C語言的設計目標是提供一種能以簡易的方式編譯、處空褲理低級存儲器、產生少量的機器碼以及不需要任何運行環境支持便能運行的編程語言。盡管C語言提供了許多低級處理的功能,但仍然保持著良好跨平台的特性,以一個標准規格寫出的C語言程序可在許多電腦平台上進行編譯,甚至包含一敬鉛些嵌入式處理器(單片機或稱MCU)以及超級電腦等作業平台。
⑹ Linux內核中用戶空間棧和內核棧的區別
您好,很高興為您解答。
1.進程的堆棧
內核在創建進程的時候,在創建task_struct的同事,會為進程創建相應的堆棧。每個進程會有兩個棧,一個用戶棧,存在於用戶空間,一個內核棧,存在於內核空間。當進程在用戶空間運行時,cpu堆棧指針寄存器裡面的內容是用戶堆棧地址,使用用戶棧;當進程在內核空間時,cpu堆棧指針寄存器裡面的內容是內核棧空間地址,使用內核棧。
2.進程用戶棧和內核棧的切換
當進程因為中斷或者系統調用而陷入內核態之行時,進程所使用的堆棧也要從用戶棧轉到內核棧。
進程陷入內核態後,先把用戶態堆棧的地址保存在內核棧之中,然後設置堆棧指針寄存器的內容為內核棧的地址,這樣就完成了用戶棧向內核棧的轉換;當進程從內核態恢復到用戶態之行時,在內核態之行的最後將保存在內核棧裡面的用戶棧的地址恢復到堆棧指針寄存器即可。這樣就實現了內核棧和用戶棧的互轉。
那麼,我們知道從內核轉到用戶態時用戶棧的地址是在陷入內核的時候保存在內核棧裡面的,但是在陷入內核的時候,我們是如何知道內核棧的地址的呢?
關鍵在進程從用戶態轉到內核態的時候,進程的內核棧總是空的。這是因為,當進程在用戶態運行時,使用的是用戶棧,當進程陷入到內核態時,內核棧保存進程在內核態運行的相關信心,但是一旦進程返回到用戶態後,內核棧中保存的信息無效,會全部恢復,因此每次進程從用戶態陷入內核的時候得到的內核棧都是空的。所以在進程陷入內核的時候,直接把內核棧的棧頂地址給堆棧指針寄存器就可以了。
3.內核棧的實現
內核棧在kernel-2.4和kernel-2.6裡面的實現方式是不一樣的。
在kernel-2.4內核裡面,內核棧的實現是:
union task_union {
struct task_struct task;
unsigned long stack[init_stack_size/sizeof(long)];
}; 其中,init_stack_size的大小隻能是8k。
內核為每個進程分配task_struct結構體的時候,實際上分配兩個連續的物理頁面,底部用作task_struct結構體,結構上面的用作堆棧。使用current()宏能夠訪問當前正在運行的進程描述符。
注意:這個時候task_struct結構是在內核棧裡面的,內核棧的實際能用大小大概有7k。
內核棧在kernel-2.6裡面的實現是(kernel-2.6.32):
union thread_union {
struct thread_info thread_info;
unsigned long stack[thread_size/sizeof(long)];
}; 其中thread_size的大小可以是4k,也可以是8k,thread_info佔52bytes。
當內核棧為8k時,thread_info在這塊內存的起始地址,內核棧從堆棧末端向下增長。所以此時,kernel-2.6中的current宏是需要更改的。要通過thread_info結構體中的task_struct域來獲得於thread_info相關聯的task。更詳細的參考相應的current宏的實現。
struct thread_info {
struct task_struct *task;
struct exec_domain *exec_domain;
__u32 flags;
__u32 status;
__u32 cpu;
… ..
}; 注意:此時的task_struct結構體已經不在內核棧空間裡面了。
如若滿意,請點擊右側【採納答案】,如若還有問題,請點擊【追問】
希望我的回答對您有所幫助,望採納!
~
o(∩_∩)o~
⑺ linux 設置堆棧大小 為無限制
你好。
執行命令ulimit -a,查看棧大小的限制。
通過使用 ulimit -s 數字 進行設置。
⑻ Linux進程內存如何管理
Linux系統提供了復雜的存儲管理系統,使得進程所能訪問的內存達到4GB。在Linux系統中,進程的4GB內存空滑物間被分為兩個部分—顫讓掘—用戶空間與內核空間。用戶空間的地址一般分布為0~3GB(即PAGE_OFFSET,在Ox86中它等於OxC0000000),這樣,剩下的3~4GB為內核空間,用戶進程通常只能訪問用戶空間的虛擬地址,不能訪問內核空間的虛擬地址。用戶進程只有通過系統調用(代表用戶進程在內核態執行)等方式才可以訪問到內核空間。每個進程的用戶空間都是完全獨立、互不相乾的,用戶進程各自有不同的頁表。而內核空間是由內核負責映射,它並不會跟著進程改變,是固定的。內核空間的虛擬地址到物理地址映射是被所有進程共享的,內核的虛擬空間獨立於其他程序。Linux中1GB的內核地址空間又被劃分為物理內存映射區、虛擬內存分配區、高端頁面映射區、專用頁面映射區和系統保留映射區這幾個區域。對於x86系統而言,一般情況下,物理內存映射區最大長度為896MB,系統的物理內存被順序映射在內核空間的這個區域中。當系統物理內存大於896MB時,超過物理內存映射區的那部分內存稱為高端內存(而未超過物理內存映射區的內存通常被稱為常規內存),內核在存取高端內存時必須將它們映射到高端頁面映射區。Linux保留內核空間最頂部FIXADDR_TOP~4GB的區域作為保留區。當系統物理內存超過4GB時,必須使用CPU的擴展分頁(PAE)模式所提供的64位頁目錄項才能存取到4GB以上的物理內存,這需要CPU的支持。加入了PAE功能的Intel Pentium Pro及以後的CPU允許內存最大可配置到64GB,它們茄核具備36位物理地址空間定址能力。由此可見,對於32位的x86而言,在3~4GB之間的內核空間中,從低地址到高地址依次為:物理內存映射區隔離帶vmalloc虛擬內存分配器區隔離帶高端內存映射區專用頁面映射區保留區。
⑼ linux系統最大堆棧內存
linux系統最大堆棧消搜內存是-Xmx512m。根據查找相關公開資料顯敏簡示,linux系統堆棧大小拿拿歷的配置啟動參數,初始堆大小-Xms32m最大堆大小-Xmx512m。