Попытка получить физический адрес с использованием карты страницы с CAP_SYS_ADMIN не удалась - PullRequest
0 голосов
/ 30 декабря 2018

Я пытаюсь использовать / proc / self / pagemap, чтобы получить физический адрес, который совпадает с виртуальным, с помощью следующей программы на C, которая должна дать мне PFN (номер кадра страницы) с помощью /proc/self/pagemap.

#include <assert.h>
#include <stdio.h>
#include <unistd.h>

int
main ()
{
  unsigned long addr = (unsigned long) main;    //address  of main function 
  unsigned long offset = 8 * (addr / getpagesize ());   //for pagemap file
  FILE *f = fopen ("/proc/self/pagemap", "rb");
  if (f == NULL)
  {
    perror ("fopen");
    return -1;
  }
  assert (fseek (f, offset, SEEK_SET) == 0);
  unsigned long long r;
  fread (&r, 8, 1, f);
  if ((r & 0x7fffffffffffff) == 0)      //if page is present
    printf ("PFN= %016llX\n", r & 0x7fffffffffffff);
  fclose (f);

}

, затем я компилирую его, используя gcc -o pagemaputils pagemapbasic.c, и даю ему возможность CAP_SYS_ADMIN с sudo setcap cap_sys_admin+ep pagemaputils.Затем я просто выполняю $ ./pagemaputils

Если я выполняю все предыдущие операции в /tmp, я все равно получаю PFN равным нулю.Если я выполняю все предыдущие операции в своем домашнем каталоге, я получаю fopen: Permission denied.

Итак, вопросы:

  • Почему я не могу получить PFN с CAP_SYS_ADMIN, как указано в https://www.kernel.org/doc/Documentation/vm/pagemap.txt
  • Почему у меня два разных поведения в зависимости от того, нахожусь ли я в /tmp или в моем домашнем каталоге?

Ответы могут быть в разрешениях на монтирование?Поэтому для информации я даю вам результат mount:

proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
sys on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
dev on /dev type devtmpfs (rw,nosuid,relatime,size=8170068k,nr_inodes=2042517,mode=755)
run on /run type tmpfs (rw,nosuid,nodev,relatime,mode=755)
efivarfs on /sys/firmware/efi/efivars type efivarfs (rw,nosuid,nodev,noexec,relatime)
/dev/sda2 on / type ext4 (rw,relatime)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
pstore on /sys/fs/pstore type pstore (rw,nosuid,nodev,noexec,relatime)
bpf on /sys/fs/bpf type bpf (rw,nosuid,nodev,noexec,relatime,mode=700)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=27,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=16944)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime,pagesize=2M)
configfs on /sys/kernel/config type configfs (rw,relatime)
tmpfs on /tmp type tmpfs (rw,nosuid,nodev)
mqueue on /dev/mqueue type mqueue (rw,relatime)
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,relatime)
/dev/sda1 on /boot/efi type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro)
tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=1635364k,mode=700,uid=1000,gid=1000)
gvfsd-fuse on /run/user/1000/gvfs type fuse.gvfsd-fuse (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)
fusectl on /sys/fs/fuse/connections type fusectl (rw,relatime)

Обратите внимание, что $ sudo ./pagemaputils дает мне хорошее (я полагаю, поскольку оно не равно нулю) PFN независимо от того, где я нахожусь.

Также, если это может помочь, uname -a дает Linux archlinux 4.19.12-arch1-1-ARCH #1 SMP PREEMPT Fri Dec 21 13:56:54 UTC 2018 x86_64 GNU/Linux

...