2017-11-09 11:00:36 -05:00
|
|
|
#include "info.h"
|
2017-11-04 08:01:10 -04:00
|
|
|
|
2017-11-04 10:03:45 -04:00
|
|
|
static unsigned char cmdline_terminated(const char *s);
|
|
|
|
|
2017-11-04 08:01:10 -04:00
|
|
|
unsigned char kernelmq_info_validate_and_copy(
|
|
|
|
struct KernelMQ_Info *const dest,
|
|
|
|
const struct KernelMQ_Info *const src
|
|
|
|
) {
|
|
|
|
if (!src) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-11-08 07:39:56 -05:00
|
|
|
if (!dest) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-11-04 10:03:45 -04:00
|
|
|
if (!cmdline_terminated(src->cmdline)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src->modules_count > KERNELMQ_INFO_MODULES_MAX) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src->areas_count > KERNELMQ_INFO_AREAS_MAX) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src->kernel_size == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src->kernel_offset == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src->kernel_phys_base + src->kernel_size != src->kernel_phys_limit + 1) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src->kernel_virt_base + src->kernel_size != src->kernel_virt_limit + 1) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src->kernel_virt_base - src->kernel_phys_base != src->kernel_offset) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned long modules_total_size = 0;
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < src->modules_count; ++i) {
|
|
|
|
const struct KernelMQ_Info_Module *const module = &src->modules[i];
|
|
|
|
|
|
|
|
modules_total_size += module->size;
|
|
|
|
|
|
|
|
if (module->size == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (module->base + module->size != module->limit + 1) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!cmdline_terminated(module->cmdline)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src->modules_total_size != modules_total_size) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src->kernel_and_modules_total_size != src->kernel_size + src->modules_total_size) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned long long last = 0;
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < src->areas_count; ++i) {
|
|
|
|
const struct KernelMQ_Info_Area *const area = &src->areas[i];
|
|
|
|
if (last > area->base) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (area->size == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (area->base + area->size != area->limit + 1) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
last = area->limit + 1;
|
|
|
|
|
|
|
|
if (!area->is_available) {
|
|
|
|
if (src->kernel_phys_base >= area->base &&
|
|
|
|
src->kernel_phys_base <= area->limit) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src->kernel_phys_limit >= area->base &&
|
|
|
|
src->kernel_phys_limit <= area->limit) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (unsigned int j = 0; j < src->modules_count; ++j) {
|
|
|
|
const struct KernelMQ_Info_Module *const module = &src->modules[j];
|
|
|
|
|
|
|
|
if (module->base >= area->base &&
|
|
|
|
module->base <= area->limit) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (module->limit >= area->base &&
|
|
|
|
module->limit <= area->limit) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-04 08:01:10 -04:00
|
|
|
*dest = *src;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2017-11-04 10:03:45 -04:00
|
|
|
|
|
|
|
unsigned char cmdline_terminated(const char *const s)
|
|
|
|
{
|
|
|
|
for (unsigned int i = 0; i < KERNELMQ_INFO_CMDLINE_SIZE_MAX; ++i) {
|
|
|
|
if (s[i] == 0) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|