2016-07-15 36 views
6

Ich habe eine Template-Funktion mit einer Spezialisierung, die Nullsetzung durchführt:Wie man Coverity für "verdächtige sizeof" oder SIZEOF_MISMATCH findet?

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 Feststellung produziert auf SecureWipeBuffer:

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

Der Befund ist:

>>>  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); 

Wie Zug Coverity, dass SecureWipeBuffer zählt eine Anzahl von Elementen und nicht eine Anzahl von Bytes?


EDIT: Wir haben zwei ähnliche Ergebnisse mit unseren Windows-Code aufgenommen. Darüber hinaus erstellt Coverity Ergebnisse zu Standardbibliotheksfunktionen. Es ist so, als ob es nicht realisiert, dass C++ die Anzahl der Elemente und nicht die Anzahl der Bytes behandelt.

Unten ist von Microsft Standardbibliothek Code in <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' hat bereits den Typ' volatile T * ', so dass der Cast redundant ist –

+1

Falls Sie nicht wissen, dass der Standard in der nicht-specialisierten Version für" volatile "optimiert ist Compiler könnte dies sogar durch einen Memset-Aufruf ersetzen. (Die Regel über den Erhalt des Zugriffs auf flüchtige Objekte ist genau das; kein Zugriff durch flüchtige qualifizierte Zeiger). –

+1

@ M.M - * "' --p' hat bereits den Typ 'volatileT *', also ist die Besetzung redundant "* - das sollte man meinen, aber zwei Versionen von GCC erfüllen nicht das, was erwartet wird. Compiler, die unerwartete Dinge tun, sind der Grund, warum wir diese Schleife auch umgekehrt ausführen müssen. Es ist eine der Freuden, 20 Jahre Compiler auf fast jeder wichtigen Plattform zu unterstützen. – jww

Antwort

2

fand ich diese Github, die das zu unterdrücken versucht *, indem dies zu tun:

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); 

, die auch in wird empfohlen, Silencing false positives in Coverity Prevent, und ein anderer Ansatz ist hier abgedeckt: Coverity SA - excluding boost, stlport errors.


* Ich bin nicht sicher, ob das, was Sie wollen, aber das ist alles, was ich habe!

+2

Danke gsamaras.Ich bin schon seit ein paar Wochen darüber (ich war der Upvote vor ein paar Wochen). Es fühlt sich an wie ein Hack, und ich denke, das Problem sollte auf andere Weise angegangen werden. Ich habe ein Kopfgeld auf die Frage gegeben, in der Hoffnung, dass einer der Coverity-Leute interessiert wird. Hoffentlich wird einer der Coverity-Leute erklären, warum die Analyse C++ - Elementzählungen als eine "Anzahl von Bytes" behandelt; und hoffentlich werden sie uns sagen, wie man es ohne einen Hack anspricht (Code Annotationen, Modellierung, etc.). – jww

+1

Großartig @jww, ich bin neugierig! :) – gsamaras