我正在尝试使用 Linux 内核模块对我的树莓派进行一些硬件控制。这是相当简单的用户级代码,但将某些功能实现为内核模块是必要的学术练习。按下按钮时,内核模块会向用户级代码发送 SIGIO 信号,该信号会输出到使用
aplay
连接到面包板的扬声器。 aplay
连接到pulseaudio服务器,该服务器(正确地)拒绝以root身份连接。如何告诉我的程序我想以普通用户身份运行这行代码?
这是基于用户级代码的粗略骨架,而不是内核模块。
/* various includes */
void main() {
// stuff that requires sudo perms
fd = open("/dev/manager", O_WRONLY);
/* setup signal_handler() to handle signal from fd [omitted] */
close(fd);
}
void signal_handler(int signo) {
// None of this needs to be run with sudo privilege, and malfunctions if so
setgid(1000); setuid(1000); // see https://stackoverflow.com/questions/3357737/dropping-root-privileges
setenv("HOME", "/home/raspi", 1); // aplay uses $HOME, which was /root and inaccessible
/* generate output.wav [omitted] */
system("aplay /path/to/file/output.wav");
}
这是一些沙箱代码的最小可编译版本,以便您可以更好地自己重现问题。它以普通用户身份运行时播放,但不能以
sudo
身份运行。如果我可以运行下面的代码 sudo
,修复上面的代码应该变得很简单。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void main() {
setgid(1000);
setuid(1000);
setenv("HOME", "/home/raspi", 1);
system("aplay /path/to/file/output.wav");
}
我什至没有依附于
aplay
。如果有人可以给我任何使用您手头上的任何音频实用程序运行时从 C 程序播放音频的最小工作示例,我很乐意看到它。相关问题:
[1] 放弃 root 权限- 这几乎回答了我的问题。这应该回答我的问题。当我尝试时它实际上并没有起作用。 [2] c 程序中的 sudo 权限问题 - 我知道这里什么需要 sudo,什么不需要 sudo。我不清楚的是如何在运行时从一种切换到另一种。
@CraigEstey sudo chmod 666 /dev/manager 成功了!我流下了喜悦的泪水,非常感谢!您想为此发表回复帖子吗? – PR4v1
虽然我们需要
sudo
来做
sudo
之类的事情,但我们不需要它来调用您的程序。
我们需要insmod/modprobe
sudo
。它[可能]由 /dev/manager
所有,并获得(例如)root
或 600
的许可。由于 644
您的设备驱动程序,因此我们可以将所有权和/或权限设置为我们想要的任何值。 让设备文件全局可写并没有什么坏处。也就是说,我们
需要以/dev/manager
运行:
root
chown raspi: /dev/manager
chmod 666 /dev/manager
将以非root用户身份运行(并且它将
不再抱怨是
aplay
)。