从内核读取 user-space 页面的内容
Reading the contents of a user-space page from Kernel
我因调用 kmap
而崩溃,我不知道为什么。我希望有人比我有更多的内核知识可以帮助解决这个问题。这是代码:
pgd_t *pgd = pgd_offset(vma->vm_mm, userspace_addr);
pud_t *pud = pud_offset(pgd, userspace_addr);
pmd_t *pmd = pmd_offset(pud, userspace_addr);
pte_t *pte = pte_offset_map(pmd, userspace_addr);
if (pte_present_user(*pte)) {
void *p = NULL;
struct page *page = pte_page(*pte);
get_page(page);
p = kmap(page); /* CRASH HERE??? */
/* Read from 'p' */
kunmap(p);
put_page(page);
}
我已经确定对 kmap
的调用是罪魁祸首,因为没有它代码 运行 没问题。据我所知,所有指针都是有效的。
我不确定 pte_offset_map
是否应该与 kmap
结合使用...
上面的代码 运行 mm->mmap_sem
和 vma->vm_mm->page_table_lock
锁定在内核上下文中 kthread
。
我想我解决了。我的代码中的主要问题是我将从 kmap
返回的指针传递给 kunmap
。我应该传入页面指针。
另一个变化是使用 pte_offset_kernel
而不是 pte_offset_map
。
我因调用 kmap
而崩溃,我不知道为什么。我希望有人比我有更多的内核知识可以帮助解决这个问题。这是代码:
pgd_t *pgd = pgd_offset(vma->vm_mm, userspace_addr);
pud_t *pud = pud_offset(pgd, userspace_addr);
pmd_t *pmd = pmd_offset(pud, userspace_addr);
pte_t *pte = pte_offset_map(pmd, userspace_addr);
if (pte_present_user(*pte)) {
void *p = NULL;
struct page *page = pte_page(*pte);
get_page(page);
p = kmap(page); /* CRASH HERE??? */
/* Read from 'p' */
kunmap(p);
put_page(page);
}
我已经确定对 kmap
的调用是罪魁祸首,因为没有它代码 运行 没问题。据我所知,所有指针都是有效的。
我不确定 pte_offset_map
是否应该与 kmap
结合使用...
上面的代码 运行 mm->mmap_sem
和 vma->vm_mm->page_table_lock
锁定在内核上下文中 kthread
。
我想我解决了。我的代码中的主要问题是我将从 kmap
返回的指针传递给 kunmap
。我应该传入页面指针。
另一个变化是使用 pte_offset_kernel
而不是 pte_offset_map
。