Implementace copy_from_user()
je velmi závislá na architektuře.
Na x86 a x86-64 jednoduše přímo čte z adresy uživatelského prostoru a zapisuje na adresu jaderného prostoru, přičemž dočasně deaktivuje SMAP (Supervisor Mode Access Prevention), pokud je nakonfigurován. Záludná část je v tom, že copy_from_user()
kód je umístěn do speciální oblasti, aby obslužný program chyby stránky mohl rozpoznat, kdy v ní dojde k chybě. Chyba ochrany paměti, ke které dochází v copy_from_user()
nezabije proces, jako kdyby byl spuštěn jakýmkoli jiným kontextovým kódem procesu, ani nezpanikaří jádro, jako kdyby k němu došlo v kontextu přerušení – jednoduše obnoví provádění v cestě kódu, která vrátí -EFAULT
volajícímu.
ohledně "jak je to s copy_to_user, protože jádro předává adresu prostoru jádra, jak k němu může proces uživatelského prostoru přistupovat"
Proces uživatelského prostoru se může pokusit o přístup k jakékoli adrese. Pokud však adresa není namapována v uživatelském prostoru daného procesu (tj. v tabulkách stránek tohoto procesu) nebo pokud existuje problém s přístupem, jako je pokus o zápis do umístění pouze pro čtení, je vygenerována chyba stránky. Všimněte si, že alespoň na x86 má každý proces veškerý prostor jádra namapován v nejnižším 1 gigabajtu virtuálního adresového prostoru tohoto procesu, zatímco 3 horní gigabajty z celkového adresového prostoru 4 GB (používám zde 32bitovou klasiku case) se používají pro text procesu (tj. kód) a data. Kopírování do nebo z uživatelského prostoru je prováděno kódem jádra, který se provádí jménem procesu, a ve skutečnosti je to mapování paměti (tj. tabulky stránek) tohoto procesu které se používají během kopírování. K tomu dochází, když je spouštění v režimu jádra – tj. v režimu privilegovaného/supervisoru v jazyce x86. Za předpokladu, že kód uživatelského prostoru předal legitimní cílové umístění (tj. adresu správně namapovanou v adresovém prostoru tohoto procesu), aby byla data zkopírována do, copy_to_user , spouštěný z kontextu jádra by byl schopen normálně zapisovat na danou adresu/oblast bez problémů a poté, co se ovládání vrátí uživateli, může uživatelský prostor také číst z tohoto umístění nastavení samotným procesem. naleznete v kapitolách 9 a 10 knihy Understanding the Linux Kernel, 3rd Edition, Daniel P. Bovet, Marco Cesati. Zejména access_ok() je nezbytná, ale ne dostatečná kontrola platnosti. Uživatel může stále předávat adresy, které nepatří do adresního prostoru procesu. V tomto případě dojde k výjimce Chyba stránky, když kód jádra spouští kopii. Nejzajímavější na tom je, jak obslužný program chyby stránky jádra určí, že chyba stránky v takovém případě není způsobena chybou v kódu jádra, ale spíše špatnou adresou od uživatele (zejména pokud dotyčný kód jádra pochází z modulu jádra načteno).