Koruma Mekanizması, Çekirdek ve Kullanıcı Modları

advertisement
Koruma Mekanizması, Çekirdek ve Kullanıcı Modları
Kaan Aslan
21 Nisan 2005
Çok prosesli sistemlerde işletim sisteminin kendisi ve çalışan tüm prosesler aynı
fiziksel bellekte bulunur. Bir prosesin kendi bellek alanı dışına çıkarak işletim
sisteminin ya da başka proseslerin bellek alanlarına erişmesi güvenli bir durum
değildir. Örneğin C’de bir göstericiye işletim sisteminin bulunduğu bir bölgenin
adresini yerleştirip orayı bozmaya çalışabilirsiniz. İşletim sisteminin bellekteki kod ve
veri alanlarının bozulması tüm sistemi çökertebilir. Bir banka görevlisinin tam bir
işlem yaparken o sırada başka bir prosesin yanlışlıkla ya da kötü niyetle bu işlemin
yapıldığı alana erişerek orayı rastgele bozduğunu düşünün. Program çökebilir ya da
yanlış bilgiler veritabanına aktarılabilir. Böyle bir sistem güvenli olabilir mi?..
Şüphesiz güvenliği tehdit eden tek unsur bellek erişimi değildir. Bazı makina
komutları sistemi anında çökertebilir. Örneğin Intel işlemcilerinde CLI komutu ile
işlemci donanım kesmelerine kapatılır. İşletim sistemi dışsal kesmlere gereksinim
duyduğundan sistem hemen çöker. Ya da haberleşme portlarına OUT komutuyla
rastgele değerler aktarılarak da sistem çökertilebilir. O halde güvenli bir sistemde
sıradan proseslerin bazı makina komutlarını kullanamaması gerekir. Bu tür
korumalara komut koruması denilmektedir.
Koruma mekanizması daha ilk elden işlemci tarafından sağlanmaktadır. İşlemci
aktarım yapan makina komutlarını denetleyerek prosesin kendi bellek alanının dışına
çıkıp çıkmadığını belirlemeye çalışır. Sıradan prosesler özel makina komutlarını
kullandığında bu durum yine öncelikle işlemci tarafından belirlenir. İşlemcinin görevi
koruma ihlallerini belirleyip bunu işletim sistemine iletmektir. İşletim sistemi koruma
mekanizmasını tehdit eden prosesleri cezalandırıp sonlandırabilir. Windows
sistemlerinde sık sık gördüğünüz “Bu program geçersiz bir işlemi yürüttü,
sonlandırılacak” gibi mesajlar ya da UNIX/Linux sistemlerinde karşılaşmış
olabileceğiniz “segmentation violation...” gibi mesajlar bu durumu anlatmaktadır.
Koruma mekanizmasına sahip olan işlemcilerde en azından iki çalışma modu
bulunur. Bunlardan birine çekirdek modu (kernel mode), diğerine ise kullanıcı modu
(user mode) denilmektedir. Eğer kod çekirdek modunda çalıştırılıyorsa işlemci
çalışmakta olan koda yönelik hiçbir erişim kontrolü uygulamaz. Yani çekirdek
modunda çalışan kodlar belleğin her yerine erişebilir, her makina komutunu işletebilir.
Buna karşılık kullanıcı modunda çalışan programlar bellekte ancak kendileri için
ayrılan alanlara erişebilirler ve ancak zararsız makina komutlarını işletebilirler.
Intel işlemcilerinde çalışan her koda 0, 1, 2, 3 biçiminde belirtilen öncelik
derecelerinden biri atanır. 0 en yüksek önceliği, 3 en düşük önceliği belirtir. Yani bu
işlemcilerde çekirdek modu ve kullanıcı modu biçiminde 2 çalışma modu değil,
toplam 4 çalışma modu vardır. Ancak Windows ve Linux gibi işletim sistemleri
yalnızca 0 ve 3 modlarını kullanırlar. 0 çekirdek modunu, 3 ise kullanıcı modunu
temsil eder.
1
Kaan Aslan Makale Arşivi – www.kaanaslan.net
Pek çok işlemcide fiziksel bellek de sayfa (page) denilen bloklara ayrılmaktadır.
Fiziksel bellekteki her sayfanın bir numarası vardır. Sayfa büyüklüklerinin işlemciden
işlemciye değişebildiğini belirtelim. Örneğin, Intel işlemcilerinde sayfalar 4 KB, Alpha
işlemcilerinde 8 KB uzunluğundadır. (Intel işlemcileri 4 MB’lik sayfalar kullanabiliyorsa
da işletim sistemleri 4 MB’lik sayfaları tercih etmiyorlar.) Koruma mekanizmasına
sahip işlemcilerde bellekteki bu sayfalara da çekirdek modu, kullanıcı modu biçiminde
bir öncelik derecesi atanır. Örneğin, Intel işlemcilerinde her sayfaya 0, 1, 2, 3 öncelik
derecelerinden biri atanabilmektedir. (Fakat Windows ve Linux gibi sistemler yine
yalnızca 0 ve 3 öncelik derecelerini kullanıyorlar.) Çekirdek modunda çalışan kodlar
bellekte her sayfaya erişebilirken kullanıcı modunda çalışan kodlar yalnızca kullanıcı
moduna ayarlanmış sayfalara erişebilirler. İşletim sistemi kendi kod ve verilerinin
bulunduğu sayfaları çekirdek moduna ayarlar. İşletim sisteminin kendisi çekirdek
modunda sıradan prosesler ise kullanıcı modunda çalışmaktadır. Böylece işletim
sistemi bellekte her yere erişebilirken sıradan prosesler işletim sisteminin kod ve
verilerinin bulunduğu fiziksel sayfalara erişemezler.
Sıradan proseslerin işletim sisteminin bellek alanına erişemediğini söyledik. Peki,
bir prosesin diğerinin bellek alanına erişmesi nasıl engellenmektedir? Aslında bazı
işlemcilerde çalışan kodun yalnızca belirli bir bölgeye (yani kendi bölgesine)
erişebilmesi, başka bölgelere erişememesi sağlanabiliyor. (Örneğin, Intel
işlemcilerinde bunu sağlamak için betimleyiciler içerisinde offset ve limit değerleri
bulunur.) Fakat modern işletim sistemleri işlemcilerin sayfalama mekanizmalarını
kullanarak prosesleri birbirlerinden tamamen ayırmaktadır. Windows ve Linux gibi
sistemlerde işletim sistemi her proses için bellekte hep aynı yerde dururken, sıradan
prosesler bellekte yalnızca kendileri varmış gibi çalışırlar. İşlemcilerin sayfalama
mekaznizması ayrıca ele alınması gereken geniş bir konudur.
Anlattıklarımızdan bir özet yapalım isterseniz. (Intel işlemcilerinin kullanıldığı bir
PC’de çalıştığımızı düşünelim):
1. İşletim sistemi çekirdek modunda (0 öncelik derecesinde), sıradan prosesler
kullanıcı modunda (3 öncelik derecesinde) çalışır.
2. İşletim sistemi bellekte her yere erişebilir fakat sıradan prosesler işletim sisteminin
bellek alanına erişemez. Çünkü işletim sisteminin yüklü olduğu bellek alanının
sayfaları çekirdek moduna (yani Intel’de 0 önceliğe) ayarlanmıştır.
3. Proseslerin bellek alanları birbirlerindne izole edilmiştir. Bir proses kendi alanının
dışına çıkarak başka bir prosesin bellek alanına erişemez.
Şimdi prosesimizin bir sistem fonksiyonunu çağırdığını düşünelim. Örneğin open
fonksiyonuyla bir dosya açmak isteyelim:
fd = open(....);
open fonksiyonu işletim sisteminin bir sistem fonksiyonudur. Bu fonksiyon da doğal
olarak işletim sisteminin kendi alanındaki birtakım veri yapılarına erişerek onlar
üzerinde değişiklikler yapacaktır. Peki, proses kullanıcı modunda olduğuna göre
open gibi bir sistem fonksiyonu çağrıldığında çekirdek alanına erişim nasıl mümkün
olacak? Koruma hatası oluşmayacak mı? İşte kullanıcı modunda çalışan prosesler
2
Kaan Aslan Makale Arşivi – www.kaanaslan.net
işletim sisteminin sistem fonksiyonlarını çağırdığında onların öncelikleri geçici olarak
çekirdek moduna yükseltilmektedir. Bu duruma çalışmakta olan prosesin kullanıcı
modundan çekirdek moduna geçmesi denir. Proses sistem fonksiyonu çalıştığı
sürece çekirdek modunda kalır, sistem fonksiyonu geri döndüğünde proses de
yeniden kullanıcı moduna geri döner. Buraya dikkat ediniz: Bir proses kendi istediği
zaman önceliğini yükselterek çekirdek moduna geçemez. Ancak güvenilir olduğu
bilinen sistem fonksiyonları çağrılırken çekirdek moduna geçebilir. Intel işlemcilerinde
kullanıcı modundan çekirdek moduna geçişi sağlayan mekznizmaya kapı (gate)
denilmektedir.[1][2]
Çekirdek modunda çalışacak bir program yazamaz mıyız? Evet yazabiliriz. Bu tür
programlara çekirdek modülü (kernel module) ya da aygıt sürücü (device driver)
denilmektedir. Bu tür programlar çekirdek modunda çalışırlar. Böylece kullanıcı
modundaki programlara yasaklanmış olan IN, OUT gibi makina komutlarını
kullanarak çevre birimlerini programlayabilirler. Çekirdek modülleri ve aygıt sürücüler
sistem yöneticisi (UNIX türevi sistemlerde root kullanıcısı) tarafından yüklenebildiği
için kötü niyetli programların bu yolla sistemi çökertmeleri engellenmiş olmaktadır.
[1]
Intel mimarisinde çalışan Linux sistemlerinde tüm sistem fonksiyonlarının ana girişi
80H kesmesidir. 80H kesmesine bir tuzak kapısı (trap gate) yerleştirilmiştir. Bu tuzak
kapısı yoluyla çekirdek moduna geçiş yapılmaktadır.
[2]
Daha ayrıntılı bilgi için Kaan Aslan'ın Intel İşlemcileri Korumalı Mod Yazılım
Mimarisi isimli kitabının 5. Bölümüne başvurabilirsiniz.
3
Kaan Aslan Makale Arşivi – www.kaanaslan.net
Download