2017-11-09 16:00:36 +00:00
|
|
|
#include "info.h"
|
2017-11-04 12:01:10 +00:00
|
|
|
|
2021-12-17 22:35:04 +00:00
|
|
|
#include <kernaux/libc.h>
|
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
static bool cmdline_terminated(const char *s);
|
2017-11-04 14:03:45 +00:00
|
|
|
|
2021-12-17 22:45:22 +00:00
|
|
|
void kernel_info_initialize(
|
|
|
|
struct Kernel_Info *const kinfo,
|
|
|
|
const size_t offset,
|
|
|
|
const size_t size,
|
|
|
|
const size_t phys_base,
|
|
|
|
const size_t virt_base,
|
|
|
|
const size_t stack_top
|
|
|
|
) {
|
2021-12-17 22:35:04 +00:00
|
|
|
memset(kinfo, 0, sizeof(*kinfo));
|
2021-12-17 22:45:22 +00:00
|
|
|
|
|
|
|
kinfo->kernel_offset = offset;
|
|
|
|
kinfo->kernel_size = size;
|
|
|
|
|
|
|
|
kinfo->kernel_phys_base = phys_base;
|
|
|
|
kinfo->kernel_virt_base = virt_base;
|
|
|
|
|
|
|
|
kinfo->kernel_phys_limit = phys_base + size - 1;
|
|
|
|
kinfo->kernel_virt_limit = virt_base + size - 1;
|
|
|
|
|
|
|
|
kinfo->kernel_stack_top = stack_top;
|
2021-12-17 22:35:04 +00:00
|
|
|
}
|
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
bool kernel_info_validate(const struct Kernel_Info *const kinfo)
|
2020-11-26 18:50:25 +00:00
|
|
|
{
|
2021-12-17 22:32:04 +00:00
|
|
|
if (!kinfo) return false;
|
2017-11-04 14:03:45 +00:00
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
if (!cmdline_terminated(kinfo->cmdline)) return false;
|
2017-11-04 14:03:45 +00:00
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
if (kinfo->modules_count > KERNEL_INFO_MODULES_MAX) return false;
|
|
|
|
if (kinfo->areas_count > KERNEL_INFO_AREAS_MAX) return false;
|
2017-11-04 14:03:45 +00:00
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
if (kinfo->kernel_offset == 0) return false;
|
|
|
|
if (kinfo->kernel_size == 0) return false;
|
2017-11-04 14:03:45 +00:00
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
if (kinfo->kernel_phys_base + kinfo->kernel_size !=
|
|
|
|
kinfo->kernel_phys_limit + 1)
|
|
|
|
{
|
|
|
|
return false;
|
2017-11-04 14:03:45 +00:00
|
|
|
}
|
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
if (kinfo->kernel_virt_base + kinfo->kernel_size !=
|
|
|
|
kinfo->kernel_virt_limit + 1)
|
|
|
|
{
|
|
|
|
return false;
|
2017-11-04 14:03:45 +00:00
|
|
|
}
|
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
if (kinfo->kernel_virt_base - kinfo->kernel_phys_base !=
|
|
|
|
kinfo->kernel_offset)
|
|
|
|
{
|
|
|
|
return false;
|
2017-11-04 14:03:45 +00:00
|
|
|
}
|
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
size_t modules_total_size = 0;
|
2017-11-04 14:03:45 +00:00
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
for (size_t i = 0; i < kinfo->modules_count; ++i) {
|
2021-12-12 14:00:17 +00:00
|
|
|
const struct Kernel_Info_Module *const module = &kinfo->modules[i];
|
2017-11-04 14:03:45 +00:00
|
|
|
|
|
|
|
modules_total_size += module->size;
|
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
if (module->size == 0) return false;
|
|
|
|
if (module->base + module->size != module->limit + 1) return false;
|
|
|
|
if (!cmdline_terminated(module->cmdline)) return false;
|
2017-11-04 14:03:45 +00:00
|
|
|
}
|
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
if (kinfo->modules_total_size != modules_total_size) return false;
|
2017-11-04 14:03:45 +00:00
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
if (kinfo->kernel_and_modules_total_size !=
|
|
|
|
kinfo->kernel_size + kinfo->modules_total_size)
|
|
|
|
{
|
|
|
|
return false;
|
2017-11-04 14:03:45 +00:00
|
|
|
}
|
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
uint64_t last = 0;
|
2017-11-04 14:03:45 +00:00
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
for (size_t i = 0; i < kinfo->areas_count; ++i) {
|
2021-12-12 14:00:17 +00:00
|
|
|
const struct Kernel_Info_Area *const area = &kinfo->areas[i];
|
2017-11-04 14:03:45 +00:00
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
if (last > area->base) return false;
|
|
|
|
if (area->size == 0) return false;
|
|
|
|
if (area->base + area->size != area->limit + 1) return false;
|
2017-11-04 14:03:45 +00:00
|
|
|
|
|
|
|
last = area->limit + 1;
|
|
|
|
|
|
|
|
if (!area->is_available) {
|
2020-11-26 18:50:25 +00:00
|
|
|
if (kinfo->kernel_phys_base >= area->base &&
|
2021-12-17 22:32:04 +00:00
|
|
|
kinfo->kernel_phys_base <= area->limit)
|
|
|
|
{
|
|
|
|
return false;
|
2017-11-04 14:03:45 +00:00
|
|
|
}
|
|
|
|
|
2020-11-26 18:50:25 +00:00
|
|
|
if (kinfo->kernel_phys_limit >= area->base &&
|
2021-12-17 22:32:04 +00:00
|
|
|
kinfo->kernel_phys_limit <= area->limit)
|
|
|
|
{
|
|
|
|
return false;
|
2017-11-04 14:03:45 +00:00
|
|
|
}
|
|
|
|
|
2020-11-26 18:50:25 +00:00
|
|
|
for (unsigned int j = 0; j < kinfo->modules_count; ++j) {
|
2021-12-17 22:32:04 +00:00
|
|
|
const struct Kernel_Info_Module *const module =
|
|
|
|
&kinfo->modules[j];
|
2017-11-04 14:03:45 +00:00
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
if (module->base >= area->base && module->base <= area->limit) {
|
|
|
|
return false;
|
2017-11-04 14:03:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (module->limit >= area->base &&
|
2021-12-17 22:32:04 +00:00
|
|
|
module->limit <= area->limit)
|
|
|
|
{
|
|
|
|
return false;
|
2017-11-04 14:03:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-04 12:01:10 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2017-11-04 14:03:45 +00:00
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
bool cmdline_terminated(const char *const str)
|
2017-11-04 14:03:45 +00:00
|
|
|
{
|
2021-12-17 22:32:04 +00:00
|
|
|
for (size_t i = 0; i < KERNEL_INFO_CMDLINE_SIZE_MAX; ++i) {
|
|
|
|
if (str[i] == '\0') return true;
|
2017-11-04 14:03:45 +00:00
|
|
|
}
|
|
|
|
|
2021-12-17 22:32:04 +00:00
|
|
|
return false;
|
2017-11-04 14:03:45 +00:00
|
|
|
}
|