LSN-0107-1: Kernel Live Patch Sicherheitshinweis
LSN-0107-1: Kernel Live Patch Sicherheitshinweis
5 NOV 2024
Releases
Ubuntu 24.04 LTS Ubuntu 22.04 LTS Ubuntu 20.04 LTS Ubuntu 18.04 ESM Ubuntu 16.04 ESM Ubuntu 14.04 ESM
Softwarebeschreibung
aws - Linux-Kernel für Amazon Web Services (AWS) Systeme - (>= 4.15.0-1159, >= 5.4.0-1009, >= 5.4.0-1061, >= 5.15.0-1000, >= 6.8.0-1008, >= 4.4.0-1129, >= 4.4.0-1159)
aws-5.15 - Linux-Kernel für Amazon Web Services (AWS) Systeme - (>= 5.15.0-1000)
aws-hwe - Linux-Kernel für Amazon Web Services (AWS-HWE)-Systeme - (>= 4.15.0-1126)
azure - Linux-Kernel für Microsoft Azure Cloud-Systeme - (>= 5.4.0-1010, >= 5.15.0-1000, >= 6.8.0-1007, >= 4.15.0-1114)
azure-4.15 - Linux-Kernel für Microsoft Azure Cloud-Systeme - (>= 4.15.0-1168)
azure-5.15 - Linux-Kernel für Microsoft Azure-Cloud-Systeme - (>= 5.15.0-1069)
gcp - Linux-Kernel für Google Cloud Platform (GCP)-Systeme - (>= 5.4.0-1009, >= 5.15.0-1000, >= 6.8.0-1007, >= 4.15.0-1118)
gcp-4.15 - Linux-Kernel für Google Cloud Platform (GCP)-Systeme - (>= 4.15.0-1154)
gcp-5.15 - Linux-Kernel für Google Cloud Platform (GCP)-Systeme - (>= 5.15.0-1000)
generic-4.15 - Linux-Kernel zur Hardware-Erweiterung (HWE) - (>= 4.15.0-214, >= 4.15.0-143, >= 4.15.0-143)
generic-4.4 - Linux-Kernel - (>= 4.4.0-168, >= 4.4.0-211, >= 4.4.0-243)
generic-5.15 - Linux Hardware Enablement (HWE) Kernel - (>= 5.15.0-0)
generic-5.4 - Linux-Kernel - (>= 5.4.0-150, >= 5.4.0-26)
gke - Linux-Kernel für Google Container Engine (GKE)-Systeme - (>= 5.4.0-1033, >= 5.15.0-1000)
gke-5.15 - Linux-Kernel für Google-Container-Engine-(GKE)-Systeme - (>= 5.15.0-1000)
Details
Im Linux-Kernel wurde die folgende Sicherheitslücke behoben
behoben: inet: inet_defrag: Verhindert die Freigabe von sk während der Benutzung
ip_local_out() und andere Funktionen können skb->sk als Funktionsargument übergeben.
Wenn das skb ein Fragment ist und der Zusammenbau erfolgt, bevor der Funktionsaufruf
zurückkehrt, darf das sk nicht freigegeben werden. Dies betrifft skb-Fragmente
die über netfilter oder ähnliche Module, z. B. openvswitch oder ct_act.c, neu zusammengesetzt werden,
wenn sie als Teil der tx-Pipeline ausgeführt werden. Eric Dumazet hat eine erste Analyse von
dieses Fehlers. Zitat Eric: Der Aufruf von ip_defrag() im Ausgabepfad impliziert auch
skb_orphan(), was fehlerhaft ist, weil der Ausgabepfad davon abhängt, dass sk
verschwindet. Ein relevanter alter Patch zu diesem Problem war: 8282f27449bf
('inet: frag: Immer verwaiste skbs innerhalb von ip_defrag()') [..
net/ipv4/ip_output.c hängt davon ab, dass skb->sk gesetzt ist, und zwar wahrscheinlich auf einen inet
Socket, nicht auf ein beliebiges. Wenn wir das Paket in ipvlan verwaisen lassen, dann
nachgelagerte Dinge wie der FQ-Paket-Scheduler nicht richtig funktionieren. Wir müssen
ip_defrag() so ändern, dass es skb_orphan() nur benutzt, wenn es wirklich gebraucht wird, d.h.
wenn frag_list benutzt werden soll. Eric schlug vor, sk in der
fragment queue zu speichern und hat einen ersten Patch gemacht. Allerdings gibt es ein Problem mit
damit: Wenn skb gleich danach erneut fragmentiert wird, kopiert ip_do_fragment()
head->sk in die neuen Fragmente, und setzt den Destruktor auf sock_wfree. IOW,
wir haben keine andere Wahl, als sk_wmem so zu korrigieren, dass es das vollständig
skb widerzuspiegeln, da sonst wmem unterlaufen wird. Diese Änderung verschiebt das verwaiste
nach unten in den Kern, zum letztmöglichen Zeitpunkt. Da ip_defrag_offset ein Alias ist
mit dem sk_buff->sk-Mitglied verknüpft ist, müssen wir den Offset in die FRAG_CB verschieben, da sonst
skb->sk wird geklotzt. Dies ermöglicht es, das Verwaisen lange genug hinauszuzögern, um
zu erfahren, ob der skb in eine Warteschlange gestellt werden muss oder ob der skb die reasm
Warteschlange. Im ersten Fall funktioniert alles wie zuvor, skb wird verwaist. Dies ist
sicher, weil skb in die Warteschlange gestellt/gestohlen wird und nicht über die reasm-Engine hinausgeht.
Im zweiten Fall stehlen wir die skb->sk-Referenz, binden sie wieder an den
head skb und reparieren das wmem-Accouting, wenn inet_frag truesize aufbläht.)(CVE-2024-26921)
Im Linux-Kernel wurde die folgende Sicherheitslücke
behoben: af_unix: Fix Garbage Collector Rennen gegen connect() Garbage
Kollektor berücksichtigt nicht das Risiko, dass Embryo während der Garbage Collection in eine
während der Garbage Collection. Wenn ein solcher Embryo einen Peer hat, der
SCM_RIGHTS trägt, können zwei aufeinanderfolgende Durchläufe von scan_children() eine andere
Satz von Kindern sehen. Dies führt zu einer fälschlicherweise erhöhten Anzahl von Kindern und
und zu einem "Dangling Pointer" innerhalb der gc_inflight_list.
AF_UNIX/SOCK_STREAM S ist ein unverbundener Socket L ist ein lauschender In-Flight
Socket gebunden an addr, nicht in fdtable V's fd wird über sendmsg() übergeben,
erhält die Anzahl der während des Fluges gesammelten Daten connect(S, addr) sendmsg(S, [V]); close(V)
unix_gc() ---------------- ------------------------- ----------- NS =
unix_create1() skb1 = sock_wmalloc(NS) L = unix_find_other(addr)
unix_state_lock(L) unix_peer(S) = NS // V count=1 inflight=0 NS =
unix_peer(S) skb2 = sock_alloc() skb_queue_tail(NS, skb2[V]) // V wurde
in-flight // V count=2 inflight=1 close(V) // V count=1 inflight=1 // GC
Kandidatenbedingung erfüllt for u in gc_inflight_list: if (total_refs ==
inflight_refs) u zu gc_candidates hinzufügen // gc_candidates={L, V} for u in
gc_candidates: scan_children(u, dec_inflight) // Embryo (skb1) war noch nicht //
von L aus noch nicht erreichbar, also bleibt V's // inflight unverändertskb_queue_tail(L, skb1) unix_state_unlock(L) for u in gc_candidates: if
(u.inflight) scan_children(u, inc_inflight_move_tail) // V count=1
inflight=2 (!) Wenn es einen GC-Kandidaten gibt, der den Socket abhört, sperre/entsperre seinen
Zustand. Dadurch wartet GC bis zum Ende eines laufenden connect() zu diesem
Socket. Nach dem Umdrehen der Sperre ist ein möglicherweise SCM-beladener Embryo bereits
in der Warteschlange. Und wenn ein weiterer Embryo kommt, kann er nicht mit
SCM_RIGHTS TRAGEN. Zu diesem Zeitpunkt kann unix_inflight() nicht ausgeführt werden, weil
unix_gc_lock bereits belegt ist. Der Inflight-Graph bleibt davon unberührt.)(CVE-2024-26923)
Im Linux-Kernel wurde die folgende Sicherheitslücke
behoben: mm: swap: Wettlauf zwischen free_swap_and_cache() und swapoff() behoben
Zuvor gab es ein theoretisches Fenster, in dem swapoff() laufen konnte und
ein swap_info_struct abreißen konnte, während ein Aufruf von free_swap_and_cache()
in einem anderen Thread lief. Dies konnte, neben anderen schlechten
Möglichkeiten, swap_page_trans_huge_swapped() (aufgerufen von
free_swap_and_cache()) auf den freigegebenen Speicher für swap_map zugreifen. Dies ist ein
theoretisches Problem, und ich konnte es noch nicht in einem Testfall provozieren.
Bei der Überprüfung des Codes hat man sich jedoch darauf geeinigt, dass dies möglich ist
(siehe Link unten). Beheben Sie es, indem Sie get_swap_device()/put_swap_device() verwenden,
was swapoff() zum Stillstand bringen wird. Es gab eine zusätzliche Prüfung in _swap_info_get(), um
zu bestätigen, dass der Swap-Eintrag nicht frei war. Dies ist nicht vorhanden in
get_swap_device() nicht vorhanden, weil es wegen des Wettlaufs zwischen
zwischen dem Erhalten der Referenz und dem Swapoff. Deshalb habe ich eine entsprechende
Prüfung direkt in free_swap_and_cache() hinzugefügt. Details zum Auslösen eines
mögliches Problem zu provozieren (Dank an David Hildenbrand für die Herleitung): --8 swap_entry_free() könnte der letzte Benutzer sein und zu 'count ==
SWAP_HAS_CACHE'. swapoff->try_to_unuse() hört auf, sobald
si->inuse_pages==0. Die Frage ist also: könnte jemand das Folio zurückfordern und
si->inuse_pages==0 machen, bevor wir
swap_page_trans_huge_swapped() ausgeführt haben. Stellen Sie sich folgendes vor: 2 MiB Folio im
Swapcache. Nur 2 Unterseiten sind noch durch Swap-Einträge referenziert. Prozess 1
referenziert immer noch die Unterseite 0 über einen Swap-Eintrag. Prozeß 2 verweist immer noch
Unterseite 1 über einen Swap-Eintrag. Prozess 1 beendet sich. Ruft free_swap_and_cache() auf. ->
count == SWAP_HAS_CACHE [dann, preempted im Hypervisor usw.] Prozess 2
wird beendet. Ruft free_swap_and_cache() auf. -> count == SWAP_HAS_CACHE Prozess 2
macht weiter, übergibt swap_page_trans_huge_swapped(), und ruftstry_to_reclaim_swap() auf.
__try_to_reclaim_swap()->folio_free_swap()->delete_from_swap_cache()->
put_swap_folio()->free_swap_slot()->swapcache_free_entries()->
swap_entry_free()->swap_range_free()-> ... WRITE_ONCE(si->inuse_pages,
si->inuse_pages - nr_entries); Was hält swapoff davon ab, erfolgreich zu sein, nachdem Prozess
2 den Swap-Cache zurückerobert hat, aber bevor Prozess1 seinen Aufruf an
swap_page_trans_huge_swapped() beendet hat? --8
Im Linux-Kernel wurde die folgende Sicherheitslücke
behoben: Bluetooth: Behebung von Use-after-free-Fehlern, die durch sco_sock_timeout verursacht werden
Wenn die sco-Verbindung aufgebaut wird und dann der sco-Socket
Socket freigegeben wird, wird timeout_work eingeplant, um zu beurteilen, ob die sco
Unterbrechung ein Timeout ist. Der Sock wird später wieder freigegeben, aber er wird
in sco_sock_timeout erneut dereferenziert. Infolgedessen werden die use-after-free
Fehler auftreten. Die Hauptursache ist unten dargestellt: Aufräum-Thread
Worker
Thread sco_sock_release
sco_sock_close
__sco_sock_close
sco_sock_set_timer
schedule_delayed_work
sco_sock_kill
(eine Zeit warten)
sock_put(sk) //FREE
sco_sock_timeout
sock_hold(sk) //USE Der KASAN
Bericht, der durch POC ausgelöst wurde, ist unten dargestellt: [ 95.890016