staging.inyokaproject.org

ioctl() - Was tut dieser Systemcall und warum könnte er fehlschlagen?

Status: Ungelöst | Ubuntu-Version: Ubuntu 20.04 (Focal Fossa)
Antworten |

Tanrim

Anmeldungsdatum:
14. September 2012

Beiträge: Zähle...

Hallo,

was hier vielleicht jemand was die Funktion ioctl() genau macht und vor allem, warum sie Fehlschlagen könnte?

Für ein Studiumsprojekt muss ich einen bestimmten Quelltext bei mir zum Laufen bringen, der ioctl() benutzt. Bei der Ausführung der Quellcodes kommt es zum Abbruch mit dem Fehlercode 25 in der Fehlervarable ERRNO, die den Fehler genauer spezifizieren soll. Laut meiner Recherche steht Code 25 für [Errno 25] Inappropriate ioctl for device.

Kann mir vielleicht jemand weiterhelfe? Was könnte den Fehler verursachen, vor allem, wenn man davon ausgeht, dass alle Parameter für die Funktion korrekt übergeben werden?

Vielen Dank im Voraus.

Mit freundlichen Grüßen

Tanrim

P.S. Mein Testgerät - Dell Inspiron 15 3000 - CPU: Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz - RAM: 8 GB - OS: Ubuntu 20.04.6 LTS - Kernel: 5.15.0-67-generic

Moderiert von kB:

Aus dem Forum „Sicherheit“ in einen besser passenden Forenbereich verschoben. Bitte beachte die als wichtig markierten Themen („Welche Themen gehören hier her und welche nicht?“) im jeweiligen Forum! Danke.

Bearbeitet von Thomas_Do:

Titel korrigiert.

ChickenLipsRfun2eat Team-Icon

Supporter
Avatar von ChickenLipsRfun2eat

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12070

Hallo!

ioctl ist die Schnittstelle in Linux, um mit Gerätetreibern zu kommunizieren: https://www.kernel.org/doc/html/latest/driver-api/ioctl.html#

Inappropriate ioctl bedeutet, das der von dir abgesetzte Befehl nicht funktioniert hat. Das kann viele Gründe haben. Hast du Zugriff auf das entsprechende Gerät per Benutzer und Gruppen oder arbeitest du mit root? Welches Gerät versuchst du wie zu beeinflussen? Linux behandelt alles als Datei, diese kann aber auch nur lesend sein, oder nur schreibend. Unterstützt das Gerät den entsprechenden Aufruf?

Ich habe nur wenig mit ioctl gemacht und kann dir daher vermutlich keine Detailfragen beantworten, falls du nicht gerade die Tastatur manipulieren willst 😉

Tanrim

(Themenstarter)

Anmeldungsdatum:
14. September 2012

Beiträge: 28

@ChickenLipsRfun2eat

Vielen Dank für deine Antwort. Zu deiner Frage,

...arbeitest du mit root?

Ich arbeite als root.

Welches Gerät versuchst du wie zu beeinflussen?

Letztlich geht es um den APIC - Advanced Programmable Interrupt Controller

Spätestens jetzt brauche ich wohl kein Geheimnis mehr daraus zu machen. Ich arbeite an einem Projekt für mein Studium welches sich um die Sicherheitslücke AEPIC Leak dreht, die den APIC betrifft.

Mir ist klar, ich begebe mich hier jetzt wohl auf dünnes Eis, weil sich jetzt jeder fragen könnte, welche Absichten hat dieser Tanrim wirklich und weil man in einem Forum wie diesem letztlich sehr viel schreiben kann.

Die Sicherheitsforscher, die die Lücke entdeckten, haben nach Absprache mit Intel, Quellcode zu dieser Lücke veröffentlicht um Systeme auf diese Lücke zu testen und ihre Auswirkungen demonstrieren zu können. Diesen Quellcode auf meinem Testgerät zu kompilieren und ausführen zu können ist Teil meines Projekts. Der von mir verwendete Prozessor ist das selbe Modell, welches die Sicherheitsforscher auch verwendet haben. Den Quellcode der Forscher zu kompilieren funktioniert inzwischen bei mir. Wenn es jetzt konkret wird Daten von meinem Testgerät zu leaken, bricht die entsprechende "dumper"-Komponente aus dem Quellcode der Forscher, mit der von mir genannten Fehlermeldung ab.

ChickenLipsRfun2eat Team-Icon

Supporter
Avatar von ChickenLipsRfun2eat

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12070

Tanrim schrieb:

Spätestens jetzt brauche ich wohl kein Geheimnis mehr daraus zu machen. Ich arbeite an einem Projekt für mein Studium welches sich um die Sicherheitslücke AEPIC Leak dreht, die den APIC betrifft.

Geheimnisse brauchen wir bei Sicherheitslücken doch eh nicht. Deswegen werden die ja veröffentlicht und idealerweise schnell behoben. Du kannst also ruhig Links zu den Recherchen posten und konkrete Ausgaben nutzen.

…meinem Testgerät zu leaken, bricht die entsprechende "dumper"-Komponente aus dem Quellcode der Forscher, mit der von mir genannten Fehlermeldung ab.

Was vieles bedeuten kann. Vielleicht ist es in deiner Konstellation nicht möglich die Lücke auszunutzen, sie wurde bereits teilweise geschlossen, etc.

Ich würde wohl versuchen zunächst mal den Intel Microcode zu entfernen, um eventuelle Fixes auszuschließen. Dazu wäre es dann interessant die Umgebung zu debuggen — Details dazu kann ich dir natürlich keine nennen. gdb und valgrind helfen dabei.

ioctl ist eine Abstraktion. Du könntest natürlich die funktionsweise nachlesen und in Teilausgaben aufteilen, allerdings halte ich das in dem Fall für wenig zielführend. Ein Treiber besteht ja aus mehreren Komponenten mit unterschiedlichen Zugriffen. Ich würde also bei allem beschreibbaren ansetzen und da gucken, welche Optionen ich habe (Handbuch des Controllers, etc.)

Vielleicht äußert sich hier mal ein „echter Programmierer“ dazu, mein Wissen übersteigt das ziemlich 😉

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 10978

Intel hat gegen den AEPIC Leak ja ein Microcode-Update nachgeschoben: https://www.phoronix.com/news/Intel-20220809-Microcode - und Ubuntu lädt standardmäßig die als Paket (https://packages.ubuntu.com/de/focal-updates/intel-microcode) verfügbaren Microcode-Updates beim Start. Um das zu verhindern, musst du zumindest den initramfs-Hook entfernen und ein neues initramfs bauen (oder das Paket deinstallieren, wodurch das automatisch passiert).

Tanrim

(Themenstarter)

Anmeldungsdatum:
14. September 2012

Beiträge: 28

@ChickenLipsRfun2eat

Ich würde wohl versuchen zunächst mal den Intel Microcode zu entfernen, um eventuelle Fixes auszuschließen. Dazu wäre es dann interessant die Umgebung zu debuggen — Details dazu kann ich dir natürlich keine nennen. gdb und valgrind helfen dabei.

Das Paket intel-microcode habe ich entfernt. Laut "cat /proc/cpuinfo" | grep microcode" habe ich Version 0xb2. GDB werde ich noch etwas austesten müssen.

ioctl ist eine Abstraktion. Du könntest natürlich die funktionsweise nachlesen und in Teilausgaben aufteilen, allerdings halte ich das in dem Fall für wenig zielführend. Ein Treiber besteht ja aus mehreren Komponenten mit unterschiedlichen Zugriffen. Ich würde also bei allem beschreibbaren ansetzen und da gucken, welche Optionen ich habe (Handbuch des Controllers, etc.)

Ich habe bisher nur eine ioctl()-Funktion im mitgelieferten SGX-Treiber gefunden. Ich habe versucht mir innerhalb der Funktion die Werte der einzelnen Variablen ausgeben zu lassen. Einfach durch printf() ausgeben lassen. Leider war es danach nicht möglich die Treiber neu zu kompilieren, da die Include-Datei stdio.h nicht gefunden werden kann, obwohl diese zweifelsfrei da ist.

Im Anhang habe ich die Log-Dateien von "strace" über die Systemaufrufe.

dumper_strace.log (8.6 KiB)
Systemaufrufe
Download dumper_strace.log

Dakuan

Avatar von Dakuan

Anmeldungsdatum:
2. November 2004

Beiträge: 6234

Die Funktion ioctl() ist mir bisher nur zweimal begegnet. Einmal in einem Beispielprogramm in einem Buch, wo gezeigt wird, wie man eine CD auswerfen kann. Und aktuell in einem Beispiel zu einem Server, wo mit FIONREAD der Socket Treiber befragt wird. Leider vergaß der Autor zu erklären, was er da macht.

Offenbar kann man mit ioctl() eine ganze Menge, auch Blödsinn, machen. Ich bin mir auch nicht sicher, ob das alles dokumentiert ist. Gefunden habe ich:

hat mich bisher aber auch nicht viel weiter gebracht.

ChickenLipsRfun2eat Team-Icon

Supporter
Avatar von ChickenLipsRfun2eat

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12070

Tanrim schrieb:

Ich habe bisher nur eine ioctl()-Funktion im mitgelieferten SGX-Treiber gefunden.

ioctl liegt im Kernel: https://github.com/torvalds/linux/blob/master/fs/ioctl.c, aktuell definiert in Zeile 910. Aber so genau musst du dich damit nicht befassen, eher mit dem Gerät.

…da die Include-Datei stdio.h nicht gefunden werden kann, obwohl diese zweifelsfrei da ist.

Wenn dein Compiler auch weiß wo „da“ ist, sollte es klappen. Unter Ubuntu brauchst du die -dev-Pakete zusätzlich, die die Header enthalten. Ansonsten muss eventuell der Pfad übergeben werden (-I bei gcc). Als Helfer steht pkgconf zur Verfügung, welchen du für die Standards allerdings nicht brauchst. Falls du Kernelmodule kompilieren willst, sieht das anders aus, da reicht ein „normales Makefile“ nicht, da die Kernel-Header aus {/usr,}/lib/modules/$(uname -r)/build/include/linux/ und so gebraucht werden: KBuild Modules. Und natürlich müssen die Kernelheader installiert sein, bzw. irgendwo™ vorliegen.

Im Anhang habe ich die Log-Dateien von "strace" über die Systemaufrufe.

Sieht alles fehlerfrei aus, lediglich der Schreibaufruf wird vom Gerät nicht unterstützt.

Nachtrag:
Ein Minimalbeispiel für ein Kernelmodul habe ich hier gepostet. Vielleicht hilft dir das weiter beim Verständnis.

Tanrim

(Themenstarter)

Anmeldungsdatum:
14. September 2012

Beiträge: 28

Hallo, ich habe den Quellcode um den es mir geht mit gdb und der graphischen Oberfläche Nemiver versucht zu durchleuchten. Etwas neue warum dieser ioctl()-Aufruf fehlschlägt habe ich damit nicht gefunden. Jedenfalls nichts was mir aufgefallen wäre.

Allerdings bekam ich Meldungen, dass Dateien wie die open64.c und atoi.c nichtgefunden werden konnten. Die Meldungen sind im Anhang. Wenn ich mir den restlichen Quellcode ansehe glaube ich das da ein Zusammenhang bestehen könnte. Ich vermute, dass bestimmte Pakete bei mir dann einfach nicht sauber installiert sind. Weiß hier vielleicht jemand zu welchen Paketen diese Dateien im Normalfall gehören und in welchem Verzeichnis sie bei korrekter Installation normalerweise zu finden sind?

Die übrigen Systemaufrufe habe ich mir mittels strace auch angesehen und festegestellt, dass ioctl nicht der einzige Systemcall mit Fehlermeldung ist. Hier das Ergebnis:

Für die einzelnen Systemcalls: Programmaufruf: strace -f -e access ./dumper 5775 0 dsr test Ergebnis für jeweiligen Systemcall: access("/etc/ld.so.preload", R_OK) = -1 ENOENT (Datei oder Verzeichnis nicht gefunden)

Programmaufruf: strace -f -e ioctl ./dumper 5775 0 dsr test Ergebnis für jeweiligen Systemcall: ioctl(3, _IOC(_IOC_READ|_IOC_WRITE, 0xa4, 0xae, 0xb0), 0x7ffd348d74e0) = -1 ENOTTY (Unpassender IOCTL (I/O-Control) für das Gerät

Programmaufruf: strace -f -e arch_prctl ./dumper 5775 0 dsr test Ergebnis für jeweiligen Systemcall: arch_prctl(0x3001 /* ARCH_??? */, 0x7ffe467cffd0) = -1 EINVAL (Das Argument ist ungültig) arch_prctl(ARCH_SET_FS, 0x7f4e8b33c740) = 0

An dieser Stelle nochmals vielen Dank für Hilfe, die ihr mir bisher gegeben habt.

Beste Grüße

Tanrim

Bilder

Dakuan

Avatar von Dakuan

Anmeldungsdatum:
2. November 2004

Beiträge: 6234

Allerdings bekam ich Meldungen, dass Dateien wie die open64.c und atoi.c nichtgefunden werden konnten.

Davon solltest du dich nicht verwirren lassen. atoi() ist eine normale Bibliotheksfunktion (stdlib.h). Wenn die nicht da ist hättest du das bereits gemerkt. Nemiver will dir aber den Quelltext anzeigen.

Weiß hier vielleicht jemand zu welchen Paketen diese Dateien im Normalfall gehören ...

Nicht genau, aber das ist unwichtig. Ich habe aber mal gehört, dass es dazu sog. Debug Pakete gibt, habe mich aber nicht weiter darum gekümmert.

Aber wenn Nemiver das nicht laden kann, bekommt strace das natürlich auch mit. BTW. mit strace tue ich mich schwer. Der haut einem so viel um die Ohren und das was man sucht ist oft nicht dabei.

... = -1 EINVAL (Das Argument ist ungültig) ...

Das sieht schon eher nach einem Problem aus, aber anfangen kann ich damit auch nichts.

Antworten |