2009-05-18 42 views
10

有些人可能知道,Microsoft banned memcpy() from their Security Development Lifecycle,用memcpy_s()替換它。Microsoft SDL和memcpy depobation

void *memcpy(void *dest, const void *src, size_t n); 

/* simplified signature */ 
errno_t memcpy_s(void *dst, size_t dstsize, const void *src, size_t n); 

所以,如果用你的代碼是:

if (in_len > dst_len) { 
    /* error */ 
} 
memcpy(dst, src, in_len); 

就變成:

if (memcpy_s(dst, dst_len, src, src_len)) { 
    /* error */ 
} 

或者,用截斷,

memcpy(dst, src, min(in_len, dst_len)); 

VS

(void)memcpy_s(dst, dst_len, src, src_len); 

問題:一個額外的長度參數如何使代碼更安全?要使用memcpy(),我應該已經知道所有四個參數,並將適當的長度作爲第三個參數。什麼阻止了我錯誤地計算目標緩衝區大小和傳遞錯誤值dst_size?我不明白爲什麼它與memcpy()有什麼不同,以及它爲什麼會被棄用。有沒有我看不到的常見用例? 我在這裏錯過了什麼?

+0

閱讀類似的東西,請記住,memcpy_s()是C11附錄K,這是唯一一個的一部分*可選* C11規範的一部分。有幾個編譯器實現者拒絕了附件K,並且永遠不會實現它。所以,只有在定義'__STDC_LIB_EXT1__'時才使用它。 Redhat建議將它從未來的C規範中刪除。 – DavidJ 2017-01-31 22:30:27

回答

14

沒有什麼能阻止你在「安全」版本中獲取錯誤的參數。微軟似乎認爲你總是會使用類似於:

errno_t e = memcpy_s (&dstbuff, sizeof(dstbuff), &srcbuff, sizeof(srcbuff)); 

並檢查錯誤。

但是,這隻能幫助那些不知道他們在用語言做什麼的人。在我看來,這一羣人不應該使用這種語言,或者他們應該學習如何正確運作。

從長遠來看,這類柺杖並沒有給他們任何好處,因爲他們的代碼不會攜帶。

現在可能是微軟做了一些分析,發現人們濫用memcpy()造成了很多問題,他們認爲這會解決它。但是,如果是這樣的話,我懷疑更好的解決方案是教育開發人員,而不是強迫他們使用標準編譯器無法使用的非標準功能。

+3

「從長遠來看,這種柺杖對他們沒有任何好處......」完全同意,Pax。 – ninesided 2009-05-18 07:30:09

+3

第一部分是正確的,第二部分是錯誤的 - 它不是一個柺杖,它實際上更適合那些認爲自己是「語言如何工作」的專家,並且總是在尋找捷徑。正如@ninesided所說,新的「安全」版本讓你思考你在做什麼,並且(希望)不要試圖繞過這種語言。 – AviD 2009-05-18 07:49:08

+0

但是我應該強調的是,你所說的依賴於sizeof(buf)的一般模式是非常好的一點,應該鼓勵它(除非你沒有從緩衝區的開頭做拷貝。 。) – AviD 2009-05-18 07:50:57

4

您不會錯過任何東西,我覺得從文章這個片段您鏈接到幾乎涵蓋它:

如果不出意外,memcpy_s讓你 想想目標 緩衝區的大小。

6

你是絕對正確的。如果您正在跟蹤兩個緩衝區的長度,memcpy可以安全使用。如果你不是,memcpy_s不會拯救你。

1

根據微軟的說法,這將使編寫代碼質量檢查更容易 - 您可以檢查以確保程序員不會將相同的值傳遞給兩個大小參數(許多人可能仍會執行此操作懶惰)。另一件事(實際上並沒有真正與代碼安全性有關)是,你可以使用這種方法清理你的代碼,因爲你的代碼中有很少的檢查 - memcpy_s函數會檢查你是否有足夠的空間目標緩衝區,消除你的一個檢查。

最重要的是,memcpy_s返回一個錯誤代碼,指示整個副本是否成功,但使用memcpy無法確定這一點。 This是Microsoft認爲使得memcpy_smemcpy更安全。

+0

我認爲依靠memcpy_s來做普通的邏輯檢查是不好的做法,我相信即使是那些主張這個功能的人也會同意。 – 2009-05-18 07:55:03

+0

我同意 - 推理線不是我的,但微軟的 - 我已更新我的評論,使之更清晰。第二部分是我的看法,但我不認爲代碼清晰是禁止此功能的一個重要原因。 – 2009-05-18 08:07:10

8

信息的複製總是不好的設計 - 它只是給你更多的機會來弄錯。當涉及到API設計時,微軟有了一個非常好的記錄,並且只有通過其文檔的卓越才能保存過去。令人欣慰的是,它們無法刪除原來的memcpy()函數 - 它是ANSI C的一部分。

+1

+1我同意。我認爲MS和其他低級別「硬核」程序員應該處理的主要安全問題是緩衝區溢出。其他任何東西都可以(應該)通過強類型語言(C#,Java,Ada等)進行檢查。 – ATorras 2009-05-18 08:37:20

+1

「他們無法刪除原始的memcpy()函數」 - 但他們可以做的事情是讓它吐出警告。如果他們想要,他們可以使這些警告很難或不可能被忽視。 – 2009-06-04 10:47:20

-1

實際上,我確實有點遺憾,真的沒有很多真正的程序員在世界上離開了,機器是什麼,愛是什麼,並且喜歡轉移位。有一點我知道,但我想知道到底發生了什麼事情,並且明確地不希望任何蹩腳的屁股垃圾收集器繞着背景絕望地嘗試清理雜亂無章的程序員。我的意思是,將free()調用與malloc()/ strdup()調用進行匹配有多困難,要確保您已經分配了足夠的緩衝區空間以確保可以調用memcpy()函數有多難?答:並不是很多,但有99.9%的程序員真的不在乎他們在做什麼,因爲他們只是爲了錢而不是在寫一些冗長的代碼。

End Rant。

0

Ç形組件是那些知道自己在做什麼的人,我記得direcly給K & [R