我正在读取另一个生成输出(缓慢且无限)的进程的输出。因为我想实时读取这些数据,所以我使用“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/