/* basquiat's lovely winter riot */: a unique and beautiful snowflake in your heart's lovely winter riot

My first OpenBSD kernelbug

Mit ‘pf’, ‘pfsync’ und ‘CARP’ bietet OpenBSD eine vergleichsweise einfach zu administrierende, leistungsfähige Infrastruktur für das Failover redundant aufgesetzter Firewalls. Neben dem essentiellen Paketfilter ‘pf’ kümmert sich ’pfsync’ in diesem Kontext um das synchrone Statehandling der verschiedenen Nodes, um bei einem Wechsel des aktiven Firewallrechners im Cluster bestehende Netzwerkverbindungen aufrecht erhalten zu können. Der Einsatz des Common Address Redundancy Protocols CARP erledigt auf OSI-Schicht 2 und 3 dabei das eigentliche Procedere zur Hochverfügbarkeit, bei dem es klassischerweise zwischen MASTER- und BACKUP-Rollen auf Interface-Ebene unterscheidet. Eine detailreichere doch kurz gehaltene Übersicht bietet der Artikel “Firewall Failover with pfsync and CARP”.

Mit dem lange überfälligen Upgrade eines schon etwas in die Jahre gekommenen OpenBSD 3.7 Clusters auf Release 4.1 erhielt ich die einmalige Chance, meinen ersten OpenBSD-Kernelbug - wenn auch eher unfreiwillig in gewohnt unpassendster Situation - zu entdecken; das sequentielle Neuladen der Regeln des auf zwei Clusternodes verteilten Paketfilters führte nach wenigen Iterationen regelmäßig zum Absturz des Systems:

kernel: page fault trap, code = 0
Stopped at	pfsync_insert_net_state+0x472:	movl	0(%eax,%edx,4),%edx

Für Neulinge unter den digitalen Kammerjägern beschreibt die Kurzanleitung “How to debug kernel crashes” das Erstellen verwertbarer Bugreports für die Entwickler - in der Regel sollte man das fehlerhafte Verhalten jedoch zuerst unter Einsatz unmodifizierter GENERIC-Kernel reproduzieren können. Gesagt, getan; nun folgend das übersetzte Kochrezept.

Mit der Analyse des Trace-Outputs (im OpenBSD-Kerneldebugger ’ddb’ per ‘trace’ aufgerufen) kann die betreffende Funktion erkannt und im Quellcode schnell lokalisiert werden. Im Falle des gestorbenen Firewallnodes lässt folgende Ausgabe das Problem auf das Sourcefile ‘sys/net/if_pfsync.c’ zurückführen:

pfsync_insert_net_state(e34d4038,1,8,e34d4038) at pfsync_insert_net_state+0x472

pfsync_input(e3486a00,14,0,0,d0d1a034) at pfsync_input+0xa21
ipv4_input(e3486a00,d0d0e900,0,d08ab000,30) at ipv4_input+0x4f1
ipintr(d0640058,d30010,d08a0010,d08a0010,d08ab000) at ipintr+0x70
Bad frame pointer: 0xd08ace24
Erneut mit Debuginformationen kompiliert und disassembliert finden wir per ‘grep’ die fehlerhafte Funktion und addieren der dort angegebenen Speicheradresse den Offset aus unserem Trace-Output hinzu:
# grep “<pfsync_insert_net_state>” if_pfsync.dis
> 000002f4 <pfsync_insert_net_state>

Adam Riese addiert die Hexadezimalzahlen 0x2f4 + 0x472 zu 0x766 - genau in jener Zeile sollte sich innerhalb unseres disassemblierten Codes die Instruktion aus unserem Kerneltrap finden, und siehe da:

/usr/src/sys/net/if_pfsync.c:248
      756:       a1 b4 04 00 00          mov    0x4b4,%eax
      757:       R_386_32   pf_main_anchor
      75b:       66 c1 ca 08             ror    $0x8,%dx
      75f:       c1 ca 10                ror    $0x10,%edx
      762:       66 c1 ca 08             ror    $0x8,%dx
      766:       8b 14 90                mov    (%eax,%edx,4),%edx
      769:       89 55 ec                mov    %edx,0xffffffec(%ebp)
      76c:       e9 e5 fb ff ff          jmp    356 <pfsync_insert_net_state+0x62>
      771:       8d 76 00                lea    0x0(%esi),%esi

Damit haben wir die genaue Zeilenangabe des betreffenden Codeteils innerhalb der Funktion ‘pfsync_insert_net_state’ gewonnen, welche wir schon im Sourcefile ‘sys/net/if_pfsync.c’ festmachen konnten. Mit etwas Kontext sprechen also alle Indizien das folgende Konstrukt schuldig:

/*
* If the ruleset checksums match, it’s safe to associate the state
* with the rule of that number.
*/
if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) && chksum_flag)
        r = pf_main_ruleset.rules[
            PF_RULESET_FILTER].active.ptr_array[ntohl(sp->rule)];
else
        r = &pf_default_rule;

Tiefer bewanderte Kerneldeveloper identifizieren hier eine Racecondition zwischen den Ruleset-Reloads beider Maschinen und stellen - keine 24 Stunden nach Meldung des Bugs - den ersten Patch zur Evaluation, der mittlerweile mit Revision 1.83 im CVS des MAIN-Branches enthalten ist - und auch hier erfolgreich unter Stress gesetzt wurde:

/*
* If the ruleset checksums match, it’s safe to associate the state
* with the rule of that number.
*/
if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) && chksum_flag &&
    ntohl(sp->rule) <
    pf_main_ruleset.rules[PF_RULESET_FILTER].active.rcount)
        r = pf_main_ruleset.rules[
            PF_RULESET_FILTER].active.ptr_array[ntohl(sp->rule)];
else
        r = &pf_default_rule;

Das Fazit: Selbst durchaus unerfreuliche Vorkommnisse bieten bei Verfügbarkeit des Quellcodes das Potential, ungekannte Hintergründe zu verstehen und von Ihnen manchesmal Neues zu erlernen. Die Kommunikation mit den Entwicklern freier Software lässt darüber hinaus das gute Gefühl entstehen, selbst als einfacher Bote einer schlechten Nachricht beim Prozess der stetigen Verbesserung der quelloffenen Produkte positiv mitwirken zu können. Denn auch gerade davon lebt Open Source - den ausführlichen Bugreports dankbarer User.

1713 Klicks

Bugs

Yeah, found a bug!

Was ich an einem jeden Sommer weniger mag, sind die dazugehörigen, lästigen Insekten - besonders dann, wenn sie sich derart dreist in den Vordergrund drängen müssen. Zum totschlagen bin ich zu weich, ganz abgesehen davon, dass das zu wirklich hässlichen Flecken auf dem Monitor führen kann und oft noch eklig zuckt. Im Moment versucht sich das Getier in der Hitze der Halogenlampe auf meinem Schreibtisch das kurze Leben zu nehmen - ich wünsche viel Erfolg dabei. Alles in allem hat das kühle Weissbier nach fruchtbarer Codingsession auf dem sommerlichen Balkon im Grünen jedoch mal wieder für derlei Kleinigkeiten und mehr entschädigen können. Ein Dank an Phil für das gelungene Catering! ;-)

2580 Klicks

Hartz IV AKA Maut II?

Staatlich finanzierte Groß- und Prestigeprojekte scheinen in letzter Zeit unter keinem guten Stern zu stehen, sie sind ganz im Gegenteil offensichtlich in großen Teilstücken erst einmal zum spektakulären Scheitern verurteilt.

Nach dem Desaster eines unnötig überdimensionierten Mautprojektes müssen nun aller Wahrscheinlichkeit nach wegen erneuten Pfusches am virtuellen Bau hunderttausende Arbeitslosengeld-II-Empfänger den Jahresbeginn 2005 ohne Geld verbringen.

Die neuerliche Glanzleistung: Kontonummern mit weniger als zehn Stellen wurden dank der Finanzbuchhaltungssoftware der Bundesagentur für Arbeit von der falschen (nämlich der rechten) Seite her aufgefüllt. Aus der Kontonummer “123456” wurde so eine neue Kontonummer, im Beispiel die “1234560000”. Nach korrekter Schreibweise hätten die Nullen linksbündig eingefügt werden müssen, um so richtig “0000123456” zu ergeben.

Nunja - wer den Schaden hat, braucht für den Spott nicht zu sorgen. “Made in Germany” allerdings dürfte bei solch grandiosen Verfehlungen bald eher an Schilda gemahnen. Peinliche Fehler dieser Art sollten bei sorgfältigen Vorabtests eben nicht passieren. Ein hehrer Wunsch, ich weiss.

Relevante Links:

Hartz IV: GAU bei der Arbeitslosengeld-II-Zahlung

2289 Klicks

No, it's not a bug!

Paketdatenbanken spielen bei RPM-basierten Linux Distributionen wie Fedora eine zentrale Rolle, sie sind ein äußerst kritischer Bestandteil des ganzen Systems. Programme, die darauf zugreifen, sollten demnach so stabil und fehlerfrei wie möglich sein und in keinem Fall inkonsistente Daten zurücklassen - es sei denn, dies diene der gezielten Bestrafung einzelner Nutzer bei versehentlichen Fehlbedienungen. So zumindest lesen sich die beharrlichen Antworten eines Fedora Entwicklers auf den Bugreport eines betroffenen Users, der vor dem Update seines Fedora Systems per “yum” vergessen hatte, die sonst “read only” gemountete /usr-Partition in einen beschreibbaren Zustand zu versetzen.

Die recht amüsante Diskussion auf Red Hats Bugtracker findet sich hier:
“Bug 119185: yum update corrupts rpm database if /usr is readonly”

Legal Disclaimer: Kaffeetassen sind beiseite zu stellen. Für im Affekt auf Monitor oder Tastatur ergossene Nahrungsmittel wird keine Haftung übernommen.

Stilblüten:

Linux is a system for experts only. If you make a mistake you deserve to have your database corrupted.

Gefunden via “Almost virtual everything”, das im Verhalten des besagten Developers Parallelen zu ganz anderen, bekannten Größen des IT Business auszumachen glaubt. ;-)

Köstlich!

2651 Klicks