So, nun gibt es endlich das Kernel-Module (mit dem Namen "
yf_patchkernel.ko"), welches beim Laden die drei Stellen im laufenden Kernel entsprechend patchen kann.
Man muß das nur vor dem Start des Datenverkehrs entsprechend laden ... entweder mit "modprobe" - sofern die "modules.dep" vorhanden ist und den Eintrag für dieses Module enthält - oder mit "insmod", wo man den Pfad zum ko-File angeben kann. Die ausgeführten Patches werden als Kernel-Messages protokolliert. Wenn man das LKM wieder entlädt (über "rmmod yf_patchkernel"), werden die Änderungen wieder rückgängig gemacht, auch das wird protokolliert.
Apropos Protokoll ... da dieses LKM nicht in der Module-Tabelle von AVM steht (das Patchen ist ja nur erforderlich, wenn man einen originalen AVM-Kernel verwenden will - sonst kann man gleich ohne die Traps übersetzen), gibt es beim Laden ein paar Fehlermeldungen von der Speicherverwaltung für den Kernel ... das ist nicht weiter tragisch und tatsächlich für jedes zusätzlich geladene LKM so - bei den GRX-Boxen, wo der "tun"-Driver nicht im Kernel enthalten ist, kann man dieses Phänomen auch für ihn beobachten. Wenn also beim Laden eines eigenen LKM Nachrichten wie diese auftauchen:
Code:
[module-alloc-by-name] give 0x1000 bytes at 0x8a672000 to module 'yf_patchkernel' (0xb6000 total bytes left)
module_alloc_size_list_alloc: error: module 'yf_patchkernel' reserved size 0 too small for demand size 4096 - need 4096 more (module_alloc_waste=-4096)
, dann ist das nicht weiter problematisch. Geladen wird trotzdem und der Code wird auch ausgeführt - das "error" ist hier eher eine Übertreibung - zumal der Platz für ein Datensegment ja offenbar doch reserviert wird, wie man an den 4 KB in der Message oben sehen kann.
Da sich die LKM für VR9- und GRX5-Boxen schon deshalb unterscheiden, weil das "sk"-Feld in der "sk_buff"-Struktur des Kernels an einem anderen Offset steht, braucht es (mind.) für jede Architektur ein gesondertes LKM - wobei bisher wohl nur die MIPS-Modelle betroffen sind vom AVM-Patch (der vermutlich ja auch mit der speziellen Hardware zusammenhängt). Für VR9 und GRX5 habe ich jedenfalls die vorübersetzten LKM auch im "
yf_bin"-Repository hinterlegt - jeweils als "yf_patchkernel.ko" (mit separater Signaturdatei) in einem Unterverzeichnis mit der passenden Kernel-Version.
Ansonsten muß man ein paar Vorbereitungen treffen, wenn man sein eigenes LKM zusammen mit dem Freetz-Image erstellen will ... die notwendigen Patches habe ich in einem Branch "
yf_patchkernel" meines Freetz-Klons zusammengestellt, den werde ich als Pull-Request für den Freetz-Master "annoncieren". Ob, wie und wann der dann im Freetz-Master landet, kann ich nicht beeinflussen.
============================================================
@er13: Meine Integration ist ein Vorschlag ... wenn Du das LKM anders integrieren möchtest, tu Dir keinen Zwang an. Sorge aber bitte dafür, daß als Ausgangsbasis für die C-Quelle des LKM dann die Datei aus dem YourFritz-Repo (im Unterverzeichnis "patch_kernel") verwendet wird und leicht aktualisiert werden kann - deshalb ist das bei mir eine getrennte Patch-Datei und auch ein solcher "patch" anstelle eines simplen "cp", weil ich keine anderen "Vorbereitungskommandos" für die Kernel-Sourcen kenne, die in Freetz verfügbar sein könnten.
Sollten weitere Patches notwendig werden, wäre diese Datei meine Ausgangsbasis und es liegt durchaus im Rahmen des Möglichen, daß ich da auch ansonsten noch ein paar Modifikationen (etwas mehr Dokumentation, ausführlicherer Header, ggf. sogar ein "proc"-Interface zur Abfrage der gepatchten Stellen und zur (De-)Aktivierung über ein Control-File auch ohne Entladen) vornehmen werde. Wenn Du Änderungen am Inhalt der C-Quellen möchtest, erstelle sie bitte Deinerseits als PR und nicht unbedingt als Patch bzw. als Änderung an der "900-patchkernel_source".
============================================================
Wer schon vorher die Änderungen in seinem Build berücksichtigen möchte (ich habe auch noch einen (ungetesteten) Patch des "rc.openvpn"-Files für das V2-CGI hinzugefügt, mit dem sowohl das "tun.ko" als auch "yf_patchkernel.ko" automatisch ge- und entladen werden beim Starten bzw. Stoppen von OpenVPN - zumindest solange die "ko"-Dateien unterhalb von "/lib/modules/$(uname -r)" zu finden sind beim Laden), der kann entweder den Branch "yf_patchkernel" meines "freetz"-Repos zum Checkout des Freetz-Masters hinzumischen oder er kann auch gleich den kompletten Checkout mit diesem Branch aus meinem Freetz-Repo machen. Dort nimmt man aber besser den richtigen Branch, denn der Standard dort ist der "YourFritz"-Branch und der enthält einige Änderungen, die ein Freetz-Benutzer eher nicht haben möchte (zumindest nicht so).
Getestet habe ich (das Patchen, nicht die Funktion mit OpenVPN) auf einer 7490 und einer 7580 - die Ausgaben sehen dabei dann zur Zeit in etwa so aus:
(7490)
Code:
root@FB7490:~ $ insmod /var/media/ftp/yf_patchkernel.ko
root@FB7490:~ $ dmesg -c
[ 812.200000][1][module-alloc-by-name] give 0x1000 bytes at 0x81845000 to module 'yf_patchkernel' (0xcd000 total bytes left)
[ 812.200000][1]module_alloc_size_list_alloc: error: module 'yf_patchkernel' reserved size 0 too small for demand size 4096 - need 4096 more (module_alloc_waste=-4096)
[ 812.210000][1][yf_patchkernel] Initialization started
[ 812.210000][1][yf_patchkernel] Any preceding error messages regarding memory allocation are expected and may be ignored.
[ 812.220000][1][yf_patchkernel] Patching kernel function 'ip_forward' at address 0x805468e0.
[ 812.220000][1][yf_patchkernel] Found instruction to patch (0x8c820010) at address 0x805468f8, replaced it with 0x24020000.
[ 812.240000][1][yf_patchkernel] Patching kernel function 'netif_receive_skb' at address 0x804efa20.
[ 812.240000][1][yf_patchkernel] Found instruction to patch (0x00020336) at address 0x804efa34, replaced it with 0x00000000.
[ 812.250000][1][yf_patchkernel] Patching kernel function '__netif_receive_skb' at address 0x804ef980.
[ 812.250000][1][yf_patchkernel] Found instruction to patch (0x00030336) at address 0x804ef988, replaced it with 0x00000000.
[ 812.250000][1][yf_patchkernel] 3 patches applied.
root@FB7490:~ $ rmmod yf_patchkernel
root@FB7490:~ $ dmesg -c
[ 829.840000][0][yf_patchkernel] Deinitialization started
[ 829.840000][0][yf_patchkernel] Reversed patch in 'ip_forward' at address 0x805468f8 to original value 0x8c820010.
[ 829.840000][0][yf_patchkernel] Reversed patch in 'netif_receive_skb' at address 0x804efa34 to original value 0x00020336.
[ 829.840000][0][yf_patchkernel] Reversed patch in '__netif_receive_skb' at address 0x804ef988 to original value 0x00030336.
[ 829.840000][0][yf_patchkernel] All applied patches have been reversed.
[ 829.840000][0]release_bug_debug_table: warning: 'yf_patchkernel' not found! (driver maybe bugfree)
root@FB7490:~ $
(7580)
Code:
# insmod /var/media/ftp/yf_patchkernel.ko
# dmesg -c
[ 193.152000] [yf_patchkernel] Initialization started
[ 193.152000] [yf_patchkernel] Any preceding error messages regarding memory allocation are expected and may be ignored.
[ 193.212000] [yf_patchkernel] Patching kernel function 'ip_forward' at address 0x80ab97a4.
[ 193.212000] [yf_patchkernel] Found instruction to patch (0x8c820020) at address 0x80ab97c0, replaced it with 0x24020000.
[ 193.268000] [yf_patchkernel] Patching kernel function 'netif_receive_skb' at address 0x80a62474.
[ 193.268000] [yf_patchkernel] Found instruction to patch (0x00020336) at address 0x80a62498, replaced it with 0x00000000.
[ 193.320000] [yf_patchkernel] Patching kernel function '__netif_receive_skb' at address 0x80a623f0.
[ 193.320000] [yf_patchkernel] Found instruction to patch (0x00030336) at address 0x80a623f8, replaced it with 0x00000000.
[ 193.320000] [yf_patchkernel] 3 patches applied.
# rmmod yf_patchkernel
# dmesg -c
[ 205.012000] [yf_patchkernel] Module will be removed now.
[ 205.012000] [yf_patchkernel] Reversed patch in 'ip_forward' at address 0x80ab97c0 to original value 0x8c820020.
[ 205.012000] [yf_patchkernel] Reversed patch in 'netif_receive_skb' at address 0x80a62498 to original value 0x00020336.
[ 205.012000] [yf_patchkernel] Reversed patch in '__netif_receive_skb' at address 0x80a623f8 to original value 0x00030336.
[ 205.012000] [yf_patchkernel] All applied patches have been reversed.
[ 205.012000] release_bug_debug_table: warning: 'yf_patchkernel' not found! (driver maybe bugfree)
#
Sofern es jetzt keine gravierenden Probleme mit der Funktion des LKM gibt, ist das Thema für mich erst einmal gegessen ... bis es mich mit dem "proc"-Interface vielleicht noch einmal packt. Da man nach längerer Laufzeit in den Kernel-Messages die Nachrichten vom Laden nicht mehr finden wird und auch die Tatsache, daß das LKM dann in der Ausgabe von "lsmod" erscheint, nicht unbedingt etwas über den Erfolg der einzelnen Patches aussagt (es sind ja drei unabhängige Stellen), kann man nach einiger Zeit nicht mehr ohne weiteres feststellen, ob das Patchen erfolgreich war oder nicht ... und genau dafür würde dann ein "procfs"-Interface noch Sinn ergeben, über das man den Status im Nachhinein noch abfragen kann.
Aber das ist "Zukunftsmusik" und funktionieren sollte es auch im derzeitigen Zustand. Solange AVM keine weiteren Änderungen vornimmt, sollte das auch so bleiben. Die Tatsache, daß das LKM einfach so in eine Code-Seite im Speicher schreiben kann (selbst wenn es die Rechte dazu nur hat, weil es als Bestandteil des Kernels läuft, könnten bzw. sollten die Code-Seiten im Speicher natürlich gegen Schreibzugriffe geschützt sein und erst freigeschaltet werden müssen), zeigt auch ein klein wenig "Schlamperei" bei der Speicherverwaltung - aber das soll bei anderen MIPS-Geräten ja auch nicht besser aussehen:
https://www.heise.de/security/meldu...ablierten-Sicherheitsmechanismen-4268046.html (Kurzlink:
https://heise.de/-4268046). Trotzdem könnte das natürlich für AVM auch ein Anlaß sein, den Speicherschutz für Kernel-Code irgendwann mal zu aktivieren ... es ist sicherlich leichter, wildes Schreiben per Exploit auszulösen als ein geordnetes Aufheben eines Schreibschutzes. Für einen Teil des I/O-Memory versucht das AVM ja offenbar schon, wenn ich die Absichten richtig verstehe in der "arch/mips/avm_enh/avm_writeprotect.c" bei den GRX-Modellen.