Frage

Ich bin kürzlich darüber gestolpert ein Artikel das behauptet, dass Microsoft das verbietet memcpy() Funktion in seinen sicheren Programmiershops.Ich verstehe die mit der Funktion verbundenen Schwachstellen, aber ist es notwendig, ihre Verwendung vollständig zu verbieten?

Sollten Programme, die ich schreibe, vermieden werden? memcpy() vollständig oder nur um sicherzustellen, dass es sicher verwendet wird?Welche Alternativen gibt es, die eine ähnliche, aber sicherere Funktionalität bieten?

War es hilfreich?

Lösung

Microsoft stellt bereit Alternativen an memcpy und wmemcpy, die ihre Parameter validieren.

memcpy_s sagt: „Hmm, bevor ich von dieser Adresse lese, möchte ich selbst überprüfen, dass es sich nicht um einen Nullzeiger handelt.und bevor ich an diese Adresse schreibe, werde ich diesen Test noch einmal durchführen.Ich werde auch die Anzahl der Bytes, die ich kopieren soll, mit der angegebenen Größe des Ziels vergleichen.Nur wenn der Anruf alle diese Tests besteht, werde ich die Kopie durchführen.“

Memcpy sagt: "Setzen Sie das Ziel in ein Register, füllen Sie die Quelle in ein Register, füllen Sie die Anzahl in ein Register, führen Sie Movsb oder Movsw aus." (Beispiel zu Geocities, nicht lange für diese Welt: http://www.geocities.com/siliconvalley/park/3230/x86asm/asml1013.html)

Bearbeiten:Für ein Beispiel in der Wildnis des Dein Wunsch ist mir Befehl Herangehensweise an memcpy, denken Sie an OpenSolaris, wo sich memcpy befindet (für einige Konfigurationen) definiert in Bezug auf bcopy, Und 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!Folgendes stand auf der Geocities-Seite, die ich oben verlinkt habe:

MOVS

Die Anweisung movs wird verwendet, um die Quellzeichenfolge in das Ziel zu kopieren (ja, kopieren, nicht verschieben).Diese Anleitung hat zwei Varianten:movsb und movsw.Das movsb („move string byte“) verschiebt jeweils ein Byte, während movsw jeweils zwei Bytes verschiebt.

Da wir mehrere Bytes gleichzeitig verschieben möchten, werden diese Movs-Anweisungen stapelweise mit dem Präfix rep ausgeführt.Die Anzahl der Bewegungen wird durch das CX-Register angegeben.Siehe das Beispiel unten:

:
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 Auswirkung.Sie verschieben ein Byte (wenn es movsb ist, oder 2 Bytes, wenn es movsw ist).

Andere Tipps

Eine Kettensäge, wenn sie richtig verwendet wird, ist sicher. Das Gleiche gilt für memcpy (). Aber in beiden Fällen, wenn Sie einen Nagel treffen, kann es fliegen und dich verletzen.

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

Sie nicht stören. Microsofts Alternativen sind nicht viel besser. Der Hauptwert ist, dass diese der Code dazu führen, Linux zu werden unportable. Microsoft macht viel mehr Geld für das Betriebssystem sie an Ihren Kunden verkaufen, als sie auf der Kopie von Visual C ++ machen Sie gekauft haben.

Der Artikel selbst beschreibt eine sicherere Alternative: memcpy_s, die Sie die maximale Länge des Ziels zu spezifizieren erfordert. Wenn diese Zahl vorgesehen ist unabhängig von der Anzahl der Bytes zu kopieren, wirkt es als Barriere Pufferüberlauf zu verhindern. Natürlich können Sie, dass missbrauchen, indem sie die gleiche Anzahl an beide geben.

Ist das Verbot memcpy () in meinem Code mir zu einem besseren Programmierer und meiner Anwendung sicherer oder nur mehr inkompatibel zu machen? Ich bin unsicher, wenn MS wirklich will, etwas ändern oder macht nur jeden neuer C-Code nicht mit anderen Compilern. Btw. MS hat diesen Trick auf viele Funktionen und es ist ziemlich ärgerlich. strcpy -> strcpy_s. -> StringCchCopy

Ich denke, dass C eine Option für den Programmierer verlassen sollte seinen eigenen Fuß zu schießen. manuelle Speicherverwaltung ist sicher, wenn es richtig gemacht.

Sie hat es selbst gesagt: "Microsoft hat die memcpy () Funktion in seiner sicheren Programmierung Shops ist ein Verbot, das verstehe ich die Schwachstellen, die mit der Funktion "

memcpy () und eine Vielzahl von anderen Standardfunktionen sind bekannte Schwachstellen verursachen, also warum sollte eine sichere Programmierung Geschäft ihre Verwendung zulassen, wenn eine (wenn auch inkrementell) Verbesserung trivial ist?

Kein Zweifel, in ihren Bemühungen um die Sicherheit ihrer eigenen Produkte zu verbessern, zeigte der Code-Reviews klar, dass diese Funktionen für einen beträchtlichen Teil der Schwachstellen verantwortlich waren, Pufferüberläufe usw. Anstatt Wrapper für die internen Gebrauch macht nur eingeführt sie sie in die Standard-Bibliothek und fügte hinzu, einen Compiler (kein Verbot) zum Nutzen aller zu warnen.

Wenn Sie ältere Versionen verwenden, wie C99 oder C ++ 98 oder auf Solaris, können Sie nicht memcpy_s verwenden, es sei denn, Sie die Sichere C-Bibliothek installiert haben.

memcpy_s () ist eine Microsoft-spezifische Implementierung, die auf nicht-MS-Implementierungen nicht existiert, einschließlich ANSI, vor C11, je ihre eigenen Standards.

Ich werde die pro-MS und anti-MS Sachen beiseite lassen, weil es irrelevant ist.

memmove () ist eine bessere Lösung sowieso, da es die Überlappung Thema angesprochen. memmove_s () ist robuster, aber auch hier nur, wenn Sie in C11 oder höher sind.

Die Alternative zu nennen, ist memcpy_s

Sie sollen memcpy_s () stattdessen verwenden. Die gleiche Art von _s Versionen gibt es für eine Vielzahl von anderen Funktionen als unsicheres betrachtet.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top