2017-08-02 11 views
1

I compilé le programme exemple de l'homme pthread_setname_np avecpthread_setname_np() lorsque les capacités sont définies

g++ -pthread example.cpp 

Je tournai la capacité de CAP_NET_RAW de mon a.out programme.

sudo setcap 'cap_net_raw=+eip' a.out 

Étonnamment, le programme échoue lors de l'exécution:

$./a.out 
Created a thread. Default name is: a.out 
pthread_setname_np: Permission denied 

lorsque je retire les capacités ça marche ..

$sudo setcap 'cap_net_raw=-eip' a.out 
$./a.out 
Created a thread. Default name is: a.out 
The thread name after setting it is THREADFOO. 
Done 

Donc, pour moi, il semble que j'ai moins de privilèges quand j'ajoute une capacité. Quelqu'un peut-il expliquer cela?

Thanky vous pour votre réponse ;-)

Quelques infos supplémentaires:

  • Les capacités sont pris en charge sur mon objectif je l'ai vérifié avec la commande ping et CAP_NET_RAW
  • noyau 4.4.32-RT43
  • RFS: ext4
  • J'ai réduit le poste au programme d'exemple Je reconnais que cela n'a aucun sens d'ajouter le CAP_NET_RAW à ce programme.
  • Cela fonctionnerait si j'ajoutais le CAP_DAC_OVERRIDE mais je veux éviter cela.

Répondre

1

La définition d'une capacité de système de fichiers est à bien des égards similaire à la création du programme SUID/SGID. Dans ce mode d'exécution AT_SECURE == 1, le noyau restreint ce que l'utilisateur d'origine peut faire avec le processus. Les actions potentiellement invasives, telles que l'utilisation du ptrace pour attacher le processus ou l'accès au processus via /proc, sont bloquées par le noyau de sorte que l'utilisateur ne peut pas utiliser le programme pour augmenter ses privilèges. (les bibliothèques glibc et autres désactivent également certaines fonctionnalités pour des raisons de sécurité.) Normalement, ces restrictions ne s'appliquent qu'aux processus appartenant à différents ID utilisateur, mais avec des capacités (et des contextes SELinux), une simple comparaison d'ID utilisateur n'est plus nécessaire pour détecter le franchissement d'une limite de confiance.

Dans la glibc, pthread_setname_np pour un thread distinct du thread actuel est implémenté en écrivant dans le fichier /proc/self/task/TID/comm, afin qu'il s'exécute dans ces restrictions. Le noyau pourrait concevable mettre en œuvre une exception pour ce type d'auto-modification d'une tâche qui partage le même espace d'adressage, mais il semble que cela ne soit pas implémenté, d'où l'échec. Et je ne peux pas vraiment blâmer les gens du noyau parce qu'il est difficile d'obtenir de telles choses correctes, sans introduire de vulnérabilités.

+0

Merci Florian pour la réponse. Je suppose également que pthread_setname_np essaie d'écrire dans/proc/PID/comm si ce n'est pas le thread où le programme est en cours d'exécution. Que me recommandez-vous pour une solution? Est-il facile d'écrire directement dans/proc/self/task/TID/comm ..? Donc sorte d'écrire ma propre fonction pthread_setname. – gees

+0

Donc, dans ma solution finale, je donne le nom du thread comme paramètre à la fonction invoquée dans pthread_create et j'appelle cette fonction pthread_setname_np pour définir le nom. Parce que la définition du nom n'est autorisée que dans le propre thread décrit par Florian. – gees