flawopen.com/Teardowns/cve-2024-26642-linux-nftables-anonymous-set-timeout

● CVE-2024-26642 · CVSS 7.8 · Tinggi
Riset Keamanan · FlawOpen

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.

💡 Penjelasan Sederhana (ELI5)

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_NEWSET dan ditangani nf_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 meter lama. 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

Langkah 1

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.

Langkah 2

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.

Langkah 3

Kernel menerimanya

nf_tables_newset() tidak menemukan pasangan flag terlarang dan membuat set anonim yang terikat aturan dengan elemen berwaktu kedaluwarsa.

Langkah 4

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

IMPLEMENTASI RENTAN
/* 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. */
	}
PERBAIKAN AMAN & KUAT
/* 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

Sumber