【问题标题】:Permission error when using mmap to modify a file使用 mmap 修改文件时出现权限错误
【发布时间】:2017-02-12 20:48:58
【问题描述】:

创建了一个修改字节文件的简单 mmap 程序。 在一个简单/小文件上以 root 身份运行它,出现错误

# ./a.out tmp.txt 92
fd=3
mmap: Permission denied

代码sn-p

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

int main(int argc, char *argv[]) {
    int fd = open(argv[1], O_WRONLY);
    printf("fd=%d\n", fd);
    char *p = mmap(0, 0x1000, PROT_WRITE, MAP_SHARED, fd, 0);
    if (p == MAP_FAILED) {
        perror ("mmap");
        return 1;
    }
    p[0] = 0xde;
    close(fd);
    return 0;
}

想知道出了什么问题。谢谢。

更新1 修正了代码 sn-p 中的一个错字,我的意思是在那里使用PROT_WRITE

【问题讨论】:

  • 感谢@mch 指出,我使用PROT_WRITE 更正了代码sn-p,但得到了同样的结果。
  • 文件大小真的是0x1000字节吗?那是 4096 字节。
  • 大小实际上是92字节,使用0x1000因为它是我Linux上的页面大小
  • tmp.txt 有哪些所有者/用户和权限,您以什么用户身份运行该程序? ls -l tmp.txt; id

标签: c linux


【解决方案1】:

来自 mmap 的手册页:

EACCES 文件描述符是指非常规文件。或者请求了文件映射,但 fd 未打开以供读取。或者 MAP_SHARED 已请求并且 PROT_WRITE 已设置,但 fd 未设置 以读/写 (O_RDWR) 模式打开。或者 PROT_WRITE 已设置,但 文件只能追加。

所以为了映射文件MAP_SHARED,您需要以读/写模式打开它,而不是只写。有道理,因为需要读取文件的内容来初始化您不写入的部分内存。

此外,IA-32 不允许页面的只写映射,因此在此类机器上使用PROT_WRITE 进行映射将隐含地启用PROT_READ,因此对于不可读的文件描述符将失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    • 2014-05-20
    • 1970-01-01
    相关资源
    最近更新 更多