【问题标题】:Create accessible file from root privilege process从 root 特权进程创建可访问文件
【发布时间】:2020-04-19 07:11:36
【问题描述】:

我有一堆来自不同权限的进程,所有进程都运行一个共享代码,这些代码使用带有“a+”标志的 fopen_s 打开(并在需要时创建)一个用于写入的文件。

但是,由于没有提供给此命令的权限,并且 root 进程首先创建文件,因此其他非 root 进程无法访问此文件。

我可以使用int open(const char *pathname, int flags, mode_t mode); 来控制文件权限(由mode_t 表示)以允许所有人访问,但我需要文件描述符(FILE *)而不是文件ID。所以我可以使用FILE *fdopen(int fd, const char *mode); 进行转换。

也许有更直接的方法可以做到这一点?

【问题讨论】:

  • 对术语有点挑剔,FILE * 是一个 C 文件流(不要与 C++ 流对象混淆),而由例如返回的整数open 是一个描述符(在open 的情况下它是一个文件描述符)。
  • 至于你的问题,open 后跟fdopen 可能是最简单最直接的方法,除非你想在打开文件后打扰chmod
  • 最后再吹毛求疵:C、C++ 或 POSIX 标准中没有 fopen_s 函数,它是 Microsoft Visual C++ CRT 特定的扩展。
  • 嗨,我在这里https://en.cppreference.com/w/c/io/fopen 读到了 fopen_s,所以我认为它也支持 posix。
  • @Someprogrammerdude 在 C11 标准的可选附录 K 中有一个 fopen_s()。除了 Microsoft 之外,没有其他重要的实现,而且 Microsoft 也不完全符合 C 标准。

标签: c++ c linux file fopen


【解决方案1】:

我可以使用 int open(const char *pathname, int flags, mode_t mode);从而控制文件权限(由mode_t表示)

不是真的。除非你设置your process's umask setting。因为传递给open() 的权限并不是创建文件的必要权限。

Per POSIX open()(我的粗体字):

文件模式的访问权限位(见<sys/stat.h>)应设置为oflag参数后面的参数值,类型为mode_t 修改如下:a对文件模式位和进程的文件模式创建掩码的补码中的相应位执行按位与。因此,文件模式创建掩码中相应位被设置的所有文件模式位都被清除。

所以

int fd = open( someFileName, O_CREAT | O_RDWR, 0644 );

保证将文件权限设置为0644

如果您的文件创建掩码设置为0077,则文件实际上将在权限设置为0600 的情况下创建。

请注意,umask() 设置是一个进程范围的属性,更改它并不是一个好主意。而且,如果您正在尝试编写没有副作用的通用代码,那么完全更改它是一个坏主意。例如,更改多线程进程中的umask() 设置以允许更广泛地访问正在创建的文件可能会导致 如果另一个线程同时创建一个文件,则会出现安全问题。

将文件权限设置为您想要的最佳方式是使用fchmod() 将文件权限设置为您想要的:

FILE *f = fopen(...);
fchmod( fileno( f ), 0644 );

事实上,由于umask() 设置是一个进程范围的属性,通常它总是可以被另一个线程随时更改,所以通过chmod() 或@ 显式设置权限987654341@ 是在所有情况下准确获得指定权限的唯一有保证的方法

【讨论】:

  • 在您在fopen 之后立即调用fchmod 的解决方案中,我应该检查文件是否已创建或只是更改权限?
  • @IradK 您需要从fopen() 检查是否成功,否则使用NULL 参数进行fileno() 调用可能会调用未定义的行为,可能是SIGSEGV 这里。
【解决方案2】:

没有。您描述的技术(open 后跟fdopen)是实现您想要做的正确方法。正如一些程序员老兄指出的那样,您可以在程序中调用chmod 以在创建文件后更改文件权限,但这是一种更迂回的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多