LibRaw 0.17-Alpha3 и 0.16.1

Один очень хороший человек взялся аудитить LibRaw, большое ему спасибо. С его помощью нашлось одно плохое место в разборе Makernotes (и была выпущена LibRaw 0.17-Alpha2, старые стабильные версии этим затронуты не были).

Но он не остановился и докопался до Dave Coffin, в результате чего:

  1. Сегодня выйдет advisory c большим списком затронутых проектов.
  2. LibRaw уже исправлена:

Чтобы огрести эту ошибку - нужен специально подготовленный (либо битый) RAW. Шансов столкнуться с ней в реальности со своими файлами - примерно ноль (ну и не страшно, в случае своих файлов - это будет битый RAW со случайными данными, от них в худшем случае все упадет).  Если же вы разбираете равчики, которые любой может вам залить (как это делают всяки сервисы хранения данных с целью показа превьюшек) - у вас могут быть проблемы, когда вам начнут заливать специально подготовленные файлы и гадить на стек.

Comments

Слуууушай, я тут подумал. Есть такая штука AFL -- American Fuzzy Lop, очень хороший и умный фаззер.

Я могу его погонять на dcraw-сделанном-из-libraw, но ему нужны исходные данные, которые он будет мутировать по итогам анализа поведения программы под тестом. А у меня только DNG от разных пентаксов. Я начну с них, но где вообще всякие RAW брать? Вот была бы пачка "по два RAW с каждой поддерживаемой камеры" -- это вообще волшебно было бы.

imaging-resource.com
photographyblog.com
dpreview.com (их компаратор)
Ну и по мелочи бывает.

В общем, запустил на трёх файлах от трёх пентаксов (пока) drcaw_emu с дефолтовыми ключами.
Правда, afl очень недоволен скоростью 0.55 итераций/сек и размером тесткейсов :)
Надо вообще сделать программку, которая делает тот же дефолтовый dcraw_emu но без записи на диск. Это существенно должно сократить!

Там есть mem-image, оторви ему запись на диск. Это проще всего.

И, кстати, демозаику (dcraw_process()) тоже можно оторвать. Оставить open_file, unpack и все.

Угу, сейчас оторву. И исходники на ram-Вшыл положу ещё. Будем выжимать максимум.

Вот, 1-1.5 вызова в секунду.

Это i7-950

Всё равно не ясно а чо так медленно. По top'у там idle time -- 85%. Или это просто оно не успевает реагировать на быстропомирающие процессы?

Я ж не вижу отсюда что ты делаешь.

Распаковка raw - в один поток в любом случае (и с ljpeg нет другого пути), постпроцессинг в несколько - только если OpenMP (привет clang!)

В общем, запустил 4 в параллель, благо afl умеет. Работает...

Крееееешится! :)
Я пару суток погоняю и соберу все входные файлы, на которых крешится.
В целом, находятся файлики похожие на DNG, по 100 килобайт плюс-минус на которых read + unpack крешатся.

Отлично же!

Ага! Я вот добавил в seeds по одному RAW со свежих никон, кенон, панаосник, фуджи, сони, самсунг, олик (просто последние рассмотренные на photographyblog). Пусть пашет. Потом соберу архив.

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

Смотри тут какая история. Есть чтение метаданных (open_file), есть распаковка raw (unpack())
Распаковка, на самом деле, штука простая. Их разных много (там штук 20 декодеров), но они почти все легко обозримые глазом.

Если скорость работы конструкции (под мутатором) играет роль, можно разнообразие создать убрав unpack(), оставив только open_file().

Это, на самом деле, сильно важнее unpack() - потому что и код разбора сложнее (и сильно более Ad hoc) и разнообразие данных больше и вероятность получить их помятыми - тоже больше, на самом деле.

Надо самому стенд такой поднять, пусть NAS работает!

У меня явно всё упирается в диск. Засрал RAM-диск до OOM-киллера, перешёл на обычный обратно, скорость упала вдвое.

Но за ночь 8 потоков там уже ещё 14 крешей намутатили.

Стенд поднимается очень просто:

(1) Собираем последий afl (security/afl на FreeBSD, но там не последний, но я подправил версию в порте, надо бы закоммитить). Тут одна тонкость: после конфигурирования но до сборки надо вручную поправить config.h на предмет MAX_FILE, там смехотворный размер, надо вкрутить 64 мегабайта, например.

(2) Делаем

CC=/path/to/afl-{gcc|clang} CXX=/path/to/afl-{g|clang}++ ./configure && [g]make для вашей альфы

Я ещё на этом этапе оторвал процессинг и, главное, сохранение у mem_image, сразу после unpack -- reset и конец цикла.

(3) Готовим сколько-нибудь RAW'вчиков для затравки в каталоге, скажем, "data" (имя не важно).

(4) Делаем каталог "out" (имя тоже произвольное)

(5) 1 раз запускаем (под screen/tmux, не забываем LD_LIBRARY_PATH указать в место с только что собранной библиотекой самой, что бы она была инструментированная а не из системы)

afl-fuzz -i ${datadir} -o ${outdir} -t 120000 -M fuzzer00 ./LibRaw-0.17.0-Alpha3/bin/.libs/mem_image @@

(6) NCPU-1 раз запускаем (меняя параметр -S что бы у всех было разное имя)

afl-fuzz -i {datadir} -o ${outdir} -t 120000 -S fuzzerXX ./LibRaw-0.17.0-Alpha3/bin/.libs/mem_image @@

(7) Ждём N суток, иногда запуская "afl-whatsup ${outdir}" что бы видеть общий статус (ну или смотрим по окошкам на экземпляры глазами).

(8) Инпуты, приведшие к крешам ищем в ${outdir}/*/crashes/

Вот значит я с FRV закончил, часть детей выгнал к бабушке и буду рад этим злым файлам.

Сам AFL не поднимал еще, не до того было.

У меня ещё цикл далёк от завершения, но сейчас выложу всё что уже нашлось.
Имена файлов будут так себе :)

От 8 потоков результаты тут: http://lev.serebryakov.spb.ru/_sklad/libraw-alpha-afl-results.txz

*/crashes — падал mem_image
*/hangs — не мог за 2 минуты загрузить

ЛОКАЛЬНО они уникальны (в рамках одного фаззера) по путям исполнения, а вот между ними уникальность, увы, не гарантирована.

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

В общем, развлекайтесь :)
Отличная штука этот afl, даже обидно, что я нейтив-кода уже давно не пишу :)

Ага, третья - это rwidth + 8, при том что rwidth - в районе 65535 и unsigned short.
Штука прекрасная, да.

То есть баги в LibRaw нормальному юзеру (со своими фоточками) не страшны, но вот стоит ее поставить куда-то на веб-сервис, так будет веселуха.

Угу. Как только оно торчит наружу, так сразу всё это становится очень неприятным.

Если я не обсчитался, то всего 6 багов. Три наших, три Коффиновских.
Будешь продолжать - бери Альфу4 отсюда: http://www.libraw.org/download

Оно пока не анонсировано т.к. надо часть этих багфиксов загнать в 0.16, вечером сделаю и анонсирую обе две сразу.

Там и в alpha4е что-то находится уже :)

Ну и отлично.

Там вот для меня мутный вопрос (на тему "как правильно") - это битые теги EXIF/TIFF(/Makernotes для тех, у кого makernotes в этом же формате).
Вот два примера:
1) Тег указывает за пределы текущего файла (текущая позиция + offset - в космос). Казалось бы, битый файл, его не надо принимать, однако у Лейки половина файлов такая (а у второй половины - кажет в космос, но внутрь файла попадает). Вот скандал с Apple Photos и Leica Typ 246 - скорее всего ровно из этой области.
2) Тег корректный, но невдолбенная длина, которой у данного тега быть не должно.

Эти две штуки мешают отрезать некорректное сразу, всякие условия по длине тега приходится ставить по месту, а мест - много.

Я ещё вижу проблему в том, что там после полутора недель работы в 8 ядер покрытие — 9%. Понятно почему — seed'ом служат 8 файлов из скольки там форматов, которые поддерживаются? Штук 50 заметно разных ведь наберётся?

Оно фрактальное, в каждом месте - БЕЗДНЫ. Если вдаться на первый уровень, то

  • метаданные: основное количество EXIF, но есть некоторое количество отдельно стоящих (Foveon, .mos, внешний JPEG)
    • следующий уровень фрактала: DNG-файлы, конвертированные из не-DNG, разными версиями конвертора Adobe с сильно разными приколами
  • распаковщики, не помню сколько, но штук 25 их вроде есть. 8 файлов покрывают, понятно, не более 8 (я тут не ожидаю особых траблов, хотя вот зацикленный ljpeg_start уже поправили)
  • постпроцессинг базовый (демозаика и помимо нее)
  • - постпроцессинг расширенный (HL recovery, коррекция всякой разной фигни)

Последние два твои тесты вовсе не трогают. А там могут быть свои приколы, вроде вынутого из камеры кривой матрицы color space которая, к примеру, не инвертируется (и никто этого не проверяет)

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

UPD: вот у Canon с десяток версий Makernotes (это байтовый массив, одни и те же данные лежат с разными смешениями). Интересно, оно мутировало их в разные варианты, али по одному пути ходим.

А вот ещё дофига всего на alpha4

http://lev.serebryakov.spb.ru/_sklad/libraw-alpha4-afl-results.txz

Спасибо.
Скачал, можно удалять. Когда заниматься буду - пока не знаю.

Альфа, впрочем, просто имеет кривой configure который добавляет -lstdc++ при попытке собрать clang'ом. Которого, конечно, нет.

Вообще, отлаживать autotools -- это тот ещё ад. Увы, они создают проблем больше, чем решают :(

Ну то есть, FreeBSD 10.1/amd64, вот так оно не собирается.
В портах на это есть затычка

${REINPLACE_CMD} -e "s/-lstdc++//g" ${WRKSRC}/configure

Не ожидал лично от тебя, да :)

Ну этот фикс, увы, негодящий, я не могу такую ./configure положить в дистрибутив.
Придет port maintainer, сделает что-нибудь
(сам я, естественно, не пользуюсь ./configure)

port maintainer вот и сделал.

Вопрос: почему ему вообще пришлось это сделать, почему там есть такие хардкоды а не соотвествующие макросы в configure.ac, которые всё проверят и добавят если есть и если надо?

Потому что он поленился заслать патч?

Мое отношение к LibRaw достаточно утилитарное, проект развивается
а) так как надо мне
б) все патчи беру без звука (если они разумные)
в) сам для кого-то еще - вообще ничего не делаю.

Ну, мейнетейнер тоже утилитарен -- ему проще поправить configure прямо и тупо ровно под свою платформу, а не разбираться с autocrap :) Но этот патч вам, очевидно, не годится.

Ох, это у вас прямо написано про LIBS="-lm -lstdc++". Да что де это вы такое делаете-то! Используете систему, которая по идее (!) должна узнавать что вам надо и как оно зовётся на данной платформе а потом сверху вот так, с размаху.

Зашли патч, включу в 0.17 без звука.
Оно все user contributed

Вот так вот вроде-бы open-source разработка переключается на "вам надо - делайте" style.

PS: Nothing personal, just Vodka inside ;(

Некротред ожил!

За прошедший отчетный период не только "кому надо - тот и делает", там еще и подропали системы сборки, которые не можем/не хотим поддерживать (Cmake, к примеру).

А почему? А потому что конкуренции нет, что хотим, то и воротим.

Да понятно, что что хотите, то и ворошите. Просто выглядит странненько.

Кормить в пути никто не обещал!

Я заглянул (вот прям ща) в google://llvm autoconf libc++, готового рецепта не увидел и опять успокоился.
Кому вдруг надо - тот пусть и.

Любые автоматические средства конфигурирования создают массу проблем.
Я бы их вообще бы истребил (в смысле, из LibRaw), но народ не поймет.
Cmake, впрочем, истребил тут недавно.

imake был хорош. Но где тот imake? :(

а нельзя ли бинарники примеров тоже для apha релизов положить ?

Z / V

Я альфу не собираю (потому и держу подольше альфой), гемороя много.

Но конкретный 1 (из 4) - соберу, скажите какой.

> Но конкретный 1 (из 4) - соберу, скажите какой.

win64/32, я конечно и сам могу - но если для вас это минута то для меня мб час (ибо не тот профиль)

Z / V

С демозаик-паками или AHD хватит?

С демозаиком это не минута, там demosaic_packs.cpp компилятор жует минут 10.

> это не минута

я имел ввиду не длительность компиляции конечно же, а борьбу с тем что make с первого раза не заведется же наверное Ё-)

Z / V

nmake -f Makefile.msvc вообще-то работает, я так и собираю под винду.

(соберу минут через 20, стиральную машину только на место верну)

> nmake -f Makefile.msvc вообще-то работает, я так и собираю под винду.

я тут после 2-3 летнего перерыва что-то собирал сам, так 30+ минут ушло чтобы понять что "rb/wb" флаги в fopen на windows не использованы в и посему в dcp профили пишется лишний байт (много раз)... а в ведь знал же ! поэтому подозреваю что у меня так быстро не заработает... даже если код в вашем случае вылизан под

Z / V

Ну вот конкретно это место - работает. Потому что сам использую.

А ./configure, как заметили выше, не работает. Или, точнее, работает не везде. По аналогичной (анти)причине. И тронуть страшно - уберешь -lstdc++ - обязательно где-то сломается же.

любой

Z / V

https://www.dropbox.com/s/ujydsqqrk7axaua/LibRaw-017A3-Winx64.zip?dl=0

Несколько дней пролежит.

Собиралось под Win8.1, компилятор VisualStudio 2010, скорее всего оно хочет от этого компилятора рантайм, его берут тут: https://www.microsoft.com/en-us/download/details.aspx?id=14632

Или можно готовые DLL-ки от RawDigger x64 (в смысле - они там точно есть) подсунуть, вот эти: msvcp100.dll msvcr100.dll

спасибо !

Z / V

"Шансов столкнуться с ней в реальности со своими файлами - примерно ноль"
Вот за это я Вас и ценю!
Респект.