контроль целостности сегментов кода

Взгляд изнутри

Модератор: Модераторы разделов

Ответить
Zulkidal
Сообщения: 7

контроль целостности сегментов кода

Сообщение Zulkidal »

Пишу модуль ядра с целью отслеживания повреждений памяти. Для этого периодически вычисляю контрольные суммы сегментов кода для каждой задачи и сравниваю с предыдущими значениями. Все было бы хорошо, если бы в результате не получалось, что области, которые я пытаюсь контролировать, оказались изменяющимися. Такое явление можно было бы объяснить например свопингом, но у меня ядро работает без поддержки свопинга. Значит остается вариант, что я неверно нахожу адреса:

прохожусь по всем задачам и по всем областям для каждой из задач,
для сегментов кода вызываю функцию вычисления контрольной суммы
for_each_task(ts)
{
struct vm_area_struct *mmap = ts->mm->mmap;
while (mmap)
{
if (Code_Segment(mmap)) Check_Summ(mmap);
mmap = mmap->next;
}
}

а вот здесь как раз вопрос: почему возвращаются адреса (start_code), которые в действительности не соответствуют сегментам кода?... поэтому и контрольные суммы у меня не сходятся... (как я понимаю)
void Check_Summ(struct vm_area_struct *mmap)
{
unsigned long start = mmap->vm_start,
end = mmap->vm_end,
size = end - start;
pgd_t *pgd = pgd_offset(mmap->vm_mm, start);//перевожу виртуальный адрес пространства задачи в физ.
pmd_t *pmd = pmd_offset(pgd, start);
pte_t *pte = pte_offset(pmd, start);
unsigned long phys_addr = pte_val(*pte);
void *start_code = __va(phys_addr); //перевожу физический адрес в виртуальный пространства ядра
unsigned int csum = Crc32(start_code, size);
printk("sum=%10u\n",csum);
}
Спасибо сказали:
Zulkidal
Сообщения: 7

Re: контроль целостности сегментов кода

Сообщение Zulkidal »

интересен даже такой факт:
преобразую виртуальный адрес пространства задачи в физический известным методом через таблицы страниц

pgd_t *pgd = pgd_offset(mm, start);
pmd_t *pmd = pmd_offset(pgd, start);
pte_t *pte = pte_offset(pmd, start);
unsigned long phys_addr = pte_val(*pte);

и получаю физический адрес, который больше максимально доступной памяти!))

господа!, объясните новичку. мое знание не согласуется с происходящим
Спасибо сказали:
int_0dh
Сообщения: 20
ОС: Linux

Re: контроль целостности сегментов кода

Сообщение int_0dh »

Zulkidal писал(а):
29.01.2010 15:16
интересен даже такой факт:
преобразую виртуальный адрес пространства задачи в физический известным методом через таблицы страниц

pgd_t *pgd = pgd_offset(mm, start);
pmd_t *pmd = pmd_offset(pgd, start);
pte_t *pte = pte_offset(pmd, start);
unsigned long phys_addr = pte_val(*pte);

и получаю физический адрес, который больше максимально доступной памяти!))

господа!, объясните новичку. мое знание не согласуется с происходящим


1) значением pte entry является не физический адрес, там еще флаги есть (Intel Software Developers Manual в помощь)
2) ядро содержит отображение 1:1 только для примерно гига памяти (на самом деле меньше), так
что если физический адрес будет выше этой границы, __va() работать не будет.
Спасибо сказали:
Zulkidal
Сообщения: 7

Re: контроль целостности сегментов кода

Сообщение Zulkidal »

int_0dh писал(а):
29.01.2010 16:51
1) значением pte entry является не физический адрес, там еще флаги есть (Intel Software Developers Manual в помощь)
2) ядро содержит отображение 1:1 только для примерно гига памяти (на самом деле меньше), так
что если физический адрес будет выше этой границы, __va() работать не будет.


при чем здесь pte entry? тут в коде такого вообще нет.
и при чем здесь флаги?

>intel developers manual
я-то как раз прочитал этот мануал.

про __va() я знаю. у меня 512 метров оперативки - далеко еще до ХайМем (896 м.). так что вопрос про преобразование адресов открыт.
Спасибо сказали:
int_0dh
Сообщения: 20
ОС: Linux

Re: контроль целостности сегментов кода

Сообщение int_0dh »

>>1) значением pte entry является не физический адрес, там еще флаги есть (Intel Software Developers Manual в помощь)>>>
>>2) ядро содержит отображение 1:1 только для примерно гига памяти (на самом деле меньше), так
>>что если физический адрес будет выше этой границы, __va() работать не будет.

>при чем здесь pte entry? тут в коде такого вообще нет.
>и при чем здесь флаги?


да ну?
вот строчка из кода что вы привели:
unsigned long phys_addr = pte_val(*pte);

теперь тут находится отнюдь на физический адрес а просто значение PTE entry.
чтобы получить физический адрес надо сделать phys_addr &= ~PTE_FLAG_MASK;

>>intel developers manual
>я-то как раз прочитал этот мануал.

ок, еще раз прочесть всегда полезно :)
Спасибо сказали:
Zulkidal
Сообщения: 7

Re: контроль целостности сегментов кода

Сообщение Zulkidal »

int_0dh писал(а):
30.01.2010 09:56
вот строчка из кода что вы привели:
unsigned long phys_addr = pte_val(*pte);
теперь тут находится отнюдь на физический адрес а просто значение PTE entry.
чтобы получить физический адрес надо сделать phys_addr &= ~PTE_FLAG_MASK;


спасибо. именно такую конкретику и хотел услышать
могли бы вы объяснить преобразование phys_addr &= ~PTE_FLAG_MASK ?
и главное: в ядре 2.4.32 нигде не определено это зничение маски
вот есть в <asm-i386/page.h> такое
#define PAGE_MASK (~(PAGE_SIZE-1))
#define PTE_MASK PAGE_MASK
Спасибо сказали:
int_0dh
Сообщения: 20
ОС: Linux

Re: контроль целостности сегментов кода

Сообщение int_0dh »

надо просто отрезать младшие 12 бит (0-11).
перед этим неплохо проверить что страница действительно присутствует в памяти.

и учесть что в вашем коде возможны гонки, так что время от времени вы можете
получать неверные значения чексумм.
Спасибо сказали:
Zulkidal
Сообщения: 7

Re: контроль целостности сегментов кода

Сообщение Zulkidal »

int_0dh писал(а):
30.01.2010 17:10
в вашем коде возможны гонки, так что время от времени вы можете
получать неверные значения чексумм.


откуда гонки?
Спасибо сказали:
int_0dh
Сообщения: 20
ОС: Linux

Re: контроль целостности сегментов кода

Сообщение int_0dh »

Zulkidal писал(а):
01.02.2010 13:53
int_0dh писал(а):
30.01.2010 17:10
в вашем коде возможны гонки, так что время от времени вы можете
получать неверные значения чексумм.


откуда гонки?


ну, я не телепат и не знаю из какого контекста
вызывается ваша хрень. если вы не хватаете
соответсвующие блокировки/семафоры то ,например, вполне возможны
модификации системой/другими потоками процесса
списка vma/pde/pte во время ваших по ним прогулок.
Спасибо сказали:
Zulkidal
Сообщения: 7

Re: контроль целостности сегментов кода

Сообщение Zulkidal »

Zulkidal писал(а):
30.01.2010 11:55
теперь тут находится отнюдь на физический адрес а просто значение PTE entry.
чтобы получить физический адрес надо сделать phys_addr &= ~PTE_FLAG_MASK;
- надо просто отрезать младшие 12 бит (0-11).


что-то я не понимаю:
после действий
pgd_t *pgd = pgd_offset(mm, start);
pmd_t *pmd = pmd_offset(pgd, start);
pte_t *pte = pte_offset(pmd, start);
unsigned long phys_addr = pte_val(*pte);
я получаю виртуальный адрес Page Table Entry. затем вы мне предлогаете маскировать первые 12 бит (для получения физического адреса), которые являются в адресе смещением относительно начала страницы - получаем совсем не физический адрес!)) получили всего-навсего адрес Page Table Directory в которой лежит наш PTE.

как же тогда получить физический адрес?
прочитав intel developers manual я как раз все понял. как говорится, и ежу ясно. но множество функций и определений в ядре вместе еще и со средним каталогом, не несущим никакой смыловой нагрузки, сбивают меня с толку

как я себе представляю это дело:
в результате получив pte, я беру старшие 20 бит из этой структуры, соответствующие адресу дескриптора страничного кадра, смещаю на 12 и получаю адрес struct page. по адресу дескрипотра и началу массива дескрипоторов страничных кадров вычисляю номер в последнем. номер смещаю на 12 и получаю физический адрес.
хм, осталось дело за малым))
Спасибо сказали:
Zulkidal
Сообщения: 7

Re: контроль целостности сегментов кода

Сообщение Zulkidal »

Хм, я загнул. Да и думал неверно: работал с адресом, когда надо работать с содержимым по этому адресу))

структура PTE не может указывать на такой маленький объект, как struct page. Она непосредственно содержит физический адрес страницы.
Спасибо сказали:
Ответить