Das Ausführen von Coverity in meinem Code führt zu einer fehlerhaften String-Fehlermeldung. Ich verwende die "path" Variable, die im Stack deklariert wurde, also bin ich mir nicht sicher warum ich Fehler sehe. Ich kann nur denken, dass die Verwendung von getenv()
direkt in strncpy()
den Fehler verursacht. Würde der Fix unten diesen Fehler beseitigen?
bis
%Vor%Nein, das wird den Fehler wahrscheinlich nicht beheben.
Coverity sagt Ihnen, dass die Daten in der Umgebungsvariablen "A" so ziemlich alles sein können; Diese Daten unterliegen nicht der Kontrolle Ihres Programms.
Daher müssen Sie die Daten überprüfen, bevor Sie sie verwenden.
Ihr vorgeschlagenes Update enthält derzeit einen Pufferüberlauf, wenn jemand die Umgebungsvariable A auf eine Zeichenfolge mit 1025 Zeichen setzt.
Darüber hinaus wird keine der beiden Codeversionen die Zeichenfolge "path" jemals mit NULL beenden. Dies liegt daran, dass Sie strncpy verwenden, das nicht NUL-terminiert, wenn das Byte-Limit angewendet wird (was in diesem Fall der Fall sein wird, weil Sie sagen "Begrenzen Sie die kopierte Zeichenfolge auf die Länge, die ich gerade von der Zeichenfolge erhalten habe") / p>
Was Sie tun sollten, ist die Größe zuerst überprüfen. Wenn es zu groß ist, geben Sie eine Art von Fehlercode zurück; Der Pfad in der Variablen A ist zu groß, sodass der Code nicht wie gewünscht funktioniert. Wenn es nicht zu groß ist, kopieren Sie es in den Pfadpuffer. Wenn Sie strncpy verwenden möchten, stellen Sie sicher, dass Sie am Ende Platz für ein NUL lassen, und fügen Sie es dann explizit hinzu, da strncpy nicht garantiert, dass dort ein NUL eingefügt wird.
Ihr Code ist falsch: Sie haben einen potenziellen Pufferüberlauf in beiden Alternativen.
Ich bin mir nicht sicher, ob Coverity das Problem richtig diagnostiziert, Sie haben die genaue Fehlermeldung nicht gepostet. Coverity weist möglicherweise darauf hin, dass Sie eine Zeichenfolge aus der Umgebung verwenden, die eine beliebige Länge haben könnte, was möglicherweise zu einem Pufferüberlauf führen würde, wenn sie von Ihrem Code in einen 1024-Byte-Puffer kopiert wird. Hier ist warum:
strncpy
tut nicht, was Sie denken, dass es tut. Diese Funktion sollte nie verwendet werden, ihre Semantik ist fehleranfällig, sie ist nicht das richtige Werkzeug für Ihren Zweck. strncpy(dest, src, n)
kopiert nicht mehr als n
chars von src
nach dest
und füllt den Rest des Arrays bei dest
mit '
bytes, bis n
'dest
bytes geschrieben wurden. n
muss auf ein Array von mindestens src
chars zeigen. Wenn src
kürzer ist, ist das Verhalten ineffizient, da das Auffüllen normalerweise nicht notwendig ist, aber wenn n
eine Länge von mindestens dest
hat, wird strncpy
nicht null terminiert durch getenv
, was zu undefiniertem Verhalten führt in vielen Fällen.
Ihr Code:
%Vor%entspricht
%Vor%Wie Sie sehen, wird kein wirklicher Schutz gewährt.
Sie rufen path
3 mal auf, es wäre in der Tat effizienter, Ihre alternative Implementierung zu verwenden, aber es gibt andere Probleme:
Sie initialisieren { NULL, }
mit NULL
. Dies ist inkonsistent und in vielen Fällen nicht korrekt. ((void*)0)
wird häufig als char
definiert, daher ein ungültiger Initialisierer für path
. path
könnte auf diese Weise initialisiert werden:
Um zu vermeiden, dass der Zielpuffer überläuft, verwenden Sie diesen Code:
%Vor% Dies würde jedoch den Umgebungswert abschneiden, der je nach Verwendung von setenv
möglicherweise nicht angemessen ist.
Eine Alternative besteht darin, den Umgebungswert direkt zu verwenden:
%Vor% Und wenn Sie die Umgebungswerte während der Ausführung Ihres Programms mit path = strdup(path);
ändern, möchten Sie möglicherweise eine Kopie des Umgebungswerts mit %code% erstellen. Dies könnte auch die beschädigte Zeichenfolge Warnung von Coverity beheben, obwohl die Kopie die gleiche Größe wie das Original hätte und nicht genügend Speicher verfügbar wäre, was getestet werden sollte. Nach Tainted string in C zu urteilen, scheint es, dass Coverity ein bisschen extrem über verdorbene Streicher ist. Die Warnung, die Sie erhalten, weist auf ein echtes Problem hin. Wenn Sie die Warnung loswerden, sind jedoch manchmal seltsame Problemumgehungen erforderlich.
Würde der folgende Fix diesen Fehler beheben?
Nein, aber das würde fast sicher:
%Vor% Das Hauptproblem mit Ihrem Code tritt auf, wenn getenv("A")
eine Zeichenfolge mit 1024 Byte oder mehr zurückgibt; Wenn Sie dies in path
kopieren, führt dies zu einem Pufferüberlauf, da nicht garantiert ist, dass strlen(getenv("A"))
kleiner oder gleich 1024 ist. Sie können dies beheben, indem Sie Folgendes verwenden:
... aber dann wird path
nicht mit einem '
-Zeichen beendet; path
''
wird in dieser Situation keine Zeichenfolge sein, da eine Zeichenfolge definitionsgemäß mit einem %code% -Zeichen abgeschlossen werden muss. Dies bedeutet, dass Sie sie nicht als a verwenden können Zeichenfolge. '%code%'
'
Hier beklagt sich Coverity höchstwahrscheinlich, und mein Code beseitigt das Problem, indem ein VLA (variable length array) verwendet wird, das groß genug ist, um den gesamten String und das %code% am Ende des Strings zu speichern.
Tags und Links c coverity coverity-prevent