Зачем нужны copy_from_user()
и copy_to_user()
, если ядро отображается в то же виртуальное адресное пространство, что и сам процесс?
Разработав несколько (игрушечных) модулей ядра в учебных целях, я быстро понял, что copy_from_user()
они copy_to_user()
нужны для копирования данных из/в буферы пользовательского пространства; в противном случае ошибки, связанные с недействительными адресами, приводили к сбоям.
Но если 0x1fffff
это виртуальный адрес, указывающий на буфер пользовательского пространства, то почему этот адрес недействителен в ядре? Ядро находится в том же виртуальном адресном пространстве, поэтому 0x1fffff
будет сопоставлено с той же физической памятью.
решение1
Отображение адресного пространства одинаково на некоторых (не на всех!) архитектурах, но даже на архитектурах, где оно одинаково, уровни защиты различаются. copy_from_user
и т. д. служат трем основным целям:
- они проверяют, что разрешения на доступ к памяти, из которой выполняется чтение или запись, позволяют процессу, работающему в пользовательском пространстве, выполнять чтение или запись в нее — это гарантирует, что процессы не смогут обмануть ядро и получить доступ к памяти, к которой процесс не должен иметь доступа;
- они позволяют выполнять специфическую обработку ошибок, чтобы сбои защиты не приводили к сбою ядра, например, если запрошенные адреса в данный момент не сопоставлены (например, нулевые страницы или выгруженные страницы);
- они гарантируют, что ядро не нарушит свою собственную защиту,например СМАПили адресные пространства, специфичные для ядра (S/390).
Некоторые архитектуры используют структуры памяти, которые позволяют этим функциям использовать сокращения,напримериспользуя прямое отображение физической памяти, но вы не можете предполагать, что это так, и в любом случае это не обрабатывает все ситуации (выгруженные страницы не присутствуют в физической памяти).