Autor : A. Wolny z drobnymi przerobkami
Procesory rodziny x86 ( i każzde inne też) posiadają pewien zbiór
instrukcji _uprzywilejowanych_, tj. takich, które nie mogą być wykonywane
przez byle kogo. Czy to znaczy, że jeśli masz prawa roota możesz wykonywać
takie instrukcje? Niezupełnie.
Wszystkie
instrukcje uprzywilejowane muszą się wykonywać na poziomie ochrony 0 i to czy
program jest wykonywany z prawami root'a czy nie, nie ma tu żadnego znaczenia.
Prawa użytkownikow (w tym root'a) maja znaczenie tylko w odniesieniu do
odwolań do jadra systemu -- po prostu warunkiem koniecznym zakończenia sie
powodzeniem niektorych syscall'i jest to by mialy EUID rowny 0. Program
chodzący z prawami root'a dalej wykonuje się w trybie użytkownika i przez
procesor widziany jest jak każdy inny proces (oprócz tzw. procesów
systemowych, czyli procesów jadra, ale to zupelnie inna bajka :-)) i ma też
takie same prawa jak każdy inny. Skutkiem tego jest to, ze instrukcje
uprzywilejowane mogą być wykonywane tylko i wyłącznie przez jądro (po
przełączeniu sią podczas wywolania syscall'a przez int 0x80, lub podczas
obsługi przerwań), a poza nim powodują wyjątek i kończy się to zabiciem
procesu.
Instrukcjami uprzywilejowanymi sa:
CLTS ,
HLT ,
LGDT ,
LIDT ,
LLDT ,
LMSW ,
LTR ,
MOV (przy dostepie do rejestrow CR, TR i DR).
Oprocz tego mozna za
uprzywilejowane uwazac instrukcje:
CLI ,
STI,
IN,
OUT,
INS,
OUTS,
LOCK (mozna,
bo ogolnie rzecz biorac takimi nie musza byc, ale w linuxie akurat sa).
Użycie zabronionej instrukcji spowoduje wygenerowanie sygnalu SIGILL.
Jak zapewne wiesz obslugi tego sygnalu nie mozna przechwycić i kończy się
on zakończeniem procesu. Jeżeli twój program zakończył się natomiast
komunikatem "Segmentation fault" to otrzymal sygnal SIGSEGV, czyli
usiłował złamać ochronę pamięci bądź odwołać się do strony spoza segmentu.