2016-07-15 18 views
6

Tôi có một hàm mẫu với một chuyên môn mà thực hiện zeroization:Cách đào tạo Mức độ phù hợp cho tìm kiếm "kích thước đáng ngờ" hoặc SIZEOF_MISMATCH?

template <class T> 
void SecureWipeBuffer(T *buf, size_t n) 
{ 
    volatile T *p = buf+n; 
    while (n--) 
     *((volatile T*)(--p)) = 0; 
} 
... 

template <> 
void SecureWipeBuffer(word64* p, size_t n) 
{ 
    asm volatile("rep stosq" : "+c"(n), "+D"(p) : "a"(0) : "memory"); 
} 

Coverity được sản xuất một phát hiện trên SecureWipeBuffer:

word64 val; 
... 
SecureWipeBuffer(&val, 1); 

Phát hiện này là:

>>>  CID 164713: Incorrect expression (SIZEOF_MISMATCH) 
>>>  Passing argument "&val" of type "word64 *" and argument "1UL" to function "SecureWipeBuffer" is suspicious because "sizeof (word64)" /*8*/ is expected. 
275    SecureWipeBuffer(&val, 1); 

Làm thế nào để đào tạo Mức độ phù hợp mà SecureWipeBuffer tính tổng số phần tử chứ không phải là số byte?


EDIT: chúng tôi đã nhặt hai kết quả tương tự với mã Windows của chúng tôi. Ngoài ra, Coverity đang tạo ra các phát hiện về các chức năng thư viện chuẩn. Nó như thể nó không nhận ra C++ giao dịch với số lượng các phần tử, và không đếm byte.

Dưới đây là từ Microsft mã thư viện tiêu chuẩn trong <xmemory>

25 if (_Count == 0) 
26  ; 
27 else if (((size_t)(-1)/sizeof (_Ty) < _Count) 
    CID 12348 (#1 of 1): Wrong sizeof argument (SIZEOF_MISMATCH) 
    suspicious_sizeof: Passing argument _Count * 4U /* sizeof (std::allocator<void *>::value_type) */ 
    to function operator new which returns a value of type std::allocator<void *>::value_type is suspicious. 
28  || (_Ptr = ::operator new(_Count * sizeof (_Ty))) == 0) 
29   _Xbad_alloc(); // report no memory 
+1

'--p' đã có loại' dễ bay hơi T * ', do đó, dàn diễn viên dư thừa –

+1

Trong trường hợp bạn không biết, trong phiên bản không được đặc biệt, tiêu chuẩn cho phép 'bay hơi' được tối ưu hóa và trình biên dịch thậm chí có thể thay thế điều này bằng một cuộc gọi memset. (quy tắc bảo quản quyền truy cập vào các đối tượng dễ bay hơi chỉ là vậy; không truy cập thông qua các con trỏ có khả năng bay hơi). –

+1

@ M.M - * "' --p' đã có loại 'biến động T *', do đó, dàn diễn viên thừa "* - bạn sẽ nghĩ rằng, nhưng hai phiên bản của GCC không làm những gì được mong đợi. Các trình biên dịch thực hiện những điều bất ngờ là lý do chúng ta phải chạy vòng lặp đó ngược lại. Đó là một trong những niềm vui hỗ trợ 20 năm trình biên dịch trên hầu hết các nền tảng chính. – jww

Trả lời

2

tôi thấy Github này, mà cố gắng để ngăn chặn mà *, bằng cách làm này:

std::fill_n(out, spec_.width_ - 1, fill); 
    out += spec_.width_ - 1; 
} else if (spec_.align_ == ALIGN_CENTER) { 
    // coverity[suspicious_sizeof] 
    out = writer_.fill_padding(out, spec_.width_, 1, fill); 
} else { 
    std::fill_n(out + 1, spec_.width_ - 1, fill); 

mà cũng được thông báo trong Silencing false positives in Coverity Prevent và cách tiếp cận khác được đề cập ở đây: Coverity SA - excluding boost, stlport errors.


* Tôi không chắc chắn nếu đó là những gì bạn muốn, nhưng đó là tất cả tôi nhận!

+2

Cảm ơn gsamaras.Tôi đang nghiền ngẫm về điều này trong một vài tuần nay (tôi đã là một người ủng hộ vài tuần trước). Nó cảm thấy như một hack, và tôi nghĩ rằng vấn đề cần được giải quyết theo một cách khác. Tôi đặt một tiền thưởng vào câu hỏi với hy vọng nhận được một trong những kẻ Coverity quan tâm. Hy vọng rằng một trong những nhân vật Coverity sẽ giải thích lý do tại sao phân tích đang xử lý phần tử C++ được tính là "số byte"; và hy vọng họ sẽ cho chúng tôi biết cách giải quyết nó mà không cần hack (chú thích mã, mô hình hóa, v.v.). – jww

+1

Tuyệt vời @ jww, tôi tò mò! :) – gsamaras

Các vấn đề liên quan