nmap EPERM 错误,启用了 MAP_FIXED 标志。

问题描述 投票:1回答:2

我有一个简单的mmap程序,在两台linux机器上的表现是不同的。

cat a. c

   #include <sys/types.h>
   #include <sys/stat.h>
   #include <fcntl.h>
   #include <errno.h>


   #include <sys/mman.h>
   #include <err.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <unistd.h>

   int
   main(void)
   {
           int fd = -1;
           char *A, *zero;

           if ((fd = open("./a.out", O_RDONLY, 0)) == -1)
                   exit(1);

           A = mmap(NULL, 65536, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, fd, 0);

           if (A == MAP_FAILED)
              printf("error %d, errno=%d\n", A, errno);
           else
               printf("OK %d\n", A);
           return (EXIT_SUCCESS);
   }

在一台机器上 mmap 返回成功,但另一台机器却显示错误(errno为1)。

相关的差异在 strace 结果是。

好的一个。

(2.6.9-78.ELsmp #1 SMP Wed Jul 9 15:46:26 EDT 2008 x86_64 x86_64 x86_64 GNU/Linux)
open("./a.out", O_RDONLY)               = 3
mmap(NULL, 65536, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0

失败的一个

( 2.6.18-194.26.1.el5 #1 SMP Fri Oct 29 14:21:16 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux)
open("./a.out", O_RDONLY)               = 3
mmap(NULL, 65536, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = -1 EPERM (Operation not permitted)

在失败的进程中,如果我把MAP_FIXED标志去掉,mmap就成功了 似乎失败的进程没有可用的内存空间[0,65535]来进行映射。

我不知道这个问题该从哪里查起?有什么原因会导致不同的行为和失败?或者更具体地说,如果我的猜测是由于不可用的[0,65535]造成的,那么一台机器有可用的内存空间而另一台没有的原因是什么?

linux mmap
2个回答
0
投票

mmap MAP_FIXED 根据手册页面的规定 [Doesn't] interpret addr as a hint: place the mapping at exactly that address.. 在你的例子中,[addr]ess是NULL(第一个mmap参数)。

NULL几乎总是被映射到一个零页,所以EPERM可能是一个预期的响应。

它之前的工作情况可能是一个bug(A被映射到一个包含文件内容的零页?)


0
投票

你已经指定了 MAP_FIXED 地址为零。在最近的Linux版本中,默认情况下,也可以在一些早期版本中配置,在低虚拟地址的映射是被禁止的,以防止内核null pointer dereference bug的利用。

© www.soinside.com 2019 - 2024. All rights reserved.