→ applecool:似乎是無解 10/24 22:10
→ scwg: signal handler + longjump? 10/24 22:14
→ applecool:我好好研究一下,好像沒有直接的方式 10/24 22:35
→ applecool:memcpy 本身好像不會丟 signal 出來 10/24 22:36
→ applecool:而且我只要偵測某一段的 memcpy,而不是整個code... 10/24 22:36
→ applecool:沒用過 signal 得好好研究,所以這是明路?總之感謝! 10/24 22:37
→ Schottky:如果你講的是事後偵測而不是當下偵測, 有一個常用的方法 10/24 22:41
→ Schottky:allocate memory 時前後各多 allocate 1KB, 整塊填滿固定 10/24 22:42
→ Schottky:pattern, 我喜歡填 ~*^.<*~ 加空白共八 bytes 10/24 22:43
→ Schottky:然後就很容易看見是否有寫到不該寫的區域 10/24 22:44
→ applecool:那讀取呢? 10/24 23:02
→ Schottky:讀取用 boundary check 比較容易, 也就是在每個讀取時機 10/24 23:05
→ Schottky:檢查 pointer(address) 是否已經是界外球了... 10/24 23:05
推 Arim:GDB不行嗎? 10/24 23:05
→ cyrano:AddressSanitizer ? 10/24 23:22
→ Slither:windows -> SEH? 10/25 07:12
→ applecool:因為是要寫給 user 用的,傳進來的是 void * 10/25 08:26
→ applecool:請問要怎麼用 boundary check 阿 10/25 08:26
推 Bencrie:存取到非法的記憶體位址不見得會觸發 segfault 10/25 10:52
→ Bencrie:用 signal handler 還是有可能漏網 10/25 10:52
→ Bencrie:如果沒有一定要在程式裡偵測的話就用 valgrind 吧 10/25 10:53
→ applecool:唉~需要在程式裡面偵測,看來又是無解的一題 10/25 22:57
→ applecool:感謝各位了!! 10/25 22:58
→ Schottky:傳進指標來的時候沒有要求上層必須一併傳size進來嗎? 10/25 22:59
→ Schottky:不照size使用記憶體是你的錯,傳進來的size不符是他的錯 10/25 23:00
→ applecool:理論上是這樣,但實際上是當在誰那邊誰就要解.... 10/25 23:01
→ Schottky:要做boundary check首先要定義boundary啊... 10/25 23:01
→ Schottky:你只要證明是對方傳進來的size有誤就可以把問題踢回去 10/25 23:02
→ applecool:是阿...不過實務上有難言之隱阿 10/25 23:02
→ Schottky:不釐清責任歸屬再debug一百年還是無解,程式不是這樣寫滴 10/25 23:02
→ applecool:所以要想辦法回傳 error code 10/25 23:03
→ Schottky:那只有一個可能做法,他allocate的記憶體也是你allocate的 10/25 23:05
→ Schottky:你自己做記憶體管理才有機會知道boundary在哪 10/25 23:05
→ applecool:恩恩感謝,看來是無解了 10/25 23:22
→ Schottky:前提是你要先確定自己的程式是對的! 所以還是要檢查 10/25 23:22
推 EdisonX:agreen Schottky, 工作有一環是在證明問題出在哪區段 XD 10/25 23:50
→ rephansu:換C#就知道要怎麼解這問題了 10/26 09:38
→ rephansu:提供有傳入desc和src size版本的memcpy 10/26 09:40
→ rephansu:比較size和 copy的長度, 不合法就給個錯誤 10/26 09:40
→ rephansu:從上面回文來看有點疑惑, 你到底是用純c還是c++?? 10/26 09:41
→ rephansu:C++才有exception, 所以你是用C++? 10/26 09:46
→ applecool:有提到 EXCEPTION 嗎 10/26 12:47
→ rephansu:azureblaze丟的是C++的範例 10/26 14:08
→ rephansu:SIGSEGV只要是操作非法記憶體就會觸發, 跟memcpy無關吧? 10/26 14:09
→ rephansu:這問題解法就如同微軟提供memcpy_s, 要求輸入DstSize 10/26 14:13
→ rephansu:這種情況再出錯就一定是destination和DstSize不匹配 10/26 14:15
→ applecool:所以 memcpy 應該是不會主動丟出 SIGSEGV 吧 10/26 17:19
→ rephansu:在vc下跑memcpy(0,0,1)就會觸發, gcc應該是一樣 10/27 00:00
→ applecool:如果傳非 null 指標然後 SIZE 超過呢 10/27 08:21
→ applecool:應該就不一定了吧 10/27 08:21
→ rephansu:這種必須自己檢查, 所以才要user自己傳size資訊 10/27 11:12
→ rephansu:甚至是將Size資訊和資料綁在一起 10/27 11:13
→ rephansu:在C++會做成struct去操作, 甚至直接用std::vector存取 10/27 11:14
→ rephansu:其他語言都會把size資訊保留, 因此很方便, 例如C# 10/27 11:26
→ rephansu:寫C也可以仿照那種方式來寫啊 10/27 11:27
→ applecool:感謝,後來找到解法了,組和混用 sigsetjmp, siglongjmp 10/27 14:56
→ applecool:去檢查 adress 再來 memcpy,不過怕太慢我只抽樣調查 10/27 14:57
→ applecool:我悟性太低,應該跟 1, 3 樓想表示的做法一樣 10/27 15:18
→ applecool:不過或許真有漏洞 10/27 15:19