Seit den letzten Kernel-Updates von Juni 2017 stürzt Java auf beinahe allen gepatchten Linux-Servern fröhlich ab. Konkret: Java-Prozesse lassen sich nach dem Reboot nicht mehr starten.

Bemerkt habe ich es bei einigen Oracle-Produkten, wobei auch Tomcats und viele andere betroffen sind. Im Prinzip dürfte jedes Java betroffen sein, von JDK 1.6.* bis 1.8.0_131. Was die ganze Angelegenheit nicht gerade vereinfacht.

Ursache

Etwas Recherche hat mir aufgezeigt, die Ursache ist ein gehärteter Kernel. Java crashed damit auf einer ganzen Armada an Kernels, also eigentlich auf allen Kernels die seit 2010 existieren und seit Juni 2017 gepatcht werden. Und damit ist auch so gut wie jede Distribution betroffen, augenscheinlich sogar Unix bzw. Solaris.

Workaround/Lösung

Der bisherige Workaround besteht darin, während jedem Java Prozess-Start -Xss zu erhöhen:

export JAVA_OPTIONS=-Xss2M

Der Default von -Xss liegt übrigens bei 256KB oder 1024KB, der Wert soll aber höher als 1MiB sein. RedHat empfiehlt 2MB zu setzen. -Xss steht für -XX:ThreadStackSize.

Lustigerweise verlinkt jeder Blog einen anderen CVE der als Ursache herhalten müsste . Einmal sei es CVE-2017-1000366 (hier crashed Hadoop), dann sei aber doch der Stack Clash-Exploit als CVE-2017-1000370/71 die Ursache, und an vielen anderen Stellen wird verwiesen auf CVE-2017-1000364. Meines Erachtens müsste die Ursache im Falle von Java letzteres sein, also CVE-2017-1000364 und alle CVE’s haben ein bisschen recht, denn alle behandeln den Stack Clash Exploit nur auf einer anderen Ebene.

Aber wieso genau muss nun -Xss erhöht werden?

Ich versuche das mal mit meinen Worten zu erklären, keine Gewähr auf vollständige Korrektheit:

Damit erschwert wird, dass irgendwelche Prozesse unerlaubt fremde Memory-Inhalte auslesen (und Rechte erweitert, also root erschleicht), erhöht der Kernel die geschützte Zone von „one Page“ hinauf zu „1MiB“. Bedeutet im Umkehrschluss, wenn ein Prozess weniger als 1 MiB für -XX:ThreadStackSize allozieren möchte sagt der Kernel: Nope! und der Java Prozess fällt mit einem ekligen Core Dump auf die Schnauze. 1 Mebibyte (MiB) sind  1 MB 48 KB 576 B oder 1.048576 MB. Deshalb sollte man höher 1MiB wählen, 1280KB oder gleich 2MB.

RedHat erklärt es so:

A flaw was found in the way memory was being allocated on the stack for user space binaries. If heap (or different memory region) and stack memory regions were adjacent to each other, an attacker could use this flaw to jump over the stack guard gap, cause controlled memory corruption on process stack or the adjacent memory region, and thus increase their privileges on the system. This is a kernel-side mitigation which increases the stack guard gap size from one page to 1 MiB to make successful exploitation of this issue more difficult. Quelle

Nun kämpfen auch wir @Work mit einem heillosen Durcheinander, immerhin hat Oracle in recht vielen hauseigenen Scripts kein -Xss definiert. Workaround hier, Workaround da, füge jedes mal hinzu export JAVA_OPTIONS=-Xss2M… Ich kann mir lebhaft vorstellen, wie viele Firmen mit ihren Java-Anwendungen seit Juni 2017 auch zu kämpfen haben.

Ob das neuste Java, höher als 1.8.0_131 bald Xss per Default auf höher 1MiB setzen wird? Vielleicht…

  • Pit

    Ein kleines Kernel Update, millionen von Bugs behoben, 95% weniger RAM Verbrauch im System und 50% der CPU Zeit freigegeben
    Das nenn ich mal effektiv, bitte weiter so!

  • Schroeffu

    :’D

  • Axel Birndt

    Cool, danke für die Info!
    PS: auf meinem Blog kannst du auch gern Deine Mailadresse eintragen, um über neue Beiträge informiert zu werden. Gibt es bei Dir auch die Möglichkeit Mails bei neuen Beträgen zu bekommen?
    Vg Axel