Skip to content

RDS atomic_op_unmap_sg data-only attack (CVE-2022-3910)

CVE-2022-3910, bir io_uring IORING_OP_MSG_RING refcount-underflow use-after-free'idir: handler, sahibi olmadığı bir reference'ı bir fixed (registered) file üzerinde drop eder ve ring'de hâlâ canlı olan bir struct file'ı free eder — file-based DirtyCred data-only attack olarak exploit edilebilir.

İsimlendirme uyarısı

"RDS / atomic_op_unmap_sg" alias'ı public kayıtla örtüşmez. CVE-2022-3910 için her primary source bir io_uring MSG_RING struct file refcount bug'ını anlatır — işin içinde RDS (Reliable Datagram Sockets) ya da atomic_op_unmap_sg yoktur. Bu not gerçek, doğrulanmış güvenlik açığını belgeler; slug/alias yalnızca index sürekliliği için korunmuştur.

Mechanism

Note

Neden çalışır: io_uring, bir process'in file'ları bir ring'in fixed-file table'ına register etmesine (pin'lemesine) izin verir, böylece her request bir file'a fd yerine index ile referans verebilir ve op başına fget/fput önlenir. Lifetime kontratı şu: bir fixed file'ın reference'ı ring'in ömrü boyunca table'a aittir ve request başına asla drop edilmemelidir. IORING_OP_MSG_RING completion path'i bunu ihlal etti: request'in hatalı bir IOPOLL'ünden kaçınmak için koşulsuz olarak io_put_file(req->file) çağırdı — req->file REQ_F_FIXED_FILE ile flag'lenmiş bir fixed file olsa bile. Böyle her op, hiç increment etmediği bir file->f_count'u decrement eder, dolayısıyla tekrarlanan MSG_RING op'ları refcount'u sıfıra sürer ve ring'in hâlâ işaret ettiği bir struct file'ı free eder: bir use-after-free (CWE-416).

Free edilen obje bir struct file olduğu için bu, bir data-only attack (DirtyCred tarzı) için ideal tohumdur: hiçbir function pointer'ı corrupt etmezsin. Kernel'in burnunun dibinde yazılabilir bir file'ı free edersin, slot'u farklı bir file (ya da privileged field'lara alias yapan bir structure) ile reclaim edersin ve uçuşta olan bir operasyonun swap edilmiş obje üzerinde işlem yapmasına izin verirsin — orijinalde zaten geçilmiş olan access-mode check'ini bypass ederek.

Walkthrough

Fix ve onun tersi, tam trigger'ı tarif eder. Vulnerable completion logic:

/* io_uring MSG_RING completion (pre-fix) */
/* put file to avoid an attempt to IOPOLL the req */
io_put_file(req->file);     /* drops f_count even for a FIXED file */
req->file = NULL;

Patch (commit fc7222c3a9f5, Jens Axboe), put'u ownership'e göre gate'ler:

-   io_put_file(req->file);
+   if (!(req->flags & REQ_F_FIXED_FILE))
+       io_put_file(req->file);
    req->file = NULL;

Trigger taslağı (konsept):

/* 1. register a file into the ring's fixed-file table */
int fd = open("/some/file", O_RDWR);
io_uring_register_files(&ring, &fd, 1);   /* index 0 now owns +1 on f_count */

/* 2. submit IORING_OP_MSG_RING repeatedly against fixed index 0
 *    (IOSQE_FIXED_FILE). Each completion does the unbalanced io_put_file(),
 *    decrementing f_count it does not own. */
for (;;) submit_msg_ring(&ring, /*fixed idx*/0);
/* 3. once f_count hits 0 the struct file is freed while still registered -> UAF */
File-based DirtyCred / data-only escalation (STAR Labs)

STAR Labs, CVE-2022-3910'u bir file-based DirtyCred primitive olarak belgeledi:

  • Free: tekrarlanan MSG_RING op'ları f_count'u 0'a sürer, io_uring hâlâ referans verirken struct file'ı free eder.
  • Swap: O_RDWR ile açılmış bir file'a bir write() başlat; mode/permission check'inden sonra ama write handler çalışmadan önce, free edilen struct file slot'unu privileged bir hedefe işaret eden bir file ile heap spray üzerinden reclaim et.
  • Race'i genişlet: shmem hole-punch / page-fault stall'ları reclaim spray için window'u büyütür.
  • İndir: privileged write /proc/sys/kernel/modprobe'a (modprobe_path) çarpar, böylece bir sonraki modprobe trigger'ı attacker binary'sini root olarak çalıştırır — AppArmor devre dışı bırakılmadan bir containerd container escape olarak gösterilmiştir.

Beklenen sonuç: çağıran process'in asla izni olmadığı bir file/offset'e write erişimi, herhangi bir control-flow hijack olmadan elde edilir (SMEP/SMAP/KASLR saf bir data-only swap için alakasızdır).

Detection

  • io_msg_ring / io_put_file ve filp/files_cache slab'ına referans veren KASAN use-after-free raporları.
  • Beklenmedik struct file refcount underflow uyarıları (VFS: ... f_count).
  • IORING_OP_MSG_RING'i IOSQE_FIXED_FILE ile birleştiren io_uring kullanımını denetle; iyi huylu workload'larda nadirdir.

Mitigation

  • Upstream'de 6.0-rc6'da düzeltildi; stable backport 5.19.11'de. Etkilenen: Linux 5.18.0 – 5.19.10. Commit fc7222c3a9f5 "io_uring/msg_ring: check file type before putting" (aa184e8671f0'ı düzeltir).
  • Untrusted workload'lar için io_uring'i kısıtla (6.6+ üzerinde io_uring_disabled sysctl, io_uring_setup için seccomp-filter, ya da CONFIG_IO_URING=n ile devre dışı bırak).
  • Genel DirtyCred hardening (örn. cred/file allocation'larını ayrı cache'lere izole etmek) reclaim adımının çıtasını yükseltir.

References