netfilter nf_tables anonymous set UAF (CVE-2023-3390)¶
NFT_MSG_NEWRULEüzerinde yanlış ele alınan error handling, aynı transaction içinde bir anonymous set'e dangling bir pointer bırakır ve root'a escalate eden bir use-after-free üretir.
Mechanism¶
Note
nf_tables, değişiklikleri bir transaction içinde batch'ler. Aktif transaction list'inden reference verilen object'ler, commit ya da abort onları çözene kadar geçerli kalmalıdır. Bug bu invariant'ı bozar: bir anonymous set'e atıfta bulunan yeni bir rule'un eklenmesi başarısız olduğunda, orijinal error path rule/expression'ı yanlış transaction state kullanarak yıktı ve anonymous set'i hem free hem de aynı transaction'da hâlâ reachable bıraktı.
Resmi CVE kaydı bunu doğrudan belirtir: "Mishandled error handling with NFT_MSG_NEWRULE makes it possible to use a dangling pointer in the same transaction causing a use-after-free."
Fix'in mantığı: expression'lar NFT_TRANS_RELEASE değil, NFT_TRANS_PREPARE
state üzerinden deactivate edilmelidir. RELEASE, anonymous set'i prepare phase
için queue'lamak yerine hemen destroy eder, böylece dangling reference commit
processing'e kadar hayatta kalır.
Walkthrough¶
Error-path diff'i (düzelten commit'ten), hemen yapılan bir release'i bir prepare-then-destroy ile değiştirir:
/* before: */
nf_tables_rule_release(&ctx, rule);
/* after: */
nft_rule_expr_deactivate(&ctx, rule, NFT_TRANS_PREPARE);
nf_tables_rule_destroy(&ctx, rule);
Kavramsal trigger:
- Bir
CAP_NET_ADMINcontext'inden (user namespace'leri üzerinden unprivileged reachable) bir anonymous set'e atıfta bulunan yeni bir rule oluşturan bir batch kurun (örneğin birnftexpression'ında inline bir{ ... }set). - Anonymous set oluşturulduktan/bind edildikten sonra rule add'in başarısız olmasını zorlayın.
- Error path anonymous set'i release eder ama transaction list'inde dangling bir pointer kalır; sonraki transaction processing free edilmiş belleği dereference eder.
Standart devam: free edilen nft_set/element slab chunk'ını kontrollü bir spray
object (örneğin msg_msg, user_key_payload) ile reclaim edin, KASLR'ı yenmek
için bir kernel pointer leak edin, sonra bir arbitrary read/write primitive'i
kurun.
Detection¶
- KASAN, nf_tables transaction commit/abort path'lerinde bir use-after-free raporlar.
- Anonymous set'lerle NEWRULE üzerinde kasıtlı olarak hata veren rtnetlink
NFNL_SUBSYS_NFTABLESbatch'lerini audit etmek yararlı bir heuristic'tir.
Mitigation¶
- Commit
1240eb93f0616b21c675416516ff3d74798fdc97ile düzeltildi ("netfilter: nf_tables: incorrect error path handling with NFT_MSG_NEWRULE"). 3.16'dan 6.4 öncesine kadar etkilendi. - Unprivileged user namespace'leri kısıtlamak, çoğu local kullanıcı için attack surface'i kaldırır.