6
votes

Intermixing C ++ Manipulation d'exception et SEH (Windows)

J'ai une fonction dans laquelle j'appelle gettaddrinfo () pour obtenir un sockaddr * quelle mémoire est attribuée par le système. Comme beaucoup peuvent savoir, vous devez appeler freaddrinfo () pour libérer la mémoire allouée par getaddrinfo ().

MAINTENANT, dans ma fonction, il y a quelques endroits où je peux jeter une exception , parce qu'une certaine fonction a échoué. Ma première solution consistait à incorporer le freeaddrinfo () dans chaque bloc IF. Mais cela a l'air moche pour moi, car j'aurais dû l'appeler de toute façon avant que ma fonction ne revienne, alors je suis venu avec SEH's essaie-enfin ...

Mais le problème que j'ai rencontré est, qu'il n'est pas autorisé à coder les instructions de lancement dans le bloc __try

alors, j'ai lu sur le MSDN et j'ai essayé d'échanger les relevés de lancement dans la fonction d'assistance appelée à partir du bloc de __try. .. et Voila, le compilateur n'a plus gémit ...

Pourquoi est-ce? Et est-ce sûr? Cela n'a pas de sens pour moi: /

code: xxx

édition:

Essayé ce qui suit et ça fonctionne avec le lancement Un entier, mais ne veut pas quand j'utilise une classe comme une exception: xxx

pourquoi? : /


0 commentaires

3 Réponses :


3
votes

Vous pouvez envelopper l'addrinfo dans une classe qui appelle gettaddrinfo dans le constructeur et freeaddrinfo dans son destructeur.

De cette façon, il sera toujours libéré, qu'il y ait une exception ou non.


0 commentaires

9
votes

Vous ne pouvez pas mélanger les deux types d'exception. Sous les couvertures, les exceptions C ++ utilisent SEH et votre gestionnaire d'exception SEH pourraient gâcher la logique de propogation d'exception. En conséquence, le compilateur C ++ vous permettra de les mélanger.

PS: La manipulation des exceptions structurées est presque toujours une très mauvaise idée. Interne Microsoft a interdit l'utilisation de SEH sauf dans des circonstances très limitées. Tout composant qui utilise une manipulation des exceptions structurés est automatiquement soumis à des évaluations de code Intense (nous avons des outils qui recherchent l'utilisation de son utilisation pour s'assurer qu'aucun cas n'est manqué).

Le problème avec Seh est qu'il est extrêmement facile d'introduire accidentellement des vulnérabilités de sécurité lors de l'utilisation de Seh.


4 commentaires

J'ai un grand respect pour vous et les grandes explications que vous avez toujours sur votre blog, mais je dois être en désaccord ici. Visual C ++ mélange les deux types, lorsque / eha est utilisé. Catch (...) Catches Seh et __ Enfin Exécute pour les exceptions C ++. J'aimerais savoir, cependant, les manutentionnaires SEH sont-ils interdits ou simplement du code qui utilise Seh pour le contrôle de flux (c'est-à-dire synthétiser une exception SEH)? .NET CODE Poignée des exceptions SEH partout .


Activation / EHA a des conséquences potentielles de sécurité. Il désactive également la plupart des optimisations du compilateur car le compilateur doit désactiver toutes les analyses de flux de code (lorsque / EHA est défini, il indique au compilateur que toute instruction peut provoquer une exception, pas seulement des appels de méthodes). Certains des gestionnaires légaux de SEH sont les suivants: l'argument de noyau Sondage (où les gestionnaires de SEH sont obligatoires), la gestion de l'exception C ++, la gestion des exceptions, la gestion des exceptions, les manutentionnaires d'exception de RPC et un petit ensemble d'autres. Tous ces cas sont examinés de manière intensive.


Avez-vous une référence à un article de blog ou similaire qui décrit ces conséquences de sécurité?


Recherchez certains des articles écrits sur la vulnérabilité de .ani il y a quelques années, Michael Howard et David Leblanc en ont écrit à ce sujet. N'oubliez pas que ce sont des conséquences de sécurité potentielles , pas des conséquences directes. Il est possible d'utiliser / eha correctement. Mais c'est très difficile et vous devez sérieusement savoir ce que vous faites. Le plus gros problème avec / eha est les conséquences de la performance associées au commutateur (et aux conséquences de fiabilité associées à l'utilisation du SEH du tout).



0
votes
catch(int& X)
{
    std::cout << "caught a X" << std::endl;
}

1 commentaires

Je pense que vous n'avez pas compris, ou peut-être que je n'ai pas écrit assez clairement: j'ai d'abord essayé de lancer un int, après cela avec un X ... J'ai peut-être mélangé le deuxième code tout en l'écourtant ici, pardon pour cela