
Исходное дерево ядра Linux 4.1.15 с патчами для CVE-2023-28772, предоставляющее справочную информацию для анализа уязвимостей и исследований по эксплуатации.
Выпуск ядра Linux 4.x http://kernel.org/
Это примечания к выпуску для Linux версии 4. Внимательно прочитайте их, так как они рассказывают, что это такое, объясняют, как установить ядро, и что делать, если что-то пошло не так.
ЧТО ТАКОЕ LINUX?
Linux — это клон операционной системы Unix, написанный с нуля Линусом Торвальдсом при помощи слабо связанной команды хакеров со всего Интернета. Он стремится к соответствию стандартам POSIX и Single UNIX Specification.
Он обладает всеми функциями, которые можно ожидать от современной полноценной Unix, включая истинную многозадачность, виртуальную память, разделяемые библиотеки, подкачку по требованию, разделяемые исполняемые файлы с копированием при записи, правильное управление памятью и многостековую сеть, включающую IPv4 и IPv6.
Он распространяется под лицензией GNU General Public License — подробности см. в прилагаемом файле COPYING.
НА КАКОМ ОБОРУДОВАНИИ ОН РАБОТАЕТ?
Хотя изначально разрабатывался для 32-битных ПК на базе x86 (386 или выше), сегодня Linux также работает (как минимум) на архитектурах Compaq Alpha AXP, Sun SPARC и UltraSPARC, Motorola 68000, PowerPC, PowerPC64, ARM, Hitachi SuperH, Cell, IBM S/390, MIPS, HP PA-RISC, Intel IA-64, DEC VAX, AMD x86-64, AXIS CRIS, Xtensa, Tilera TILE, AVR32 и Renesas M32R.
Linux легко портируется на большинство 32- или 64-битных архитектур общего назначения при условии наличия страничного блока управления памятью (PMMU) и порта компилятора GNU C (gcc) (часть набора компиляторов GNU, GCC). Linux также портирован на ряд архитектур без PMMU, хотя функциональность в этом случае, очевидно, несколько ограничена. Linux также портирован на самого себя. Теперь можно запускать ядро как приложение пользовательского пространства — это называется UserMode Linux (UML).
ДОКУМЕНТАЦИЯ:
Существует много документации, доступной как в электронном виде в Интернете, так и в книгах, как специфичной для Linux, так и касающейся общих вопросов UNIX. Я рекомендую заглянуть в подкаталоги документации на любом FTP-сайте Linux для книг LDP (Linux Documentation Project). Этот README не предназначен для документации по системе: есть гораздо более качественные источники.
В подкаталоге Documentation/ находятся различные файлы README: они обычно содержат специфические для ядра заметки по установке, например, для некоторых драйверов. Смотрите Documentation/00-INDEX для списка того, что содержится в каждом файле. Пожалуйста, прочитайте файл Changes, так как он содержит информацию о проблемах, которые могут возникнуть при обновлении ядра.
Подкаталог Documentation/DocBook/ содержит несколько руководств для разработчиков и пользователей ядра. Эти руководства могут быть отображены в различных форматах: PostScript (.ps), PDF, HTML и man-страницы, среди прочих. После установки команды "make psdocs", "make pdfdocs", "make htmldocs" или "make mandocs" отобразят документацию в запрошенном формате.
УСТАНОВКА исходных кодов ядра:
Если вы устанавливаете полные исходники, поместите tarball ядра в каталог, где у вас есть права (например, ваш домашний каталог), и распакуйте его:
xz -cd linux-4.X.tar.xz | tar xvf -
Замените "X" на номер версии последнего ядра.
НЕ используйте область /usr/src/linux! В этой области находится (обычно неполный) набор заголовков ядра, которые используются заголовочными файлами библиотек. Они должны соответствовать библиотеке и не должны портиться тем, чем бы ни оказалось ядро дня.
Вы также можете обновляться между выпусками 4.x с помощью патчей. Патчи распространяются в формате xz. Чтобы установить с помощью патча, получите все новые файлы патчей, войдите в верхний каталог исходного кода ядра (linux-4.X) и выполните:
xz -cd ../patch-4.x.xz | patch -p1
Замените "x" для всех версий, больших, чем версия "X" вашего текущего дерева исходников, по порядку, и у вас всё должно получиться. Возможно, вы захотите удалить резервные файлы (some-file-name~ или some-file-name.orig) и убедиться, что нет неудачных патчей (some-file-name# или some-file-name.rej). Если они есть, значит, либо вы, либо я допустили ошибку.
В отличие от патчей для ядер 4.x, патчи для ядер 4.x.y (также известные как -stable ядра) не являются инкрементальными, а применяются непосредственно к базовому ядру 4.x. Например, если ваше базовое ядро — 4.0, и вы хотите применить патч 4.0.3, вы не должны сначала применять патчи 4.0.1 и 4.0.2. Аналогично, если у вас работает версия ядра 4.0.2, и вы хотите перейти на 4.0.3, вы должны сначала отменить патч 4.0.2 (то есть patch -R) перед применением патча 4.0.3. Подробнее об этом можно прочитать в Documentation/applying-patches.txt
Альтернативно, сценарий patch-kernel может быть использован для автоматизации этого процесса. Он определяет текущую версию ядра и применяет все найденные патчи.
linux/scripts/patch-kernel linux
Первый аргумент в команде выше — это расположение исходного кода ядра. Патчи применяются из текущего каталога, но альтернативный каталог может быть указан вторым аргументом.
Убедитесь, что у вас нет устаревших файлов .o и зависимостей:
cd linux make mrproper
Теперь исходники должны быть правильно установлены.
ТРЕБОВАНИЯ К ПРОГРАММНОМУ ОБЕСПЕЧЕНИЮ
Компиляция и запуск ядер 4.x требует актуальных версий различных программных пакетов. Обратитесь к Documentation/Changes для получения минимальных номеров версий и инструкций по обновлению этих пакетов. Имейте в виду, что использование чрезмерно старых версий этих пакетов может вызвать косвенные ошибки, которые очень трудно отследить, поэтому не предполагайте, что вы можете просто обновить пакеты, когда очевидные проблемы возникают во время сборки или работы.
КАТАЛОГ СБОРКИ для ядра:
При компиляции ядра все выходные файлы по умолчанию будут храниться вместе с исходным кодом ядра. Использование опции "make O=output/dir" позволяет указать альтернативное место для выходных файлов (включая .config). Пример:
исходный код ядра: /usr/src/linux-4.X
каталог сборки: /home/name/build/kernel
Для настройки и сборки ядра используйте:
cd /usr/src/linux-4.X
make O=/home/name/build/kernel menuconfig
make O=/home/name/build/kernel
sudo make O=/home/name/build/kernel modules_install install
Пожалуйста, обратите внимание: если используется опция 'O=output/dir', она должна использоваться для всех вызовов make.
НАСТРОЙКА ядра:
Не пропускайте этот шаг, даже если вы обновляетесь всего на одну минорную версию. Новые параметры конфигурации добавляются в каждом выпуске, и могут возникнуть странные проблемы, если файлы конфигурации не настроены должным образом. Если вы хотите перенести существующую конфигурацию на новую версию с минимальными усилиями, используйте "make oldconfig", который задаст вам только ответы на новые вопросы.
Альтернативные команды настройки:
"make config" Обычный текстовый интерфейс.
"make menuconfig" Текстовые цветные меню, радиосписки и диалоги.
"make nconfig" Улучшенные текстовые цветные меню.
"make xconfig" Инструмент настройки на основе X windows (Qt).
"make gconfig" Инструмент настройки на основе X windows (Gtk).
"make oldconfig" Ответить по умолчанию на все вопросы на основе содержимого вашего существующего файла ./.config и спросить о новых символах конфигурации.
"make silentoldconfig" Как выше, но избегает загромождения экрана уже отвеченными вопросами. Дополнительно обновляет зависимости.
"make olddefconfig" Как выше, но устанавливает новые символы в их значения по умолчанию без запроса.
"make defconfig" Создать файл ./.config, используя значения символов по умолчанию из arch/$ARCH/defconfig или arch/$ARCH/configs/${PLATFORM}_defconfig, в зависимости от архитектуры.
"make ${PLATFORM}_defconfig" Создать файл ./.config, используя значения символов по умолчанию из arch/$ARCH/configs/${PLATFORM}_defconfig. Используйте "make help", чтобы получить список всех доступных платформ вашей архитектуры.
"make allyesconfig" Создать файл ./.config, устанавливая значения символов в 'y' насколько это возможно.
"make allmodconfig" Создать файл ./.config, устанавливая значения символов в 'm' насколько это возможно.
"make allnoconfig" Создать файл ./.config, устанавливая значения символов в 'n' насколько это возможно.
"make randconfig" Создать файл ./.config, устанавливая значения символов в случайные значения.
"make localmodconfig" Создать конфиг на основе текущего конфига и загруженных модулей (lsmod). Отключает любую опцию модуля, которая не нужна для загруженных модулей.
Чтобы создать localmodconfig для другой машины,
сохраните lsmod этой машины в файл
и передайте его как параметр LSMOD.
target$ lsmod > /tmp/mylsmod
target$ scp /tmp/mylsmod host:/tmp
host$ make LSMOD=/tmp/mylsmod localmodconfig
Вышеописанное также работает при кросс-компиляции.
"make localyesconfig" Аналогично localmodconfig, за исключением того, что преобразует все опции модулей во встроенные (=y) опции.
Дополнительную информацию об использовании инструментов конфигурации ядра Linux можно найти в Documentation/kbuild/kconfig.txt.
ПРИМЕЧАНИЯ к "make config":
Наличие ненужных драйверов сделает ядро больше и может при некоторых обстоятельствах привести к проблемам: опрос несуществующей карты контроллера может сбить с толку ваши другие контроллеры
Компиляция ядра с "Processor type" выше 386 приведет к ядру, которое НЕ РАБОТАЕТ на 386. Ядро обнаружит это при загрузке и остановится.
Ядро с включенной эмуляцией математического сопроцессора всё равно будет использовать сопроцессор, если он присутствует: эмуляция математики просто не будет использоваться в этом случае. Ядро будет немного больше, но будет работать на разных машинах независимо от наличия математического сопроцессора.
Детали конфигурации "kernel hacking" обычно приводят к большему или более медленному ядру (или и тому, и другому) и могут даже сделать ядро менее стабильным, настраивая некоторые процедуры на активную попытку сломать плохой код для поиска проблем ядра (kmalloc()). Таким образом, вам, вероятно, следует ответить 'n' на вопросы, касающиеся функций "development", "experimental" или "debugging".
КОМПИЛЯЦИЯ ядра:
Убедитесь, что у вас есть как минимум gcc 3.2. Для получения дополнительной информации обратитесь к Documentation/Changes.
Пожалуйста, обратите внимание, что вы всё ещё можете запускать программы пользовательского пространства в формате a.out с этим ядром.
Выполните "make", чтобы создать сжатый образ ядра. Также возможно сделать "make install", если у вас установлен lilo, подходящий для make-файлов ядра, но вы, возможно, захотите сначала проверить вашу конкретную настройку lilo.
Для фактической установки вы должны быть root, но ни одна из обычных сборок не должна этого требовать. Не поминайте имя root всуе.
Если вы настроили какие-либо части ядра как `modules', вам также нужно будет выполнить "make modules_install".
Подробный вывод компиляции/сборки ядра:
Обычно система сборки ядра работает в довольно тихом режиме (но не полностью беззвучном). Однако иногда вам или другим разработчикам ядра нужно видеть команды компиляции, компоновки или другие команды точно так, как они выполняются. Для этого используйте "verbose" режим сборки. Это делается вставкой "V=1" в команду "make". Например:
make V=1 all
Чтобы система сборки также сообщала причину пересборки каждой цели, используйте "V=2". По умолчанию используется "V=0".
Держите резервное ядро под рукой на случай, если что-то пойдет не так. Это особенно важно для выпусков разработки, так как каждый новый выпуск содержит новый код, который не был отлажен. Убедитесь, что у вас также есть резервная копия модулей, соответствующих этому ядру. Если вы устанавливаете новое ядро с тем же номером версии, что и ваше рабочее ядро, сделайте резервную копию каталога модулей перед выполнением "make modules_install".
Альтернативно, перед компиляцией используйте опцию конфигурации ядра "LOCALVERSION", чтобы добавить уникальный суффикс к обычной версии ядра. LOCALVERSION можно установить в меню "General Setup".
Чтобы загрузить ваше новое ядро, вам нужно скопировать образ ядра (например, .../linux/arch/i386/boot/bzImage после компиляции) туда, где находится ваше обычное загружаемое ядро.
Загрузка ядра непосредственно с дискеты без помощи загрузчика, такого как LILO, больше не поддерживается.
Если вы загружаете Linux с жесткого диска, скорее всего, вы используете LILO, который использует образ ядра, указанный в файле /etc/lilo.conf. Файл образа ядра обычно находится в /vmlinuz, /boot/vmlinuz, /bzImage или /boot/bzImage. Чтобы использовать новое ядро, сохраните копию старого образа и скопируйте новый образ поверх старого. Затем вы ДОЛЖНЫ ПЕРЕЗАПУСТИТЬ LILO для обновления карты загрузки!! Если этого не сделать, вы не сможете загрузить новый образ ядра.
Переустановка LILO обычно заключается в запуске /sbin/lilo. Возможно, вы захотите отредактировать /etc/lilo.conf, чтобы указать запись для вашего старого образа ядра (например, /vmlinux.old) на случай, если новый не сработает. Смотрите документацию LILO для получения дополнительной информации.
После переустановки LILO всё должно быть готово. Выключите систему, перезагрузитесь и наслаждайтесь!
Если вам когда-нибудь понадобится изменить корневое устройство по умолчанию, видеорежим, размер ramdisk и т. д. в образе ядра, используйте программу 'rdev' (или альтернативно параметры загрузки LILO, когда это уместно). Нет необходимости перекомпилировать ядро для изменения этих параметров.
Перезагрузитесь с новым ядром и наслаждайтесь.
ЕСЛИ ЧТО-ТО ПОШЛО НЕ ТАК:
Если у вас возникли проблемы, которые, как кажется, связаны с ошибками ядра, пожалуйста, проверьте файл MAINTAINERS, чтобы узнать, есть ли конкретный человек, связанный с частью ядра, с которой у вас возникли проблемы. Если там никто не указан, тогда второй наилучший вариант — отправить их мне ([email protected]) и, возможно, на любой другой соответствующий список рассылки или в группу новостей.
Во всех сообщениях об ошибках пожалуйста сообщайте, о каком ядре вы говорите, как воспроизвести проблему и какова ваша конфигурация (используйте здравый смысл). Если проблема новая, сообщите мне об этом, а если проблема старая, пожалуйста, попробуйте сообщить, когда вы впервые её заметили.
Если ошибка приводит к сообщению типа
unable to handle kernel paging request at address C0000010 Oops: 0002 EIP: 0010:XXXXXXXX eax: xxxxxxxx ebx: xxxxxxxx ecx: xxxxxxxx edx: xxxxxxxx esi: xxxxxxxx edi: xxxxxxxx ebp: xxxxxxxx ds: xxxx es: xxxx fs: xxxx gs: xxxx Pid: xx, process nr: xx xx xx xx xx xx xx xx xx xx xx
или подобной информации отладки ядра на вашем экране или в системном журнале, пожалуйста, воспроизведите её точно. Дамп может показаться вам непонятным, но он содержит информацию, которая может помочь в отладке проблемы. Текст над дампом также важен: он сообщает, почему ядро сбросило код (в примере выше это из-за неверного указателя ядра). Дополнительная информация о том, как понять дамп, находится в Documentation/oops-tracing.txt
Если вы скомпилировали ядро с CONFIG_KALLSYMS, вы можете отправить дамп как есть, в противном случае вам придётся использовать программу "ksymoops", чтобы понять дамп (но компиляция с CONFIG_KALLSYMS обычно предпочтительнее). Эту утилиту можно загрузить с ftp://ftp..kernel.org/pub/linux/utils/kernel/ksymoops/ . Альтернативно, вы можете выполнить поиск по дампу вручную:
При отладке дампов, подобных приведённому выше, огромную помощь оказывает, если вы можете найти, что означает значение EIP. Шестнадцатеричное значение как таковое мало помогает мне или кому-либо ещё: оно будет зависеть от вашей конкретной конфигурации ядра. Что вам нужно сделать, так это взять шестнадцатеричное значение из строки EIP (игнорируйте "0010:") и найти его в списке имён ядра, чтобы увидеть, какая функция ядра содержит проблемный адрес.
Чтобы узнать имя функции ядра, вам нужно найти системный двоичный файл, связанный с ядром, которое проявило симптом. Это файл 'linux/vmlinux'. Чтобы извлечь список имён и сопоставить его с EIP из краха ядра, выполните:
nm vmlinux | sort | less
Это даст вам список адресов ядра, отсортированных по возрастанию, из которого легко найти функцию, содержащую проблемный адрес. Обратите внимание, что адрес, указанный в сообщениях отладки ядра, не обязательно будет точно совпадать с адресами функций (на самом деле, это очень маловероятно), поэтому вы не можете просто 'grep' список: однако список даст вам начальную точку каждой функции ядра, поэтому, найдя функцию, начальный адрес которой ниже искомого, но за которой следует функция с более высоким адресом, вы найдёте нужную. Фактически, может быть хорошей идеей включить немного "контекста" в ваш отчёт о проблеме, указав несколько строк вокруг интересующей.
Если вы по какой-то причине не можете сделать вышеописанное (у вас предварительно скомпилированный образ ядра или подобное), сообщение мне как можно больше информации о вашей конфигурации поможет. Пожалуйста, прочитайте документ REPORTING-BUGS для подробностей.
Альтернативно, вы можете использовать gdb на работающем ядре. (только для чтения; т.е. вы не можете изменять значения или устанавливать точки останова.) Для этого сначала скомпилируйте ядро с -g; отредактируйте arch/i386/Makefile соответствующим образом, затем выполните "make clean". Вам также нужно будет включить CONFIG_PROC_FS (через "make config").
После перезагрузки с новым ядром выполните "gdb vmlinux /proc/kcore". Теперь вы можете использовать все обычные команды gdb. Команда для поиска точки, где произошёл крах вашей системы, — "l *0xXXXXXXXX". (Замените XXX на значение EIP.)
gdb на незапущенном ядре в настоящее время не работает, потому что gdb (неправильно) игнорирует начальное смещение, для которого скомпилировано ядро.