Linuxカーネルにバグが見つかった可能性があります。メインスレッドと1つの補助スレッドから/ proc/self/loginuidに書き込むアプリケーションを考えてみましょう。以下のコードは次のとおりです。これは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;
}
、このアプリケーションを実行した後、我々が得る:
私たち-EPERMで失敗したスレッドの書き込みを伝え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
。
我々は最初のチェックイン時に参照)(カーネルファイルFSは/ proc/base.cと機能proc_loginuid_writeを見る:
static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
{
struct inode * inode = file_inode(file);
uid_t loginuid;
kuid_t kloginuid;
int rv;
/* this is the probably buggy check */
rcu_read_lock();
if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) {
rcu_read_unlock();
return -EPERM;
}
rcu_read_unlock();
ので、我々は唯一の正確なPID(のためのことがわかり上記のコードを見て私はprintksと私によってチェックされた)私たちは通過します。比較した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();
は、あなたがそれについてどう思いますか:これはバグですか、私はスレッドで、このファイルへのアクセス権を書き込み拡張修正が書かれていないかどうか
スレッドは、グループ内の子であるため、異なるPIDを持ちます。親のPIDは、実際には私が推測できるようにそこでチェックされているPIDです。 – 0andriy
はい、これは私がそれを記述したときの問題です。同じプロセス、異なるスレッド。そのうち1人だけが/ proc/self/loginuidにアクセスできます。これはなぜ起こっているのですか?このバグや意図的な行動ですか? – sibislaw