安全函數(shù)整改——內(nèi)存溢出、內(nèi)存泄漏和內(nèi)存越界

由于身體不舒服,再加上去華為實習(xí)沒時間。太久沒有更新學(xué)習(xí)比筆記了,希望能保持記錄學(xué)習(xí)中的點點滴滴小知識
內(nèi)存溢出:(Out Of Memory---OOM)

系統(tǒng)已經(jīng)不能再分配出你所需要的空間,比如你需要100M的空間,系統(tǒng)只剩90M了,這就叫內(nèi)存溢出

例子:一個盤子用盡各種方法只能裝4個果子,你裝了5個,結(jié)果掉倒地上不能吃了。這就是溢出。比方說棧,棧滿時再做進棧必定產(chǎn)生空間溢出,叫上溢,??諘r再做退棧也產(chǎn)生空間溢出,稱為下溢。就是分配的內(nèi)存不足以放下數(shù)據(jù)項序列,稱為內(nèi)存溢出。說白了就是我承受不了那么多,那我就報錯。

內(nèi)存泄漏: (Memory Leak)

是指程序在申請內(nèi)存后,無法釋放已申請的內(nèi)存空間,一次內(nèi)存泄露危害可以忽略,但內(nèi)存泄露堆積后果很嚴重,無論多少內(nèi)存,遲早會被占光。

一般我們所說的內(nèi)存泄漏是指堆內(nèi)存的泄漏,堆內(nèi)存是指程序從堆中分配的,大小任意的(內(nèi)存塊的大小可以在程序運行期決定),使用完成之后必須顯示釋放內(nèi)存。應(yīng)用程序一般使用malloc、realoc、new等函數(shù)從堆中分配到一塊內(nèi)存塊,使用完成后,程序必須負責(zé)相應(yīng)的釋放。在C中使用free(),C++中delete、delete[]、free()

例子:你向系統(tǒng)申請分配內(nèi)存進行使用(new),可是使用完了以后卻不歸還(delete),結(jié)果你申請到的那塊內(nèi)存你自己也不能再訪問(也許你把它的地址給弄丟了),而系統(tǒng)也不能再次將它分配給需要的程序。就相當(dāng)于你租了個帶鑰匙的柜子,你存完東西之后把柜子鎖上之后,把鑰匙丟了或者沒有將鑰匙還回去,那么結(jié)果就是這個柜子將無法供給任何人使用,也無法被垃圾回收器回收,因為找不到他的任何信息。

內(nèi)存越界

是指向系統(tǒng)申請一塊內(nèi)存后,使用時卻超出申請范圍。

? 數(shù)組越界

數(shù)組越界錯誤主要包括數(shù)組下標(biāo)取值越界和指向數(shù)組的指針的指向范圍越界。

? 避免操作內(nèi)存的函數(shù)造成越界:

比如sprintf、strcpy、strcat、vsprintf、memcpy、memset、memmove。在編程軍規(guī)中也有明確的規(guī)定。如下:

【軍規(guī)4 】:內(nèi)存拷貝前必須進行長度有效性判斷,避免內(nèi)存越界

引申:避免使用魔鬼數(shù)字來進行人工計算字符長度,引起內(nèi)存越界。

例如:memcpy_s

復(fù)制源緩沖區(qū)的數(shù)據(jù)到目的緩沖區(qū)。


errno_t memcpy_s(

   void* dest,

   size_t destMax,

   const void* src,

   size_t count

)

參數(shù)

dest
[In/Out] 目的緩沖區(qū)
destMax
[In] 目的緩沖區(qū)大小
src
[In]源緩沖區(qū)
count
[In] 從源緩沖區(qū)中復(fù)制的字符數(shù)

錯誤碼

image.png

其它情況,操作成功,返回值EOK(0)。

注意

  1. 確保入?yún)⒄_:

    a. 拷貝長度參數(shù)和目的緩沖區(qū)大小參數(shù)要大于0且小于等于SECUREC_MEM_MAX_LEN;

    b. 目的緩沖區(qū)大小參數(shù)不能超過目的緩沖區(qū)的實際長度、且大于等于要拷貝長度,以便目的緩沖區(qū)有足夠的空間來保存要復(fù)制的內(nèi)容;

    c. 源緩沖區(qū)和目的緩沖區(qū)不能為NULL、且源和目的不存在重疊。

2、調(diào)用函數(shù)時,必須對返回值進行檢查,確保返回值正確后再進行后續(xù)操作。

注意:在源緩沖區(qū)為NULL、拷貝長度大于目的緩沖區(qū)大小參數(shù)、源和目的重疊的情況下,函數(shù)會將目的緩沖區(qū)大小參數(shù)確定的目的緩沖區(qū)范圍清零。

之所以會對安全函數(shù)整改,需要明確不是使用了安全函數(shù)就絕對安全。安全函數(shù)安全性基于調(diào)用者傳入了正確參數(shù),特別是緩沖區(qū)長度一定要正確。安全函數(shù)將傳入的長度參數(shù)作為緩沖區(qū)的邊界,只保證執(zhí)行結(jié)果不會溢出用戶所指定的邊界。如果傳入的緩沖區(qū)長度參數(shù)超過實際緩沖區(qū)大小,依然可能會溢出。

如下就是目的緩沖區(qū)pucBlock的大小有問題,memcpy中為了方便,很多都寫成了2,4參數(shù)一致。這樣就存在2參數(shù)不是1參數(shù)的實際大小。雖然在拷貝的時候可能不會出現(xiàn)問題,但為了安全還是應(yīng)該認真檢查四個參數(shù),并確保使用正確。

修改前: iRet = memcpy_s( (VOS_VOID *)pucBlock,IPV6_ADDR_LEN, (VOS_VOID *)pucIpV6, IPV6_ADDR_LEN );

修改后:iRet = memcpy_s( (VOS_VOID *)pucBlock, DB_IP_PORT, (VOS_VOID *)pucIpV6, IPV6_ADDR_LEN );

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容