Was sind „Schattenbytes“ in AddressSanitizer und wie soll ich sie interpretieren?

Lesezeit: 8 Minuten

the_endians Benutzeravatar
the_endian

Ich debugge ein C-Programm und bin ernsthaft verwirrt etwa die untere Hälfte der AddressSanitizer-Ausgaben, wenn Probleme gefunden werden. Lassen Sie uns dies zum Beispiel verwenden:

==33184==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000005 at pc 0x55f312fe2509 bp 0x7ffc99f5f5c0 sp 0x7ffc99f5f5b0
WRITE of size 1 at 0x602000000005 thread T0
    #0 0x55f312fe2508 in main /home/user/c/friends/main.c:20
    #1 0x7fa5ea0e9b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #2 0x55f312fe21c9 in _start (/home/user/c/friends/cmake-build-debug/friends+0x11c9)

0x602000000005 is located 11 bytes to the left of 5-byte region [0x602000000010,0x602000000015)
allocated by thread T0 here:
    #0 0x7fa5eb2b8b40 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb40)
    #1 0x55f312fe23f4 in main /home/user/c/friends/main.c:18
    #2 0x7fa5ea0e9b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/user/c/friends/main.c:20 in main

  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000:[fa]fa 05 fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==33184==ABORTING

Alles über dieser Zeile verstehe ich: SUMMARY: AddressSanitizer: heap-buffer-overflow /home/user/c/friends/main.c:20 in main

Meine Frage betrifft die unter dieser Zeile dargestellten Daten. Ich habe diese Antwort gelesen, aber sie hat meine Frage nicht beantwortet. Der von ASAN angezeigte Speicherauszug sieht folgendermaßen aus:

  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000:[fa]fa 05 fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  1. Was will mir die Zeile mit dem Pfeil sagen? Das ist meine Vermutung 05 die zwischen den erscheint fas bezieht sich auf die 0x602000000005 is located 11 bytes to the left of 5-byte region „5-Byte-Region.“ Allerdings bin ich immer noch verwirrt, weil die Legende das sagt fa bedeutet „Heap links Redzone“, erscheint aber dennoch Nach rechts des 05 Und links davon. Warum gibt es keine „Heap Right Redzones“?

  2. In diesem Beispiel sagt ASAN, dass das Programm 11 Bytes über den 5-Byte-Bereich hinausgegangen ist, zeigt aber weit mehr an fas als das.

  3. Gibt es eine ordnungsgemäße, detaillierte Dokumentation, die tatsächlich erklärt, was diese Begriffe „Heap Left Redzone“, „Stack Mid Redzone“, „Global Redzone“ usw. bedeuten? Ich konnte keine finden.

  4. Was ist in diesem Zusammenhang ein „Schattenbyte/eine Schattenadresse“?

  • hast du kontrolliert en.wikipedia.org/wiki/Shadow_memory ?

    – bolov

    8. Mai 2020 um 7:56

  • Vielleicht könnten Sie eine Reihe von Testprogrammen schreiben, in denen Sie absichtlich etwas Bekanntes an einem bekannten Ort außerhalb der Grenzen schreiben? Nach einigen Experimenten könnten Sie verstehen, was Sie in verschiedenen Out-of-Bounds-Szenarien erwartet.

    – Roberto Caboni

    8. Mai 2020 um 8:22

  • @RobertoCaboni Auch das war schwierig, da ASAN das Programm sofort abbricht, sodass ich die genauen Speicheradressen in gdb nicht überprüfen kann, nachdem ich die Ausgabefehlermeldung sehe. Ihre Dokumente, in denen erläutert wird, wie in GDB ein Break vor dem Beenden durchgeführt wird, sind veraltet und stammen aus dem Jahr 2016. Möglicherweise kann ich ASLR deaktivieren und einfach dasselbe Programm ein paar Mal ausführen und die Adresse in einer Nicht-ASAN-Version mit Crossrefs versehen, aber sie schaffen es nicht einfach.

    – the_endian

    8. Mai 2020 um 8:28

  • Wenn es abbricht, haben Sie einen Core-Dump des gesamten Programmstatus einschließlich Speicher, oder? ulimit natürlich zulassen.

    – Nutzlos

    10. Mai 2020 um 21:59 Uhr

  • @Useless, eigentlich nicht. Ich bekomme immer wieder Coredump entry has no core attached (neither internally in the journal nor externally on disk). von coredumpctl. Dies ist ein separates Thema, daher werde ich hier nicht weiter darauf eingehen.

    – the_endian

    12. Mai 2020 um 4:21

Benutzeravatar von Useless
Nutzlos

Was sind „Schattenbytes“ in AddressSanitizer und wie soll ich sie interpretieren?

Von dem AddressSanitizerAlgorithmus Seite auf GitHub (die auch von der verlinkt ist LLVM AddressSanitizer-Seite):

Der virtuelle Adressraum ist in zwei disjunkte Klassen unterteilt:

  • Hauptanwendungsspeicher (Mem): Dieser Speicher wird vom regulären Anwendungscode verwendet.
  • Schattenspeicher (Shadow): Dieser Speicher enthält die Schattenwerte (oder Metadaten). Es besteht eine Entsprechung zwischen dem Schatten und dem Hauptspeicher der Anwendung. Ein Byte im Hauptspeicher zu vergiften bedeutet, einen speziellen Wert in den entsprechenden Schattenspeicher zu schreiben.

„Schattenbytes“ sind also Metadaten, die den Zustand des adressierbaren Speichers Ihres Programms beschreiben.

Wenn wir uns die Asan-Ausgabe ansehen:

Shadow byte legend (one shadow byte represents 8 application bytes):

Es sagt uns, dass der Hexdump vom Schattenspeicher stammt, der den Zustand des „realen“ Speichers Ihres Programms beschreibt. Welche Zustände werden verfolgt?

  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  ...

Wenn also eine ganze 8-Byte-Zeile adressierbar ist, sollte das Schattenbyte, das sie verfolgt (oder beschattet), einen Wert haben 00. Wenn es teilweise adressierbar ist, ist es das Schattenbyte 01..07was vermutlich die Anzahl der adressierbaren Bytes in der Zeile ist.

Der Wert, auf den Sie der Hex-Dump hinweist, ist faoder „Heap left redzone“ – vermutlich ist dies eine Art Schutzbereich um Heap-Zuweisungen, um Überläufe zu erkennen.

Vom selben Link:

Die Laufzeitbibliothek ersetzt die Funktionen malloc und free. Das Gedächtnis um mallocierte Regionen (rote Zonen) ist vergiftet

Im weiteren Sinne ist diese Beschreibung (in Programmadressen)

0x602000000005 is located 11 bytes to the left of 5-byte region
  [0x602000000010,0x602000000015)

entspricht der angezeigten Schattenkarte:

=>0x0c047fff8000:[fa]fa 05 fa ...

Unter der Annahme einer natürlichen Ausrichtung,

  • Schattenbyte 0x0c047fff8000 beschreibt (oder wiederum beschattet) Programmadressen 0x602000000000..0x602000000007 Dazu gehört auch die Adresse, auf die Sie zugegriffen haben
  • das nächste Schattenbyte um 0x0c047fff8001 beschreibt Programmadressen 0x602000000008..0x60200000000F
  • Beides hat seinen Wert fawas „Haufen links Redzone“ bedeutet
  • Die nächste Schattenbyte bei 0x0c047fff8002 beschreibt Programmadressen 0x602000000010..0x602000000007 und hat Wert 05, was bedeutet, dass 5 Bytes adressierbar sind. Dies sind die 5 Bytes Ihrer Heap-Zuweisung.

All dies steht im Einklang mit dem Teil des Fehlers, den Sie gemacht haben tat verstehen.

  1. Allerdings bin ich immer noch verwirrt, weil die Legende besagt, dass fa „Haufen links in der Redzone“ bedeutet, aber es erscheint trotzdem Nach rechts des 05 Und links davon. Warum gibt es keine „Heap Right Redzones“?

    Ich weiß nicht, was die Direktionalität hier wirklich bedeutet. Heaps wachsen typischerweise zunächst in eine Richtung (traditionell nach oben, wenn der Stapel nach unten wächst), können aber fragmentiert, freigegeben, zusammengeführt und neu zugewiesen werden. Ist der Steg zwischen zwei Zuordnungen „rechts“ oder „links“ oder beides oder keines von beiden? Wir müssen lediglich wissen, dass es sich um einen vergifteten Heap-Bereich handelt, der dem Benutzer nie zugewiesen wurde.

    Vielleicht sollte es einfach „Heap Redzone“ sein, wenn es keine Ausrichtung gibt, die den Stapelwerten links/mitte/rechts entspricht.

  2. In diesem Beispiel gibt ASAN an, dass das Programm 11 Bytes über den 5-Byte-Bereich hinausgegangen ist, zeigt aber weit mehr als das an.

    jede fa stellt acht Bytes dar, wie die Legende sagt. Wenn Sie also vor der Zuweisung auf etwas zwischen neun und fünfzehn Bytes zugegriffen hätten (Modulo-Arithmetikfehler), wäre es im selben Schattenbyte aufgetaucht. Wenn Sie zuvor auf ein bis acht Bytes zugegriffen hätten, wäre es im angezeigt worden nächste Schattenbyte (direkt vor dem 05).

    Der Rest des faEs handelt sich lediglich um eine Karte der Umgebung, was in diesem Fall nicht hilfreich erscheint, in anderen Fällen jedoch möglicherweise hilfreich ist.

  3. Gibt es eine ordnungsgemäße, detaillierte Dokumentation, die tatsächlich erklärt, was diese Begriffe „Heap Left Redzone“, „Stack Mid Redzone“, „Global Redzone“ usw. bedeuten?

    Keine Ahnung. Sie scheinen sich jedoch ziemlich natürlich aus dem Anwendungsfall zu ergeben – Sie erreichen einen roten Bereich = Sie haben auf eine Adresse zugegriffen, die Sie nicht sollten. Sie können den Code jederzeit einfach lesen, z. asan_internal.h definiert die kAsanHeapLeftRedzoneMagic Wert und asan_allocator.cpp vergiftet damit Schattenbytes.

  4. Was ist in diesem Zusammenhang ein „Schattenbyte/eine Schattenadresse“?

    Der Vollständigkeit halber: Ein Schattenbyte ist ein Byte, das Schatten eine Gruppe von acht normalerweise zugänglichen Programmbytes und verfolgt einige Informationen darüber, die für den Sanitizer nützlich sind.

    Eine Schattenadresse ist die Adresse eines Schattenbytes.

  • Das war eine ausgezeichnete Antwort. Ich entschuldige mich dafür, dass es so lange gedauert hat, das Kopfgeld zu vergeben. Mir war nicht klar, dass ich noch andere Maßnahmen ergreifen muss, als dies als Antwort auszuwählen. Es sieht jedoch so aus, als hätte Ihnen das System jetzt das Kopfgeld zugesprochen. 🙂 🙂

    – the_endian

    20. Mai 2020 um 0:12

  • Keine Sorge, es ist kein Rennen 🙂

    – Nutzlos

    20. Mai 2020 um 10:00 Uhr

1453710cookie-checkWas sind „Schattenbytes“ in AddressSanitizer und wie soll ich sie interpretieren?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy