>>165117>>165118Nein, hat nichts mit Policies zu tun (sowieso ein völlig überholtes und unsicheres Konzept von ImageMagick. Immer wenn sie eine CVE haben, passen sie eine XML-Datei an, damit das, was die CVE ausgelöst hat, nicht mehr erlaubt ist). Es hatte wahrscheinlich nicht mal was mit dem Q16HDR-Zeugs zu tun, das war vermutlich ein Fehlschluss von mir.
Es hat was damit zu tun, dass
a) ImageMagick Ranz ist
b) ELF-Dateien ins Gas gehören
c) dynamisches Linken der Turbokrebs ist
d) Debian im letzten Jahrhundert feststeckt
Kurze Erklärung: Der JPEG-Encoder von ImageMagick macht, in Kombination mit den von mir gewählten Parametern, eine eigentlich recht stupide, aber wirksame Optimierung: Er schreibt mehrere Versionen der Ausgabe in eine temporäre Datei und macht so eine binäre Suche, bis er die beste Qualität findet, die unter einer vorgegebenen Größenschwelle liegt. Das erhöht die Qualität deutlich im Vergleich dazu, als wenn man einfach nur einen konstanten Qualitätsfaktor setzt (wie man hier deutlich sieht).
Das Problem ist: secmagick ist ja so konzipiert mit seccomp die Rechte von ImageMagick so weit wie möglich einzuschränken, weil es eben der letzte Rotz ist, der jeden Tag eine neue CVE hat. Also ist sowas wie neue Dateien öffnen (auch temporäre) während der Hauptphase natürlich nicht erlaubt.
Leider macht der JPEG-Encoder im Gegensatz zu allen anderen sein eigenes Ding und versucht temporäre Dateien zu öffnen, weil der Patch vermutlich von irgendeinem Studenten geschrieben wurde und bei ImageMagick sowieso keine Qualitätskontrolle stattfindet und der ganze Kot aussieht wie Kraut und Rüben und überall Logik dupliziert ist. Leider hat aber gerade dieser Patch wie gesagt auch einen großen Einfluss auf die Qualität, was mir wichtig ist. Das ist auch der Grund, warum ich immer noch ImageMagick verwende statt GraphicsMagick - die haben diesen Patch nämlich nicht.
Also habe ich hier [0] bzw [1] hier Kot geschrieben, der durch die fürchterlichen ELF-Header durchläuft und dort die Funktion, die der JPEG-Enkoder verwendet, durch meine eigene [2] ersetzt, damit die temporären Dateien, die benötigt werden, vorab bereits geöffnet werden können, bevor in die kritische Phase eingetreten wird, damit in der kritischen Sandbox-Phase nichts mehr geöffnet werden muss.
Unter Arsch funktioniert das auch. Das Problem ist, dass ELF drölftausend verschiedene Relozierungstypen hat und Debian wohl mit anderen Flags kompiliert und deshalb extrem krebsiges
R_X86_64_JUMP_SLOT (soweit ich es verstehe quasi Lazy-Loading) statt
R_X86_64_GLOB_DAT verwendet. Arsch macht also, wenn ich es richtig verstanden habe, Early-Binding und Debian macht wie anno dazumal Lazy-Loading beim ersten Funktionszugriff, obwohl heute eigentlich jeder weiß, dass das scheiße ist. Secmagick selbst ist auch zwingend mit early-binding (
-fno-plt) kompiliert [4] aus genau jenem Grund, nur leider nützt das hier nichts, weil der JPEG-Encoder in einer eigenen, von Debian kompilierten .so steckt. Arch kompiliert wohl alles mit
-fno-plt, Debian aber nicht. Und deshalb funktioniert das hier nicht.
(Das alles wird übrigens noch zusätzlich dadurch verkompliziert, dass ImageMagick selbst natürlich kein Monolith sondern ein aus mehreren dynamisch gelinkten Modulen bestehender Haufen Scheiße ist, der zur Laufzeit Teile nachlädt (was in der Seccomp-Box natürlich auch streng haram ist), aber auch für dieses Problem habe ich bereits einen Workaround [3].)
Also nochmal zusammenfassend: Unter Arsch funktioniert mein Hook, weil die
blabla-jpeg.so zwar dynamisch geladen wird, aber zumindest die Relozierungen
darin bereits early gemacht werden, also direkt beim Laden. Danach kann mein Kot dann hergehen, durch die Relozierungstabellen iterieren und den Eintrag flicken. Bei Debian hingegen wird die .so geladen, aber da wird erst mal nix reloziert, und deswegen findet mein Kot den Eintrag für die Funktion nicht und kann ihn nicht flicken, weil mein Kot nur
R_X86_64_GLOB_DAT versteht und nicht
R_X86_64_JUMP_SLOT.
Und ich hatte eigentlich diesen Freitag morgen auch nicht vorgehabt zu lernen, was zum Fick jetzt wieder
R_X86_64_JUMP_SLOT ist und wie man damit richtig umgeht.
[0] https://gitgud.io/zuse/secmagick/-/blob/master/sandbox/elf_hook.c?ref_type=heads
[1] https://gitgud.io/zuse/secmagick/-/blob/master/sandbox/sandbox.c?ref_type=heads#L153
[2] https://gitgud.io/zuse/secmagick/-/blob/master/sandbox/sandbox.c?ref_type=heads#L45
[3] https://gitgud.io/zuse/secmagick/-/blob/master/common/common.c?ref_type=heads#L1416
[4] https://gitgud.io/zuse/secmagick/-/blob/master/CMakeLists.txt?ref_type=heads#L100