10
votes

GDB semble ignorer les capacités exécutables

Je débogage d'un programme utilisant libnetfilter_queue code>. La documentation indique qu'une application de traitement de la file d'attente d'utilisateurs doit avoir besoin de la fonctionnalité CAP_NET_ADMIN CODE> à la fonction. Je l'ai fait à l'aide de l'utilitaire SetCap code> comme suit:

$ getcap ./a.out
./a.out = cap_net_admin,cap_net_raw+eip


4 commentaires

GDB utilise le sous-système PTRACE. At-il la capacité CAP_SYS_PTRACT? Est-ce que ça marche avec d'autres binaires? Par exemple. Un programme Hello World?


@thkala: J'ai édité la question pour être plus précis. gdb fonctionne bien, il peut déboguer tout programme (y compris celui-ci) sinon.


Souhaitez-vous mentionner le message d'erreur exact?


Il n'y a pas de message d'erreur en soi. J'utilise Ce exemple de code fourni par les développeurs et nfq_unbind_pf () renvoie -1 (et errno est défini sur 1 ), indiquant une défaillance.


6 Réponses :


3
votes

Il y a quelque temps, j'ai rencontré le même problème. Je suppose que la gestion du programme débogué avec les capacités supplémentaires est une question de sécurité.

Votre programme a plus de privilèges que l'utilisateur qui l'exécute. Avec un débogueur, un utilisateur peut manipuler l'exécution du programme. Donc, si le programme fonctionne sous le débogueur avec les privilèges supplémentaires, l'utilisateur pourrait utiliser ces privilèges à d'autres fins que pour lesquels le programme avait l'intention de les utiliser. Ce serait un trou de sécurité sérieux, car l'utilisateur n'a pas les privilèges en premier lieu.


4 commentaires

Cette réponse a beaucoup de sens pour moi. Je vais essayer de regarder dans la source gdb pour confirmer que c'est le cas, mais je vais marquer votre réponse comme acceptée maintenant de toute façon.


Je suppose que cela est géré par le noyau au lieu de GDB. Vous devriez probablement regarder l'appel du système PTRACE.


De Linux Execve Manpage: "Si le bit de l'utilisateur SET-User est défini sur le fichier de programme pointé sur par le nom de fichier, et que le système de fichiers sous-jacent n'est pas monté NOSUID (le drapeau MS_NOSUID pour le montage (2)) et le processus d'appel Ne pas être ptracé, l'ID utilisateur efficace du processus d'appel est remplacé par celui du propriétaire du fichier de programme. " Cela détient probablement également des capacités de fichiers, car comme suid / SGID, ils fournissent une élévation de privilège.


La supposition est fausse - voir la réponse de Nick Huang. Cela a fonctionné pour moi.



4
votes

Pour ceux qui ont le même problème, vous pouvez contourner celui-ci en exécutant le GDB avec sudo.


1 commentaires

+1, bien que ce ne soit pas une solution pour chaque cas. J'ai deux applications. D'abord ont défini certaines capacités mais dépend de la deuxième application, qui communique avec d'abord les signaux RT. Ainsi, en utilisant seulement gdb ./a.out ne fonctionne pas car l'application a perdu ses capacités et en utilisant sudo gdb ./a.out ne fonctionne pas, car on utilise l'utilisateur L'application ne peut pas envoyer de signaux aux applications fonctionnant sous racine. Il est difficile de déboguer cela et on dirait qu'il n'y a pas de solution de contournement :)



14
votes

Je rencontre le même problème et au début, je pensais que la même chose que ci-dessus que GDB ignore la capacité de l'exécutable en raison de la raison de la sécurité. Cependant, lire le code source et même utiliser Eclipse débogage de GDB lui-même lorsqu'il débogage de mon ext2fs-prog, qui ouvre / dev / sda1 , je me rends compte que:

  1. gdb n'est pas spécial comme tout autre programme. (Tout comme c'est dans la matrice, même les agents eux-mêmes qu'ils obéissent à la même loi physique, à la gravité, etc., sauf qu'ils sont tous des gardiens de porte.)
  2. gdb n'est pas le processus parent de déboguer exécutable, c'est-à-dire grand-père.
  3. Le vrai processus parent de l'exécutable débogué est "Shell", c'est-à-dire / bin / bash dans mon cas.

    Donc, la solution est très simple, à part l'ajout cap_net_admin, cap_net_raw + EIP à gdb, vous l'appliquez également à votre coquille. IE SETCAP CAP_NET_ADMIN, CAP_NET_RAW + EIP / BASH

    La raison que vous avez aussi pour le faire sur GDB est parce que GDB est le processus parent de / bin / bash avant de créer un processus débogué.

    La vraie ligne de commande exécutable à l'intérieur de GDB est comme suit: xxx

    et ceci est paramètre à VFORK à l'intérieur de GDB.


0 commentaires

2
votes

Pour ceux qui exécutent GDB à travers une IDE, SUDO-ING GDB (comme dans la réponse de @ Stéphane J.) peut ne pas être possible. Dans ce cas, vous pouvez exécuter: xxx

puis joindre l'instance de BDB de votre IDE à cette (local) gdbserver.

dans le cas de l'éclipse CDT, cela signifie que faire Une nouvelle configuration de débogage «C / C / C ++ à distance», puis sous l'onglet Debugger> Connexion, entrant TCP / localhost / 12345 (ou quel que soit le port que vous avez choisi ci-dessus). Cela vous permet de déboguer dans Eclipse, tandis que votre demande a un accès privilégié.


0 commentaires

0
votes

OK, alors j'ai eu un peu du mal avec ceci, donc je pensais pouvoir combiner des réponses et résumer.

La solution facile est juste pour sudo gdb comme suggéré mais simplement être un peu prudent. Ce que vous faites ici, c'est exécuter le programme débogué en tant que root. Cela peut bien faire fonctionner différemment que lorsque vous l'exécutez à partir de la ligne de commande en tant qu'utilisateur normal. Pourrait être un peu déroutant. Pas que je tombe jamais dans ce piège ... Oopies.

Tout cela ira bien si vous exécutez le programme débogué en tant que root avec sudo ou si le programme débogué contient le fichier setuid . Mais si le programme de débogage est en cours d'exécution avec les fonctionnalités de POSIX ( SETCAP / GetCap ) Ensuite, vous devez refléter ces autorisations plus granulaires dans Bash et GDB, comme suggère Nick Huang plutôt que de brute forcer les autorisations avec 'sudo'.

Faire toute autre chose peut vous conduire à un mauvais endroit d'apprentissage extrême.


0 commentaires

2
votes

J'ai utilisé la solution de @ Nickhuang jusqu'à, avec l'une des mises à jour système, elle a cassé des services SystemD (trop de capacités sur Bash pour SystemD pour le démarrer ou d'autres). Passé à quitter Bash seul et passez une commande à GDB pour invoquer directement l'exécutable. La commande est xxx


0 commentaires