2012-05-12 7 views
18

Kann jemand wichtige Aufgaben auflisten, die der Bytecode-Verifizierer ausführen muss, um die Korrektheit des Programms zu gewährleisten? Gibt es in der JVM-Spezifikation einen standardmäßigen, minimalen Verantwortungsbereich? Ich habe mich auch gefragt, ob Verifizierungen sich über andere Phasen wie das Laden und Initialisieren erstrecken.Aufgaben des JVM-Bytecode-Verifizierers

Antwort

15

Dies ist in der JVM Specification: Chapter 4.10. Verification of class Files angegeben.

Der Großteil der Seite beschreibt die verschiedenen Aspekte der Typensicherheit. Um zu überprüfen, ob das Programm typsicher ist, muss der Verifizierer herausfinden, welche Arten von Operanden sich in dem Operandenstapel bei jedem Programmpunkt befinden, und sicherstellen, dass sie dem Typ entsprechen, der von dem jeweiligen Befehl erwartet wird.

Andere Dinge, die es überprüft, umfassen, ist aber nicht beschränkt auf die folgenden:

  • Zweige innerhalb der Grenzen des Code-Array für das Verfahren sein.

  • Die Ziele aller Steueranweisungen sind jeweils der Beginn einer Anweisung. Im Fall eines breiten Befehls wird der breite Operationscode als der Beginn des Befehls betrachtet, und der Operationscode, der die Operation angibt, die durch diesen breiten Befehl modifiziert wurde, wird als nicht zum Starten eines Befehls angesehen. Verzweigungen in die Mitte einer Anweisung sind nicht erlaubt.

  • Keine Anweisung kann auf eine lokale Variable an einem Index zugreifen oder ändern, der größer oder gleich der Anzahl der lokalen Variablen ist, die ihre Methode angibt.

  • Alle Verweise auf den Konstantenpool müssen auf einen Eintrag des entsprechenden Typs verweisen. (Beispielsweise muss das Anweisungs-Getfield auf ein Feld verweisen.)

  • Der Code endet nicht in der Mitte einer Anweisung.

  • Die Ausführung kann nicht vom Ende des Codes fallen.

  • Für jede Ausnahmebehandlung muss der Anfangs- und Endpunkt des vom Handler geschützten Codes am Anfang einer Anweisung oder im Falle des Endpunkts unmittelbar nach dem Ende des Codes stehen. Der Startpunkt muss vor dem Endpunkt liegen. Der Ausnahmebehandlungscode muss bei einer gültigen Anweisung beginnen und darf nicht bei einem Opcode beginnen, der durch die Wide-Anweisung geändert wird.

Als letzten Schritt der Verifizierer führt auch eine Datenflußanalyse, die dafür sorgt, dass keine Befehlsreferenz alle nicht initialisierten lokale Variablen.

+0

Ist der Java-Verifier beim Laden von Klassen aus dem lokalen Dateisystem aktiviert? Wenn zum Beispiel Eclipse oder Apache eine Klasse lädt, ist dieser Bytecode verifiziert? –

2

Es macht folgendes:

  • Es gibt keine Operanden-Stack überläuft oder unterläuft
  • Die Typen der Parameter aller Bytecode-Anweisungen bekannt sind, immer richtig
  • Objektfeld Zugriffe werden sollen bekannt als legal - privat, öffentlich, oder geschützt

Referenz: http://java.sun.com/docs/white/langenv/Security.doc3.html

7

Alternativ können Sie auch einen Blick auf das Java Language Environment Whitepaper von James Gosling werfen.

enter image description here

Die Bytecode-Verifizierer durchlaufen den Bytecodes, konstruieren die Art Zustandsinformationen, und prüfen die Typen der Parameter an all Bytecode-Anweisungen.

Die Abbildung zeigt den Datenfluss und die Kontrolle von Java-Sprache Quellcode durch den Java-Compiler, um den Klassenlader und Bytecode Verifier und damit auf der Java Virtual Machine, die den Interpreter und Runtime-System enthält. Das wichtige Problem ist , dass der Java Class Loader und der Bytecode Verifier keine Annahmen über die primäre Quelle des Bytecode-Streams machen - der Code könnte aus dem lokalen System kommen, oder es kann die halbe Strecke um den Planeten gereist sein. Der Bytecode-Verifier fungiert als eine Art Gatekeeper: Er stellt sicher, dass der an den Java-Interpreter übergebene Code in einem Fit-Zustand ausgeführt wird und ohne Angst laufen kann, den Java Interpreter zu brechen. Importierter Code darf keinesfalls ausführen, bis er die Tests des Verifizierers bestanden hat. Sobald der Verifizierer getan wird, werden eine Reihe wichtiger Eigenschaften bekannt:

  • Es gibt noch keine Operanden-Stack überläuft oder Unterschreitungen
  • Die Typen der Parameter aller Bytecode-Anweisungen sind dafür bekannt, immer korrekt sein
  • zu bekannt sind legal - privat, öffentlich oder geschützt

Während all diese Überprüfung erscheint quälend detaillierte, von der Zeit der Bytecode Verifier hat seine Arbeit getan, die Java int erpreter kann fortfahren, zu wissen, dass der Code sicher ausgeführt wird. Die Kenntnis dieser Eigenschaften macht den Java-Interpreter viel schneller, weil es keine alles überprüfen muss. Es gibt keine Überprüfung des Operandentyps und keine Überprüfungen des Stacks . Der Interpreter kann somit bei voller Geschwindigkeit arbeiten, ohne die Zuverlässigkeit zu beeinträchtigen.