С патчами мы сталкиваемся не так часто, но и не так редко. В этой статье мы научимся патчить и создавать патчи. Патчить на самом деле легче, чем можно себе представить.
1) Учимся патчить.
Патчить будем на примере уязвимости для FreeBSD (http://www.securitylab.ru/vulnerability/368343.php). Качаем оттуда патч (wget http://security.FreeBSD.org/patches/SA-09:05/telnetd.patch). После этого нужно выяснить, куда же его положить, что бы патч прошёл успешно. Для этого можно вывести на экран первые несколько строк:
Index: contrib/telnet/telnetd/sys_term.c
===================================================================
--- contrib/telnet/telnetd/sys_term.c (revision 188667)
+++ contrib/telnet/telnetd/sys_term.c (working copy)
@@ -1271,8 +1271,18 @@
Смотрим внимательно и видим, какой файл он патчит. Поскольку путь начинается с contrib/telnetто можно предполодить, что файл должен находится в папке /usr/src. Копируем его туда и пробуем патчить:
#patch < telnetd.patch
Если после этого у вас на экран вывелось похожее на то, что ниже – значит всё удалось. Обычно стоит прочесть, вывод и удостоверится, что всё прошло succeed:
Hmm... Looks like a new-style context diff to me...
The text leading up to this was:
--------------------------
|*** ../convert.sh Fri Dec 5 17:00:52 2008
|--- convert.sh Sat Apr 11 13:52:43 2009
--------------------------
Patching file convert.sh using Plan A...
Hunk #1 succeeded at 6.
done
Если вдруг патчу не удаётся найти нужный файл, он выдаёт запрос на указания пути вручную:
Hmm... Looks like a new-style context diff to me...
The text leading up to this was:
--------------------------
|*** convert1.sh Sat Apr 11 13:40:58 2009
|--- convert.sh Fri Dec 5 17:00:52 2008
--------------------------
File to patch:
после введения пути:
File to patch: ../convert.sh
Patching file ../convert.sh using Plan A...
Reversed (or previously applied) patch detected! Assume -R?
Hunk #1 succeeded at 6.
done
Хочу заметить, что утилита patch имеет так же параметры, которые можно использовать. Например, довольно позным может оказаться ключ -C (–check), который позволяет посмотреть, какие изменения будут произведены с файлом, но не пропатчит.
2) Создание патчей.
– обычный
Создание патчей происходит немного сложнее, чем патчить. Для этого берём 2 версии одного и того же файла, помещаем их в разные директории, называем одинаково. После этого будем пользоваться командой diff для выявления разницы между файлами. Здесь самое главное соблюсти порядок в котором подаются имена файлов. ИСХОДНЫЙ_ФАЙЛ – эталонный файл, ИЗМЕНЁННЫЙ_ФАЙЛ – файл, который содержит изменения.
$diff -u ИСХОДНЫЙ_ФАЙЛ ИЗМЕНЁННЫЙ_ФАЙЛ > file.patch
где -u – означает унифицированный вывод, то есть с —/+++.
После такой операции будет создан файл file.patch, который собственно будет патчем. Файл патча можно так же открыть в текстовом редакторе и подредактировать пути к файлам, если необходимо.
Вот это и всё. Если хотите большего функционала – читайте man к указанным здесь бинарникам.
– через svn
Расскажу на примере коммита . Это исправление не вышло в качестве патча, зато вошло в коммит 269687. Наша идея такова: делаем diff между 2-мя соседними (нашим 269687 и предыдущим 269686) коммитами и накладываем патч:
# svn diff -r269686:269687 svn://svn.freebsd.org/base/stable/9 > /path/to/openssl.patch
# cd /usr/src && patch < /path/to/openssl.patch
Оригинал статьи здесь.
Опубликовано с разрешения редакции журнала RootUA и газеты FOSS News