суббота, 5 ноября 2011 г.

Тараканьи бега: Обзор самых интересных багов в *nix’ах

По данным Гугла, на сегодняшний день существует примерно 31 000 000 OpenSource-проектов, которые суммарно содержат около 2 000 000 000 строк кода. Естественно, что в таком количестве исходников — миллионы багов, описанные в тысячах багтрекеров. Но не все ошибки одинаково интересны — я расскажу о самых знаменитых.

Самый старый

Начну обзор с самых старых багов, которые не фиксились долгие годы: либо о них никто не знал, либо они никому не были интересны. Первый баг из этой категории почти отпраздновал свои 30 лет, когда его пофиксили. Скорее всего, этот жук закрался еще в 4.1BSD (а может, и еще раньше), откуда успешно перекочевал уже во все современные BSD-системы. Он проявил себя в новых релизах Samba — сервер падал при попытке доступа к каталогу. Имя героя, откопавшего древний баг еще в середине 2008 года, — Марк Балмер. Сначала Марк винил во всем новый релиз Samba, но потом нашел баг в OpenBSD’шной библиотеке libc (если быть точным, в файлах lib/libc/gen/{readdir.c,telldir.c}, отвечающих за доступ к каталогам). Ошибку нельзя было обнаружить с более ранними версиями Samba из-за специального костыля, который в новых релизах почему-то убрали. Оказалось, что баг затрагивал все современные BSD-системы, в том числе и Mac OS X.
Следующему багу, пожалуй, можно вручить чемпионский титул бага-долгожителя. Целых 33 года о нем никто не подозревал. За нахождение и ликвидацию ошибки можно сказать спасибо двум людям – Отто Мёрбеку и Николаю Штурму. Эта история произошла также в середине 2008. Отто Мёрбек работал над новой реализацией malloc в OpenBSD, а Николай Штурм тестировал код. В результате тестирования на платформе sparc64 было обнаружено, что иногда компиляция большого C++ проекта может заканчиваться с ошибкой Internal Compiler Error. Мёрбек начал искать причину этой проблемы и обнаружил переполнение буфера в генераторе синтаксических парсеров yacc(1): в файле skeleton.c, в функции yyparse(), происходило обращение к несуществующему элементу массива.
Для OpenBSD Отто выпустил шестистрочный патч, исправляющий данную проблему. Скорее всего (за давностью лет точно сказать уже сложно), баг берет свое начало примерно с UNIX V6 (который был выпущен в мае 1975) или UNIX V7.

Самый глупый

Первый претендент на эту номинацию — GRUB2, в версии 1.97 которого был обнаружен баг, позволяющий очень просто подобрать пароль на загрузчик. Смысл ошибки в том, что для ввода пароля необязательно знать весь пароль целиком — GRUB’у было достаточно хотя бы его части. Например, если пароль — xakep, то достаточно было ввести «xake», «xak», «xa» или даже просто «x». Таким образом, подобрать любой пароль можно было, просто подобрав первый символ. Баг был быстренько пофиксен в новой версии 1.97.1.
Следующий участник — Ping of Death в OpenBSD Packet Filter (CVE-2009-0687), был обнаружен 9 апреля 2009 года и исправлен спустя два дня. Как можно понять из названия, ошибка заключалась в возможности вызвать kernel panic с помощью специально сформированного пакета. Не то чтобы баг сам по себе очень глупый.
Просто тот факт, что OpenBSD можно вот так запросто положить одним пингом — это нонсенс и больше похоже на первоапрельскую шутку. Уязвимы были все версии OpenBSD с pf вплоть до 4.5, на всех архитектурах, а также NetBSD 5.0 RC3. Причем, никаких особых эксплоитов не нужно, достаточно сделать:
nmap -sO $target_IP
или
hping -0 -H 58 $target_IP
К слову сказать, это не первая уязвимость подобного рода в OpenBSD, просто на моей памяти самая широко распространенная. К примеру, в 2005 году из-за ошибки в драйвере беспроводного адаптера ral(4) при использовании IPsec ОС тоже паниковала, но уже от самого обычного пинга — достаточно было отправить 2 эхо-запроса. Прим. ред.: сам себя не похвалишь, никто не узнает — этот баг был обнаружен мной во время настройки домашнего Wi-Fi.
После исследования проблемы я отправил разработчикам детальное описание сценария, при котором возникает remote crash, конфиги pf.conf, isakmpd.conf и isakmpd.policy, а также traceback ядра, полученный с помощью отладчика ddb(4). Тео де Раадту и команде понадобилось три с половиной месяца, чтобы странить эту брешь. И, наконец, чемпион в номинации «Самый глупый» — глюк в прошивке первого Android-телефона HTC G1. Оказалось, что все нажатия клавиш переадресовывались в рутовую консоль.
То есть, например, набрал ты в SMS слово «reboot», а потом , и очень удивился, что телефон послушался и ушел в ребут. А ведь можно и что пострашнее набрать! Но нет худа без добра — с помощью этой ошибки на G1 можно было легко поставить Debian. Эх, такой баг пофиксили! :)

Самый «железный»

Ни для кого не секрет, что баги в ПО могут выводить из строя железо. Хорошо, что встречаются такие ошибки очень редко, а широкое распространение получают еще реже. Самый скандальный (а вероятнее, просто раздутый) за последнее время баг такого типа — «Ubuntu убивает ноутбучные винты».
Винт в ноутбуке отличается от винта на десктопе тем, что во время работы от батареи он периодически останавливается (паркует головку). Часто при этом слышен характерный щелчок. Это реализовано ради экономии заряда батареи (еще один плюс — в остановленном состоянии винт способен выдержать большие перегрузки от встряхиваний и падений).
И Ubuntu все правильно делала — останавливала винт, когда он был не нужен. Вот только на некоторых моделях это происходило многократно — частично по вине прошивки самого винта. С большой долей вероятности на таких моделях наблюдалась бы частая парковка головок под любой ОС. Посмотреть, подвержен ли твой винт такому багу, можно следующим образом. Ставим пакет smartmontools:
$ sudo apt-get install smartmontools
Если твой винт — sda, то:
$ sudo smartctl -a /dev/sda | grep Load_Cycle
Последнее число в этой строке — это количество парковок головки. У меня это значение равно 13 137, что совсем не много. Ресурс обычного ноутбучного винта, гарантированный производителем, может доходить до 600 000. Теперь можно подождать несколько минут/ча сов и снова проверить это значение, чтобы примерно определить скорость, с которой оно растет.
По идее, быстро расти не должно, так как фикс был доступен еще для 8.04 (путем активации менее агрессивного режима сохранения энергии). Если баг все же присутствует, то можно попробовать отключить парковку головок с помощью APM (Advanced Power Management):
$ sudo hdparm -B 254 /dev/sda
Если и после этого проблема осталась (как вариант, попалась модель с нестандартными значениями APM или невозможностью управлять APM в принципе), то полезно почитать комментарии на страничке goo.gl/bTNhy, там предлагается несколько возможных решений.
И еще один довольно свежий баг, связанный с железом. Правда, к OpenSource он не имеет особого отношения. Разве что тот факт, что он также проявляется и на *nix-системах. Речь пойдет о закрытых драйверах от Nvidia. Весной 2010 года на официальном сайте появились новые версии драйверов — 196.75 и 195.36.
Спустя некоторое время пользователи начали сообщать о выходящих из строя видеокартах. Оказалось, что в новые драйвера закралась ошибка, которая иногда приводила к полному выключению или снижению до минимума скорости вращения кулера видеоадаптера, несмотря на сильный нагрев видеоядра. После обнаружения бага новые версии дров были спешно убраны с сайта, а всем пользователям было рекомендовано откатиться до старых версий.

Самый массовый

Выше я описывал баги, которые встречаются не у всех и не часто. Пришла пора рассмотреть более массовые экземпляры, с которыми сталкивался, пожалуй, любой пользователь *nix-систем. Первый баг уже пофиксен, но, думаю, многие его помнят: неработающие хоткеи Firefox в русской раскладке на *nix’ах (goo.gl/Hiagm). Был обнаружен в 2001 году, а исправлен только спустя семь лет, в Firefox 3 beta 2. На более старых версиях можно было решить проблему костылем в виде аддона Russian hot keys bugfix. Примечателен баг еще и тем, что он был исправлен в рамках программы «Деньги за исправление багов» от Mozilla Russia. Имя героя — Олег Крылов. Mozilla Russia готова платить за устранение багов, специфичных для российских пользователей.
Размер вознаграждения не очень большой — от $300 до $500, а все «лоты», на которых его можно заработать, указаны на страничке проекта: goo.gl/dhYxN. Подробнее про вознаграждения за отстрел багов в OpenSource-продуктах читай во врезке.
Следующий претендент тоже связан с хоткеями, но теперь проект уже посолиднее — X.Org, да и затрагивает этот баг всех пользователей, вне зависимости от раскладки. Описать его можно так: применение хоткея происходит при нажатии, а не при отпускании клавиш. Приведу пример: допустим, переключение раскладки клавиатуры в системе забиндено на . Тогда вместе с прокручиванием назад списка открытых окон (Alt+Shift+Tab) будет переключаться раскладка.
В багтрекере X.Org баг висит с 2004 года: goo.gl/GaRqQ. Но вся проблема в том, что патч (дружно скажем за него спасибо Илье Муравьеву), устраняющий глюк, нарушает спецификацию XKB. А спецификации, как известно, нарушать нельзя :). Поэтому пока в апстрим патч не будет принят, по крайней мере, до внедрения XKB2 (а это счастливое событие откладывается уже несколько лет). Единственный известный мне дистрибутив, который уже включил этот патч — Ubuntu (с версии 11.04). Для более старых версий можно установить патченый X.Org из ppa. Ссылка на баг в убунтовском трекере: goo.gl/7E6uK. Следующий интересный и достаточно известный в узких кругах баг раньше был серьезным контраргументом против использования FreeBSD на десктопе.
Вызвать его было просто: втыкаем USB-флешку, монтируем, вытаскиваем флешку не отмонтировав — хоп, получаем Kernel Panic. Жила себе эта ошибка преспокойно с самой первой версии FreeBSD вплоть до восьмой, в которой поменяли весь USB-стек.
И, наверное, самый распространенный баг — кракозябры в нелатинских именах файлов при распаковке RAR и ZIP-архивов, созданных под Windows. В случае с RAR проблема, как правило, решается очень просто:
$ sudo apt-get remove rar
$ sudo apt-get install unrar

С ZIP все гораздо сложнее. На launchpad’е уже давно висит баг goo.gl/Y5YVj, собравший более сотни комментариев (правда, не все из них одинаково полезны) и около 1000 голосов (благодаря недавно прошедшему «флешмобу» баг поднялся на второе место в launchpad по количеству голосов), подтвердивших существование проблемы. Одно время эту ошибку номинировали в категорию HundredPaperCuts – это позволило было надеяться на то, что ее скоро исправят. Однако вскоре одумались (видимо, посчитав, что фикс слишком сложен). Рассмотрим, какие решения есть на данный момент.
1. Поставить AltLinux, там эта проблема решена.
2. Попытаться прикрутить решение из AltLinux в свой дистрибутив. К сожалению, не все так тривиально, как может показаться на первый взгляд. Кроме самого патча на zip/unzip, придется прикручивать еще специальную библиотеку libnatspec. Для Ubuntu есть ppa: goo.gl/AFSQq (здесь лежат патченные zip/unzip) и goo.gl/eGGAe (здесь — libnatspec).
3. Собрать последнюю бета-версию unzip: goo.gl/0Bd9Y. К сожалению, это решение работает только для некоторых архивов и не устраняет проблему полностью.
4. Перекодировать имена распакованных файлов с помощью convmv (который надо предварительно установить):
$ convmv -f cp866 -t utf8 -r --notest *
5. Поставить скрипт для Nautilus:
$ sudo apt-get install nautilus-fi lename-repairer

Самый неуловимый

Этот титул безоговорочно отходит #12309. 12309 — баг-легенда, летучий голландец. Им пугают начинающих линуксоидов, его используют как железный аргумент в холиварах Linux vs FreeBSD vs Windows. Проявляется он на абсолютно разном железе и на разных конфигурациях ядра и файловых систем. Сам баг звучит как «Large I/O operations result in poor interactive performance and high iowait times», и его обсуждение собрало более 550 комментариев: goo.gl/uMKEn.
Баг был описан в декабре 2008 года и на данный момент имеет приоритет P1 high. Проверить, восприимчива ли к нему твоя система, очень просто. Нужно всего лишь запустить:
$ dd if=/dev/zero of=/tmp/test bs=1M count=1M
и понаблюдать за отзывчивостью ОС, особенно графических приложений. Если при этом дико подскочет wa (а с ним и LA), и система станет неюзабельной чуть более, чем полностью, — бинго, ты поймал 12309.
На самом деле 12309 — это не один, а несколько багов, смешанных в кучу. Можно выделить следующие случаи появления:
  • при копировании больших объемов данных с винта на винт (или с раздела на раздел одного винта);
  • при нехватке ОЗУ (и, соответственно, диком своппинге);
  • при копировании на USB-девайсы;
  • при использовании зашифрованных разделов;
Соответственно, фиксы тоже будут разные:
1. Смена планировщика ввода-вывода на какой-нибудь не-cfq. Посмотреть текущий планировщик можно так:
$ cat /sys/block/sdX/queue/scheduler
где sdX — нужный девайс (обычно — sda). Используемый в данный момент планировщик будет указан в квадратных скобках. Можно сменить планировщик и посмотреть на результат:
# echo deadline > /sys/block/sdX/queue/scheduler
Чтобы выбранный планировщик устанавливался при загрузке, нужно передать ядру параметр elevator=deadline. В случае с grub необходимо изменить строку GRUB_CMDLINE_LINUX_DEFAULT в /etc/default/grub, а затем обновить конфигурацию:
$ sudo update-grub
2. Настроить ОС на менее агрессивное использование swap:
# echo 10 > /proc/sys/vm/swappiness
Теперь система начнет использовать swap только в том случае, если свободной ОЗУ останется меньше 10%. В Ubuntu, например, значение swappiness по умолчанию — 60. Чтобы значение не менялось после ребута, не забудь добавить его в /etc/sysctl.conf.
3. Добавить ОЗУ. Часто проблема возникает при активном использовании swap.
4. В некоторых случаях помогает смена ядра на что-нибудь старше 2.6.17 или новее 2.6.34.
К слову, я сам несколько раз видел 12309, но только на ядрах < 2.6.35. Иногда глюк проявляется только при копировании на USB-носитель.

Самый-самый

Самый важный баг зарегистрирован под гордым первым номером в багтрекере Ubuntu, bugs.launchpad.net, 20 августа 2004 и называется «Microsoft has a majority market share». Авторство принадлежит Марку Шаттлворту. Мой вольный перевод описания: «У Microsoft доминирующее положение на рынке десктопов. Ubuntu создана для того, чтобы пофиксить этот баг. Закрытое ПО сдерживает инновации в IT-отрасли, ограничивает доступ к IT для небольшого процента мирового населения и не позволяет разработчикам во всем мире в полной мере реализовывать свой потенциал. Этот баг очень широко распространен.
Способ воспроизведения бага: Посетить компьютерный магазин в своем районе.
Что мы там увидим:
  1. Большинство ПК продается с предустановленным закрытым ПО.
  2. Очень небольшая доля ПК продается с предустановленной Ubuntu и/или другим свободным ПО.
Что должны будем увидеть:
  1. Большинство новых компьютеров должны включать только свободное программное обеспечение — например Ubuntu.
  2. Ubuntu должна продвигаться таким образом, чтобы ее удивительные возможности и преимущества были очевидны и известны всем.
  3. С течением времени система должна становиться все более и более дружественной пользователю.»
Странно, что на момент написания статьи этот баг затрагивает всего 619 человек, однако имеет 1500 комментариев. Будем с нетерпением ждать фикса :).

Заключение

Да, в больших OpenSource проектах много багов. Но и в больших проектах с закрытыми исходниками их не меньше — просто не всегда они доступны широкой общественности. Большое преимущество OpenSource здесь в том, что при желании ты сам можешь провести аудит кода и поправить любой баг.

Links

  • Подробности про баг с доступом к каталогу в BSD: goo.gl/qH316;
  • Ping of Death в OpenBSD: goo.gl/uHoCj;
  • Описание планировщиков вводавывода в Linux: goo.gl/LJ2B1.

ADSL модем + роутер

Чаще всего Wi-Fi-роутер с ADSL-модемом приходится связывать владельцам модемов типа D-Link 2500 - у которых есть только один Ehernet-порт (разъем). Пока дома был один компьютер - модем замечательно справлялся со своей задачей. Но после появления какого-нибудь Wi-Fi устройства (телефон, коммуникатор, ноутбук, планшет и пр.), хочется это устройство “выпустить” в интернет и здесь уже одного модема не хватает. Решений есть несколько, но очень многие выбирают именно вариант покупки Wi-Fi-роутера. Настроить получается не у всех, поэтому большинство ищет решение в интернете, некоторые находят мой сайт и интересуются как настроить выход в интернет с помощью ADSL-модема и Wi-Fi-роутера.
Итак, способ первый.
Сначала нужно настроить модем на работу в режиме бриджа. Настройка модема будет немного отличаться для разных моделей и разных провайдеров. Для примера настраиваю модем D-Link DSL-2640U для провайдера Укртелеком (услуга ОГО!). Подключаем модем к компьютеру с помощью кабеля который шел в комплекте с модемом. Сетевая карта должна быть настроена на автоматическое получение сетевых настроек (IP-адреса). После получения IP-адреса, заходим в web-интерфейс, выбираем пункт Advanced Setup - WAN, нажимаем на кнопку Add и заполняем параметры как на рисунке ниже (это параметры для провайдера Укртелеком, услуга ОГО! - для вашего провайдера они могут отличаться):
Настройка ADSL модема в режиме бриджа
Нажимаем на кнопку Next и заполняем далее:
Как настроить модем в режиме бриджа
Нажимаем кнопку Next:
Настройка модема в режиме бриджа для ОГО!
Нажимаем кнопку Save:
Завершение настройки режима бриджа
Затем нажимаем на кнопку Save/Reboot и ждем пока модем перезагрузится. После перезагрузки модем должен настроится на работу с оборудованием провайдера. Об успешной настройке можно судить либо по индикатору DSL (который должен гореть постоянно), либо по стартовой странице web-интерфейса:
ADSL модем работает в режиме бриджа для ОГО!
Если есть ненулевые значения у параметров Line Rate, значит модем и оборудование провайдера настроилось на совместную работу. Перед тем как индикатор DSL будет гореть постоянно, может пройти какое-то время (в этом время индикатор будет мигать), как правило, не превышающее двух минут.
Еще раз подчеркиваю, что любой другой ADSL-модем таким же образом настраивается на работу в режиме бриджа.
Считаем, что оборудование связалось, DSL горит и можно двигаться дальше - настраивать роутер.
Отсоединяем патч-корд от ADSL-модема и подключаем его к роутеру в любой LAN-порт. После этого желательно выполнить в командной строке команду ipconfig /renew (для ОС Windows), для того чтобы компьютер получил новый IP-адрес от DHCP-сервера роутера. Далее заходим в web-интерфейс роутера (напомню, что речь идет о модели DIR-130), открываем раздел SETUP - Internet и нажимаем на кнопку Manual Configure:
Настройка роутера D-Link Dir-130 для ОГО
Далее прописываем логин и пароль, которые выдал Укртелеком:
Настройка dir-130 для ОГО!
и нажимаем на кнопку Save Settings.
После этого подключаем роутер к модему так как на рисунке:
Как подключить роутер к ADSL-модему
Модем на рисунке - слева, а роутер - справа. Соединяем порт роутера с надписью Internet c LAN-портом модема. На рисунке эти порты соединены патч-кордом синего цвета. Таким образом получается связка ADSL-модем - роутер - компьютер. После того как роутер пройдет аутентификацию и получит сетевые настройки от провайдера можно будет выходить в сеть Интернет.
При такой схеме подключения DIR-130 является тем устройством которое получает внешний IP-адрес от провайдера (в данном случае от Укртелекома) и “раздает” интернет всем устройствам которые подключены к его LAN-портам. Если бы на его месте был Wi-Fi-роутер, то достаточно было бы настроить в нем Wi-Fi-сеть, и доступ в интернет получали бы все Wi-Fi-устройства в доме.

Размер Ubuntu 12.04 увеличен до 750 МБ

Размер дистрибутива Ubuntu 12.04 Precise Pangolin теперь будет равен 750 МБ, что больше не позволит записывать его на обычный CD-R диск, но можно будет воспользоваться DVD диском или USB накопителем размером в 1 ГБ.

Скорее всего включение дополнительных 50МБ станет переходным этапом, а к следующим релизам он и вовсе может дойти до 1,5 ГБ.
Официальный ответ из обсуждения на саммите звучит просто:
Новый размер в 750 МБ, теперь ориентирован на использование USB (или DVD) вместо CD дисков.
Зато увеличение размера дистрибутива позволит вместить больше различных GNOME3 компонентов и других приложений.

Концепт бесконечной флешки

Миниатюрные USB-накопители, называемые в повседневной речи флешками, являются одним из крупнейших открытий за последние годы, они предельно компактны, удобны и универсальны. Конечно, большим недостатком является их ограниченный объем памяти, иной раз не хватает совсем чуть-чуть, тогда флешку приходится извлекать и вставлять вместо нее вторую. Лишние действия.

LG

Любопытный вариант предложил в своем концепте португальский дизайнер Педро Мачадо (Pedro Machado), он разработал концепт флешки, озаглавленный Endless Storage то есть «бесконечный накопитель». Идея автора предельно проста: флешка является еще и USB-концентратором с одним разъемом. Как только на первой кончается свободное место, пользователь прямо к ней подключает вторую, ко второй третью, и так далее до бесконечности. А для солидности автор начертал на корпусе флешки логотип LG.

LG

Не верх комфорта, конечно, но все же удобнее, чем постоянно подключать то один, то другой накопитель. В данном концепте нет ничего технически невозможного, однако на практике каждый последующий накопитель будет распознаваться компьютером как отдельный диск, хотя намного удобнее было бы пользоваться единым дисковым пространством. Это сделало бы Endless Storage не только забавной игрушкой, но еще и действительно удобным средством хранения данных.

LG