адреса имён ядра (ASLR)

Вопросы программного кода и архитектуры Linux

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: адреса имён ядра (ASLR)

Непрочитанное сообщение Olej » 01 июн 2022, 15:11

В конфигурации:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/BHV.kernel$ sudo inxi -MSxxx
[sudo] пароль для olej:       
System:    Host: R420 Kernel: 5.4.0-113-generic x86_64 bits: 64 compiler: gcc v: 9.4.0 Desktop: Cinnamon 5.2.7 
           wm: muffin 5.2.1 dm: LightDM 1.30.0 Distro: Linux Mint 20.3 Una base: Ubuntu 20.04 focal 
Machine:   Type: Server System: Dell product: PowerEdge R420 v: N/A serial: 9DDFKY1 Chassis: type: 23 serial: 9DDFKY1 
           Mobo: Dell model: 0CN7CM v: A06 serial: ..CN1374035400RO. BIOS: Dell v: 2.9.0 date: 01/09/2020 

Смотрю произвольное имя ядра ... из самых известных printk:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/BHV.kernel/examples/tools/export-data$ cat /proc/kallsyms | grep T | grep ' printk'
0000000000000000 T printk_timed_ratelimit
0000000000000000 T printk_percpu_data_ready
0000000000000000 T printk_safe_flush
0000000000000000 T printk_safe_flush_on_panic
0000000000000000 T printk_nmi_enter
0000000000000000 T printk_nmi_exit
0000000000000000 T printk_nmi_direct_enter
0000000000000000 T printk_nmi_direct_exit
0000000000000000 T printk
0000000000000000 T printk_deferred
0000000000000000 T printk_safe_init
0000000000000000 T printk_all_partitions
Это совершенно понятно - никому кроме root не нужно знать адреса точек входа ядра.
А так:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/BHV.kernel/examples/tools/export-data$ sudo cat /proc/kallsyms | grep T | grep ' printk'
ffffffffa8904d90 T printk_timed_ratelimit
ffffffffa89071f0 T printk_percpu_data_ready
ffffffffa89081c0 T printk_safe_flush
ffffffffa8908240 T printk_safe_flush_on_panic
ffffffffa89082a0 T printk_nmi_enter
ffffffffa89082b0 T printk_nmi_exit
ffffffffa89082c0 T printk_nmi_direct_enter
ffffffffa89082f0 T printk_nmi_direct_exit
ffffffffa928a3a0 T printk
ffffffffa928a681 T printk_deferred
ffffffffaa4d60a4 T printk_safe_init
ffffffffaa4fbdb4 T printk_all_partitions
Совершенно резонно... Это динамические (реальные) адреса + смещённые.
А вот это статические, считанные из конфиг файла:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/BHV.kernel/examples/tools/export-data$ cat /boot/System.map-`uname -r` | grep T | grep ' printk'
cat: /boot/System.map-5.4.0-113-generic: Отказано в доступе

olej@R420:~/2022/own.BOOKs/BHV.kernel/examples/tools/export-data$ sudo cat /boot/System.map-`uname -r` | grep T | grep ' printk'
ffffffff81104d90 T printk_timed_ratelimit
ffffffff811071f0 T printk_percpu_data_ready
ffffffff811081c0 T printk_safe_flush
ffffffff81108240 T printk_safe_flush_on_panic
ffffffff811082a0 T printk_nmi_enter
ffffffff811082b0 T printk_nmi_exit
ffffffff811082c0 T printk_nmi_direct_enter
ffffffff811082f0 T printk_nmi_direct_exit
ffffffff81a8a3a0 T printk
ffffffff81a8a681 T printk_deferred
ffffffff82cd60a4 T printk_safe_init
ffffffff82cfbdb4 T printk_all_partitions
Срабатывает ALSR

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/BHV.kernel/examples/tools/export-data$ cat /boot/config-`uname -r` | grep CONFIG_RANDOMIZE_BASE
CONFIG_RANDOMIZE_BASE=y
И все адреса смещены на фиксированную величину!
Вложения
Снимок экрана от 2022-06-01 14-13-46.png
Снимок экрана от 2022-06-01 14-13-46.png (48.53 КБ) 603 просмотра

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: адреса имён ядра (ASLR)

Непрочитанное сообщение Olej » 02 июн 2022, 00:21

Olej писал(а):
01 июн 2022, 15:11
Срабатывает ALSR
Сравнил как это происходит в 32-бит ARM - микрокомпьютер Orange Pi One с системой сборки Armbian:

Код: Выделить всё

olej@orangepione:~/2022/kernel$ sudo inxi -MSxxx
System:    Host: orangepione Kernel: 5.15.25-sunxi armv7l bits: 32 compiler: N/A Console: tty 13 
           dm: LightDM 1.26.0 Distro: Armbian GNU/Linux 10 (buster) 
Machine:   Type: ARM Device System: Xunlong Orange Pi One details: Allwinner sun8i Family rev: N/A 
           serial: 02c000815fd5e717 
Здесь просто не знают такого параметра конфигурирования ядра:

Код: Выделить всё

olej@orangepione:~/2022/kernel$ cat /boot/config-`uname -r` | grep CONFIG_RANDOMIZE_BASE
olej@orangepione:~/2022/kernel$

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: адреса имён ядра (ASLR)

Непрочитанное сообщение Olej » 02 июн 2022, 00:25

Olej писал(а):
02 июн 2022, 00:21
Сравнил как это происходит в 32-бит ARM - микрокомпьютер Orange Pi One с системой сборки Armbian:
Ещё один микрокомпьютер 32-бит ARM -

Код: Выделить всё

olej@raspberrypi:~ $ sudo inxi -MSxxx
System:    Host: raspberrypi Kernel: 5.15.32-v7+ armv7l bits: 32 compiler: gcc v: 10.2.1 Console: tty 5
           DM: LightDM 1.26.0 Distro: Raspbian GNU/Linux 11 (bullseye)
Machine:   Type: ARM Device System: Raspberry Pi 2 Model B Rev 1.1 details: BCM2835 rev: a21041
           serial: 00000000f57e2ca8

Код: Выделить всё

olej@raspberrypi:~ $ cat /boot/config-`uname -r` | grep CONFIG_RANDOMIZE_BASE
cat: /boot/config-5.15.32-v7+: Нет такого файла или каталога
Здесь совсем непривычная ситуация :-o :

Код: Выделить всё

olej@raspberrypi:~ $ ls /boot
bcm2708-rpi-b.dtb       bcm2710-rpi-3-b-plus.dtb  cmdline.txt    fixup_db.dat      start4cd.elf
bcm2708-rpi-b-plus.dtb  bcm2710-rpi-cm3.dtb       config.txt     fixup_x.dat       start4db.elf
bcm2708-rpi-b-rev1.dtb  bcm2710-rpi-zero-2.dtb    COPYING.linux  issue.txt         start4.elf
bcm2708-rpi-cm.dtb      bcm2710-rpi-zero-2-w.dtb  fixup4cd.dat   kernel7.img       start4x.elf
bcm2708-rpi-zero.dtb    bcm2711-rpi-400.dtb       fixup4.dat     kernel7l.img      start_cd.elf
bcm2708-rpi-zero-w.dtb  bcm2711-rpi-4-b.dtb       fixup4db.dat   kernel8.img       start_db.elf
bcm2709-rpi-2-b.dtb     bcm2711-rpi-cm4.dtb       fixup4x.dat    kernel.img        start.elf
bcm2710-rpi-2-b.dtb     bcm2711-rpi-cm4s.dtb      fixup_cd.dat   LICENCE.broadcom  start_x.elf
bcm2710-rpi-3-b.dtb     bootcode.bin              fixup.dat      overlays

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: адреса имён ядра (ASLR)

Непрочитанное сообщение Olej » 02 июн 2022, 01:36

Olej писал(а):
30 окт 2021, 00:38
Насколько я понимаю (предполагаю) это случайное смещение даёт вызов API ядра kaslr_get_random_long :
Подробное описание (слишком подробное :lol: ) описание как происходит рандомизация адреса ядра при загрузке системы: Рандомизация адреса ядра
Параметры конфигурации ядра имеющие к этому отношение:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/BHV.kernel/examples/aslr$ cat /boot/config-`uname -r` | grep CONFIG_PHYSICAL_START
CONFIG_PHYSICAL_START=0x1000000

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/BHV.kernel/examples/aslr$ cat /boot/config-`uname -r` | grep CONFIG_RANDOMIZE_BASE
CONFIG_RANDOMIZE_BASE=y

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: адреса имён ядра (ASLR)

Непрочитанное сообщение Olej » 13 июн 2022, 16:33

Olej писал(а):
11 авг 2019, 23:53
Тема эта возникла из-за одной "мелочи", которую я не могу пока понять...
- когда загружается модуль ядра Linux, то он связывается с именем ядра по абсолютному адресу имени...
- без ASLR это элементарно просто и понятно
- но с ASLR все адреса имён должны быть скорректированы на фиксированную величину (+6E00000 в примере выше)
- и это смещение меняется при каждой перезагрузке системы...
Разбираясь с модулями ядра (см. модули ядра (римэйк)) по-новой...

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/BHV.kernel/examples/tools/aslr$ sudo cat /proc/kallsyms | grep " printk"$
ffffffff8348b926 T printk

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/BHV.kernel/examples/tools/aslr$ sudo cat /boot/System.map-`uname -r` | grep " printk"$
ffffffff81a8b926 T printk
Разница: ffff8348b926−ffff81a8b926 = 1A00000 ... Это при том и потому, что во всех AMD 64-бит архитектурах (x86_64) в адресе используется только 48 (0...47) значащих бит - 12 значащих hex знаков справа...

Вопрос то в том: какой из этих 2-х адресов должен использоваться runtime для косвенного вызова функции из кода модуля ядра?

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: адреса имён ядра (ASLR)

Непрочитанное сообщение Olej » 13 июн 2022, 16:37

Olej писал(а):
13 июн 2022, 16:33
Вопрос то в том: какой из этих 2-х адресов должен использоваться runtime для косвенного вызова функции из кода модуля ядра?
Делал, совсем для другой цели, тестовый модуль ядра - посмотреть как в разных форматах %p выводятся адресные данные в 32 и 64 бит режимах:

Код: Выделить всё

#include <linux/module.h>

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Oleg Tsiliuric <olej.tsil@gmail.com>>");

static int __init my_init(void) {
        uint16_t d = 1234;
        void show(void* p) {
                printk("%20p%20px%20pK%20lx\n",
                       p, p, p, (uintptr_t)p);
        }
        if (IS_ENABLED(CONFIG_64BIT)) {
                printk("64-bit");
        }
        else {
                printk("32-bit");
        }
        printk("%20s%20s%20s%20s\n", "%p", "%px", "%pK", "int");
        show(&d);
#if defined(CONFIG_64BIT)
        show(printk);
#else
        show(_printk);
#endif
        show((void*)PAGE_OFFSET);
        show((void*)current);
        show((void*)0xffff800000000000);
        return -2;
}

module_init(my_init);

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/BHV.kernel/examples.tmp/aslr$ uname -a
Linux R420 5.4.0-117-generic #132-Ubuntu SMP Thu Jun 2 00:39:06 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/BHV.kernel/examples.tmp/aslr$ make
make -C /lib/modules/5.4.0-117-generic/build M=/home/olej/2022/own.BOOKs/BHV.kernel/examples.tmp/aslr modules
make[1]: вход в каталог «/usr/src/linux-headers-5.4.0-117-generic»
  CC [M]  /home/olej/2022/own.BOOKs/BHV.kernel/examples.tmp/aslr/aslr.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC [M]  /home/olej/2022/own.BOOKs/BHV.kernel/examples.tmp/aslr/aslr.mod.o
  LD [M]  /home/olej/2022/own.BOOKs/BHV.kernel/examples.tmp/aslr/aslr.ko
make[1]: выход из каталога «/usr/src/linux-headers-5.4.0-117-generic»

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: адреса имён ядра (ASLR)

Непрочитанное сообщение Olej » 13 июн 2022, 16:41

Olej писал(а):
13 июн 2022, 16:33

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/BHV.kernel/examples/tools/aslr$ sudo cat /proc/kallsyms | grep " printk"$
ffffffff8348b926 T printk

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/BHV.kernel/examples/tools/aslr$ sudo cat /boot/System.map-`uname -r` | grep " printk"$
ffffffff81a8b926 T printk

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/BHV.kernel/examples.tmp/aslr$ sudo insmod aslr.ko
[sudo] пароль для olej:
insmod: ERROR: could not insert module aslr.ko: Unknown symbol in module

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/BHV.kernel/examples/tools/aslr$ dmesg | tail -n7
[21606.985381] 64-bit
[21606.985384]                   %p                 %px                 %pK                 int
[21606.985388]             4a0f4ec6    ffffb7354dddbc56    ffffb7354dddbc56    ffffb7354dddbc56
[21606.985389]             ab07503d    ffffffff8348b926    ffffffff8348b926    ffffffff8348b926
[21606.985389]              9c02798    ffff8eb780000000    ffff8eb780000000    ffff8eb780000000
[21606.985390]             7bdc3bda    ffff8ec3322c9740    ffff8ec3322c9740    ffff8ec3322c9740
[21606.985391]              75ed937    ffff800000000000    ffff800000000000    ffff800000000000
2-я строчка в этом выводе модуля - это адрес самого имени printk .
И он в точности совпадает с тем, что мы видим в /proc/kallsyms

1. Уф! :oops: ... это во многом упрощает ... хотя и ожидаемо.
2. Для вывода адресов используем везде формат %px

Ответить

Вернуться в «Linux изнутри»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя