c语言 - 为什么我的程序不能使用 mkdir 系统调用设置 0777 模式?



我编写了以下代码来尝试在Linux上创建一个具有0777模式的目录:

#include <sys/stat.h>
#include <sys/types.h>
int main () {
    mkdir("/tmp/mkdir-test", 0777);
    return 0;
}

但实际上,新目录有0755模式。

# stat /tmp/mkdir-test
  File: `/tmp/mkdir-test'
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: 802h/2050d  Inode: 1772304     Links: 2
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-09-27 20:23:54.000000000 -0700
Modify: 2016-09-27 20:23:54.000000000 -0700
Change: 2016-09-27 20:23:54.000000000 -0700

有人能解释一下吗?该程序如何创建一个真正的0777模式目录?

在shell中运行umask;它会报告022

创建文件或目录时,将删除umask设置的位。

在单线程程序中,真正设置0777权限的一种方法是与umask()连接:

mode_t old_mask = umask(0);
mkdir("/tmp/mkdir-test", 0777);
umask(old_mask);

保留当前设置,除非您确定需要覆盖它。然而,这在多线程程序中是危险的,因为umask值是全局的每个进程,而不是每个线程(感谢Peter Cordes指出这一点)。

设置权限的另一个选项是使用chmod(),这样做对于多线程程序也是安全的:
const char *dirname = "/tmp/mkdir-test";
mode_t target_mode = 0777;
if (mkdir(dirname, 0) == 0)
    chmod(dirname, target_mode);

chmod()函数设置的权限不受umask值的影响。

调用mkdir()的权限最好设置为0,如下图所示;它将始终可靠地工作,并且不会通过修改umask值来影响其他线程。或者,如果您愿意,也可以在调用mkdir()时使用所需的目标权限(这个答案的前一个版本建议这样做,使用0777作为硬编码的目标权限)。

const char *dirname = "/tmp/mkdir-test";
mode_t target_mode = 0777;
if (mkdir(dirname, target_mode) == 0)
    chmod(dirname, target_mode);

如果您使用这种习惯用法,传递给mkdir()的模式与传递给chmod()的模式相同,或者不那么宽松,这一点很重要- 0比任何其他模式都不那么宽松(并且总是有效)。如果在对mkdir()的调用中使用更宽松的模式,则在mkdir()chmod()调用之间存在TOCTOU(检查时间,使用时间)样式的漏洞,在此期间,某人(某些进程)可能以宽松的权限进入目录并造成破坏;这可能存在安全风险。

请注意,umask()是一个非常简单的系统调用,因此也非常快速(作为系统调用,与open(), mkdir()chmod()等重量级系统调用相比)。

最新更新