今天在fortify代碼掃描的時候檢測出一個HOT,漏洞類型是Buffer Overflow,元兇是sprintf。
1
sprintf(aTmp, "16.2f", TransAmt);
其中aTmp是20位字符數組,TransAmt為double型金額字段,值不確定。
理論上來說,是TransAmt按照格式16.2f寫進aTmp的時候,有可能產生越界的錯誤。我一開始考慮將aTmp長度放長后,double應該可以順利拷進aTmp,嘗試將aTmp的長度分配到50,100,200,還是消除不掉這個HOT,因為不明白是double所表示的浮點數的長度有可能超過200位還是fortify認死理,而銀行又強制規定代碼掃描不能有HOT(-。-),所以將sprintf替換成snprintf。
1
snprintf(aTmp, sizeof(aTmp), "16.2f", TransAmt);
需要注意的一點是,第二個參數的值。網上有人提到寫成snprintf(buf, 10, "%10s", p)其實是不對的,因為這里的長度,是包括結束符0x00的,也就是說,既然需要按照%10s格式化,那么這里的第二個參數必須寫成11而不是10。
相似的,strcpy等不帶長度的字符串操作函數,如果不注意寫法,往往會有Buffer Overflow的隱患。這時候,一般來說以strncpy等類似的帶長度參數的函數替換就可以避免漏洞的產生。
另外,在網上查這個問題的時候,看到一個關于sprintf和snprintf的自拷貝的問題。
1
sprintf(buf, "%s world\n", buf);
因為我自己有時候也會有這種寫法,但也是不太確定會不會有問題。既然網上已經有明確的研究了,那我就直接拿結論。
關于這兩個函數的自拷貝問題,在不同的編譯器上,結果不同。編譯器可以有不同的策略,有的簡單的把原先的值抹去,有的會保留。因此,一般來說,我們應該盡量避免這種寫法。
posted on 2010-02-09 23:25
RayRiver 閱讀(2130)
評論(0) 編輯 收藏 引用 所屬分類:
C/C++