Login
Newsletter
Werbung

Mo, 28. Juli 2014, 08:59

Software::Kernel

Fehler in GCC kann falschen Kernel-Code erzeugen

Linux-Kernel, die mit neueren Versionen von GCC erzeugt wurden, können sporadische Abstürze zeigen. Bisher dürften nur wenige Anwender betroffen sein, doch das Problem könnte auch in weiterem Kernel-Code auftreten, so dass wohl in Kürze Updates von GCC bereitstehen werden.

gnu.org

Ein Bericht von Michel Dänzer vom 17. Juli, der mit der Testversion von Linux 3.16 Abstürze zu zufälligen Zeitpunkten beobachtete, führte zu einer intensiven Fehlersuche bei den Kernel-Entwicklern. Linux-Initiator Linus Torvalds selbst war es, der dann eine Woche später die grundlegende Ursache fand. Nicht der Kernel war das Problem, sondern fehlerhafter Code, der von GCC 4.9.0 generiert worden war.

Torvalds fand in dem generierten Code einen Zugriff auf eine Adresse 136 Bytes unterhalb des Stack-Pointers, bevor der Stack-Pointer entsprechend dekrementiert wurde. Dieser war gar nicht nötig, denn der Wert, der dort abgelegt wurde, war eine Konstante, die im Programmcode hätte bleiben können. Doch das war nur eine kleine Ineffizienz, der eigentliche Fehler war der Zugriff auf nicht reservierten Speicher. Dadurch konnten Daten überschrieben werden, die von einem anderen Thread oder Interrupt dort abgelegt wurden.

Nun ist es bei der x86_64-Architektur erlaubt, die ersten 128 Bytes unter dem Stack-Pointer auch ohne Reservierung zu nutzen. Dies nennt sich »Red Zone« und wird von GCC auch unterstützt und ausgenutzt. Das gilt allerdings nur für Anwendungsprogramme. Im Kernel dagegen gibt es keine »Red Zone«, da Interrupts im Kernel-Modus den Stack ohne sie nutzen müssen. Aus diesem Grund ist die »Red Zone« bei der Kernel-Compilierung mit der GCC-Option -mno-red-zone abgeschaltet.

Der Fehler von GCC besteht darin, dass er die Option -mno-red-zone unter bestimmten Umständen, beispielsweise bei einer Optimierung auf Code-Größe, missachtet. Diese Optimierung wird für den Kernel mittlerweile nicht mehr empfohlen, eine Zeitlang war das allerdings der Fall.

Diese Erkenntnis veranlasste Torvalds zu einem weiteren seiner berüchtigten Wutausbrüche, in der er GCC 4.9.0 als »komplette Scheiße« bezeichnete. Wie üblich bei Torvalds sind solche Tiraden niemals persönlich, und sie bezogen sich auch nur auf die entdeckten Fehler von GCC. Die weitere Diskussion, in die auch einige GCC-Entwickler einbezogen wurden, verlief sehr sachlich. Auf Wunsch der GCC-Entwickler schrieb Torvalds einen Fehlerbericht für GCC. GCC-Entwickler Jakub Jelinek klärte die Arbeitsweise von GCC auf und wies auf die Option -fcompare-debug hin, mit der man den generierten Code von GCC in mehreren Varianten vergleichen kann, bei der auch Torvalds eingestehen musste, dass die Option für ihn neu war.

Es stellte sich dann heraus, dass der Fehler bereits kurz zuvor gemeldet und schon behoben worden war. Er wurde daher als Duplikat geschlossen. In der Quellcodeverwaltung von GCC ist die Korrektur bereits enthalten, in veröffentlichten GCC-Versionen aber noch nicht. Aktualisierungen der unterstützten Versionen von GCC dürften daher in Kürze erscheinen. Betroffen sind alle veröffentlichten GCC-Versionen seit 4.5.0 bis hin zu 4.8.3, 4.9.0 und 4.9.1. Der Linux-Kernel selbst wird künftig die Option -fno-var-tracking-assignments einsetzen, die als Workaround für noch nicht korrigierte GCC-Versionen dient. Sie soll keine Auswirkungen auf die Geschwindigkeit des generierten Codes haben, da sie nur die Debug-Informationen betrifft.

Werbung
Kommentare (Insgesamt: 18 || Alle anzeigen )
Trolle nicht füttern (skinnie, Di, 29. Juli 2014)
Re: Wieder mal typisch Torvalds (brrrr, Mo, 28. Juli 2014)
Re: Ach du meine Nase! (funtoo, Mo, 28. Juli 2014)
Re[2]: Ach du meine Nase! (Randy Andy, Mo, 28. Juli 2014)
Re[2]: Ach du meine Nase! (Randy Andy, Mo, 28. Juli 2014)
Pro-Linux
Pro-Linux @Facebook
Neue Nachrichten
Werbung