c - 带有 setuid/capabilities 的 stdbuf

标签 c linux buffering setuid linux-capabilities

我正在读取另一个生成输出(缓慢且无限)的进程的输出。因为我想实时读取这些数据,所以我使用“stdbuf -oL”(行缓冲,数据是文本)。我无法控制生成过程,因此无法修改源以强制刷新。

到目前为止,stdbuf 工作正常,但是该进程使用 SOCK_RAW 并且需要以 root 身份运行,具有 setuid(0) 或 cap_net_raw 功能。当使用 setuid 或 capabilities 以非 root 身份运行时,stdbuf 似乎被忽略。让我演示一下这个问题:

这是一个简单的作家:

#include <stdio.h>
#include <unistd.h>

int main(){
        int i;
        for ( i = 0;; i++){
                fprintf(stdout, "%d\n", i);
                sleep(1);
        }
}

还有一个简单的阅读器:

#include <stdio.h>

int main(){
        char* line = NULL;
        size_t n = 0;
        while (getline(&line, &n, stdin) != -1 ) {
                fputs(line, stdout);
        }
}

正如预期的那样,通过执行 ./writer | ./reader 在缓冲区被填满之前不会显示任何内容。前置 stdbuf -oL 启用行缓冲,我将这些行输入阅读器:

% stdbuf -oL ./writer | ./reader
0
1
2
...

但是如果我添加 cap_net_raw+ep 它会停止工作:

% sudo setcap cap_net_raw+ep ./writer
% stdbuf -oL ./writer | ./reader
(no output)

使用 setuid 时观察到相同的行为:

% sudo chown root:root ./writer
% sudo chmod +s ./writer
% stdbuf -oL ./writer | ./reader
(no output)

我很想了解为什么会发生这种情况,以及如何在不以 root 身份运行的情况下继续使用 stdbuf。我承认我并不完全理解 setuid 在幕后做了什么。

最佳答案

从查看 stdbuf source code看起来它可以通过设置 LD_PRELOAD 来工作。将 LD_PRELOAD 与 setuid 可执行文件或 sudo 一起使用当然存在安全问题。

我发现的一个建议是 disable the noatsecure selinux attribute为您的可执行文件。

另一个更简单的选择是避免使用 stdbuf 并直接从您的源代码中调用 fflush(stdout)

关于c - 带有 setuid/capabilities 的 stdbuf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13644024/

相关文章:

c - 如何捕获Control+D信号?

node.js - 如何从 Node.js 访问 shell 变量值?

perl - 当我使用 sleep 时,为什么在循环的每次迭代中不打印输出任何内容?

原始模式下的Python stdin 打印添加空格

c - 为什么我可以在 c 中多次遍历我的链表

c - 使用C列出服务器上的所有文件

c - C语言中如何将10进制数转换为10进制数?

linux - 简单的Qt5应用程序在终端上输出空白行

linux - 如何独立于基于包的安装运行 PostgreSQL 设置?

performance - 如何通过缓冲加速 Haskell IO?