Nvidia: 2 Sicherheitslücken im Linux-Treiber

Zwei Sicherheitslücken sind im NVIDIA GFX-Kartentreiber für Linux enthalten, wenn Ihr noch nicht die brandaktuellste Version haben solltet, was schwierig sein dürfte.

Nvidia: 2 Sicherheitslücken im Linux-Treiber

Laut der Bugbeschreibung bei Nvidia, handelt sich dabei bei einer Lücke um einen Bug in der IPC Communication API, was man braucht um Daten zwischen einzelnen Prozessen hin und her zu schicken. Dieser Fehler kann dazu genutzt werden um mit erweiterten Rechten eingeschleusten Code auszuführen.

CVE-IDs
Addressed
Software ProductOperating SystemDriver BranchAffected VersionsUpdated Versions
CVE‑2020‑5963
CVE‑2020‑5967
GeForceLinuxR450All versions prior to 450.51450.51
Quadro, NVSLinuxR450All versions prior to 450.51450.51
R440All versions prior to 440.100440.100
R390All versions prior to 390.138390.138
TeslaLinuxR450All R450 versionsAvailable the week of June 29, 2020
R440All versions prior to 440.95.01440.95.01
R418All versions prior to 418.152.00418.152.00

Die zweite Schwachstelle ist dann schon schwieriger auszunutzen, da eine RACE Condition ist, es kämpfen also zwei Prozesse um eine Ressource. Der Gewinn des RACE würde einen DOS erlauben. Was ein Angreifer auf einem DesktopPC davon haben würde die Grafikkarte zu crashen, naja. Ist trotzdem gut, daß es gefixt wurde.

Für Fedora lautet die Treiberversion für meine GFX-Karte 440.82 und muß daher aktualisiert werden. Da diese aus dem Repo von RPMFusion stammt, dürfte der Verbreitungsgrad und damit der Updatezwang unter Fedora/Centos/RHEL Benutzern entsprechend hoch sein. Wie das zu Problemen führen kann und was man das machen muß, lest Ihr hier: Nvidia, Fedora, RPMFusion und der Bug, der nicht sein soll.

Bei RPMFusion habe ich heute schon angeklopft, daß Updates benötigt werden.

Quelle: https://nvidia.custhelp.com/app/answers/detail/a_id/5031

Nvidia, Fedora, RPMFusion und der Bug, der nicht sein soll.

Diese Geschichte fängt an mit: „Es war einmal eine Grafikkarte“.

„Nvidia, Fedora, RPMFusion und der Bug, der nicht sein soll“

Wie Ihr wisst, gibt es von Nvidiatreibern verschiedene Versionsnummern, z.b. 340,390,440. 440 ist der aktuelle Treiber für GTX1050 Karten.

Jetzt wirft dieser Treiber beim Systemboot eine Fehlermeldung wie folgt:

[ 222.363327] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[ 222.363328] [drm] No driver support for vblank timestamp query.
[ 222.397236] [drm] Initialized nvidia-drm 0.0.0 20160202 for 0000:05:00.0 on minor 0
[ 222.406533] ————[ cut here ]————
[ 222.406534] refcount_t: underflow; use-after-free.
[ 222.406550] WARNING: CPU: 1 PID: 513 at lib/refcount.c:28 refcount_warn_saturate+0xa6/0xf0
[ 222.406551] Modules linked in: nvidia_drm(POE) nvidia_modeset(POE) nvidia_uvm(OE) snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio snd_hda_intel nvidia(POE) snd_intel_dspcfg snd_hda_codec snd_hda_core snd_hwdep joydev snd_seq snd_seq_device edac_mce_amd drm_kms_helper snd_pcm kvm_amd snd_timer drm snd kvm ipmi_devintf sp5100_tco irqbypass wmi_bmof ipmi_msghandler k10temp i2c_piix4 soundcore pcspkr gpio_amdpt gpio_generic acpi_cpufreq nfsd binfmt_misc auth_rpcgss nfs_acl lockd grace sunrpc ip_tables dm_crypt hid_logitech_hidpp crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel ccp r8169 aacraid hid_logitech_dj wmi pinctrl_amd fuse
[ 222.406576] CPU: 1 PID: 513 Comm: plymouthd Tainted: P OE 5.5.10-200.fc31.x86_64 #1
[ 222.406577] Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./B450M Pro4, BIOS P3.90 12/09/2019
[ 222.406579] RIP: 0010:refcount_warn_saturate+0xa6/0xf0
[ 222.406581] Code: 05 2e 03 2e 01 01 e8 7b 8e bc ff 0f 0b c3 80 3d 1c 03 2e 01 00 75 95 48 c7 c7 18 99 3c 9d c6 05 0c 03 2e 01 01 e8 5c 8e bc ff <0f> 0b c3 80 3d fb 02 2e 01 00 0f 85 72 ff ff ff 48 c7 c7 70 99 3c
[ 222.406582] RSP: 0018:ffffb573c103fcb8 EFLAGS: 00010286
[ 222.406583] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000007
[ 222.406584] RDX: 0000000000000007 RSI: 0000000000000086 RDI: ffff9416ce859cc0
[ 222.406585] RBP: ffff9416bacbfce8 R08: 0000000000000413 R09: 0000000000000003
[ 222.406585] R10: 0000000000000000 R11: 0000000000000001 R12: ffff9416c70502e8
[ 222.406586] R13: ffff9416c7050000 R14: 0000000000000008 R15: 0000000000000000
[ 222.406588] FS: 00007f07558f3f00(0000) GS:ffff9416ce840000(0000) knlGS:0000000000000000
[ 222.406588] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 222.406589] CR2: 00007f0755072052 CR3: 00000004035c6000 CR4: 0000000000340ee0
[ 222.406590] Call Trace:
[ 222.406597] nv_drm_atomic_helper_disable_all+0xec/0x290 [nvidia_drm]
[ 222.406603] nv_drm_master_drop+0x22/0x60 [nvidia_drm]
[ 222.406616] drm_drop_master+0x1e/0x30 [drm]
[ 222.406628] drm_dropmaster_ioctl+0x4c/0x90 [drm]
[ 222.406639] ? drm_setmaster_ioctl+0xb0/0xb0 [drm]
[ 222.406651] drm_ioctl_kernel+0xaa/0xf0 [drm]
[ 222.406663] drm_ioctl+0x208/0x390 [drm]
[ 222.406675] ? drm_setmaster_ioctl+0xb0/0xb0 [drm]
[ 222.406678] ? do_filp_open+0xa5/0x100
[ 222.406681] ? selinux_file_ioctl+0x174/0x220
[ 222.406683] do_vfs_ioctl+0x461/0x6d0
[ 222.406685] ksys_ioctl+0x5e/0x90
[ 222.406686] __x64_sys_ioctl+0x16/0x20
[ 222.406690] do_syscall_64+0x5b/0x1c0
[ 222.406693] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 222.406695] RIP: 0033:0x7f0755bb138b
[ 222.406697] Code: 0f 1e fa 48 8b 05 fd 9a 0c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d cd 9a 0c 00 f7 d8 64 89 01 48
[ 222.406697] RSP: 002b:00007ffced5fe798 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
[ 222.406699] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f0755bb138b
[ 222.406699] RDX: 0000000000000000 RSI: 000000000000641f RDI: 0000000000000009
[ 222.406700] RBP: 000000000000641f R08: 000055b6a6ff1df0 R09: 000055b6a6fa5010
[ 222.406701] R10: 0000000000000000 R11: 0000000000000246 R12: 000055b6a6ff2970
[ 222.406701] R13: 0000000000000009 R14: 0000000000000000 R15: 0000000000000000
[ 222.406703] —[ end trace fa45bb73ed0780f4 ]—
[ 222.411358] kauditd_printk_skb: 45 callbacks suppressed

Von Euch sieht natürlich jeder sofort, daß hier NVIDIA und PLYMOUTH im Spiel sind und das der Nvidiatreiber einen Fehler bei der DRM Initialisierung verursacht. Der Server bootet danach weiter, also erstmal nicht so wichtig. Es folgen die üblichen Dinge: Bugreport bei Fedora ( wegen Plymouth ) und bei RPMFusion ( wegen Nvidia ) erstellen, und komplett entäuscht werden… !

„Da ist kein Bug, gehen Sie weiter!“

Nun kann Fedora da nicht viel machen, wenn der Nvidiatreiber da Mist baut, außer natürlich, es übergibt dem Treiber schon was falsches, da könnte der Treiber dann nicht mehr soviel für den Bug. Das werden wir aber nie erfahren, denn der Bug wurde sofort beerdigt. Nagut, wir haben ja noch den RPMFusionreport.

Sagte ich, wir haben noch einen anderen offenen Bugreport? So kann man sich irren: „Your Bugreport has been closed with „WONT FIX“.Und dann stehen wir mit einem Fehler da, von dem alle Parteien sagen „Nicht mein Problem“. Doch, Eurer Problem! Wessen denn sonst?

Der Bug wurde in der Devliste von Nvidia zwar besprochen, aber es gibt leider keinen finalen Fix dafür:

Devliste: https://forums.developer.nvidia.com/t/bug-nvidia-440-64-kernel-5-5-6-stable-boot-trace-was-nvidia-440-59-kernel-5-5-1-stable-boot-trace/111643

Der derzeitige Stand ist: Geht halt nicht; und DRM geht dann halt auch nicht. Wobei letzteres sollte man eh abschaffen, falls damit das DigitalRightsManagement gemeint ist.

Was mich aber am meisten stört: „ist nicht unser Problem“. Von RPMFusion hätte ich erwartet, daß das offen bleibt, bis das von den Nvidiadevs gefixt wurde, schon um das Problem zu tracken, aber von Scott kann man halt oft nichts anderes erwarten.

How To: Wie man nvidia akmods nachbaut

Wer Fedora benutzt und eine Nvidia Grafikkarte, wird i.d.R. auch die RPMFusion Treiber für Nvidia benutzen, da diese einfacher zu installieren sind als Nvidia selbst zu kompilieren.

Mußte man früher auf die neuen Kerneltreibermodule warten, weil sie passend vorkompiliert waren, werden diese heute über akmods gebaut, wenn ein neuer Kernel installiert wurde.

Was aber, wenn das aus irgendeinem Grund nicht ging ?

Dann bootet Eurer Rechner sich in eine Endlosschleife beim Start. Aus dieser gibt es nur ein Entkommen: Rebooten und dann einen anderen Kernel auswählen.

Damit hat man erstmal ein funktionierendes System zurück, aber nutzt einem das was ? Nein!

Die Module werden in Abhängigkeit vom aktuell laufenden Kernel getestet und notfalls beim Booten gebaut. Da ein alter Kernel läuft und gebootet hat, braucht man jetzt kein neues Modul mehr, weil es ist schon da.

Anstatt also auf alle installierten Kernel zu testen und zu bauen, wird nur auf den laufenden Kernel getestet. Also kann man die Module nur bauen, wenn der Rechner den neuen Kernel bootet: Ein Teufelskreis 😀

Wie man die Kernelmodule selbst baut

Wir brauchen die üblichen Balls-of-Steel, das Rootpasswort und jemanden, der Euch clevererweise diese Anleitung ausgedruckt hat, denn Ihr werdet Sie sonst nicht lesen können, wenn Ihr das macht 😉

1. Rebooten in das Grubmenü

2. Im Grubmenü den aktuellen Kernel auswählen und „e“ drücken

3. Ihr seht den Grubbooteintrag für diesen Kernel vor Euch:

Die ganzen XXXX sind Platzhalter für Eure UUIDS von den Festplatten, einfach ignorieren!

load_video
set gfxpayload=keep
insmod gzio
insmod part_msdos
insmod ext2
set root='hd2,msdos1'
if [ x$feature_platform_search_hint = xy ]; then
    search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos1 --hint-efi=hd2,msdos1 --hintbaremetal=ahci2,msdos1  XXXX
else
    search --no-floppy --fs-uuid --set=root XXXXX
fi
linux /vmlinuz-4.6.4-201.fc23.x86_64 root=/dev/mapper/luks-XXX ro vconsole.font=latarcyrheb-sun16 rd.luks.uuid=luks-caXXXX 
rd.luks.uuid=luks-XXX rhgb quiet splash LANG=de_DE.UTF-8 1
initrd /initramfs-4.6.4-201.fc23.x86_64.img

Die grüne Zeile ist die wichtige Zeile für Euch. Hängt am Ende eine „1“ dran, so wie oben zu sehen. Damit bootet der Rechner nicht in die Grafische Oberfläche ( Runlevel 5), sondern geht in die Rootkonsole ( Runlevel 1 ) . Im Runlevel 1  werden die ganzen nicht existenten Treiber noch nicht geladen, weswegen das funktioniert.

4. Gebt das Rootpasswort ein, wenn Ihr gefragt werdet

5. gebt „akmods“ ein .. und wartet bis es fertig ist. Es dauert ein bisschen.

6. gebt „init 5“ ein, wenn keine Fehler gemeldet wurden und Eurer Rechner bootet in die normale Oberfläche weiter – mit dem neuen Kernel