Skip to content

GSM 0710 multiplexing race UAF (CVE-2023-6546)

GSM 0710 tty multiplexor'ında (drivers/tty/n_gsm.c) iki thread'in mux-cleanup path'ini eşzamanlı çalıştırdığı bir race; birini, free'den sonra dereference ettiği stale bir struct gsm_dlci pointer'ıyla bırakır — local privilege escalation'a götüren bir UAF.

Mechanism

n_gsm line discipline'ı, bir tty üzerinden 3GPP TS 27.010 (GSM 0710) multiplexing protokolünü implemente eder. gsm_cleanup_mux(), multiplexor'ın data link channel'larını (DLCI) tear down eder. Bug, paylaşılan bir pointer üzerinde bir TOCTOU'dur.

Note

gsm_cleanup_mux(), struct gsm_dlci *dlci = gsm->dlci[0];'i mutex_lock(&gsm->mutex) almadan önce okur. İki eşzamanlı cleanup run'ı ile, Task A mutex'i alır, DLCI'leri gsm_dlci_release() ile release eder, gsm->dlci[i]'yi null'lar ve unlock eder; lock'un dışında artık stale olan dlci'yi cache'lemiş olan Task B ise free edilmiş objeyi dereference eder (dlci->dead = true yazar). Free edilmiş obje, control channel için struct gsm_dlci'dir (gsm->dlci[0]).

Warning

Fix yeni bir lock eklemez — yalnızca dlci = gsm->dlci[0] okumasını mutex_lock(&gsm->mutex)'ten sonraya taşır; böylece pointer, onu free eden aynı lock altında okunur.

Walkthrough

Kavramsal trigger:

  1. Line discipline'ı bir pty'ye install et: ioctl(fd, TIOCSETD, &(int){N_GSM0710}).
  2. Multiplexor'ı ioctl(fd, GSMIOC_SETCONF, &conf) ile aktive et.
  3. İkisi de disconnect/cleanup path'ine yeniden giren iki thread spawn et (örn. eşzamanlı GSMIOC_SETCONF reconfiguration'ları), öyle ki timing bir thread'i tutarken diğeri gsm_cleanup_mux() boyunca ilerlesin.

Free edilmiş struct gsm_dlci slot'u ardından kontrollü bir spray ile reclaim edilir (public ZDI-24-020 PoC'si userfaultfd artı add_key() kullanır), objenin gsm->output() function pointer'ı bir call primitive'ine yönlendirilir ve bir root payload (örn. chmod u+s) çalıştırılır.

Fixing commit 3c4f8333b582487a2d1e02171f1465531cde53e3 — "tty: n_gsm: fix the UAF caused by race condition in gsm_cleanup_mux".

Detection

KASAN, gsm_cleanup_mux() içindeki struct gsm_dlci üzerinde use-after-free'yi flag'ler. Policy seviyesinde, unprivileged process'ler tarafından n_gsm line discipline'ının beklenmedik yüklenmesi gözlemlenebilir.

Mitigation

gsm->dlci[0]'ı mutex altında okuyan bir kernel'a (≥ 6.5-rc7 ya da backport'u, örn. 6.4.12) güncelle. Etkilenen sürümler < 6.5'tir, 6.5 rc1–rc6 dahil. Patch'lemenin mümkün olmadığı yerde n_gsm modülünü blacklist'le.

References