2009-04-16 7 views

Respuesta

19

Oracle mismos tienen un pequeño fragmento de la página sobre cómo funciona here.

Básicamente, el JRE no confía en el JDK. Eso es porque no tiene conocimiento de qué compilador JDK creó el archivo de clase. Trata el archivo de clase como hostil hasta que se verifique.

Ampliando eso, la verificación de bytecode es un paso necesario para proteger de lo que Sun llama un "compilador hostil". El propio compilador Java de Sun garantiza que el código fuente de Java no infringe las reglas de seguridad, pero cuando una aplicación importa un fragmento de código, en realidad no conoce si el fragmento de código sigue las reglas del lenguaje Java por seguridad. En otras palabras, el código puede no haber sido producido por un compilador de Java confiable.

En ese caso, el sistema de tiempo de ejecución de Java en su máquina tiene que asumir que el fragmento es malo y lo somete a la verificación de código byte.

La máquina virtual Java ni siquiera ve el código de bytes hasta que haya pasado por este proceso de verificación. Hacer esto a medida que se carga el bytecode también tiene la ventaja de que no es necesario realizar una gran cantidad de comprobaciones de tiempo de ejecución cada vez que se ejecuta el código.Debido a que se ha verificado que es correcto, puede, una vez que se ejecuta, correr más rápido de lo que sería posible.

Una interpretación del diagrama es ligado a continuación:

    <<<=== Unsafe/Safe ===>>> 
            \ 
+---------------+  +-------------------+ 
| Java source | +--> | Class loader | --+ 
+---------------+ | | Bytecode verifier | | 
     |   | +-------------------+ | 
     V   |   /   | 
+---------------+ |    \    V 
| Java compiler | Network  / +-------------------+ 
+---------------+ |    \ |  JVM/JIT  | 
     |   |   / +-------------------+ 
     V   |    \    | 
+---------------+ |   /   V 
| Java bytecode | --+    \ +-------------------+ 
+---------------+    / | Operating system | 
            \ +-------------------+ 
           /   | 
            \    V 
           / +-------------------+ 
            \ |  Hardware  | 
           / +-------------------+ 
            \ 
        <<<=== Unsafe/Safe ===>>> 
+2

+1 para paranoia :) – dfa

+0

El problema no es solo compiladores maliciosos. Si alguien realmente intenta escribir un exploit, es probable que escriba el bytecode a mano, o al menos la parte importante. – Antimony

+0

Pero el verificador no está habilitado (o no se ejecutó) para las clases cargadas desde el CLASSPATH local ¿verdad? –

9

La mejor fuente de información es probablemente la sección relevante en la especificación de JVM, 4.10 Verification of class Files.

vea el enlace para más detalles, pero en términos generales:

verificación de enlaces de tiempo mejora el rendimiento del intérprete. Se pueden eliminar las costosas comprobaciones que de otro modo tendrían que realizarse para verificar las restricciones en el tiempo de ejecución para cada instrucción interpretada. La Máquina Virtual Java puede suponer que estas comprobaciones ya se han realizado. Por ejemplo, Java Virtual Machine ya sabrá lo siguiente:

  • No hay desbordamientos ni subflujos en la pila de operandos.
  • Todos los usos y tiendas de variables locales son válidos.
  • Los argumentos para todas las instrucciones de Java Virtual Machine son de tipos válidos.

El verificador también realiza la verificación que se puede hacer sin tener en cuenta la matriz de códigos del atributo Código (§4.7.3). Las comprobaciones realizadas incluyen lo siguiente:

  • Garantizando que las clases finales no se subclasifiquen y que los métodos finales no se anulen (§5.4.5).
  • Comprobando que cada clase (excepto Object) tiene una superclase directa.
  • Asegurándose de que el conjunto constante satisface las restricciones estáticas documentadas; por ejemplo, que cada estructura CONSTANT_Class_info en el conjunto constante contiene en su artículo name_index un índice de grupo constante válido para una estructura CONSTANT_Utf8_info.
  • Comprobando que todas las referencias de campos y métodos en el conjunto constante tengan nombres válidos, clases válidas y un descriptor de tipo válido.
+0

Hay unos pocos casos oscuro rincón donde la especificación es vaga o directamente violados por el Hotspot VM. Si está seguro de que su bytecode debe verificar y no puede descubrir por qué no lo hace, también puede echarle un vistazo al repositorio de código fuente de OpenJDK. – Antimony

+0

Si bien este enlace puede responder la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace de referencia. Las respuestas de solo enlace pueden dejar de ser válidas si la página vinculada cambia. - [De la crítica] (/ review/low-quality-posts/10765467) –

+0

@ AndréFratelli: Y, de hecho, no es una respuesta que añadiría ahora (tenga en cuenta que tienen casi 7 años ...). No es una pregunta que * respondería * ahora, sino que la cerré como demasiado amplia. He agregado * algunos * detalles aquí, pero si el enlace se vuelve a romper (se arregló dos veces hoy, de diferentes maneras) aún no sería terriblemente útil. Al mismo tiempo, aunque la pregunta en sí misma no ha sido resuelta, creo que es una respuesta útil para ... –

Cuestiones relacionadas