Bir kullanıcı modu programının çekirdek alanı belleğine erişmesine ve IN ve OUT komutlarını yürütmesine izin vermemek CPU modlarına sahip olma amacını ortadan kaldırmaz mı?


19

CPU kullanıcı modundayken, CPU ayrıcalıklı talimatları yürütemez ve çekirdek alanı belleğine erişemez.

CPU çekirdek modundayken, CPU tüm talimatları yürütebilir ve tüm belleğe erişebilir.

Artık Linux'ta, bir kullanıcı modu programı tüm belleğe erişebiliyor (kullanarak /dev/mem) ve iki ayrıcalıklı komutu INve OUT( iopl()bence kullanarak ) yürütebiliyor .

Böylece, Linux'taki bir kullanıcı modu programı çekirdek modunda yapılabilecek çoğu şeyi (sanırım çoğu şeyi) yapabilir.

Bir kullanıcı modu programının tüm bu güçlere sahip olmasına izin vermemek CPU modlarına sahip olma amacını taşımıyor mu?

Yanıtlar:


23

Böylece, Linux'taki bir kullanıcı modu programı çekirdek modunda yapılabilecek çoğu şeyi (sanırım çoğu şeyi) yapabilir.

Eh, tüm kullanıcı modu programları değil, sadece uygun ayrıcalıklara sahip olanlar olabilir. Ve bu çekirdek tarafından belirlenir.

/dev/memolağan dosya sistemi erişim izinleri ve CAP_SYS_RAWIOyetenekleri tarafından korunur . iopl()ve ioperm()aynı yeteneği sayesinde kısıtlanır.

/dev/memayrıca çekirdekten tamamen derlenebilir ( CONFIG_DEVMEM).

Bir kullanıcı modu programının tüm bu güçlere sahip olmasına izin vermemek CPU modlarına sahip olma amacını taşımıyor mu?

Pekala belki. Ayrıcalıklı kullanıcı alanı işlemlerinin ne yapmasını istediğinize bağlıdır. Kullanıcı alanı işlemleri, /dev/sdadepolama erişimini işlemek için bir dosya sistemi sürücüsüne sahip olma amacını yitirse de, erişimi (veya eşdeğeri) varsa, tüm sabit sürücüyü çöpe atabilir .

(Daha sonra iopl(), i386'da CPU ayrıcalık modlarını kullanarak çalıştığı gerçeği de var , bu yüzden amaçlarını bozduğu söylenemez.)


2
Tüm ayrıcalıklı talimatlara bile ioplizin vermiyor , bu nedenle , baytlarla başlayan yürütülebilir belleğe işaret eden bozuk bir işlev işaretçisinden atlayarak, hatalı bir kullanıcı alanı programının yanlışlıkla çalışmadığından emin olmak için hala yararlıdır . Kullanıcı alanı işlemlerinin ayrıcalıklarını yükseltmesinin faydalı olmasının güvenlikle ilgili olmayan nedenlerinden bazılarına bir yanıt ekledim. invd0F 08
Peter Cordes

16

Sadece modprobeçekirdeğe yeni kod yükleyerek güvenliği "yener".

Çeşitli nedenlerden dolayı, çekirdek iş parçacığı yerine kullanıcı boşluğunda yarı ayrıcalıklı kodun (X sunucusu içindeki grafik sürücüleri gibi) olması daha mantıklıdır.

  • HW'yi killkilitlemediği sürece daha kolay yapabilmek .
  • Kodunu / verilerini dosya sistemindeki dosyalardan talep etmesini sağlamak. (Çekirdek belleği ücretli değildir)
  • O X sunucusu hatalar kendi sanal adres alanı verilmesi olabilir çekirdeği aşağı almadan, sadece X sunucusu çökmesine.

Güvenlik için fazla bir şey yapmaz, ancak büyük güvenilirlik ve yazılım mimarisi avantajları vardır.

Grafik sürücülerini çekirdeğe hazırlamak, X istemcileri ile X sunucusu arasındaki bağlam anahtarlarını, başka bir kullanım alanı işlemine veri almak yerine yalnızca bir kullanıcı -> çekirdek -> kullanıcı gibi azaltabilir, ancak X sunucuları geçmişte çok büyük ve çok hatalıdır onları tam olarak çekirdekte istemek.


Evet, bu privs ile zararlı kod olabilir o isterse kullanarak, çekirdek devralmak /dev/memçekirdek kodlarını değiştirmek için.

Örneğin, x86'da, IO ayrıcalık düzeyini 0 olarak ayarlamak için clibir ioplsistem çağrısı yaptıktan sonra bu çekirdekteki kesintileri devre dışı bırakmak için bir talimat çalıştırın .

Ancak x86 iopl"only" bile bazı talimatlara erişim sağlar : in / out (ve dize sürümleri ins / out) ve cli / sti. "Modele özgü kayıtları" kullanmanıza rdmsrveya wrmsrokumanıza veya yazmanıza (örn IA32_LSTAR. X86-64 syscallkomutu için çekirdek giriş noktası adresini ayarlamanıza ) veya lidtinterrupt-tanımlayıcı tablosunu (tamamen almanıza izin verir) mevcut çekirdekten, en azından bu çekirdeğin üstünde).

Saldırı sürecinin /dev/memkendi sayfa tablolarını mmapdeğiştirmeye daha fazla alternatif olarak bir ofset olarak yararlı bulabileceği en üst düzey sayfa dizininin fiziksel adresini tutan CR3 gibi kontrol kayıtlarını bile okuyamazsınız /dev/mem. )

invd( geri yazma olmadan tüm önbellekleri geçersiz kılın !! ( kullanım örneği = RAM yapılandırılmadan önce erken BIOS)) sadece IOPL değil, her zaman tam CPL 0 (geçerli ayrıcalık düzeyi) gerektiren başka bir eğlencedir. Hatta wbinvdayrıcalıklıdır çünkü çok yavaştır (ve kesilemez) ve tüm çekirdeklerdeki tüm önbellekleri temizlemek zorundadır . (Bkz . Bir programla ilgili tüm CPU önbelleğini temizlemenin bir yolu var mı? Ve WBINVD talimatı kullanımı )

Verileri kod olarak çalıştıran hatalı bir adrese atlamaya neden olan hatalar, bu nedenle, kullanıcı alanı X sunucusunda yanlışlıkla bu yönergelerin hiçbirini yürütemez.


Geçerli ayrıcalık düzeyi (korumalı ve uzun modda) (kod segmenti seçicisinin) düşük 2 bitidircs . mov eax, cs/ and eax, 3ayrıcalık düzeyini okumak için herhangi bir modda çalışır.

Ayrıcalık düzeyini yazmak için bir jmp farveya call farayarlamak için CS:RIP(ancak hedef segment için GDT / LDT girişi eski ayrıcalık düzeyine göre kısıtlayabilir, bu nedenle kullanıcı alanı bunu yükseltmek için bunu yapamaz). Veya bir çekirdek giriş noktasında 0 halkasına geçmek için intveya syscalltuşunu kullanın.


Aslında, Intel parlace sadece kod "selector" eminim. 8086/8088'de, muhtemelen 80186'da bir segmentti, ancak 80286'da bir seçici olarak adlandırıldı ve o zamandan beri bu terminolojiyi resmi olarak değiştirdiklerini sanmıyorum.
CVn
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.