调用open(2)忽略S_IWGRP和S_IWOTH标志

时间:2016-07-16 20:38:26

标签: c debian

S_IWGRP中指定时,

S_IWOTHopen(2)标志不会产生任何影响。

文件已打开并创建为

open(file,O_CREAT|O_WRONLY,S_IWGRP|S_IWOTH);  

导致

---------- 1 root root 0 Jul 16 21:25 file  

任何其他标志都能正常工作。

我应该在哪里开始排查?

2 个答案:

答案 0 :(得分:1)

创建任何文件时,其权限位将被当前umask的补码掩盖。因此,如果umask已设置为022(典型值),则权限将被0755屏蔽(按位)。

如果您确实需要文件在创建时原子地具有组/世界写入权限,则可以调用umask(0),但这通常是不好的做法,因为该设置是进程全局的并且可能导致不安全在别处(或在子进程中)创建文件。更好的方法是,如果它有效,只需在打开文件后调用fchmod以添加被屏蔽的权限。

答案 1 :(得分:1)

您需要考虑进程umask的值。请参阅man 2 umask

从赋予open(2)的权限掩码中减去umask值。也就是说,如果你执行open(file,O_CREAT|O_WRONLY,mymask),那么实际的掩码不是 mymask,而是mymask & ~umask

大多数用户以022 [八进制]的umask值开头,S_IWGRP | S_IWOTH

用户的umask值可以通过shell内置命令umask控制。

进程可能会通过umask(2)系统调用更改umask值。在您的情况下,请尝试:

oldval = umask(0);
open(...);
umask(oldval);

注意:这在单线程环境中工作正常,但是应该使用多线程程序执行额外的步骤。

另一种方法是使用fchmod

fd = open(...);
fchmod(fd,mymask);

对于多线程,这可能更安全,但如果程序在open之间但在fchmod之间中止,则最终会出现与您相同的情况(例如零掩码)。因此,适时的<CTRL-C>,系统崩溃等可以产生这种效果。

<强>更新

  

我对此感到困惑,因为当我打印S_IRWXU标志的真实值时,我得到了442.为什么它不仅仅是7号

我不完全确定,因为我不知道442是十进制还是八进制,但我会尝试覆盖所有基础[双关语: - )]。

权限掩码的布局通常以八进制 ["%o"格式]打印:

owner(3) | group(3) | other(3)

也就是说,每个都是3位宽

S_IRWXU define是“所有所有者权限”的固定定义。它的八进制值为700,小数为448。所以, if 你在做printf("%d\n",S_IRWXU)我希望448

printf("%d\n",mask & S_IRWXU) [甚至printf("%d\n",mask & S_IRWXU)]可以生成442,因为 十进制值是八进制672672会被屏蔽为600八进制或384十进制。但是,这可能。

因此,如果小数值确实 448 442,则会产生700八进制,这意味着“所有者拥有所有权限“

因此,对我来说唯一有意义的方法是442整个权限掩码的八进制值[并且被777八进制掩盖了]

为了澄清,这里是stat.h的文件片段,它定义了各种值[评论是我添加的]:

#define S_IRWXU 00700       // mask for owner
#define S_IRUSR 00400       // owner may read
#define S_IWUSR 00200       // owner may write
#define S_IXUSR 00100       // owner may execute

#define S_IRWXG 00070       // mask for group
#define S_IRGRP 00040       // group may read
#define S_IWGRP 00020       // group may write
#define S_IXGRP 00010       // group may execute

#define S_IRWXO 00007       // mask for others
#define S_IROTH 00004       // others may read
#define S_IWOTH 00002       // others may write
#define S_IXOTH 00001       // others may execute

因此,442r|r|w,表示所有者和群组可以阅读而其他人可以写[但读取]。这对于给定的文件没有多大意义,因此这意味着所讨论的掩码是umask值。但是,即使这样,这仍然没有多大意义,因为作为umask值,删除所有者的读取权限并不常见。

请注意,S_IRWXU00700,因此,如果您将其右移6,则 获取7。同样地,S_IRWXG00070,所以如果将它右移3,你也会得到7

更有可能的是,您要屏蔽的值是S_IRWXG | S_IRWXO [group / others],因为这是您在原始问题中尝试覆盖的内容。

如果您仍然遇到问题,并且可以进一步澄清您正在采取的措施以获得价值,我可以进一步修改以帮助您。