flawopen.com/Teardowns/cve-2024-26642-linux-nftables-anonymous-set-timeout
CVE-2024-26642: Set Anonim dengan Flag Timeout di nf_tables Linux
CVE-2024-26642 (CVSS 7.8 menurut NIST): nf_tables_newset() menerima set anonim yang juga membawa flag timeout, kombinasi yang tidak pernah dibuat alat ruang pengguna mana pun, sehingga set yang terikat pada satu aturan ikut terkena kedaluwarsa elemen dan garbage collection. Linux 6.8 menolaknya dengan -EOPNOTSUPP.
Sebuah tempat penitipan mantel punya dua sistem. Gantungan bernomor milik satu tamu selama satu malam dan langsung dikosongkan begitu tamu itu pulang. Tiket berwaktu diperiksa setiap jam oleh petugas yang menyingkirkan semua yang sudah lewat waktunya. Formulirnya membolehkan mencentang kedua kotak untuk mantel yang sama, sehingga gantungan itu dikosongkan saat tamu pulang dan juga saat petugas berkeliling. Dua orang sama-sama merasa bertanggung jawab atas gantungan yang sama, dan tidak ada yang tahu jadwal yang lain. Perbaikannya sederhana: formulir kini menolak pasangan kotak itu.
Konsep Kunci & Istilah
nf_tables set- Struktur data kernel berisi alamat, port, atau kunci lain yang dicocokkan aturan nftables; dibuat dengan pesan netlink
NFT_MSG_NEWSETdan ditanganinf_tables_newset(). Set anonim (NFT_SET_ANONYMOUS)- Set tanpa nama, seperti
{ 22, 80 }yang ditulis langsung dalam aturan. Set ini terikat pada satu aturan itu dan dihancurkan bersamanya dalam transaksi yang sama. NFT_SET_TIMEOUT- Flag yang memberi elemen set waktu kedaluwarsa. Elemen yang kedaluwarsa dibuang oleh mekanisme garbage collection set.
NFT_SET_EVAL- Flag untuk set yang diperbarui dari jalur paket, dipakai pernyataan
meterlama. Perbaikan tetap mengizinkan anonim + timeout + eval untuk mereka. CAP_NET_ADMIN di user namespace- nf_tables menerima konfigurasi dari proses mana pun yang memegang CAP_NET_ADMIN di namespace jaringannya; pengguna tanpa hak istimewa bisa mendapatkannya dengan membuat user namespace bila distribusi mengizinkan.
Analisis Akar Masalah (Root Cause)
nf_tables_newset() di net/netfilter/nf_tables_api.c hanya memeriksa flag set terhadap bit yang tidak dikenal serta konflik MAP+OBJECT dan EVAL+OBJECT. Fungsi itu menerima NFT_SET_ANONYMOUS | NFT_SET_TIMEOUT, sehingga set yang umurnya terikat pada satu aturan dan satu transaksi juga bisa punya elemen yang kedaluwarsa dan diambil oleh garbage collection. Ruang pengguna tidak pernah menghasilkan kombinasi ini, dan kode pengelola umur objek tidak dirancang untuknya. Perbaikan upstream menolaknya dengan -EOPNOTSUPP kecuali NFT_SET_EVAL juga dipasang. Catatan publik tidak merinci kesalahan memori yang timbul; NIST memberi skor 7.8 (kerahasiaan, integritas, dan ketersediaan tinggi), sedangkan CNA kernel memberi 5.5 (hanya ketersediaan).
Alur Serangan Langkah demi Langkah
Mendapatkan CAP_NET_ADMIN
Pengguna lokal membuat user namespace dan namespace jaringan (di sistem yang mengizinkan user namespace tanpa hak istimewa) sehingga memegang CAP_NET_ADMIN atas status nf_tables namespace tersebut.
Meminta set yang tidak valid
Dalam satu batch netlink, proses mengirim NFT_MSG_NEWSET dengan NFTA_SET_FLAGS = NFT_SET_ANONYMOUS | NFT_SET_TIMEOUT dan mengikat set itu ke aturan baru lewat ekspresi lookup.
Kernel menerimanya
nf_tables_newset() tidak menemukan pasangan flag terlarang dan membuat set anonim yang terikat aturan dengan elemen berwaktu kedaluwarsa.
Jalur umur objek yang belum teruji
Commit, abort, atau penghapusan aturan kini menjalankan penghancuran set dan garbage collection elemen sekaligus, di jalur yang tidak ditangani dengan aman oleh kode transaksi nf_tables.
Kode Sumber: Rentan vs Aman
/* net/netfilter/nf_tables_api.c: nf_tables_newset(), before the fix */
if (nla[NFTA_SET_FLAGS] != NULL) {
flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
NFT_SET_INTERVAL | NFT_SET_TIMEOUT |
NFT_SET_MAP | NFT_SET_EVAL |
NFT_SET_OBJECT | NFT_SET_CONCAT | NFT_SET_EXPR))
return -EOPNOTSUPP;
/* Only one of these operations is supported */
if ((flags & (NFT_SET_MAP | NFT_SET_OBJECT)) ==
(NFT_SET_MAP | NFT_SET_OBJECT))
return -EOPNOTSUPP;
if ((flags & (NFT_SET_EVAL | NFT_SET_OBJECT)) ==
(NFT_SET_EVAL | NFT_SET_OBJECT))
return -EOPNOTSUPP;
/* BUG: NFT_SET_ANONYMOUS | NFT_SET_TIMEOUT is accepted. A rule-bound
* anonymous set now also gets per-element expiry and garbage
* collection, a combination nft never creates and the set
* lifetime code was not written for. */
}
/* net/netfilter/nf_tables_api.c: nf_tables_newset(), commit 16603605b667 */
if (nla[NFTA_SET_FLAGS] != NULL) {
flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
NFT_SET_INTERVAL | NFT_SET_TIMEOUT |
NFT_SET_MAP | NFT_SET_EVAL |
NFT_SET_OBJECT | NFT_SET_CONCAT | NFT_SET_EXPR))
return -EOPNOTSUPP;
/* Only one of these operations is supported */
if ((flags & (NFT_SET_MAP | NFT_SET_OBJECT)) ==
(NFT_SET_MAP | NFT_SET_OBJECT))
return -EOPNOTSUPP;
if ((flags & (NFT_SET_EVAL | NFT_SET_OBJECT)) ==
(NFT_SET_EVAL | NFT_SET_OBJECT))
return -EOPNOTSUPP;
/* FIX: anonymous sets are never used with timeouts from userspace,
* so reject the combination before the set exists. NFT_SET_EVAL
* stays allowed so legacy meters keep working. */
if ((flags & (NFT_SET_ANONYMOUS | NFT_SET_TIMEOUT | NFT_SET_EVAL)) ==
(NFT_SET_ANONYMOUS | NFT_SET_TIMEOUT))
return -EOPNOTSUPP;
}
Daftar Periksa Penguatan Sistem Rekayasa
- ✓Jalankan kernel yang memuat commit 16603605b667 (Linux 6.8, atau kernel stable maupun distribusi yang changelog-nya mencantumkan
CVE-2024-26642). - ✓Bila beban kerja tidak membutuhkannya, matikan user namespace tanpa hak istimewa (
kernel.di Debian dan Ubuntu,unprivileged_userns_clone=0user., atau pembatasan userns AppArmor di Ubuntu) agar pengguna lokal tidak bisa mencapai nf_tables.max_user_namespaces=0 - ✓Di host yang tidak memakai nftables, cegah modul
nf_tablesdimuat. - ✓Dalam kode kernel dan API, tuliskan kombinasi flag yang diterima sebagai daftar izin eksplisit dan tolak semua yang tidak dihasilkan klien yang didukung, alih-alih hanya menolak pasangan buruk yang sudah dikenal.
- ✓Lakukan fuzzing antarmuka netlink dengan deskripsi syzkaller yang mencakup setiap bit flag, agar kombinasi yang tidak lazim lebih dulu mencapai kode umur objek saat pengujian.