Escriba el código más corto que genera una falla de segmentación (SIGSEGV) en cualquier lenguaje de programación.
Escriba el código más corto que genera una falla de segmentación (SIGSEGV) en cualquier lenguaje de programación.
Respuestas:
main;
Es una declaración variable: el int
tipo está implícito (característica copiada del lenguaje B) y 0
es el valor predeterminado. Cuando se ejecuta, esto intenta ejecutar un número (los números no son ejecutables) y causa SIGSEGV
.
0
. static
Las variables comienzan como 0
, y main;
es static
, como lo declaré fuera de la función. c-faq.com/decl/initval.html
main
un int, se encuentra en .bss
, generalmente las funciones se encuentran en .text
, cuando el kernel carga el programa elf crea una página ejecutable para .text
y no -ejecutable para .bss
, por lo que al llamar a main, saltas a una página no ejecutable, y ejecutar algo en esa página es un error de protección.
main __attribute__((section(".text#")))=0xc3;
FTFY (al menos parece volver sin fallar en mi x86).
const main=195;
. Tan interesante es que está funcionando, el objetivo de este desafío de golf de código fue hacer que el código sea predeterminado, no funciona :).
kill -11 $$
RET
Este código es por defecto.
exec'()'*7**6
Windows informa un código de error de c00000fd (desbordamiento de pila) que supongo que es un subtipo de falla de segmentación.
Gracias a Alex A. y Mego, se confirma que también causa fallas de segmentación en sistemas Mac y Linux. Python es el lenguaje de elección para bloquear sus programas de forma portátil.
Segmentation fault: 11
en Mac
Segmentation fault (core dumped)
en Linux
\def~#1{\meaning}\write0{\expandafter~\string}\bye
En realidad, esto es probablemente un error , pero no está presente en el TeX original, escrito por Knuth: compilar el código en tex filename.tex
lugar de pdftex filename.tex
no produce un defecto de seguridad.
OBTW
No funciona en línea, solo en el intérprete C.
>>> import ctypes;ctypes.string_at(0)
Segmentation fault
Fuente: http://bugs.python.org/issue1215#msg143236
>>> import sys;sys.setrecursionlimit(1<<30);f=lambda f:f(f);f(f)
Segmentation fault
Fuente: http://svn.python.org/view/python/trunk/Lib/test/crashers/recursive_call.py?view=markup
Esta es la versión de Python que estoy probando:
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
En general, el intérprete de Python es difícil de bloquear, pero lo anterior es abuso selectivo ...
main(){raise(11);}
int func()
. es decir, una función que regresa int
, tomando parámetros no especificados. En este caso, raise
una función devuelve int, toma un argumento int, por lo que funciona (incluso si el compilador se queja).
/(?{??})/
En 5.14, el motor regex se hizo reentrante para que no pudiera estrellarse de esta manera, pero 5.12 y anteriores se volverán a fallar si intenta esto.
Esto parecerá extraño, pero en sistemas Windows de 32 bits, la creación y ejecución de un archivo .com vacío puede causar un defecto, dependiendo de ... algo. DOS simplemente lo acepta (el 8086 no tiene administración de memoria, no hay segmentos significativos para fallar), y Windows de 64 bits se niega a ejecutarlo (x86-64 no tiene modo v86 para ejecutar un archivo .com).
<.
Sí, esto depende de la implementación. SIGSEGV es el resultado probable de un buen compilador.
<
debería tener ningún efecto o envolverse.
foreign import ccall main::IO()
Esto produce un defecto de seguridad cuando se compila con GHC y se ejecuta. No se necesitan indicadores de extensión, ya que la interfaz de función externa está en el estándar Haskell 2010.
La versión C es:
*(int*)0=0;
El programa completo (no del todo compatible con ISO, supongamos que es K&R C) tiene 19 caracteres de longitud:
main(){*(int*)0=0;}
Variante de ensamblador:
orl $0,0
El programa completo tiene 24 caracteres (solo para evaluación, ya que en realidad no es ensamblador):
main(){asm("orl $0,0");}
EDITAR :
Un par de variantes C. El primero usa la inicialización cero de la variable de puntero global:
*p;main(){*p=0;}
El segundo usa recursión infinita:
main(){main();}
La última variante es la más corta: 7 (15) caracteres.
EDITAR 2 :
Se inventó una variante más que es más corta que cualquiera de las anteriores: 6 (14) caracteres. Se supone que las cadenas literales se colocan en un segmento de solo lectura.
main(){*""=0;}
EDITAR 3 :
Y mi último intento - 1 personaje de largo:
P
Solo compílalo así:
cc -o segv -DP="main(){main();}" segv.c
main
es una variable int global inicializada en cero, por lo que lo que obtenemos es el resultado de intentar ejecutar algunos bytes cero. En x86 sería algo así como add %al,(%rax)
una instrucción perfectamente válida que intenta alcanzar la memoria en la dirección almacenada %rax
. Las posibilidades de tener una buena dirección son mínimas.
[dx0]dx
provoca un desbordamiento de pila
[dx0]
se almacena dx0
en la pila, luego d
duplica el elemento de la pila superior, luego x
saca el elemento de la pila superior ( dx0
) y lo ejecuta. Lo que duplica el elemento de la pila superior y comienza a ejecutarlo ... 0
debe estar allí para evitar que esto sea una llamada de cola, por lo que todos se acumulan.
Una solución ligeramente engañosa es afeitarse un char del truco de Joey Adams :
kill 11,$$
Sin embargo, para obtener un verdadero defecto en Perl, unpack p
es la solución obvia:
unpack p,1x8
Técnicamente, esto no está garantizado como segfault, ya que la dirección 0x31313131 (o 0x3131313131313131 en sistemas de 64 bits) podría apuntar al espacio de direcciones válido por casualidad. Pero las probabilidades están en contra. Además, si alguna vez se transfiere Perl a plataformas donde los punteros tienen más de 64 bits, x8
será necesario aumentarlo.
1x8
cosa?
"11111111".
Obj.magic 0 0
Esto usa la función Obj.magic
, que coacciona inseguramente dos tipos. En este caso, coacciona 0 (almacenado como el valor inmediato 1, debido al bit de etiqueta utilizado por el GC) a un tipo de función (almacenado como un puntero). Por lo tanto, intenta desreferenciar la dirección 1, y eso, por supuesto, será por defecto.
it coerces 0 (stored as the immediate value 1)
- ¿Por qué se almacena 0 como 1?
Obj.magic()0
es un char más corto :)
Golfed
. $0
Incluya recursivamente el guión en sí mismo.
Explicado
La operación recursiva "fuente" (.) Provoca un desbordamiento de la pila, y como Bash no se integra con libsigsegv , esto da como resultado un SIGSEGV.
Tenga en cuenta que esto no es un error, sino un comportamiento esperado, como se discute aquí .
Prueba
./bang
Segmentation fault (core dumped)
⌠[]+⌡9!*.
Si lo anterior no falla, intente aumentar el número (los números de varios dígitos se especifican en En realidad con dos puntos iniciales)
Bloquea el intérprete al explotar un error en Python que involucra itertools.chain
objetos profundamente anidados , que en realidad usa para implementar el +
operador.
System.Runtime.InteropServices.Marshal.ReadInt32(IntPtr.Zero);
unsafe{int i=*(int*)0;}
Debe compilarse con / inseguro para que este funcione. Por alguna razón que no entiendo, *(int*)0=0
solo arroja una NullReferenceException, mientras que esta versión proporciona la infracción de acceso adecuada.
int i=*(int*)0;
devuelve una NullReferenceException para mí.
*(int*)-1=0
y obtener una infracción de acceso.
*(int*)0=0
arroja una excepción probablemente se deba a la optimización. Específicamente, para evitar el costo de la comprobación null
, el optimizador puede eliminar las comprobaciones nulas, pero cuando se produce una falla predeterminada, puede volver a generarla como un correcto NullReferenceException
.
$ pil
: ('0)
Segmentation fault
Este es el comportamiento previsto. Como se describe en su sitio web:
Si algunos lenguajes de programación afirman ser la "navaja suiza de programación", entonces PicoLisp bien podría llamarse el "escalpelo de programación": agudo, preciso, pequeño y liviano, pero también peligroso en manos de los inexpertos.
real,pointer::p(:)=>null()
p(1)=0.
end
Compilacion:
gfortran segv.f90 -o segv
Ejecución:
./segv
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7FF85FCAE777
#1 0x7FF85FCAED7E
#2 0x7FF85F906D3F
#3 0x40068F in MAIN__ at segv.f90:?
Erreur de segmentation (core dumped)
Materiales:
gfortran --version
GNU Fortran (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
main(a){*(&a-1)=1;}
Daña el valor de la dirección de retorno de la función principal, por lo que obtiene un SIGSEGV al regresar de main
.
(Esto se está convirtiendo en un tema para mí, tal vez porque es el único idioma que sé que nadie más aquí sabe).
inc(r0)
Aumenta el byte único direccionado por el valor inicial de r0 [que resulta ser 05162 según el depurador simh] al inicio del programa.
0000000 000407 000002 000000 000000 000000 000000 000000 000000
0000020 005210 000000
Y, como siempre, los bytes extraños al final se pueden eliminar con strip.
Hice algunos intentos para acortar la fuente, pero siempre terminé recibiendo un error de sintaxis o SIGBUS.
En respuesta a una pregunta mía, a Amro se le ocurrió esta peculiaridad:
S = struct();
S = setfield(S, {}, 'g', {}, 0)
clear()
Borra absolutamente todo, no solo el alcance actual, lo que obviamente causa muchos errores que dan como resultado JS explotando y segfaulándose
j1Z
Esta sería la parte en la que explicaría cómo se me ocurrió esta respuesta, excepto que legítimamente no tengo idea . Si alguien pudiera explicarme esto, estaría agradecido.
Aquí está en un intérprete en línea.
Explicación
j
cuadra la base y se llama recursivamente hasta que la base sea al menos tan grande como el número. Como la base es 0 , eso nunca sucede. Con un límite de recursión suficientemente alto, obtienes un segfault.
j
en 1
y 0
, que intenta convertir 1
en la base 0
. Por qué eso falla, no tengo idea ...