среда, 9 ноября 2011 г.

Интересные баги в *nix’ах, бег на месте?




По данным Гугла, на сегодня есть приблизительно 31 000 000 OPENSOURCE-проектов, которые суммарно содержат возле 2 000 000 000 строк кода. Конечно, что в таком числе исходников - миллионы багов, описанные в тысячах багтрекеров. Однако не все ошибки одинаково интересны - я расскажу о наиболее известных.

Наиболее старый


Начну обзор с наиболее старых багов, которые не фиксились длительные годы: или о них никто не знал, или они никому не были интересны. I баг из этой категории практически отпраздновал свои 30 лет, когда его пофиксили. Вероятнее всего, этот жук закрался еще в 4.1BSD (а может, и еще ранее), откуда успешно перекочевал уже во все современные BSD-системы. Он проявил себя в новых релизах Samba - сервер падал при попытке доступа к каталогу. Имя героя, откопавшего старинный баг еще в сер. 2008 г., - Марк Балмер. Сперва Марк винил во всем новый релиз Samba, однако позже отыскал баг в OPENBSD’шной библиотеке libc (если быть точным, в файлах lib/libc/gen/{readdir.c,telldir.c}, отвечающих за доступ к каталогам). Ошибку нельзя было обнаружить с более ранними версиями Samba из-за специального костыля, который в новых релизах по какой-то причине убрали. Выяснилось, что баг затрагивал все современные BSD-системы, в частности и Mac OS X.



Следующему багу, пожалуй, возможно вручить чемпионский титул бага-долгожителя. Целых 33 г. о нем никто не подозревал. За нахождение и ликвидацию ошибки так сказать спасибо 2-м людям - Отто Мёрбеку и Николаю Штурму. Эта история случилась к тому же в сер. 2008. Отто Мёрбек работал над новой реализацией malloc в OPENBSD, а Николай Штурм тестировал код. В итоге тестирования на платформе sparc64 было обнаружено, что время от времени компиляция крупного C++ проекта может кончаться с ошибкой Internal Compiler Error. Мёрбек начал искать причину этой трудности и нашел переполнение буфера в генераторе синтаксических парсеров yacc(1): в файле skeleton.c, в функции yyparse(), происходило обращение к несуществующему элементу массива.

Для OPENBSD Отто выпустил шестистрочный патч, исправляющий данную проблему. Вероятнее всего (за давностью лет точно заявить уже трудно), баг берет свое старт приблизительно с UNIX V6 (который был выпущен в мае 1975) или UNIX V7.

Наиболее бестолковый



I претендент на эту номнацию - GRUB2, в версии 1.97 которого был обнаружен баг, дающий возможность весьма просто подобрать пароль на загрузчик. Смысл ошибки в том, что для ввода пароля необязательно знать весь пароль полностью - GRUB’у было довольно как минимум его части. К примеру, если пароль - xakep, то довольно было ввести "xake", "xak", "xa" или даже просто "x". Так, подобрать каждый пароль возможно было, просто подобрав I знак. Баг был быстренько пофиксен в новой версии 1.97.1.

Следующий участник - Ping of Death в OPENBSD Packet Filter (CVE-2009-0687), был обнаружен 9 апреля 2009 г. и исправлен спустя 2 дня. Как возможно понять из наименования, ошибка заключалась в возможности вызвать kernel panic при помощи специально сформированного пакета. Не то чтоб баг сам по себе весьма бестолковый.

Просто тот факт, что OPENBSD возможно вот так запросто положить одним пингом - нонсенс и более похоже на первоапрельскую шутку. Уязвимы были все версии OPENBSD с pf вплоть до 4.5, на всех архитектурах, и NETBSD 5.0 RC3. При этом, никаких особых эксплоитов не необходимо, довольно сделать:

nmap -So $target_IP

или

hping -0 -H 58 $target_IP

К слову заявить, это не I-я уязвимость такого рода в OPENBSD, просто на моей памяти наиболее широко распространенная. Например, в 2005 г. из-за ошибки в драйвере беспроводного адаптера ral(4) при использовании IPSEC ОС также паниковала, однако уже от самого обычного пинга - довольно было отослать 2 эхо-запроса. Прим. ред.: сам себя не похвалишь, никто не узнает - этот баг был обнаружен мной в ходе настройки домашнего Wi-Fi.

После исследования трудности я отослал разработчикам детальное описание сценария, при коем появляется remote crash, конфиги pf.conf, isakmpd.conf и isakmpd.policy, и traceback ядра, полученный при помощи отладчика ddb(4). Тео де Раадту и команде понадобилось 3 с половиной мес., чтоб странить эту брешь. И, наконец, чемпион в номинации "Наиболее бестолковый" - глюк в прошивке I-го Android-телефона HTC G1. Выяснилось, что все нажатия клавиш переадресовывались в рутовую консоль.

То есть, к примеру, набрал ты в SMS слово "reboot", а позже , и весьма изумился, что телефон послушался и ушел в ребут. А ведь возможно и что пострашнее набрать! Ан нет худа без добра - при помощи этой ошибки на G1 возможно было просто поставить Debian. Эх, подобный баг пофиксили! :)

Наиболее "металлический"





Ни для кого не секрет, что баги в ПО могут выводить из строя железо. Неплохо, что встречаются подобные ошибки весьма нечасто, а широкое распространение получают еще реже. Наиболее скандальный (а вероятнее, просто раздутый) за последнее время баг подобного типа - "Убунту убивает ноутбучные винты".

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

И Убунту все верно делала - останавливала винт, когда он был не нужен. Вот лишь на некоторых моделях это происходило неоднократно - отчасти по вине прошивки самого винта. С огромной долей вероятности на этих моделях наблюдалась бы частая парковка головок под каждый ОС. Поглядеть, подвержен ли твой винт такому багу, возможно так. Ставим пакет 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, там предлагается несколько возможных решений.

И еще 1 достаточно свежий баг, связанный с железом. Правда, к OPENSOURCE он не имеет особого отношения. Разве что тот факт, что он к тому же проявляется и на *nix-системах. Речь пойдет о закрытых драйверах от Nvidia. Весной 2010 г. на официальном веб-сайте возникли новые версии драйверов - 196.75 и 195.36.
Спустя некоторое время пользователи начали сообщать о выходящих из строя видеокартах. Выяснилось, что в новые драйвера закралась ошибка, которая время от времени приводила к полному выключению или понижению до минимума скорости вращения вентилятора видеоадаптера, невзирая на сильный нагрев видеоядра. После обнаружения бага новые версии дров были спешно убраны с сайта, а всем пользователям было рекомендовано откатиться до старых версий.





БОНУС - 5 Gb "облачного" хранилища free неограниченное время!

Комментариев нет:

Отправить комментарий