Skip to content

CUDA Leaks: Information Leakage in GPU Architectures

CUDA GPU'larının (Fermi, Kepler) context'ler arasında shared memory'yi, global memory'yi ya da spilled register'ları sıfırlamadığını; böylece co-resident bir process'in bir öncülün verisini kurtarabildiğini gösteren 2013 tarihli bir çalışma — bir GPU AES implementasyonuna karşı, yalnızca standart CUDA API çağrıları kullanılarak gösterildi.

Mechanism

Neden çalışır — GPU, kiracılar arasında temiz bir sayfa vaat etmez

Bir CPU'da OS, free edilmiş belleği yeni bir process'e vermeden önce page'leri sıfırlar ve kiracılar arasında izolasyonu korur. Bu dönemin GPU'ları throughput için optimize etti ve o sıfırlamayı atladı. Kırılan invariant CUDA context'leri boyunca bellek gizliliğidir: bir process bittiğinde verisi GPU belleğinde kalır ve aynı bölgelere allocate eden ya da schedule olan bir sonraki process tarafından gözlemlenebilir.

Di Pietro, Lombardi ve Villani üç leakage primitive'i belgeler:

  • Shared memory leakage. On-chip __shared__ bellek, kernel launch'ları arasında temizlenmez. Bir kernel başlatan ikinci bir process, önceki bir kernel'in shared memory'de bıraktığı her şeyi okuyabilir.
  • Global (device) memory leakage. cudaMalloc'lanmış device belleği sıfırlanmadan verilir. Process B, A'nın free ettiği miktarın aynısını allocate ederse, B A'nın içeriğini geri okur. Önemlisi, bu cudaHostAlloc pinned belleği bile etkiler.
  • Register-spill leakage. Bir kernel var olandan daha fazla register talep ettiğinde, derleyici onları global memory'ye spill eder. Saldırgan, devasa register baskısı zorlayarak spill edilmiş bölgeleri okur — ve benzersiz biçimde, bunu victim hâlâ belleğe sahipken (cudaFree'den önce) yapabilir.

Üçü de yalnızca public CUDA Runtime API'sini kullandığından, ne root, ne driver bug'ı, ne de physical erişim gerekir — yalnızca aynı GPU üzerinde co-residency (same-system ya da shared-cloud threat model'i). Yazarların işaret ettiği takas açıktır: vendor'lar runtime overhead'inden kaçınmak için per-launch sıfırlamayı atladı.

Walkthrough

Aşağıdaki parçalar örnekleyicidir ve açıklanmış makaleyi izler; uninitialized belleği okurlar, yeni bir exploit değildirler.

Global-memory recovery (önce victim, sonra saldırgan):

  1. Victim device buffer'larını allocate eder, doldurur ve sonra free eder, ardından çıkar.
  2. Saldırgan aynı boyutta buffer'lar allocate eder ve onları initialize etmeden host'a geri kopyalar:
// Attacker: read back whatever the previous tenant left behind
size_t n = victim_size;            // match the freed allocation size
char *d_buf; cudaMalloc(&d_buf, n);            // no zeroing performed by CUDA
char *h_buf = (char *)malloc(n);
cudaMemcpy(h_buf, d_buf, n, cudaMemcpyDeviceToHost);
// h_buf now contains residual data from the prior process

Makalenin recovery döngüsü, mevcut tüm GPU belleğini allocate eder ve onu bilinen plaintext marker'ları (yazarlar Dante'nin İlahi Komedya'sının açılışını kullandı) ya da anahtar materyali için tarar.

Register-spill leakage (bir spill'i zorla, sonra onu oku):

// Declare far more registers than the hardware provides -> compiler spills to global memory
asm(".reg .u32 r<8300>;");
asm("mov.u32 %0, r0;" : "=r"(regs32[0]));   // read a spilled slot back out
// repeat across thousands of registers to sweep spilled global memory
AES vaka çalışması — raporlanan recovery oranları

SSLShader'ın GPU-hızlandırmalı AES'ine karşı yazarlar, anahtarları ya da plaintext'i — makalede raporlandığı kadarıyla, çalışılan donanım/build'lerde — kabaca Kepler'de denemelerin %30'unda (GeForce GT 640) ve Fermi'de %12'sinde (Tesla C2050) kurtardı; bu oranlar bağımsız olarak doğrulanmamıştır. SSLShader'ın cudaHostAlloc kullanımı leakage'ı engellemedi.

Detection

  • Workload denetimi. Paylaşımlı/multi-tenant GPU'larda, büyük buffer'lar allocate edip önce yazmadan hemen okuyan herhangi bir process'i şüpheli olarak değerlendir — bu, residual-memory taramasının imzasıdır.
  • Telemetry. Anormal register baskısına (spill zorlayan) sahip kernel'leri ya da tüm free VRAM'i tüketen tekrarlı allocate-read-free döngülerini izle.
  • Provenance. CI/cloud'da, hangi kiracıların bir physical GPU'yu paylaştığını logla; leakage co-residency gerektirir, bu yüzden scheduling kayıtları maruziyet penceresini sınırlar.

Mitigation

GPU belleğini trust boundary'de sıfırla — bunu GPU'nun yapmasına güvenme

  • Uygulama seviyesi: hassas veriyi free etmeden önce device buffer'larını açıkça cudaMemset(ptr, 0, size) yap ve kernel çıkışında __shared__ belleği temizle (makale bu in-kernel sıfırlamanın maliyetini, raporlandığı kadarıyla çalışılan donanımda kabaca Kepler'de 1.66 ms / Tesla'da 0.27 ms olarak ölçtü — bağımsız olarak doğrulanmamış, ama tipik buffer'lar için küçük bir overhead).
  • Platform seviyesi: context'ler arasında belleği scrub eden GPU'ları/driver'ları tercih et; modern data-center GPU'ları ve güncel driver'lar, çalışılan parçaların yoksun olduğu context/MIG izolasyonu ve bellek temizleme sağlar. Karşılıklı güvensiz kiracıları tek bir legacy GPU üzerine koyma.
  • Register spill'ler: mitigation, başkalarının hâlâ sahip olduğu bölgelere spill'lemekten kaçınmak ve serbest bırakmada spilled slot'ları sıfırlamak için driver işbirliği (kapalı bir NVIDIA bileşeni) gerektirir — driver'ları/firmware'i güncel tutmanın bir başka nedeni.

See also

References