linux 可执行文件与写操作的同步问题(文件读写操作产生的锁机制

2019-10-14 21:35:50丽君


if (vm_flags & VM_DENYWRITE) {         
        error = deny_write_access(file);
    if (error)
        goto free_vma;
    correct_wcount = 1;
}

其中,mmap调用中的flags参数会被正确的赋值给vm_flags,对应关系是MAP_DENYWRIRE被设置了,那么VM_DENYWRITE就对应的也被设置。下面写了个简单的代码,做一下测试:

#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
        int fd;
    void *src = NULL;
    fd = open("test.txt",O_RDONLY);
    if (fd != 0)
        {
        if ((src = mmap(0,5,PROT_READ|PROT_EXEC  ,MAP_PRIVATE|        MAP_DENYWRITE,fd,0))== MAP_FAILED)
                {
            printf("MMAP errorn");
            printf("%sn",strerror(errno));
                }else{
            printf("%xn",src);
        }
    }

        FILE * fd_t = fopen("test.txt","w");
    if( !fd_t)
    {
                printf("open for write errorn");
        printf("%sn",strerror(errno));
        return 0;
    }

        if (fwrite("0000",sizeof(char),4,fd_t) != 4)
    {
        printf("fwrite error n");
    }

     
        fclose(fd_t);
    close(fd);
    return 1;
}

最后的test.txt被写成了”0000”,很奇怪,貌似MAP_DENTWRITE不起作用了。于是man mmap查看,发现:

  MAP_DENYWRITE

  This  flag  is ignored.  (Long ago, it signaled that attempts to write to the underlying file should fail with ETXTBUSY. But this was a source of denial-of-service attacks.)

原来这个标识在用户层已经不起作用了啊,而且还说明了原因,容易引起拒绝式服务攻击。攻击者恶意的将某些系统程序要写的文件以MAP_DENYWRITE模式映射,会导致正常程序写文件失败。不过VM_DENYWRITE在内核里还是有使用的,在mmap中还是有对deny_write_access的调用, 但是对它的调用已经不是由mmap中的flag参数的MAP_DENYWRITE驱动的了。