为什么要在调用shm_open之前先调用shm_unlink?

3

我曾在一个旧项目中看到以下代码模式:

  1. Check whether the shared-memory has been created with name "/abc":

    int fd = shm_open("/abc", O_RDWR, 0777);
    if(fd != -1)
    {
      close(fd);
      return -1;
    }
    
  2. Remove an object previously created by shm_open():

    shm_unlink("/abc");
    
  3. create a shared memory object:

    fd = shm_open("/abc", (O_CREAT | O_RDWR), S_IWUSR);
    

第二步是否多余?

代码可能会走到第二步,因为 "/abc" 对应的共享内存对象不存在。换句话说,如果该对象存在,代码就会返回。但为什么我们要显式调用 shm_unlink 删除不存在的对象呢?

我们能把这三个步骤缩短为一个吗?

我认为我们可以按以下方式进行,并使用标记 O_EXCL 检查旧的内存对象是否存在,如果不存在,则创建它。 shm_open() 手册上写着:

O_EXCL

如果还指定了 O_CREAT,并且具有给定名称的共享内存对象已经存在,则返回错误。 对于对象的存在性检查以及如果不存在则创建对象,是原子执行的。

所以我们可以用一行代码替换上面的所有代码:

int fd = shm_open("/abc", O_RDWR | O_EXCL, 0777);

这是正确的吗?


1
你应该替换原始序列,因为它包含一个竞争窗口,另一个进程可以利用这个窗口来访问共享内存。 - EOF
1个回答

4

第二步是多余的吗?

是的,它没有任何作用。

此外,“检查是否存在”容易受到TOCTOU漏洞的影响。

我们能否将上述3个步骤缩短为单个步骤

可以,这是正确的方法。但您还需要O_CREAT标志(在您的代码中缺失)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接