n_gsm vulnerabilities (CVE-2024-36016)¶
Linux
n_gsmreceive path'inde bir out-of-bounds write: GSM 0710 mux'unu frame'in ortasında basic ve advanced option mode arasında geçirmekgsm->state/gsm->lendeğerlerini stale bırakır, böylecegsm0_receive()gsm->buf'ın ötesine yazmaya devam eder.
Mechanism¶
Note
n_gsm (drivers/tty/n_gsm.c) gelen bir byte stream'inin GSM 07.10
framing'ini decode eder. İki framing varyantını destekler:
- Basic option mode — bir length field kullanır; driver kaç payload
byte'ının kaldığını
gsm->leniçinde, ne kadarını kopyaladığını isegsm->countiçinde takip eder ve sabit buffergsm->buf'a biriktirir. - Advanced option mode — framing farklı şekilde sınırlandırılır ve
kopyayı bound'lamak için
gsm->lenkullanılmaz.
gsmld_receive_buf() byte'ları mode'a özgü receiver'a besler (basic için
gsm0_receive(), advanced için gsm1_receive()). Receiver'lar
gsm->state tarafından sürülen, byte-byte ilerleyen bir state
machine'dir.
Bug, bir mode reconfiguration sırasında ortaya çıkan bir out-of-bounds
write'tır. Protocol peer, bir frame uçuştayken mux'un option mode'unu
değiştirebilir ve bu reconfiguration gsm->state veya gsm->len'i
reset etmez. CVE açıklaması tam sırayı şöyle anlatır:
- A tarafı
n_gsm'i basic option mode'da configure eder. - B tarafı data length 1 ilan eden bir basic-mode frame header'ı gönderir.
- A tarafı advanced option mode'a geçer.
- B tarafı 2 data byte gönderir — bu
gsm->len'i aşar ama advanced mode'dagsm->len'e bakılmadığı için byte'lar kabul edilir. - A tarafı tekrar basic option mode'a geçer.
- B tarafı data göndermeye devam eder. Ne
gsm->statene degsm->lenreset edilmediği içingsm0_receive()gsm->buf'ın ötesine yazar.
İhlal edilen invariant: "framing mode her yeniden configure
edildiğinde, receive state machine'in length ve state sayaçları reset
edilmelidir." Cross-mode reconfiguration, basic-mode bookkeeping'ini
(gsm->len, gsm->state) advanced mode'un hiç bound'lamadığı bir data'yı
tarif eder halde bıraktı, böylece basic-mode kopyası buffer'ın sonunu
aştı.
Walkthrough¶
Bu peer'ın sürüklediği bir memory corruption'dır: bir gsm-mux tty'sinin diğer ucunu kontrol eden bir saldırgan (ya da local bir LPE kurulumunda her iki ucu) mode toggle'larını sürükler. Kavramsal olarak:
-
gsm line discipline'ı attach et ve mux'u basic mode'a al (A tarafı):
-
B tarafı olarak,
len == 1iddia eden bir basic-mode frame header'ı yaz, sonra A tarafını advanced mode'a reconfigure et ve 2 payload byte besle (advanced modegsm->len'i yok sayar): -
A tarafını tekrar basic mode'a geçir ve byte stream'lemeye devam et;
gsm->state/gsm->lenhiç reset edilmediği içingsm0_receive()gsm->buf'ın sonunun ötesine kopyalar:
Warning
Overflow, mux'un receive buffer'ına bitişik kernel memory'ye yapılan linear bir write'tır ve hem length hem content açısından peer tarafından kontrol edilebilir. slab grooming ile birleştiğinde bu bir kernel heap out-of-bounds write olur — crash veya privilege escalation'a yol açabilen bir memory-corruption primitive'i. CVSS, vendor scoring'ine bağlı olarak yaklaşık 7.7 (High) / 6.4 olarak raporlandı.
Upstream fix gsm0_receive()'i (ve gsm1_receive()'i) sertleştirir:
- payload-copy bound'unu bir equality test'inden
(
gsm->count == gsm->len) bir less-than test'ine (gsm->count < gsm->len) değiştir, böylece desync olmuş bir sayaç artık hedeflenen length'in ötesine adım atamaz. gsm->lenvegsm->mruüzerindeMAX_MRU'ya karşı açık upper-bound check'leri ekle, böylece bu field'ların corruption'ı buffer'dan büyük bir kopyaya yetki veremez.
Upstream çözüm: "tty: n_gsm: fix possible out-of-bounds in
gsm0_receive()", geniş çapta backport edildi (fix commit'leri arasında
0dbb44b063a651d7b9f061dab6b1030d648042cf ve mainline
774d83b008eccb1c48c14dc5486e7aa255731350 var).
Detection¶
- KASAN, mode-toggle sırası tekrar oynatıldığında
gsm0_receiveiçinde bir slab-out-of-bounds write raporlar. - Davranışsal: bir frame decode edilirken basic ve advanced option
mode arasında hızlı
GSMIOC_SETCONFtoggle'lama normal modem trafiği değildir ve güçlü bir göstergedir. - kernel'in
gsm0_receive/gsm1_receiveMAX_MRUbound check'lerini içerdiğini doğrula.
Mitigation¶
gsm0_receive()OOB fix'ini içeren bir kernel'e patch'le (CVE-2024-36016 çözümü).- GSM 0710 multiplexing kullanmayan sistemlerde
n_gsmmodülünü blocklist'e al. - gsm line discipline'ı attach etmeyi
CAP_NET_ADMINarkasına alarak receive path'i unprivileged koddan erişilemez tut.