Libseccomp: BUG: A2-Handhabung durch src/db.c Rework gebrochen

Erstellt am 26. Feb. 2018  ·  18Kommentare  ·  Quelle: seccomp/libseccomp

Um meine vorgeschlagenen Leistungsverbesserungen für den Binärbaum zu testen, habe ich einen unrealistischen Regelsatz für read() und sein Puffergrößenargument (A2) geschrieben. Aber es scheint, dass der src/db.c-Rework-Commit (ce3dda9a1) die A2-Verarbeitung unterbrochen hat - zumindest für diesen Testfall.

Vor dem db-Rework-Commit gab ein Read wie der folgende - read(devzero_fd, buf, 8000) - -10 . Nach diesem Commit gibt es jetzt -5 .

Hier ist der C-Code, den ich verwendet habe, um meine dummen read()-Regeln zu generieren:

        /* read */
        for (i = 5; i <= 12; i++) {
                rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(i), SCMP_SYS(read), 1,
                        SCMP_A2(SCMP_CMP_GT, 4 << i));
                if (rc < 0) {
                        fprintf(stdout, "%s:%d Failed to add read rule %d : rc = %d\n",
                                __FUNCTION__, __LINE__, i, rc);
                        goto error;
                }   
        }   
        rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1,
                SCMP_A2(SCMP_CMP_LE, 64));
        if (rc < 0) {
                fprintf(stdout, "%s:%d Failed to add read allow rule : rc = %d\n",
                        __FUNCTION__, __LINE__, rc);
                goto error;
        } 

Und hier ist der PFC, der generiert wurde:

  # filter for syscall "read" (0) [priority: 65525]
  if ($syscall == 0)
    if ($a2.hi32 >= 0)
      if ($a2.lo32 > 64)
      else
        action ALLOW;
      if ($a2.lo32 > 16384)
        action ERRNO(12);
      if ($a2.lo32 > 8192)
        action ERRNO(11);
      if ($a2.lo32 > 4096)
        action ERRNO(10);
      if ($a2.lo32 > 2048)
        action ERRNO(9);
      if ($a2.lo32 > 1024)
        action ERRNO(8);
      if ($a2.lo32 > 512)
        action ERRNO(7);
      if ($a2.lo32 > 256)
        action ERRNO(6);
      if ($a2.lo32 > 128)
        action ERRNO(5);
    else
      action ALLOW;
  # default action
  action ERRNO(34);
bug priorithigh

Alle 18 Kommentare

Übrigens, ich werde tun, was ich kann, um die Ursache zu finden

Mit scmp_bpf_disasm bringt die neueste libseccomp die Sprünge in die falsche Reihenfolge

KOPF

 0014: 0x25 0x11 0x00 0x00000080   jgt 128  true:0032 false:0015
 0015: 0x25 0x0f 0x00 0x00000100   jgt 256  true:0031 false:0016
 0016: 0x25 0x0d 0x00 0x00000200   jgt 512  true:0030 false:0017
 0017: 0x25 0x0b 0x00 0x00000400   jgt 1024 true:0029 false:0018
 0018: 0x25 0x09 0x00 0x00000800   jgt 2048 true:0028 false:0019
 0019: 0x25 0x07 0x00 0x00001000   jgt 4096 true:0027 false:0020
 0020: 0x25 0x05 0x00 0x00002000   jgt 8192 true:0026 false:0021
 0021: 0x25 0x03 0x00 0x00004000   jgt 16384 true:0025 false:0022
 0022: 0x25 0x01 0x00 0x00000040   jgt 64   true:0024 false:0023
 0023: 0x06 0x00 0x00 0x7fff0000   ret ALLOW

Vorarbeit

 0014: 0x25 0x01 0x00 0x00000040   jgt 64   true:0016 false:0015
 0015: 0x06 0x00 0x00 0x7fff0000   ret ALLOW
 0016: 0x25 0x0f 0x00 0x00004000   jgt 16384 true:0032 false:0017
 0017: 0x25 0x0d 0x00 0x00002000   jgt 8192 true:0031 false:0018
 0018: 0x25 0x0b 0x00 0x00001000   jgt 4096 true:0030 false:0019
 0019: 0x25 0x09 0x00 0x00000800   jgt 2048 true:0029 false:0020
 0020: 0x25 0x07 0x00 0x00000400   jgt 1024 true:0028 false:0021
 0021: 0x25 0x05 0x00 0x00000200   jgt 512  true:0027 false:0022
 0022: 0x25 0x03 0x00 0x00000100   jgt 256  true:0026 false:0023
 0023: 0x25 0x01 0x00 0x00000080   jgt 128  true:0025 false:0024
 0024: 0x06 0x00 0x00 0x00050022   ret ERRNO(34)

Interessant. Der PFC scheint also "richtig" zu sein, aber der generierte BPF ist ... rückwärts. Seltsam. Vor allem, da der Commit den BPF-Generierungscode nicht geändert hat.

Ich frage mich, ob die Prioritätswerte irgendwie durcheinander geraten?

Entschuldigung für die Mehrdeutigkeit. Auch der PFC (Nacharbeitsänderung buchen) ist in der falschen Reihenfolge. Der oben gepostete PFC ist die Reihenfolge, in der er vor der db.c-Überarbeitung war.

Hier ist der aktuell von HEAD generierte PFC

  # filter for syscall "read" (0) [priority: 65525]
  if ($syscall == 0)
    if ($a2.hi32 >= 0)
      if ($a2.lo32 > 128)
        action ERRNO(5);
      if ($a2.lo32 > 256)
        action ERRNO(6);
      if ($a2.lo32 > 512)
        action ERRNO(7);
      if ($a2.lo32 > 1024)
        action ERRNO(8);
      if ($a2.lo32 > 2048)
        action ERRNO(9);
      if ($a2.lo32 > 4096)
        action ERRNO(10);
      if ($a2.lo32 > 8192)
        action ERRNO(11);
      if ($a2.lo32 > 16384)
        action ERRNO(12);
      if ($a2.lo32 > 64) 
      else
        action ALLOW;
    else
      action ALLOW;
  # default action
  action ERRNO(34);

Okay, das macht ein bisschen mehr Sinn. Das Problem liegt definitiv irgendwo in der DB-Schicht.

Es ist ein bisschen komisch, wie es genau rückwärts ist.

Ich habe das Problem gefunden. In der Kettenargumentverwaltung wurde das Verhalten von lvl_nxt und lvl_prv nach der massiven Überarbeitung von db.c vertauscht. Ein paar kleine Änderungen an _db_tree_add() haben dazu geführt, dass es dem vorherigen Verhalten von libseccomp entspricht.

Hier ist ein Zweig mit dem Fix
https://github.com/drakenclimber/libseccomp/tree/issues/112

Ich bereinige die Änderungen, füge ein oder zwei Tests hinzu und stelle sicher, dass die Codeabdeckung auf dem neuesten Stand ist.

Ich habe heute Morgen etwas Zeit gefunden, wahrscheinlich kurz bevor Sie das oben Geschriebene gepostet haben, und beschlossen, mir das ein wenig anzusehen. Es sieht so aus, als wären wir zu ziemlich derselben Schlussfolgerung gekommen, obwohl die Korrekturen etwas unterschiedlich sind. Hier ist mein aktueller Fix, obwohl er wie bei Ihnen etwas zusätzliche Arbeit/Bereinigung erfordert:

Ich bin mir nicht sicher, welche Herangehensweise mir gerade besser gefällt, ich muss ein bisschen darüber nachdenken, Gedanken?

Hmmm... Ich werde nicht lügen; Ich bin an dieser Stelle von keinem der Fixes begeistert.

Meins ist einfach, aber es ignoriert _db_tree_prune() vollständig, das - wie Sie in Ihrem Kern gesagt haben - wahrscheinlich ähnliche Probleme hat.

Ich mag Ihre Idee, das gt()-Makro zu überarbeiten, um die Makros lt() und eq() zu verwenden, aber sie werden unhandlich - insbesondere lt(). Gibt es einen Grund, lt() nicht in eine Inline-Funktion zu konvertieren?
BEARBEITEN - Mir ist gerade aufgefallen, dass Sie einen ähnlichen Kommentar im Kern abgegeben haben.

Ich habe gdb gegen die alten libseccomp und HEAD ausgeführt, und das Verhalten von lvl_prv und lvl_nxt hat sich geändert, aber vielleicht ist das keine große Sache, da es sich um eine interne Variable handelt, die niemand außer uns sehen sollte.

Ich schätze, nach all diesem Geschwafel... Ich weiß es nicht. Ich stimme zu, muss ich mir überlegen ;)

Hmmm... Ich werde nicht lügen; Ich bin an dieser Stelle von keinem der Fixes begeistert.

Ich mache mir Sorgen , dass es einige subtile Bugs sind eine Baumebene wie dies mit Neuordnen, auch wenn es das Niveau scheint wie vielleicht neu geordnet wurde , dass frühere begehen und dies ist einer der subtilen Bugs.

In jedem Fall möchte ich verstehen, wie die gewünschte Reihenfolge für ein Level sein sollte: "größte" zuerst oder "größte" zuletzt? Sobald wir das verstanden haben, können wir mit dem Testen/Fixieren fortfahren. Ich denke, die Antwort ist, wenn auch aus keinem anderen Grund als der Kompatibilität mit früheren 2.x-Versionen, zuerst "die größte", aber das kann ich an dieser Stelle nicht mit Sicherheit sagen.

Meins ist einfach, aber es ignoriert _db_tree_prune() vollständig, das - wie Sie in Ihrem Kern gesagt haben - wahrscheinlich ähnliche Probleme hat.

Beide machen im Prinzip das gleiche, meine geht noch etwas weiter, indem sie einige zusätzliche Bedingungen hinzufügt und das db_chain_lt(x,y)-Makro aufräumt.

Ich mag Ihre Idee, das gt()-Makro zu überarbeiten, um die Makros lt() und eq() zu verwenden, aber sie werden unhandlich - insbesondere lt(). Gibt es einen Grund, lt() nicht in eine Inline-Funktion zu konvertieren?

Meist historische Gründe. Sie begannen ihr Leben als viel einfachere Makros, aber sie sind ziemlich gewachsen bis zu dem Punkt, an dem sie meiner Meinung nach wahrscheinlich Funktionen sein sollten. Ich denke, es wäre auch gut zu bewerten, ob sie wirklich in der Header-Datei sein müssen, ich glaube, sie werden nur von src/db.c verwendet.

Ich habe gdb gegen die alten libseccomp und HEAD ausgeführt, und das Verhalten von lvl_prv und lvl_nxt hat sich geändert, aber vielleicht ist das keine große Sache, da es sich um eine interne Variable handelt, die niemand außer uns sehen sollte.

Ja, es ist ein interner Zustand/Baum, darüber mache ich mir keine allzu großen Sorgen. Wichtig ist die Richtigkeit des erzeugten Filters.

Ich schätze, nach all diesem Geschwafel... Ich weiß es nicht. Ich stimme zu, muss ich mir überlegen ;)

He. Geben wir dem ein oder zwei Tage Zeit und gruppieren wir uns neu :) Im Moment betrifft dies keine veröffentlichten Versionen, es ist nur im Master-Zweig, also haben wir etwas Zeit, um die Dinge richtig zu machen.

Im Moment betrifft dies keine veröffentlichten Versionen, es ist nur im Master-Zweig, also haben wir etwas Zeit, um die Dinge richtig zu machen.

Hört sich gut an. Ich werde ein paar Tests machen, während wir über einen Plan nachdenken

Ich habe ein Programm geschrieben, um den aktuellen Umgang mit seccomp A2 auszuwerten. Das ganze Programm gibt es hier:

https://gist.github.com/drakenclimber/3c6b45ecd973ee495281ef225fa5e54a

Kurz gesagt, Größer-als-Regeln werden in einer "zuletzt erstellten" "zuerst verarbeiteten" Reihenfolge generiert.

  • Für einen Filter , bei dem > Regeln in aufsteigender Reihenfolge erstellt werden, zB
    seccomp_rule_add(ctx, action1, syscall, 1, SCMP(SCMP_CMP_GT, 10)
    seccomp_rule_add(ctx, action2, syscall, 1, SCMP(SCMP_CMP_GT, 20)
    seccomp_rule_add(ctx, action3, syscall, 1, SCMP(SCMP_CMP_GT. 30)
    dann verhält sich der Filter kohärent, zB
if (A2 > 30)
    do action3
if (A2 > 20)
    do action2
if (A2 > 10)
    do action1
  • Für einen Filter , bei dem > Regeln in absteigender Reihenfolge erstellt werden, zB
    seccomp_rule_add(ctx, action3, syscall, 1, SCMP(SCMP_CMP_GT, 30)
    seccomp_rule_add(ctx, action2, syscall, 1, SCMP(SCMP_CMP_GT, 20)
    seccomp_rule_add(ctx, action1, syscall, 1, SCMP(SCMP_CMP_GT. 10)
    dann wird der Filter erstellt, verhält sich aber seltsam. Es wird toter Code erzeugt. Die letzten beiden if Anweisungen sind nicht erreichbar
if (A2 > 10)
    do action1
if (A2 > 20)
    do action2
if (A2 > 30)
    do action1
  • Filter mit mehreren < A2-Operationen werden derzeit von seccomp nicht zugelassen. Das scheint seltsam, weil ich keinen Weg finden konnte, das <= Äquivalent des > Filters oben zu erstellen
tom<strong i="43">@OracleDesktop</strong> $ ./a2test 3
Failed to add rule
        action = 0x5000e op = 0x3 datum = 18000 rc = -17
Mode 3 (LE descending) test failed.  rc = -17
tom<strong i="46">@OracleDesktop</strong> $ ./a2test 4
Failed to add rule
        action = 0x50006 op = 0x3 datum = 250 rc = -17
Mode 4 (LE ascending) test failed.  rc = -17

Ich vermute, dass die tief in src/db.c vergrabene else if Logik die < Fehler verursacht, zB . Ich bin mir nicht sicher, ob es sich lohnt zu ändern / zu reparieren.

Ich werde versuchen, einen Teil dieses Codes in automatisierte Tests umzuwandeln, damit wir das aktuelle Verhalten erfassen können.

Wie geschrieben, hat das Wesentliche hier die automatisierten Tests, die ich letzte Woche hinzugefügt habe

 batch name: 43-sim-a2_order
 test mode:  c
 test type:  bpf-sim
Test 43-sim-a2_order%%001-00001 result:   SUCCESS
Test 43-sim-a2_order%%002-00001 result:   SUCCESS
Test 43-sim-a2_order%%003-00001 result:   SUCCESS
Test 43-sim-a2_order%%004-00001 result:   SUCCESS
Test 43-sim-a2_order%%005-00001 result:   SUCCESS
Test 43-sim-a2_order%%006-00001 result:   SUCCESS
Test 43-sim-a2_order%%007-00001 result:   SUCCESS
Test 43-sim-a2_order%%008-00001 result:   FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%009-00001 result:   FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%010-00001 result:   FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%011-00001 result:   FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%012-00001 result:   FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%013-00001 result:   FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%014-00001 result:   FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%015-00001 result:   FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%016-00001 result:   FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%017-00001 result:   FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%018-00001 result:   FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%019-00001 result:   FAILURE bpf_sim resulted in ERRNO(5)
Test 43-sim-a2_order%%020-00001 result:   FAILURE bpf_sim resulted in ERRNO(5)

Meine schlechte - ich habe das Wesentliche falsch angewendet. Die Prüfungen werden bestanden. Puh :)

Ha! :)

Ich dachte, ich hätte die Tests dagegen durchgeführt, aber ich habe zu dieser Zeit mit vielen Dingen gespielt, also dachte ich, ich erinnere mich nur falsch. Danke, dass Sie sich das weiter ansehen, ich bin immer noch ein bisschen mit SELinux und Audit festgefahren, aber da der Kernel gerade auf -rc5 ist, erwarte ich, dass er sich bald beruhigt, wenn ich vor dem Zusammenführen die Breaks in den neuen Code einfüge Fenster ...

Kein Problem. Das hat definitiv höhere Priorität.

Ich habe Ihr Wesentliches durch verschiedene unrealistische Tests geführt. Ich habe es nicht zum Brechen gebracht, aber ich trainiere bisher auch nur Teile von _db_tree_prune(). Ich beginne mich mit den Änderungen wohler zu fühlen, aber ich möchte etwas mehr Zeit dafür haben.

Ich habe den Code von _db_tree_prune () angestochen und angetippt und konnte ihn nicht knacken. Test 08-sim-subtree_checks leistet wirklich gute Arbeit beim Testen der meisten Codepfade in prune().

Ich denke, die Änderungen von Ihrem Kern sind gut zu gehen.

Ich habe Pull-Request Nr. 115 eingereicht. Ich denke, das ist bereit zu rollen

Schließen, da dies nun behoben sein sollte (siehe Verlauf oben).

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

oxr463 picture oxr463  ·  4Kommentare

pcmoore picture pcmoore  ·  20Kommentare

srd424 picture srd424  ·  18Kommentare

cgwalters picture cgwalters  ·  14Kommentare

varqox picture varqox  ·  23Kommentare