19 Stimmen

Memcpy() in der sicheren Programmierung?

Kürzlich bin ich über Folgendes gestolpert ein Artikel die behauptet, Microsoft verbiete die memcpy() Funktion in seinen sicheren Programmiershops. Ich verstehe die Schwachstellen dieser Funktion, aber ist es notwendig, ihre Verwendung ganz zu verbieten?

Sollten Programme, die ich schreibe, vermieden werden memcpy() oder nur dafür sorgen, dass es sicher verwendet wird? Welche Alternativen gibt es, die ähnliche, aber sicherere Funktionen bieten?

32voto

Thomas L Holaday Punkte 13228

Microsoft bietet Alternativen zu memcpy und wmemcpy, die ihre Parameter validieren.

memcpy_s sagt: "Hmm, bevor ich von dieser Adresse lese, möchte ich mich vergewissern, dass es sich nicht um einen Null-Zeiger handelt; und bevor ich an diese Adresse schreibe, werde ich diesen Test erneut durchführen. Ich werde auch die Anzahl der Bytes, die ich kopieren soll, mit der behaupteten Größe des Ziels vergleichen; wenn und nur wenn der Aufruf alle diese Tests besteht, werde ich die Kopie durchführen.

memcpy sagt: "Stuff the destination into a register, stuff the source into a register, stuff the count into a register, perform MOVSB or MOVSW." (Beispiel auf Geocities, nicht mehr lange auf dieser Welt: http://www.geocities.com/siliconvalley/park/3230/x86asm/asml1013.html )

Edit: Für ein Beispiel in freier Wildbahn der Dein Wunsch ist mir Befehl Ansatz zu memcpy, betrachten Sie OpenSolaris, wo memcpy (für einige Konfigurationen) definiert in Bezug auf bcopy y bcopy (für einige Konfigurationen) ist ...

void
     33 bcopy(from, to, count)
     34 #ifdef vax
     35     unsigned char *from, *to;
     36     int count;
     37 {
     38 
     39     asm("   movc3   12(ap),*4(ap),*8(ap)");
     40 }
     41 #else
     42 #ifdef u3b      /* movblkb only works with register args */
     43     unsigned char *from, *to;
     44     int count;
     45 {
     46     asm("   movblkb %r6, %r8, %r7");
     47 }
     48 #else
     49     unsigned char *from, *to;
     50     int count;
     51 {
     52     while ((count--) > 0)
     53         *to++ = *from++;
     54 }
     55 #endif

Bearbeiten: Danke, Millie Smith! Hier ist, was auf der Geocities-Seite war, die ich oben verlinkt habe:

MOVS

Die Anweisung movs wird verwendet, um die Quellzeichenkette in das Ziel zu kopieren (ja, kopieren, nicht verschieben). Diese Anweisung hat zwei Varianten: movsb und movsw. Der Befehl movsb ("move string byte") verschiebt jeweils ein Byte, während movsw zwei Bytes auf einmal verschiebt.

Da wir mehrere Bytes auf einmal verschieben möchten, werden diese movs-Befehle in Stapeln mit rep-Präfix ausgeführt. Die Anzahl der Bewegungen wird durch das Register CX festgelegt. Siehe das folgende Beispiel:

:
lds   si, [src]
les   di, [dest]
cld
mov   cx, 100
rep   movsb
:

In diesem Beispiel werden 100 Bytes von src nach dest kopiert. Wenn Sie movsb durch movsw ersetzen, kopieren Sie stattdessen 200 Bytes. Wenn Sie das Rep-Präfix entfernen, hat das CX-Register keine Wirkung. Sie verschieben ein Byte (wenn es sich um movsb handelt, oder 2 Bytes, wenn es sich um movsw handelt).

9voto

0x6adb015 Punkte 7035

Eine Kettensäge ist, wenn sie richtig eingesetzt wird, sicher. Dasselbe gilt für memcpy(). Aber in beiden Fällen kann ein Nagel fliegen und Sie verletzen, wenn Sie ihn treffen.

Kurz gesagt, memcpy() ist für Low-Level-Computing erforderlich und wird nicht verschwinden, aber für High-Level-Programmierung brauchen Sie es nicht. Es gibt kein memcpy() in Python.

9voto

MSalters Punkte 166675

Bemühen Sie sich nicht. Microsofts Alternativen sind nicht viel besser. Der Hauptwert besteht darin, dass diese Ihren Code nicht mehr auf Linux übertragen können. Microsoft verdient viel mehr Geld mit dem Betriebssystem, das sie an Ihre Kunden verkaufen, als mit der Kopie von Visual C++, die Sie gekauft haben.

6voto

TrayMan Punkte 6755

Der Artikel selbst beschreibt eine sicherere Alternative: memcpy_s, bei der Sie die maximale Länge des Ziels angeben müssen. Wenn diese Zahl unabhängig von der Menge der zu kopierenden Bytes angegeben wird, wirkt sie als Barriere, um einen Pufferüberlauf zu verhindern. Natürlich kann man das missbrauchen, indem man für beide die gleiche Zahl angibt.

3voto

merkuro Punkte 6095

Macht das Verbot von memcpy() in meinem Code mich zu einem besseren Programmierer und meine Anwendung sicherer oder nur inkompatibler? Ich bin mir nicht sicher, ob MS wirklich etwas ändern will oder nur jeden neuen C-Code inkompatibel mit anderen Compilern machen will. Übrigens macht MS diesen Trick bei vielen Funktionen und das ist ziemlich ärgerlich. strcpy -> strcpy_s -> StringCchCopy.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X