是否存在與RtlSecureZeroMemory
/SecureZeroMemory
等效的Mac OS X,這是一種將內存塊清零的函數,但編譯器不會優化該調用?相當於SecureZeroMemory/RtlSecureZeroMemory的Mac OS X?
9
A
回答
14
自己寫的函數:
void secure_zero(void *s, size_t n)
{
volatile char *p = s;
while (n--) *p++ = 0;
}
編輯:這個問題的意見,爲什麼不memset
?如果數組對象沒有被訪問,那麼編譯器可以優化memset
函數調用。
需要注意的是C11增加了(可選)功能memset_s
和標準保證了函數調用不能被優化掉:
(C11,K.3.7.4.1p4)「[...] memset的不同,任何對memset_s函數的調用都應嚴格按照(5.1.2.3)中所述的抽象機器的規則進行評估,也就是說,對memset_s函數的任何調用都應假定s和n指示的內存可以被訪問在將來,因此必須包含由c表示的值。「
3
是否有一個Mac OS X相當於RtlSecureZeroMemory/SecureZeroMemory,其中零的內存塊的功能,但通話不會被編譯器優化掉?
在更新版本的C運行時,您有memset_s
。它保證不會被優化掉。
#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
errno_t memset_s(void * restrict s, rsize_t smax, int c, rsize_t n)
OS X還包含bzero
函數。但bzero(3)
man pages不會陳述它的而不是可以被優化器移除。
避免使用volatile
限定符的技巧,因爲它不便攜。它在Windows上按預期工作,但GCC人員將volatile
解釋爲由I/O硬件支持的內存。所以你不應該使用volatile
來馴服優化器。
這是您可以使用的內聯彙編實現。奇怪的是,在ASM語句和塊上的__volatile__
都可以。它在OS X上正常工作(這是它最初編寫的地方)。
// g++ -Og -g3 -m64 wipe.cpp -o wipe.exe
// g++ -Og -g3 -m32 wipe.cpp -o wipe.exe
// g++ -Os -g2 -S -m64 wipe.cpp -o wipe.exe.S
// g++ -Os -g2 -S -m32 wipe.cpp -o wipe.exe.S
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main(int argc, char* argv[])
{
string s("Hello world");
cout << "S: " << s << endl;
char* ptr = &s[0];
size_t size = s.length();
if(ptr && size)
{
/* Needed because we can't just say to GCC, */
/* "give me a register that you choose". */
void* dummy;
__asm__ __volatile__
(
"%=:\n\t" /* generate a unique label for TOP */
#if (__WORDSIZE == 64)
"subq $1, %2\n\t" /* 0-based index */
#elif (__WORDSIZE == 32)
"subl $1, %2\n\t" /* 0-based index */
#elif (__WORDSIZE == 16)
"subw $1, %2\n\t" /* 0-based index */
#else
# error Unknown machine word size
#endif
"lea (%1, %2), %0\n\t" /* calcualte ptr[idx] */
"movb $0, (%0)\n\t" /* 0 -> ptr[size - 1] .. ptr[0] */
"jnz %=b\n\t" /* Back to TOP if non-zero */
: "=&r" (dummy)
: "r" (ptr), "r" (size)
: "0", "1", "2", "cc"
);
}
#if 0
cout.setf(ios::hex, ios::basefield);
cout.fill('0');
for(size_t i = 0; i < s.length(); i++)
cout << "0x" << setw(2) << ((int)s[i] & 0xff) << " ";
cout << endl;
#endif
cout << "S: " << s << endl;
return 0;
}
相關問題
- 1. EnumWindows相當於Mac OS X(C++)
- 2. _wfopen在Mac OS X下相當於
- 3. Windows相當於Mac OS X的「打開」命令
- 4. 的Mac OS相當於CP的-s
- 5. 相當於OS X的pbcopy/pbpaste的Solaris?
- 6. _wspawnl/_spawnl在Mac OS X或Linux上相當於
- 7. Windows cygwin相當於Mac OS X打開命令
- 8. OS X上的SWT:相當於NSSheet
- 9. 是否有相當於OS X的lsusb
- 10. OS X上的user32.dll相當於
- 11. Mac相當於UIBarButtonSystemItemAction
- 12. .dll等同於Mac OS X
- 13. Windows相當於OS X鑰匙串?
- 14. 在Mac OS X
- 15. Mac OS X Linker
- 16. 在Mac OS X
- 17. 在Mac OS X
- 18. Mac OS X PackageMaker
- 19. Mac OS X上的SimpleFTPUpload X
- 20. Debian上的選項/ alt +左/右箭頭相當於Mac OS X上的什麼?
- 21. UDID相當於在Mac
- 22. 相當於按Ctrl-W的IntelliJ的Mac
- 23. 相當於Win API SetCapture()函數的Linux/X11(和Mac OS X)是什麼?
- 24. 如何在Mac OS X上執行Raw IO? (即相當於Linux的O_DIRECT標誌)
- 25. 用於Mac OS X的Fortran調試器
- 26. 用於Mac OS X的替代CADisplayLink
- 27. 適用於Mac OS X的openAL教程
- 28. 適用於Mac OS X的構建
- 29. 適用於Mac OS X的UIPopoverController?
FWIW,如果您使用的是OpenSSL,它提供了'OPENSSL_cleanse'函數,它可以用僞隨機數據安全地覆蓋一塊內存。 –
考慮到OpenSSL確實(和AFAIK,**仍然在**)使用堆棧中未初始化的對象作爲熵源,我會毫不猶豫地將它用於這種嚴肅的安全性......作者不明白安全使用C.(這個問題在Debian修正它們的bug時引起了熵產生鍵的災難性損失。) –
R,你說的並不完全正確。 Debian刪除了堆棧變量**和其他一些有效的熵源的使用,剩下的只是進程pid。這不是OpenSSL的錯,並且使用未初始化的變量作爲**額外的**熵源非常好。 – virco