Il y a une possibilité que j'ai trouvé un bogue dans le noyau Linux. Considérons l'application qui écrit dans/proc/self/loginuid à partir du thread principal et d'un thread auxiliaire. Le code est ci-dessous:S'agit-il d'un bogue dans le noyau Linux concernant l'écriture dans/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;
}
Après l'exécution de cette application, nous obtenons:
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
qui nous dit l'écriture de fil échoué par -EPERM.
En regardant le fichier du noyau fs/proc/base.c et la fonction proc_loginuid_write(), nous voyons à la vérification de début:
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();
Alors, en regardant le code ci-dessus, nous voyons que seulement pour PID exact (vérifié par moi avec printks) nous passons à travers. Thread ne satisfait pas la condition, parce que les pids comparés diffère. Donc, ma question est la suivante: est-ce un bug? Pourquoi ne pas autoriser les threads d'un processus particulier à changer le loginuid? J'ai rencontré cela dans l'application de connexion qui a engendré un autre thread pour la connexion PAM.
Votre thread a un PID différent puisqu'il s'agit d'un enfant dans un groupe. Le PID du parent est en fait celui qui est vérifié là comme je peux le supposer. – 0andriy
Oui, c'est le problème tel que je l'ai décrit. Même processus, différents threads. Et seulement un d'entre eux a accès à/proc/self/loginuid. La question est pourquoi cela se produit? Est-ce un bug ou un comportement intentionnel? – sibislaw