首页 > 解决方案 > 如何在 C 中的用户模式下检查页面权限?

问题描述

我目前正在实现一个分布式系统及其分布式共享内存协议如果我可以在用户模式下检查某个虚拟地址的页面权限(rwx,存储在 pte 中)可能会更容易。


我想做的事:

获取虚拟地址的 pte。所以我可以检查存储在其中的最后 3 位代表PROT_READ// PROT_WRITEPROT_NONE


我做了什么:

  1. 试图使用 pmd 的自引用来获取 pte。失败的。
  2. 尝试其他方法。记录一切是愚蠢的。我已经尝试过了,它有效,但现在我想改进它。

qemu 中没有这样的宏

407         pgd_t *pgd;
408         pmd_t *pmd;
409         pte_t *ptep, pte;
410 
411         pgd = pgd_offset(mm, address);
412         if (pgd_none(*pgd) || pgd_bad(*pgd))
413                 goto out;
414 
415         pmd = pmd_offset(pgd, address);
416         if (pmd_none(*pmd) || pmd_bad(*pmd))
417                 goto out;
418 
419         ptep = pte_offset(pmd, address);
420         if (!ptep)
421                 goto out;
422 
423         pte = *ptep;

所以上面的代码对我不起作用,更不用说它在内核模式下运行了。

pgd中应该有一个自引用pmd,但我想我找错了。

// I found it in qemu/roms/qemu-palcode/init.c
#define PAGE_SHIFT 13
#define VPTPTR 0xfffffffe00000000UL
static inline unsigned long
pt_index(unsigned long addr, int level)
{
    return (addr >> (PAGE_SHIFT + (10 * level))) & 0x3ff;
}
...
static void
init_page_table(void)
{
  /* Install the self-reference for the virtual page table base register.  */
  page_dir[pt_index(VPTPTR, 2)] = build_pte(page_dir);
...

我不明白为什么将 VPTPTR 设置为这样的值,我该如何使用它?

// fill the 4th page index(47-39) with 1
    unsigned long pgd_index = 0b0000000000000000111111111000000000000000000000000000000000000000;
    unsigned long pg_addr_pte = host_addr |= pgd_index;

但它不起作用,它是一个无效的地址。


这可以等同于“获取 linux 中页面的物理地址”,因为物理地址和页面权限都存储在 pte 中。

提供一个虚拟地址,检查其页面的权限。在用户模式下。

先感谢您。

标签: clinuxqemu

解决方案


推荐阅读