C++: A Cautionary Tale, or, 1 Hour Of Your Black Hat Trip is Spoken For - Томас Пташек рассказывает почему язык С++ небезопасен. Критикует следующие моменты.
Исключения. Есть такая точка зрения, что исключения есть зло. По этому поводу еще как-то Джоэл Спольски высказывался. Пташек рассказывает о следующем: после выброса исключения останавливается выполнение всех функций по цепочке до места выброса исключения. И в этих функциях могут остаться невалидные уже указатели.
delete. В С++ есть выражение delete и есть delete[]. И их очень легко перепутать. У меня есть старый пост про работу delete'ов Что делает выражение вида delete p. Пташек дает ссылку на Attacking delete and delete [] in C++, где гораздо подробнее рассказывается о работе delete'ов, со схемами использования ошибок программистов для всяких злобных дел.
STL. Итераторы, например, вектора становятся невалидными после изменения этого вектора.
Это не все, у Пташека написано больше и подробнее. Все эти проблемы решаются, все знают как их решать. Чтобы не было неприятностей с исключениями есть RAII, потом нужно вызывать правильный вариант delete и быть повнимательнее с итераторами... Но люди, они ошибаются.
Цитата из поста Пташека:
"Я - специалист по безопасности, которому платят, чтобы проискивать исходники самых крупных и известных C++ продуктов и, проблема в том, что я продолжаю находить ошибки. Просто знать как надо делать недостаточно."
пятница, июля 13, 2007
Безопасность в С++
Подписаться на:
Комментарии к сообщению (Atom)
15 коммент.:
Все это немного притянуто за уши. Можно очень сильно сократить негатив от этих моментов. Достаточно пользоваться простыми правилами (мы используем подобные в наших проектах):
1. все операции с памятью - через умные указатели (std::auto_ptr, boost::shared_ptr, boost::scoped_ptr, scoped_array, std::vector, Loki::SmartPtr). тогда про delete вспоминать и не придется. а если не нашелся подходящий умный указатель - напиши его и локализуй в нем все эти delete.
2. все использование ресурсов - через RAII (в частности, для простых случаев очень подходит Loki::ScopeGuard)
В целом пост Пташека можно резюмировать как "C++ позволяет вам выстрелить себе в ногу". Пташек перечисляет 3 достаточно известные потенциальные ошибки, но - ничего нового по сути. SNR поста очень низкий.
А то что "люди ошибаются" - ну так люди всегда ошибаются, вне зависимости от того, насколько idiot-proof язык/инструмент им дать.
В целом пост Пташека можно резюмировать как "C++ позволяет вам выстрелить себе в ногу"
Хех, ну себе-то еще ничего. Но тут объясняется, что другие могут использовать эти ошибки с выгодой для себя.
Вопрос не не в том, похож ли C++ на опасную бритву без ручки, вопрос в том, почему им продолжают пользоваться. Для любителей безопасной езды есть ява, есть си-шарп.
Но тут объясняется, что другие могут использовать эти ошибки с выгодой для себя.
:) Это справедливо для любой более-менее серъёзной ошибки.
Кстати, такое впечатление, что пост is kind of rant. Или самореклама (см. point 1) :)
Вообще, начиная с "the notion that C++ is a more secure language than C is a myth" всё уже плохо пахнет. :)
Вопрос не не в том, похож ли C++ на опасную бритву без ручки, вопрос в том, почему им продолжают пользоваться. Для любителей безопасной езды есть ява, есть си-шарп.
Они исключают только один пункт - управление памятью.
В остальном(управление ресурсами, те же итераторы и т.д.) они ничем не лучше.
И ни один язык не выпрямит кривые руки.
Они исключают только один пункт - управление памятью.
Это на первый взгляд такая мелочь :)
Реально основной плюс -- это размещение всех объектов на хипе (boxed values) и отсутствие низкоуровневых указателей (=>нормальная безопасная система типов), а к этому уже как логичное дополнение -- сборка мусора.
Вроде бы всего ничего, а уже сразу можно и замыкания в язык добавить, и хвостовую рекурсию оптимизировать, а оттуда и до, не побоюсь этого слова, функциональщины всякой недалеко ;)
Насчет же "кривых рук" -- это разумеется.
Но если исходить из того что "плохие" программисты все же присутствуют в команде, то у них остается меньше возможностей делать трудновылавливаемые баги, и это замечательно.
Реально основной плюс -- это размещение всех объектов на хипе (boxed values) и отсутствие низкоуровневых указателей (=>нормальная безопасная система типов), а к этому уже как логичное дополнение -- сборка мусора.
Ну не знаю, не знаю. Кому это "реально основной" плюс, кому - нет. Кому это "нормальная" система типов, кому - нет(см. D&E про эту "нормальную" систему типов).
ISO/IEC 14883:2009 будет поддерживать GC как опциональную возможность языка. Точнее говоря, она будет обязательной, но ею можно будет не пользоваться(так же, как исключениями, например) и не получать падения производительности просто из-за факта, что эта возможность есть в языке(опять же, см. D&E про zero-overhead principle). Лично я, даже после этого нововведения в язык, использовать GC-MM не буду. По мне, эта технология - излишество, причём очень дорогое: возможностей RAII вполне хватает для полноценного контроля ситуации.
По поводу exceptions - Джоэль забыл добавить один чрезвычайно важный факт. Код с exceptions получается хуже (и по памяти, и по быстродействию) на десятки процентов, а то и в разы. По-крайней мере, это верно для GCC - посмотрите в результирующем ассемблере, как компилятор строит function frame. А теперь, перекомпилируйте с -fno-exceptions и посмотрите ещё раз...
Так что, как бы не был красив, логичен и лаконичен код без exceptions - в сад. По крайней мере, до тех пор, пока их кто-нибудь нормально не имплементирует.
Вообще то я про D&E - Design & Evolution, Страуструп.
2archimed7592
ISO/IEC 14883:2009 будет поддерживать GC как опциональную возможность языка.
...
По мне, эта технология - излишество, причём очень дорогое: возможностей RAII вполне хватает для полноценного контроля ситуации.
Автоматическая сборка мусора решает две проблемы из перечисленных Пташеком. Причем без участия программиста, что исключает возможность ошибиться. Я никак не могу назвать ее излишеством.
2rsx11
Так что, как бы не был красив, логичен и лаконичен код без exceptions - в сад. По крайней мере, до тех пор, пока их кто-нибудь нормально не имплементирует.
Эээ... Возможно, имелся в виду код c исключениями? А то фраза теряет смысл.
Ну не знаю, не знаю. Кому это "реально основной" плюс, кому - нет. Кому это "нормальная" система типов, кому - нет.
Ну я той точки зрения, что это все помогает сделать язык "более высокоуровневым", а систему типов более выразительной и стройной.
Когда нужно написать супербыстрый низкоуровневый код, это все может мешать, да.
Предлагаемая в C++09 сборка мусора, согласен -- во многом как пятое колесо выглядит. Чтоб было органично -- нужно ее сделать обязательной, выкинуть поинтеры и выкинуть RAII (и получится C# :).
Про C++, GC и хип я чуть подробнее тут и тут мысль развернул, если интересно.
Так что, как бы не был красив, логичен и лаконичен код без exceptions - в сад. По крайней мере, до тех пор, пока их кто-нибудь нормально не имплементирует.
Эээ... Возможно, имелся в виду код c исключениями? А то фраза теряет смысл.
Да, конечнo, имeнно с исключениями, sorry.
archimed7592
Лично я, даже после этого нововведения в язык, использовать GC-MM не буду. По мне, эта технология - излишество, причём очень дорогое: возможностей RAII вполне хватает для полноценного контроля ситуации.
Правильно :-) RAII позволяет контролировать ресурсы вообще, а не только лишь память. Все эти джавы со своими GC идут лесом, как только дело доходит до контроля за ресурсами, ибо написание exception-safe кода без RAII превращается в сущую муку (не говоря уже о том, чтобы потом этот код читать и сопровождать).
Отправить комментарий