
Linux 内核 4.1.15 源代码,重点关注 CVE-2023-4128,用于漏洞分析和内核安全的教学研究。
Релиз ядра 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 (также известных как стабильные ядра) не являются инкрементальными, а применяются непосредственно к базовому ядру 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":
Наличие ненужных драйверов сделает ядро больше и может в некоторых обстоятельствах привести к проблемам: опрос несуществующей платы контроллера может сбить с толку ваши другие контроллеры.
Компиляция ядра с типом процессора выше 386 приведёт к тому, что ядро НЕ будет работать на 386. Ядро обнаружит это при загрузке и остановится.
Ядро со встроенной эмуляцией математики будет по-прежнему использовать сопроцессор, если он присутствует: эмуляция математики в этом случае просто никогда не будет использоваться. Ядро будет немного больше, но будет работать на разных машинах независимо от наличия математического сопроцессора.
Опции конфигурации "kernel hacking" обычно приводят к увеличению или замедлению ядра (или и тому, и другому) и могут даже сделать ядро менее стабильным, настраивая некоторые процедуры на активную попытку поломать некорректный код для поиска проблем ядра (kmalloc()). Поэтому вам следует, вероятно, отвечать 'n' на вопросы о функциях "разработки", "экспериментальных" или "отладки".
КОМПИЛЯЦИЯ ядра:
Убедитесь, что у вас есть как минимум 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 (ошибочно) игнорирует начальное смещение, с которым скомпилировано ядро.