суббота, 25 июня 2011 г.

Исправлена уязвимость в безопасности модулей urllib/urllib2

Источник: urllib Security Vulnerability Fixed

Гвидо ван Россум недавно разместил в репозитории исправление уязвимости CVE-2011-1521, проблемы безопасности в библиотеках Python, обеспечивающих работу с URL. Несмотря на то, что проблемы безопасности возникают редко, это событие - хороший повод посвятить сообщество в ход работы в случае их возникновения. Работа обычно состоит из 3 этапов: сообщения о проблеме, её анализе и исправления.

Сообщение о проблеме


Если Вы нашли проблему безопасности в CPython, то первое, о чем мы просим, - не разглашать подробности этой проблемы. После того, как Вы убедились, что действительно нашли проблему безопасности, лучшим способом донести эти знания до разработчиков ядра будет создать краткий, но детальный отчет.

Из хорошего отчета можно точно определить, как обнаруженная проблема влияет на соответствующие части системы. Если проблема проявляется на какой-то конкретной платформе или зависит от наличия какого-либо другого кода в системе, то это также полезно знать разработчикам. Хорошо бы знать версии Python, которые затрагивает данная проблема, все актуальные версии Python будут протестированы на наличие указанной уязвимости. И последнее, если у Вас есть тест, отражающий данную проблему, не забудьте включить его в отчет. Всю информацию следует отправить группе security@python.org.

Нилс Хайнен из команды безопасности Google не так давно представил на рассмотрение хороший отчет. Он обнаружил проблему в обработке перенаправления HTTP 302 модулями urllib и urllib2 из стандартной бибилиотеки Python. А выявил Нилс то, что сервер может перенаправлять запросы на неподходящие схемы, что приводит к ситуациям, опасным как для данных, так и для систем. В своем исходном сообщении Нилс рассказал о двух сценариях, когда такие перенаправления могут вызвать проблемы.

Во-первых, поскольку urllib/urllib2 использует обработчик для URL схемы file://, то перенаправление на file:///etc/passwd может раскрыть информацию о паролях. Нилс также пояснил, что перенаправление на системное устройство, подобно file:///dev/zero, может привести к исчерпанию ресурсов и, как следствие, к отказу от обслуживания.

Анализ сообщения об уязвимости


Для уменьшения риска разглашения информации об уязвимости в список рассылки security@python.org входит небольшая группа доверенных разработчиков, которые анализируют и обрабатывают сообщения как можно скорее. Если Вы хотите передавать информацию этой группе в зашифрованном виде, подробно об использовании OpenPGP читайте на страничке новостей безопасности.

Если группа подтвердит наличие проблемы в безопасности, то эта уязвимость может быть анонсирована совместно с устраняющим ее патчем. В данном случае Гвидо ван Россум публично сообщил об уязвимости, которую нашел Нилс, в issue #11662, включив патч.

 

Исправление проблемы


Патч, опубликованный Гвидо, ограничивает перенаправление следующими URL схемами: http://, https:// и ftp://. Использование FTP перенаправления было признано допустимым, оно часто используется системами зеркалирования серверов загрузки, которые иногда перенаправляют запросы на географически более близкие FTP сервера.

Теперь в Python версий 2.x, когда запрашивается перенаправление на неподходящую схему, метод redirect_internal класса FancyURLopener генерирует исключение IOError. Метод http_error_302 класса HTTPRedirectHandler ведет себя аналогично, только будет генерировать исключение HTTPError. В Python 3 такие же исправления внесены в работу модуля urllib.request. В патч включены два теста, проверяющие перенаправление как на правильные, так и на неправильные схемы.

Что касается пользователей Python, то последний выпуск Python 2.5, с доработкой в области безопасности, скоро появится. Несмотря на то, что плановые даты выпуска обновлений для версий 2.6, 2.7, 3.1 и 3.2 пока не определены, их исходный код был доработан для исправления данной уязвимости.

пятница, 24 июня 2011 г.

Знакомьтесь с командой: Тарек Зиади

Этот пост является частью цикла "Знакомьтесь с командой", который создан, чтобы представить и поближе узнать членов команды разработки ядра Python.

Источник: Meet the Team: Tarek Ziadé

Имя:Тарек Зиади
Местонахождение:Тюрси неподалёку от Дижона, Бургундия, Франция
Домашняя страница:http://ziade.org

Как долго Вы программируете на Python?

Около 10 лет.

Как долго Вы являетесь разработчиком ядра?

С 21 декабря 2008 года.

Как вы стали разработчиком ядра? Помните ли свой первый коммит?

Я стал разработчиком ядра с целью поддерживать и развивать Distutils.

Моим первым коммитом была правка небольшой ошибки в функциональности distutils, которую я предложил перед тем, как стать коммитером. Эта функциональность была добавлена в Python неделей раньше. Новшество заключалось в возможности конфигурировать команды Distutils register и upload, чтобы они могли работать с несколькими серверами, подобными pypi.

Правка ошибки в этой функциональности и была моим первым коммитом, который я совершил 24 декабря 2008 года с моими только что полученными привилегиями. Этот день является ещё и моим днём рождения, а также 17-летней годовщиной выхода релиза Python 0.9.4.

Над какими частями Python Вы сейчас работаете?

Над стандартной библиотекой: sysconfig, distutils, packaging(добавлен в версии 3.3), shutil, pkgutil, а также время от времени над другими модулями.

Как Вы еще используете Python, помимо работы по разработке ядра?

Я работаю в Mozilla в сервис-команде, где создаю веб-службы с использованием Python.

Чем вы занимаетесь, когда не программируете?

Я читаю комиксы, рассказы в картинках, пишу книги, играю с моими детьми, пью вино с моей женой и пробую отреставрировать мой дом, который был построен в 1848 году.

пятница, 10 июня 2011 г.

Формализация политики управления изменением AST

Источник: Formalizing the AST Change Control Policy

В Python скомпилированные исходные тексты представляются в виде абстрактного синтаксического дерева с помощью модуля AST. Модуль AST позволяет программисту анализировать и манипулировать представлением AST между процессами разбора исходников и компиляции их в байткод.

Хотя смысл Python-кода определён в справочнике языка Python, модуль AST является деталью реализации CPython, и он не является необходимым для реализации в других воплощениях Python.

Совместимость AST

В процессе выполнения работы по переписыванию локального оптимизатора CPython для работы с AST (а не обработки сырого байткода, как это сейчас происходит), Евгению Тодеру было необходимо внести некоторые изменения в структуру AST. Так как это является особенностью реализации CPython, сразу и не ясно, какую политику обратной совместимости нужно применять к AST. По этой причине Евгений задал вопрос в списке рассылки python-dev: "Является ли необходимым при изменении AST обеспечивать обратную совместимость?"

Выработанное общими усилиями мнение было таково: совместимость не является необходимой. У модуля AST есть константа ast.__version__, которая предоставляет программисту способ изменять поведение кода в зависимости от версии AST, с которой тот столкнулся. Эта возможность была признана достаточной для обеспечения совместимости в специфичном для воплощения Python модуле.

Другие воплощения Python

В действительности, мейнтейнеры Jython и IronPython указывали, что их соответствующие реализации обе имеют совместимые AST модули, или планируют предоставлять такую возможность. Однако, они не считают, что модуль AST должен быть заморожен, и не находят ничего плохого в том, что при изменении константы ast.__version__ AST будет изменяться с нарушением совместимости.

Ещё один вопрос, который поднимался, касался полного набора тестов в test_ast.py. Такой набор помог бы другим воплощениям Python обеспечить совместимость с CPython. Увеличение покрытия в test_ast.py было бы хорошим проектом для кого-нибудь, кто хочет заняться разработкой ядра Python.

Что же дальше?

Патч, который послужил причиной дискуссии, до сих пор не включён в CPython. Поэтому, вероятно, всё останется как есть. Хотя, если он будет внесён в репозиторий, AST будет изменён с потерей совместимости. Константа ast.__version__ изменится для того, чтобы отразить это. Код пользователей сможет с помощью этой переменной определить, как себя вести. Если обобщить, то это будет способ изменить AST, который вероятно будет применяться в будущем.

Разработчики Python заинтересованы в определении того, как широко используется AST, и насколько много коллизий будет иметь данная политика. Если у кого-нибудь из читателей есть код, на который будет влиять данное изменение, у них есть стимул поучаствовать в обсуждении на python-dev этого вопроса.

Томас Хеллер, мейнтейнер ctypes, уходит в отставку

Источник: Thomas Heller Steps Down as ctypes Maintainer

Сообщество разработчиков Python горячо благодарит Томаса Хеллера, который долгое время поддерживает пакет ctypes. Ранее в этом месяце Томас заявил о своём уходе из проекта CPython, который, начиная c Python 2.5, является родительским домом для его библиотеки ctypes.

У меня случился шанс поговорить с Томасом и он рассказал мне о своей истории, связанной с Python, а также его проектами ctypes и py2exe.

Python

В 1999 году Томас искал источники для изучения языка Python и случайно приобрёл книгу Марка Лутца Programming Python. И сразу же он был очарован этим языком. В тот момент он занимался заменой Scheme как языка расширений к большой программе, которую он написал на C для ОС Windows.

Что касается его становления как члена команды разработчиков, его первым вкладом в CPython(а также в open source) был небольшой патч к distutils, относящийся только к Windows. Интерес Томаса к distutils в конечном счёте привёл его к разработке команды bdist_wininst, которая позволяет создать установочный пакет Windows, устанавливаемый в систему одним кликом мыши. Начиная с того момента Грег Уорд пригласил его в группу python-dev, где он в итоге получил доступ на внесение изменений в репозиторий.

py2exe

Как и у многих разработчиков для Windows, у Томаса существовала необходимость развёртывания готового к использованию Python-приложения как одного исполняемого файла. Ранее решения этой проблемы появились благодаря известным Python-разработчикам - Фредерику Ланду(squeeze) и Кристиану Тисмеру( sqfreeze), и Томас предложил несколько патчей Гордону МакМилану в его проект Installer, которые были приняты.

Его интерес к distutils привёл Томаса к мысли адаптировать Installer в качестве расширения к этой библиотеке. Однако, он дошёл до того, что целиком переписал Installer с целью воспользоваться существующим фреймворком distutils. В конце концов он выбрал простое, но ёмкое, имя для проекта - py2exe.

ctypes

Идея создания ctypes пришла из-за необходимости улучшения функциональности модуля pywin32. Также работа Томаса со Scheme требовала интерфейса к Windows API подобно тому, что требовался в его работе с Python, таким образом он хотел сохранить жизнь проекту.

ctypes увидел свой первый общедоступный релиз в 2003 году после того, как Томас получил многочисленные просьбы опубликовать проект. Дата релиза была приурочена к выходу Python 2.3. Томас рассказал, что ctypes был его небольшим личным проектом на его Starship странице, который затем вырос в широко используемую библиотеку в мгновение ока.

Первоначально он начал проект на Windows, но быстро услышал призыв об адаптации пакета для Linux, завершить которую ему помогло сообщество. С помощью Linux-порта Томас пришёл к мысли о подключении библиотеки libffi к своему проекту. Эту же библиотеку он также начал использовать на Windows для замены своей низкоуровневой реализации.

2006 год примечателен релизом версии 1.0 ctypes, который был связан c принятием ctypes в качестве модуля стандартной библиотеки языка Python 2.5. После нескольких лет тяжёлого труда и многочисленных релизов каждый год, ctypes стал сейчас неотъемлемой частью Python и доступен по умолчанию для обширной аудитории.

Потребовалось большое количество усилий разных людей для доведения ctypes до такого состояния, в котором она находится в настоящий момент. Томас хочет поблагодарить каждого участника, особенно Робина Бейкера. Робин был определяющим человеком на ранних фазах разработки проекта и помог как знаниями, так и своим воодушевлением.

Новый ctypes-мейнтейнер

После многих лет тяжёлой работы Томас уходит, а нам ненавистна мысль видеть проект приходящим в состояние стагнации. Если у Вас есть опыт программирования на языке C и время для помощи проекту Python, сообщество было бы весьма признательно за Ваши усилия. Дополнительную информацию можно найти на странице для новых разработчиков, а также в системе отслеживания ошибок.

Знакомьтесь с командой: Бенджамин Петерсон

Этот пост является частью цикла "Знакомьтесь с командой", который создан, чтобы представить 
и поближе узнать членов команды разработки ядра Python.

Источник: Meet the Team: Benjamin Peterson
Имя:Бенджамин Петерсон
Местонахождение:Миннесота, США
Сайт:http://benjamin-peterson.org
Блог:http://pybites.blogspot.com

Как долго Вы программируете на Python?

3.5 года.

Как долго Вы работаете разработчиком ядра?

Ровно 3 года было 25 марта.

Как вы стали разработчиком ядра? Помните ли свой первый коммит?

Гвидо лично отклонил мое первое предложение. К счастью, я устоял и некоторые патчи были приняты. По-моему, моим первым коммитом было переупорядочивание файла Misc/ACKS.

Над какими частями Python Вы сейчас работаете?

Мне нравится парсер, компилятор и ядро интерепретатора, но я славлюсь тем, что участвую понемногу практически во всех областях разработки ядра Python ...кроме Windows!

Как Вы еще используете Python, помимо работы по разработке ядра?

Я разрабатываю интерпретатор Python на Python (http://pypy.org)! На самом деле, я в глубине души разработчик языка Python. :) Я создатель пакета six (http://pypi.python.org/pypi/six) - библиотеки для обеспечения совместимости Python 2 и 3.

Что Вы делаете, когда не программируете?

Сочиняю музыку, играю на кларнете и читаю книги по математике. Еще время от времени хожу в небольшие походы.

Устаревания возможностей между Python 2.7 и 3.х

Источник: Deprecations between Python 2.7 and 3.x

Недавнее обсуждение в python-dev выявило проблему, связанную с текущими правилами устаревания интерфейсов Python, с которой сталкиваются разработчики при миграции кода с Python 2.7 на текущие версии Python 3.x. В качестве решения данной проблемы команда разработчиков изменила существующие правила устаревания с учетом того, что программисты чаще всего будут портировать код с Python 2.7 сразу на последнюю версию 3.x, минуя более старые версии.

Прeдпосылки


В Python существует сильная приверженность к поддержанию обратной совместимости. Изменения разрешаются только в случае соблюдения правил совместимости, которые, по сути, заключаются в том, что правильно написанные программы не должны ломаться при исполнении новой версией Python. Однако, это не всегда возможно, например, если API абсолютно не рабочий и должен быть заменен. В таком случае Python следует политике устаревания, основанной на одногодичном переходном периоде, во время которого возможности, которые вскоре будут удалены, становятся официально устаревшими. В течение переходного периода при попытке использования устаревшей возможности должно выдаваться соответствующее предупреждение, чтобы дать разработчикам время обновить свой код. Полная информация о политике устаревания описана в PEP 5. Поскольку изменения появляются только в новых выпусках Python, а обычно интервал между выпусками составляет 18 месяцев, нормальным оказывается период устаревания длительностью в один выпуск.

Единственным исключением такой стратегии был Python 3. Замена основной версии с Python 2 на Python 3 была сделана намеренно, чтобы допустить изменения, нарушающие обратную совместимость, и дать шанс разработчикам языка Python исправить те проблемы, которые не могли быть решены в рамках существующей политики. Например, создание строк по умолчанию в Unicode, возврат итераторов вместо списков.

Параллельные пути разработки


Учитывая то, что переход к Python 3 потребует времени, около 5 лет по многочисленным оценкам, в этот период ожидалась, в некоторой степени, параллельная разработка на Python 2 и 3.

Было решено, увеличить период поддержки Python 2.7, последнего выпуска Python 2, на значительный срок. В итоге, разработчики, которые захотят перейти на более новую версию Python, должны будут переходить на Python 3.

Здесь-то как раз и проблема...

Неожиданные устаревания


Один из участников дискуссии в python-dev обратил внимание на то, что определенная функция в C API, а именно PyCObject_AsVoidPtr, была удалена без достаточно заметного предупреждения. А это именно то, от чего политика устаревания должна была защищать. Что же случилось?

Данное изменение было частью миграции со старого API (PyCObject) на новый, усовершенствованный (PyCapsule). Проблема в том, что в 2.6 по умолчанию используется PyCObject, единственно доступный API в Python 2.6, который был объявлен устаревшим в Python 2.7. В Python 3.2 данный API отсутствует и должено использоваться новый - PyCapsule. Получается, что период объявленного устаревания, с выпуска Python 2.7 (июль 2010) до выпуска Python 3.2 (февраль 2011), составил около 7 месяцев. Что значительно меньше 12 месяцев и усложняет разработчикам поддержку приложений для достаточно широкого набора версий Python.

Для тех, кто переходит с версии 3.0 на 3.1, а затем на 3.2, процесс устаревания проходит хорошо. Python 3.1 вышел в марте 2010 с необходимыми уведомлениями об устареваниях, поэтому в рамках версий 3.х период устаревания длился почти 12 месяцев. Однако, это не тот путь, которому, на самом деле, следуют разработчики - они переходят с 2.7 сразу на последнюю версию 3.х, в данном случае 3.2, и, как следствие, получают данную проблему. Возникновение такой ситуации никогда не являлось целью python-dev, но PEP 5 не учитывал случай активной разработки параллельно двух версий Python.

Что же нам делать?


Несмотря на то, что поломка PyCObject/PyCapsule API безусловно является проблемой; ее возможно обойти, но, как минимум, у одного участника python-dev возникли сложности с ее преодолением. В общем и целом, такого не должно было произойти.

Конкретно для случая PyCObject/PyCapsule проблема уже существует и с этим ничего не поделаешь. Восстановление PyCObject, в сущности, не вариант, так как только усугубит дальнейшую несовместимость. Тем не менее, по общему мнению возможно, хотя и трудоемко, написать код, который бы подстраивался под API. В действительности, PyCObject API в Python 3.1 был написан как оболочка вокруг PyCapsule API. Было выдвинуто предложение о том, что при необходимости реализация Python 3.1 может быть выделена для использования сторонним кодом. Более того, было решено, что будет написан "ретроактивный" PEP, учитывающий изменение. Он будет описывать причины, оправдывающие изменение, и документировать ресурсы, которые помогут разработчикам в миграции.

В более общих чертах, команда разработчиков Python обратила внимание на проблему и будет работать над тем, чтобы она не возникла вновь. Гвидо описал данную ситуацию и предложил, чтобы Python 3 старался не использовать устаревания в данный момент. Как минимум, устаревшие API будут поддерживаться значительно дольше, чтобы дать возможность разработчикам корректно смигрировать с Python 2.7.
Независимо от этого, участниками дискуссии был поднят вопрос о том, как более эффективно сообщать об изменениях в Python широкой аудитории. Для решения данной задачи и был создан этот блог.

Что все это значит?


Во-первых, это означает, что разработчики Python не всегда делают все правильно. Ни у кого не было намерений усложнять жизнь разработчикам, просто эта проблема не была вовремя замечена.

Во-вторых, исправление такой ситуации может больше навредить, чем помочь, поэтому PyCObject API не будет восстановлен. Хотя восстановление, возможно, поможет разработчикам, столкнувшимся с изменением API, но в ситуация с поддежкой совместимости только усложнилась бы. Тем временем, мы должны смириться с этой проблемой и двигаться дальше. Уроки усвоены, и мы постараемся не повторять тех же ошибок.

Эта история в том числе свидетельствует о том, что команда разработчиков Python хочет иметь обратную связь от пользователей. Совместимость очень важна, и мы прилагаем все усилия, чтобы переход на новые версии был безболезненным, насколько это возможно. В частности, разработчики библиотек должны иметь возможность поддерживать различные версии Python, прикладывая при этом не слишком много усилий.

И наконец, разработчики не бросили 2.7. Несмотря на то, что не будет появляться новых возможностей и не будет версии 2.8, взгляды людей, использующих 2.7, по-прежнему важны. Для всего сообщества Python очень важно дать возможность пользователям перейти на версии 3.х в тот момент, когда они будут готовы.

среда, 8 июня 2011 г.

Про опрос, futures и параллельное исполнение

Источник: Of polling, futures and parallel execution

Одной из важных задач современной вычислительной техники является сбережение энергии. Это крайне важно для портативных устройств (ноутбуков, планшетов, карманных компьютеров). Современный процессор может находиться в различных энергосберегающих режимах во время простоя. Чем дольше простаивает процессор, тем более глубоким становится режим энергосбережения, и тем меньше потребление энергии, и, следовательно, дольше живет батарейка на одном заряде.

У энергосберегающих режимов есть враг - опрос. В ситуации, когда задача требует периодического исполнения процессором, даже для чего-то тривиального вроде обращения к ячейке памяти, проверяя наличие возможных изменений, процессор выходит из энергосберегающего режима, готовит все свои внутренние структуры для работы, но возвращается обратно в энергосберегающий режим спустя заметное время после завершения даже такой незначительной операции, что уменьшает срок жизни батарейки. Компания Intel также озабочена данной проблемой.

Python 3.2 поставляется с новым стандартным модулем, который запускает параллельные задачи и ожидает окончания их работы: модуль concurrent.futures. Внимательно изучая код модуля, я заметил, что в некоторых рабочих потоках и процессах используется опрос. Я говорю "в некоторых", поскольку реализации классов ThreadPoolExecutor и ProcessPoolExecutor отличаются. Если первый проводит опрос в каждом рабочем потоке, то последний делает это только в одном потоке, который назвается потоком управления очередью и используется для связи с рабочими процессами.

В данном случае опрос используется с единственной целью: определить, когда должна запуститься процедура обработки события завершения процесса. Остальные задачи, такие как построение очереди вызываемых объектов или сбор результатов из ранее помещенных в очередь вызываемых объектов, используют объекты типа синхронизированная очередь. Эти объекты типа очередь импортируются или из модуля threading, или из multiprocessing, в зависимости от того, какой используется Executor.

И я предложил простое решение: я заменил опрос сигнальной меткой, встроенной сигнальной меткой по имени None. Когда в очередь добавляется None, один рабочий процесс, находящийся в состоянии ожидания, естественным образом пробуждается и проверяет нужно ли ему завершаться. В случае ProcessPoolExecutor возникает небольшая сложность, поскольку нам нужно пробудить N рабочих процессов помимо потока управления очередью.

В первоначальном патче по-прежнему есть таймаут опроса, настолько большой (10 минут), чтобы все рабочие процессы успели пробудиться. Большой таймаут существует по той причине, что код содержит дефекты и процессы не получают вовремя уведомление о необходимости завершения от вышеупомянутой сигнальной метки. Из любопытства я углубился в исходный код модуля multiprocessing и пришел к другому интересному наблюдению: под Windows, метод multiprocessing.Queue.get() при ненулевом и конечном таймауте использует...опрос (по этому вопросу я открыл issue 11668). Этот метод использует интересный высокочастотный вид опроса, он начинается с таймаута в одну милисекунду, а затем увеличивается с каждой итерацией.

Очевидно, что использование таймаута, даже очень большого, делает мой патч абсолютно бесполезным под Windows, поскольку специфика реализации таймаута приводит к тому, что пробуждения происходят каждую милисекунду. Я решил взять быка за рога и удалил большой таймаут опроса. Мой последний патч совсем не использует таймаут, и потому не должны возникать периодические пробуждения, независимо от платформы.

Раньше, до версии Python 3.2, опрос использовался для всех реализаций таймаута в модуле threading, а также и в большей части модуля multiprocessing, поскольку последний использует рабочие потоки для различных задач. Это было исправлено в issue 7316.