Commit 6b2e13fc authored by Pavel Emelyanov's avatar Pavel Emelyanov

proc: Fix anon shmem mapping detection

Linux kernel emulates anon-shared mappings by mapping internal
tmpfs file in. We try to detect this by checking that the file
under map is such, but do it with error -- major == 0 check is
wrong, as regular tmpfs file can be such as well as btrfs or
ecryptfs can screw things up.

The only working way of doing this is to get the dev_t of this
internal tmpfs mount.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent bbf33fa6
......@@ -102,6 +102,39 @@ static int parse_vmflags(char *buf, struct vma_area *vma_area)
return 0;
}
static int is_anon_shmem_map(dev_t dev)
{
static dev_t shmem_dev = 0;
if (!shmem_dev) {
void *map;
char maps[128];
struct stat buf;
map = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, 0, 0);
if (map == MAP_FAILED) {
pr_perror("Can't mmap piggie");
return -1;
}
sprintf(maps, "/proc/%d/map_files/%lx-%lx",
getpid(), (unsigned long)map,
(unsigned long)map + PAGE_SIZE);
if (stat(maps, &buf) < 0) {
pr_perror("Can't stat piggie");
return -1;
}
munmap(map, PAGE_SIZE);
shmem_dev = buf.st_dev;
pr_info("Found anon-shmem piggie at %lx\n", shmem_dev);
}
return shmem_dev == dev;
}
int parse_smaps(pid_t pid, struct list_head *vma_area_list, bool use_map_files)
{
struct vma_area *vma_area = NULL;
......@@ -244,7 +277,7 @@ int parse_smaps(pid_t pid, struct list_head *vma_area_list, bool use_map_files)
* /dev/zero stands for anon-shared mapping
* otherwise it's some file mapping.
*/
if (MAJOR(st_buf.st_dev) == 0) {
if (is_anon_shmem_map(st_buf.st_dev)) {
if (!(vma_area->vma.flags & MAP_SHARED))
goto err_bogus_mapping;
vma_area->vma.flags |= MAP_ANONYMOUS;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment