%60%20%D0%B8%20%60copy_to_user()%60%2C%20%D0%B5%D1%81%D0%BB%D0%B8%20%D1%8F%D0%B4%D1%80%D0%BE%20%E2%80%8B%E2%80%8B%D0%BE%D1%82%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B0%D0%B5%D1%82%D1%81%D1%8F%20%D0%B2%20%D1%82%D0%BE%20%D0%B6%D0%B5%20%D0%B2%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5%20%D0%B0%D0%B4%D1%80%D0%B5%D1%81%D0%BD%D0%BE%D0%B5%20%D0%BF%D1%80%D0%BE%D1%81%D1%82%D1%80%D0%B0%D0%BD%D1%81%D1%82%D0%B2%D0%BE%2C%20%D1%87%D1%82%D0%BE%20%D0%B8%20%D1%81%D0%B0%D0%BC%20%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%3F.png)
Зачем нужны copy_from_user()
и copy_to_user()
, если ядро отображается в то же виртуальное адресное пространство, что и сам процесс?
Разработав несколько (игрушечных) модулей ядра в учебных целях, я быстро понял, что copy_from_user()
они copy_to_user()
нужны для копирования данных из/в буферы пользовательского пространства; в противном случае ошибки, связанные с недействительными адресами, приводили к сбоям.
Но если 0x1fffff
это виртуальный адрес, указывающий на буфер пользовательского пространства, то почему этот адрес недействителен в ядре? Ядро находится в том же виртуальном адресном пространстве, поэтому 0x1fffff
будет сопоставлено с той же физической памятью.
решение1
Отображение адресного пространства одинаково на некоторых (не на всех!) архитектурах, но даже на архитектурах, где оно одинаково, уровни защиты различаются. copy_from_user
и т. д. служат трем основным целям:
- они проверяют, что разрешения на доступ к памяти, из которой выполняется чтение или запись, позволяют процессу, работающему в пользовательском пространстве, выполнять чтение или запись в нее — это гарантирует, что процессы не смогут обмануть ядро и получить доступ к памяти, к которой процесс не должен иметь доступа;
- они позволяют выполнять специфическую обработку ошибок, чтобы сбои защиты не приводили к сбою ядра, например, если запрошенные адреса в данный момент не сопоставлены (например, нулевые страницы или выгруженные страницы);
- они гарантируют, что ядро не нарушит свою собственную защиту,например СМАПили адресные пространства, специфичные для ядра (S/390).
Некоторые архитектуры используют структуры памяти, которые позволяют этим функциям использовать сокращения,напримериспользуя прямое отображение физической памяти, но вы не можете предполагать, что это так, и в любом случае это не обрабатывает все ситуации (выгруженные страницы не присутствуют в физической памяти).