İşletim sistemi bellek erişim ihlallerini nasıl tespit eder?


12

Bir işletim sistemi (tercihen Linux), izin verilmeyen bir bellek konumuna eriştiğinizi nasıl biliyor?

Bu soru şu lanet olası işaretçilerden ilham aldı! Gördüğüm gibi: bilgisayarlardaki her şey hız, güvenlik, bütünlük ve bu tür şeyler arasında bir uzlaşma ile ilgilidir.

Linux'taki bellek haritalarının farkındayım, ancak çekirdeğin erişmeye çalıştığınız konumun HER ZAMAN eriştiğiniz geçerli bir aralıkta olup olmadığını kontrol etmesi biraz saçma geliyor. Daha verimli bir şey yapmakla harcanabilecek kadar çok zaman harcayacak gibi görünüyor (ancak kontrol olmadan muhtemelen daha az güvenli!). Ya da belki de tüm son erişimleri hatırlar ve her donanım zamanlayıcı onayında kontrol eder? (Ama bu güvensiz ve yine de yavaş görünüyor.)

Bu sorunun herhangi bir yerde cevapsız göründüğüne şaşırdım. Her zaman merak ettiğim bir şey. Bu, işletim sistemi adına bunu güzel ve kullanışlı bir soyutlama düzeyinde yapacak bir donanım bölümü olduğunu düşündürüyor. Ancak yine de, muhtemelen yavaş gelen her bağlam anahtarına sonraki işlemlerin bellek haritalarının yüklenmesini gerektirecektir.

Yani evet, her neyse, biraz devam ediyorum: bir işletim sistemi bir bellek ihlali nasıl algılar?

Teşekkürler

Yanıtlar:


11

(Aşağıdaki yanıtta "modern" bir masaüstü, sunucu veya üst uçta yerleşik bir platform (akıllı telefonlar ve daha fazla ve daha küçük sistemler gibi) varsayılmaktadır. X86 sistemleri için modern araçlar 386 ve üstü anlamına gelir. 95'ten beri neredeyse tüm unix veya Windows gibi "modern" işletim sistemleri.)

Bu işletim sisteminde gerçekleşmiyor, işlemcide, özellikle MMU'da ( bellek yönetim birimi ) oluyor . MMU, sanal adreslemeyi destekler; burada, bir işaretçi oluşturan bitler, bellekteki bitlerin fiziksel konumunu doğrudan göstermez.

Tipik bir MMU'da, bir işaretçi kaydı kaldırıldığında, MMU bitleri iki gruba ayırır: yüksek dereceli bitler sayfa numarasını ve düşük dereceli bitler sayfanın içindeki adresi oluşturur. Çoğu masaüstü ve sunucu makinesi 4kB sayfaları kullanır. MMU, sanal sayfa numarasını TLB adlı bir tabloda arar (“işlem bellek haritaları” olarak adlandırırsınız). TLB, bu sanal sayfaya karşılık gelen fiziksel sayfa sayısını belirtir. MMU daha sonra verileri bellekteki fiziksel sayfadan alır.

TLB bu sanal sayfa numarası için bir girdi içermiyorsa, MMU işlemciye geçersiz bir erişim olduğunu bildirir; buna tipik olarak istisna denir.

Şimdiye kadar işletim sisteminden bahsetmediğimi unutmayın. Çünkü tüm bu işlemler işletim sisteminden bağımsızdır. İşletim sistemi devreye girer, çünkü işleri iki şekilde yapılandırır:

  • İşletim sistemi görevleri değiştirmekle sorumludur. Bunu yaptığınızda, şüphelendiğiniz gibi, geçerli TLB'yi kaydeder ve bir sonraki zamanlanmış görev için kaydedilen TLB ile değiştirir. Bu şekilde, her işlem bir TLB'ye sahiptir, bu nedenle 0x123456X işlemindeki adres , RAM'deki Y işlemindeki aynı adresle aynı gerçek yeri göstermeyebilir veya yalnızca geçersiz olabilir. Bir işlem, adres alanının dışında bir işaretçiyi geri çekmeye çalışırsa, başka bir işlemin alanına erişmez, bunun yerine hiçbir yere ulaşmaz .

  • İşletim sistemi bir istisna ortaya çıktığında ne olacağına karar verir. Geçersiz bellek erişimi (segmentasyon hatası, genel koruma hatası, ...) yapma işlemini sonlandırabilir. Bu aynı zamanda takas işleminin uygulanma yoludur: istisna işleyici takas alanından bazı verileri almaya, TLB'yi buna göre güncellemeye ve tekrar erişim yapmaya karar verebilir.

İşlem kendi TLB'sini değiştiremediğinden MMU'nun güvenlik sağladığını unutmayın. TLB'leri yalnızca işletim sistemi çekirdeği değiştirebilir. TLB değişiklik izinlerinin nasıl çalıştığı bu cevabın kapsamı dışındadır.


6

1) Segfaultlar bellek yönetim birimi tarafından algılanır. Bellek istediğinde, İşletim Sistemi Bellek Yönetim Birimi'nden donanımdan bir miktar almasını ister. İşletim sisteminin size verdiği tüm büyük bellek bloklarını takip eden bir şey olmalı. OS tür MMU eller. Size verdiği tüm belleği bildiğinden, ayırmalardan almadığınız bir bellek konumuna erişmeye çalıştığınızda da söyleyebilir, İşletim Sisteminin bunun için özel bir etkinliği vardır, sahip olmadığınız bellek. Sonunda işletim sistemi uygulamanızı öldürür ve diğer işletim sistemlerinde bir segfault veya eşdeğerini tetikler.

Tüm işletim sistemlerinde bu koruma yoktur. MMU bunu desteklemesine rağmen 9'a kadar MacOS bunlardan hiçbirine sahip değildi. Ayrıca Kazanma 3.1. Win95'in bir koruması vardı, çünkü hiçbir korumanın olmaması ve daha sonra eklenmesi arasında geçiş yaptı.

2) İşletim sistemi bunun dışında hiçbir ayrıntı bilmiyor. Hiç ayırmadığınız belleğe erişen bir başıboş işaretçiniz varsa bunu bilir. Uygulamanızın başka bir bölümüne giren bir tane varsa, elbette bilmiyor. Bunu bozmanızı sağlar. Bu, uygulamanızdaki başıboş işaretçilerle uygulamanızın diğer bölümlerinin üzerine yazarak bozuk yığınlar elde edeceğiniz yerdir.

Yani, evet, kendi verilerinizi vidalayabilirsiniz. Kendi uygulamanızın üzerine yazan bir başıboş işaretçiniz varsa, yığınıza vurmanızı umarsınız, çünkü yığını geri döndürmeye çalıştığınızda muhtemelen başka bir ihlale neden olur, ancak kendi verilerinizi vurursanız asla bilemezsiniz.

'Koruma yok' dan daha katı olmaya çalışabilirsiniz, MMU'nuzu biraz daha çalışması için kandıracak ve daha fazlasını algılamasına neden olacak Elektrikli Çit ( http://perens.com/FreeSoftware/ElectricFence/ ) adlı bir araç var. arızalar.


Tamam, nasıl çalıştığı konusunda daha açık olabilir misiniz? Örneğin, belirli bir sürecin belirli bir konuma erişemediğini nasıl bilebilir? Hangi işlemlerin nereye erişebileceğini söyleyen nedir? Nasıl ayırt edilir? Teşekkürler
Doddy

1
@panic - wikipedia'da Memory_management_unit ve o sayfadaki bağlantılara bakın. İşlem durumunun MMU durumu içerdiğini unutmayın. Yarıyılları MMU tasarımı, özellikleri ve entegrasyonu için harcayabilirsiniz.
mpez0
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.