1 votos

reglas inescrutables para no permitir binarios en una nueva máquina Apple Silicon (Big Sur)

EDIT: Este problema parece haber sido un error en el mecanismo de firma de código de Apple, y ha sido corregido en la versión candidata 11.1 Big Sur. En el momento en que escribo esto, es necesario inscribirse en el programa de software beta de Apple para recibir esta actualización.

Versiones de software que utilicé cuando me encontré con este problema, para la posteridad:

  • PyCharm: PC-203.5981.165
  • Cadena de herramientas de Rust: 1.50.0-nightly (d274fcf86 2020-12-07)
  • Plugin de Rust IntelliJ: 0.3.136.3514-203
  • MacOS Big Sur 11.0.1 (20B50)

Sin embargo, por curiosidad académica, me sigue interesando entender por qué ocurrió esto. Mi hipótesis de trabajo en este momento es que los metadatos de codificación se corrompieron de alguna manera, pero de una forma no detectada por codesign -dv


Fui capaz de producir una aplicación de terminal de hola-mundo que se SIGKILLed en el lanzamiento, pero funciona como se pretende después de que ya sea

  1. reiniciar el sistema, o
  2. copiar el binario a una nueva ubicación. (Después de esto, sigue funcionando si lo muevo de nuevo a la ruta original).

Sin embargo, seguirá siendo SIGKILL si en lugar de copiar I mover el archivo. Otra propiedad interesante de este binario, mientras está en su estado no operativo (llamémoslo bad_hello ), es que se bloquea codesign -s - bad_hello con el error "la herramienta de ayuda codesign_allocate no puede ser encontrada o utilizada", aunque codesign_allocate está disponible y codesign -s - normalmente funciona.

No hace falta decir que esto es bastante desconcertante y parece un error en el sistema de firma de código de Apple.

Este es el resumen del problema. Ahora, para más detalles.


Recientemente he adquirido un dispositivo Apple Silicon, y me he encontrado con un extraño problema nada más empezar a escribir código.

Hice un proyecto "hola mundo" en Rust. La construcción con la cadena de herramientas de Rust desde la línea de comandos me da un binario que funciona.

Ahora, borro los artefactos de construcción, abro mi IDE basado en IntelliJ, y le pido que construya el mismo proyecto usando la misma cadena de herramientas. Se construye. Pero, intento ejecutarlo, y...

cgadski@ChristophersMBP hello % ./hello
zsh: killed     ./hello

Se hace SIGKILL al instante.

Puse los dos archivos uno al lado del otro. Uno será good_hello y el otro, bad_hello .

cgadski@ChristophersMBP hello % ./good_hello            
hello.
cgadski@ChristophersMBP hello % ./bad_hello
zsh: killed     ./bad_hello

Se construyeron a partir del mismo código con la misma cadena de herramientas con las mismas opciones, así que esperaría que fueran las mismas.

cgadski@ChristophersMBP hello % diff good_hello bad_hello
[no output here]

Sí, es cierto, diff dice que sí. xattr dice que ambos no tenían atributos extendidos, y mdls dice que sólo difieren en sus nombres y en ciertas marcas de tiempo:

cgadski@ChristophersMBP hello % diff good_mdls bad_mdls   
1,2c1,2
< _kMDItemDisplayNameWithExtensions      = "good_hello"
< kMDItemContentCreationDate             = 2020-12-14 00:41:15 +0000
---
> _kMDItemDisplayNameWithExtensions      = "bad_hello"
> kMDItemContentCreationDate             = 2020-12-14 00:39:07 +0000
4c4
< kMDItemContentModificationDate         = 2020-12-14 00:41:15 +0000
---
> kMDItemContentModificationDate         = 2020-12-14 00:39:07 +0000
13c13
< kMDItemDateAdded                       = 2020-12-14 00:41:23 +0000
---
> kMDItemDateAdded                       = 2020-12-14 00:40:55 +0000
15c15
< kMDItemDisplayName                     = "good_hello"
---
> kMDItemDisplayName                     = "bad_hello"
17,18c17,18
< kMDItemFSContentChangeDate             = 2020-12-14 00:41:15 +0000
< kMDItemFSCreationDate                  = 2020-12-14 00:41:15 +0000
---
> kMDItemFSContentChangeDate             = 2020-12-14 00:39:07 +0000
> kMDItemFSCreationDate                  = 2020-12-14 00:39:07 +0000
26c26
< kMDItemFSName                          = "good_hello"
---
> kMDItemFSName                          = "bad_hello"

codesign -dv también devuelve lo mismo para cada binario, con la excepción del Executable campo. Extraño. Y aún más extraño: después de reiniciar el ordenador, ambos funcionan.

cgadski@ChristophersMBP hello % ./bad_hello
hello.
cgadski@ChristophersMBP hello % ./good_hello
hello.

Después de aprender que los signos de código a veces se "rompen" y necesitan ser corregidos "copiando el binario y volviéndolo a firmar", hago una versión fresca de bad_hello y probarlo. En realidad, encuentro algo más misterioso: basta con copiar el archivo.

cgadski@ChristophersMBP hello % ./bad_hello
zsh: killed     ./bad_carm
cgadski@ChristophersMBP hello % cp bad_hello some_random_new_path
cgadski@ChristophersMBP hello % ./some_random_new_path 
hello.
cgadski@ChristophersMBP hello % mv some_random_new_path bad_hello
cgadski@ChristophersMBP hello % ./bad_hello
hello.

Mis preguntas son: ¿qué podría estar haciendo el IDE para romper mi binario de esta manera? (Afirma que sólo invoca el mismo comando de la cadena de herramientas, cargo build en este caso). Y, ¿qué tiene el original bad_hello que justifica un SIGKILL?

3voto

siva Puntos 23

Todos los binarios que se ejecuten en M1 deben estar firmados. Puede ser una firma ad-hoc, y la cadena de herramientas de primera parte realizará el paso necesario, pero otras herramientas pueden no hacerlo.

el sistema operativo impondrá que cualquier ejecutable debe estar firmado con una firma válida antes de que se permita su ejecución. No hay un requisito de identidad específico para esta firma: basta con una simple firma ad hoc emitida localmente, que incluye las firmas que ahora genera automáticamente el enlazador.

Esta nueva política no se aplica a los binarios x86 traducidos que se ejecutan con Rosetta, ni a MacOS 11 que se ejecuta en plataformas Intel.

https://developer.apple.com/documentation/MacOS-release-notes/MacOS-big-sur-11-universal-apps-beta-release-notes

Se puede aplicar una firma a un binario con codesign utilizando -s (signo):

codesign -s - /path/to/binary

Puede ver si un binario tiene una firma de código utilizando -d (contenido de la pantalla):

codesign -dv /path/to/binary

El diff no mostrará ninguna diferencia ya que los archivos son idénticos, pero la firma significará que el binario se ejecuta.

$ echo foo > a
$ echo foo > b

$ codesign -dv a
a: code object is not signed at all
$ codesign -dv b
b: code object is not signed at all

$ codesign -s - a
$ codesign -dv a
Executable=/Users/user/a
Identifier=a-f1d2d2f924e986ac86fdf7b36c94bcdf32beec15
Format=generic
CodeDirectory v=20100 size=187 flags=0x2(adhoc) hashes=1+2 location=embedded
Signature=adhoc
Info.plist=not bound
TeamIdentifier=not set
Sealed Resources=none
Internal requirements count=0 size=12

$ diff a b
$ echo $?
0

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X