sib*_*law 5 linux linux-device-driver linux-kernel
我有可能在 linux 内核中发现了一个错误。让我们考虑从主线程和一个辅助线程写入 /proc/self/loginuid 的应用程序。代码如下:
#include <stdio.h>
#include <pthread.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void write_loginuid(char *str)
{
int fd;
printf("%s\n", str);
fd = open("/proc/self/loginuid", O_RDWR);
if (fd < 0) {
perror(str);
return;
}
if (write(fd, "0", 2) != 2) {
printf("write\n");
perror(str);
}
close(fd);
}
void *thread_function(void *arg)
{
fprintf(stderr, "Hello from thread! my pid = %u, tid = %u, parent pid = %u\n", getpid(), syscall(SYS_gettid), getppid());
write_loginuid("thread");
return NULL;
}
int main()
{
pthread_t thread;
pthread_create(&thread, NULL, thread_function, NULL);
write_loginuid("main process");
fprintf(stderr, "test my pid = %u, tid = %u, parent pid = %u\n", getpid(), syscall(SYS_gettid), getppid());
pthread_join(thread, NULL);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
执行此应用程序后,我们得到:
main process
test my pid = 3487, tid = 3487, parent pid = 3283
Hello from thread! my pid = 3487, tid = 3488, parent pid = 3283
thread
write
thread: Operation not permitted
Run Code Online (Sandbox Code Playgroud)
这告诉我们线程写入失败 -EPERM。
查看内核文件 fs/proc/base.c 和函数 proc_loginuid_write() 我们看到开头检查:
main process
test my pid = 3487, tid = 3487, parent pid = 3283
Hello from thread! my pid = 3487, tid = 3488, parent pid = 3283
thread
write
thread: Operation not permitted
Run Code Online (Sandbox Code Playgroud)
因此,查看上面的代码,我们看到仅对于我们通过的精确 PID(由我使用 printks 检查)。Thread 不满足条件,因为比较的 pids 不同。
所以我的问题是:这是一个错误吗?为什么不允许特定进程的线程更改 loginuid?我在为 PAM 登录生成另一个线程的登录应用程序中遇到了这个问题。
无论这是否是错误,我编写了一个修复程序,通过线程扩展对此文件的写入权限:
rcu_read_lock();
/*
* I changed the condition that it checks now the tgid as returned in sys_getpid()
* rather than task_struct pointers
*/
if (task_tgid_vnr(current) != task_tgid_vnr(pid_task(proc_pid(inode), PIDTYPE_PID))) {
rcu_read_unlock();
return -EPERM;
}
rcu_read_unlock();
Run Code Online (Sandbox Code Playgroud)
你怎么看待这件事?会影响安全吗?
| 归档时间: |
|
| 查看次数: |
315 次 |
| 最近记录: |