Add Multiboot 2 tag validation functions

This commit is contained in:
Alex Kotov 2020-11-28 02:24:12 +05:00
parent 8064ee609f
commit 6745bdeba1
Signed by: kotovalexarian
GPG Key ID: 553C0EBBEB5D5F08
3 changed files with 496 additions and 9 deletions

View File

@ -13,6 +13,7 @@ noinst_PROGRAMS = \
libkernaux_a_SOURCES = \
src/arch/i386.S \
src/multiboot2.c \
src/pfa.c
tests_hang_SOURCES = $(libkernaux_a_SOURCES) tests/hang.c

View File

@ -5,9 +5,34 @@
extern "C" {
#endif
/*********************
* Common structures *
*********************/
/****************
* Common types *
****************/
enum KernAux_Multiboot2_TagType {
KERNAUX_MULTIBOOT2_TAGTYPE_NONE = 0,
KERNAUX_MULTIBOOT2_TAGTYPE_BOOT_CMD_LINE = 1,
KERNAUX_MULTIBOOT2_TAGTYPE_BOOT_LOADER_NAME = 2,
KERNAUX_MULTIBOOT2_TAGTYPE_MODULE = 3,
KERNAUX_MULTIBOOT2_TAGTYPE_BASIC_MEMORY_INFO = 4,
KERNAUX_MULTIBOOT2_TAGTYPE_BIOS_BOOT_DEVICE = 5,
KERNAUX_MULTIBOOT2_TAGTYPE_MEMORY_MAP = 6,
KERNAUX_MULTIBOOT2_TAGTYPE_VBE_INFO = 7,
KERNAUX_MULTIBOOT2_TAGTYPE_FRAMEBUFFER_INFO = 8,
KERNAUX_MULTIBOOT2_TAGTYPE_ELF_SYMBOLS = 9,
KERNAUX_MULTIBOOT2_TAGTYPE_APM_TABLE = 10,
KERNAUX_MULTIBOOT2_TAGTYPE_EFI_32BIT_SYSTEM_TABLE_PTR = 11,
KERNAUX_MULTIBOOT2_TAGTYPE_EFI_64BIT_SYSTEM_TABLE_PTR = 12,
KERNAUX_MULTIBOOT2_TAGTYPE_SMBIOS_TABLES = 13,
KERNAUX_MULTIBOOT2_TAGTYPE_ACPI_OLD_RSDP = 14,
KERNAUX_MULTIBOOT2_TAGTYPE_ACPI_NEW_RSDP = 15,
KERNAUX_MULTIBOOT2_TAGTYPE_NETWORKING_INFO = 16,
KERNAUX_MULTIBOOT2_TAGTYPE_EFI_MEMORY_MAP = 17,
KERNAUX_MULTIBOOT2_TAGTYPE_EFI_BOOT_SERVICES_NOT_TERMINATED = 18,
KERNAUX_MULTIBOOT2_TAGTYPE_EFI_32BIT_IMAGE_HANDLE_PTR = 19,
KERNAUX_MULTIBOOT2_TAGTYPE_EFI_64BIT_IMAGE_HANDLE_PTR = 20,
KERNAUX_MULTIBOOT2_TAGTYPE_IMAGE_LOAD_BASE_PHYS_ADDR = 21,
};
struct KernAux_Multiboot2 {
unsigned int total_size : 32;
@ -16,8 +41,8 @@ struct KernAux_Multiboot2 {
__attribute__((packed));
struct KernAux_Multiboot2_TagBase {
unsigned int type : 32;
unsigned int size : 32;
enum KernAux_Multiboot2_TagType type : 32;
unsigned int size : 32;
}
__attribute__((packed));
@ -25,6 +50,13 @@ __attribute__((packed));
* Tag structures *
******************/
struct KernAux_Multiboot2_Tag_None {
// type = 0
// size = 8
struct KernAux_Multiboot2_TagBase base;
}
__attribute__((packed));
struct KernAux_Multiboot2_Tag_BootCmdLine {
// type = 1
// size = ?
@ -150,7 +182,7 @@ struct KernAux_Multiboot2_Tag_APMTable {
}
__attribute__((packed));
struct KernAux_Multiboot2_Tag_EFI32bitSystemTablePointer {
struct KernAux_Multiboot2_Tag_EFI32bitSystemTablePtr {
// type = 11
// size = 12
struct KernAux_Multiboot2_TagBase base;
@ -159,7 +191,7 @@ struct KernAux_Multiboot2_Tag_EFI32bitSystemTablePointer {
}
__attribute__((packed));
struct KernAux_Multiboot2_Tag_EFI64bitSystemTablePointer {
struct KernAux_Multiboot2_Tag_EFI64bitSystemTablePtr {
// type = 12
// size = 16
struct KernAux_Multiboot2_TagBase base;
@ -227,7 +259,7 @@ struct KernAux_Multiboot2_Tag_EFIBootServicesNotTerminated {
}
__attribute__((packed));
struct KernAux_Multiboot2_Tag_EFI32bitImageHandlePointer {
struct KernAux_Multiboot2_Tag_EFI32bitImageHandlePtr {
// type = 19
// size = 12
struct KernAux_Multiboot2_TagBase base;
@ -236,7 +268,7 @@ struct KernAux_Multiboot2_Tag_EFI32bitImageHandlePointer {
}
__attribute__((packed));
struct KernAux_Multiboot2_Tag_EFI64bitImageHandlePointer {
struct KernAux_Multiboot2_Tag_EFI64bitImageHandlePtr {
// type = 20
// size = 16
struct KernAux_Multiboot2_TagBase base;
@ -266,6 +298,125 @@ struct KernAux_Multiboot2_Tag_MemoryMap_EntryBase {
}
__attribute__((packed));
/****************************
* Tag validation functions *
****************************/
unsigned char KernAux_Multiboot2_TagBase_is_valid(
const struct KernAux_Multiboot2_TagBase *tag_base
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_None_is_valid(
const struct KernAux_Multiboot2_Tag_None *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_BootCmdLine_is_valid(
const struct KernAux_Multiboot2_Tag_BootCmdLine *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_BootLoaderName_is_valid(
const struct KernAux_Multiboot2_Tag_BootLoaderName *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_Module_is_valid(
const struct KernAux_Multiboot2_Tag_Module *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_BasicMemoryInfo_is_valid(
const struct KernAux_Multiboot2_Tag_BasicMemoryInfo *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_BIOSBootDevice_is_valid(
const struct KernAux_Multiboot2_Tag_BIOSBootDevice *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_MemoryMap_is_valid(
const struct KernAux_Multiboot2_Tag_MemoryMap *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_VBEInfo_is_valid(
const struct KernAux_Multiboot2_Tag_VBEInfo *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_FramebufferInfo_is_valid(
const struct KernAux_Multiboot2_Tag_FramebufferInfo *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_ELFSymbols_is_valid(
const struct KernAux_Multiboot2_Tag_ELFSymbols *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_APMTable_is_valid(
const struct KernAux_Multiboot2_Tag_APMTable *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_EFI32bitSystemTablePtr_is_valid(
const struct KernAux_Multiboot2_Tag_EFI32bitSystemTablePtr *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_EFI64bitSystemTablePtr_is_valid(
const struct KernAux_Multiboot2_Tag_EFI64bitSystemTablePtr *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_SMBIOSTables_is_valid(
const struct KernAux_Multiboot2_Tag_SMBIOSTables *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_ACPIOldRSDP_is_valid(
const struct KernAux_Multiboot2_Tag_ACPIOldRSDP *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_ACPINewRSDP_is_valid(
const struct KernAux_Multiboot2_Tag_ACPINewRSDP *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_NetworkingInfo_is_valid(
const struct KernAux_Multiboot2_Tag_NetworkingInfo *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_EFIMemoryMap_is_valid(
const struct KernAux_Multiboot2_Tag_EFIMemoryMap *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_EFIBootServicesNotTerminated_is_valid(
const struct KernAux_Multiboot2_Tag_EFIBootServicesNotTerminated *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_EFI32bitImageHandlePtr_is_valid(
const struct KernAux_Multiboot2_Tag_EFI32bitImageHandlePtr *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_EFI64bitImageHandlePtr_is_valid(
const struct KernAux_Multiboot2_Tag_EFI64bitImageHandlePtr *tag
)
__attribute__((nonnull));
unsigned char KernAux_Multiboot2_Tag_ImageLoadBasePhysAddr_is_valid(
const struct KernAux_Multiboot2_Tag_ImageLoadBasePhysAddr *tag
)
__attribute__((nonnull));
#ifdef __cplusplus
}
#endif

335
src/multiboot2.c Normal file
View File

@ -0,0 +1,335 @@
#include <kernaux/multiboot2.h>
unsigned char KernAux_Multiboot2_TagBase_is_valid(
const struct KernAux_Multiboot2_TagBase *const tag_base
) {
switch (tag_base->type) {
case KERNAUX_MULTIBOOT2_TAGTYPE_NONE:
return KernAux_Multiboot2_Tag_None_is_valid(
(struct KernAux_Multiboot2_Tag_None*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_BOOT_CMD_LINE:
return KernAux_Multiboot2_Tag_BootCmdLine_is_valid(
(struct KernAux_Multiboot2_Tag_BootCmdLine*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_BOOT_LOADER_NAME:
return KernAux_Multiboot2_Tag_BootLoaderName_is_valid(
(struct KernAux_Multiboot2_Tag_BootLoaderName*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_MODULE:
return KernAux_Multiboot2_Tag_Module_is_valid(
(struct KernAux_Multiboot2_Tag_Module*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_BASIC_MEMORY_INFO:
return KernAux_Multiboot2_Tag_BasicMemoryInfo_is_valid(
(struct KernAux_Multiboot2_Tag_BasicMemoryInfo*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_BIOS_BOOT_DEVICE:
return KernAux_Multiboot2_Tag_BIOSBootDevice_is_valid(
(struct KernAux_Multiboot2_Tag_BIOSBootDevice*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_MEMORY_MAP:
return KernAux_Multiboot2_Tag_MemoryMap_is_valid(
(struct KernAux_Multiboot2_Tag_MemoryMap*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_VBE_INFO:
return KernAux_Multiboot2_Tag_VBEInfo_is_valid(
(struct KernAux_Multiboot2_Tag_VBEInfo*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_FRAMEBUFFER_INFO:
return KernAux_Multiboot2_Tag_FramebufferInfo_is_valid(
(struct KernAux_Multiboot2_Tag_FramebufferInfo*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_ELF_SYMBOLS:
return KernAux_Multiboot2_Tag_ELFSymbols_is_valid(
(struct KernAux_Multiboot2_Tag_ELFSymbols*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_APM_TABLE:
return KernAux_Multiboot2_Tag_APMTable_is_valid(
(struct KernAux_Multiboot2_Tag_APMTable*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_EFI_32BIT_SYSTEM_TABLE_PTR:
return KernAux_Multiboot2_Tag_EFI32bitSystemTablePtr_is_valid(
(struct KernAux_Multiboot2_Tag_EFI32bitSystemTablePtr*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_EFI_64BIT_SYSTEM_TABLE_PTR:
return KernAux_Multiboot2_Tag_EFI64bitSystemTablePtr_is_valid(
(struct KernAux_Multiboot2_Tag_EFI64bitSystemTablePtr*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_SMBIOS_TABLES:
return KernAux_Multiboot2_Tag_SMBIOSTables_is_valid(
(struct KernAux_Multiboot2_Tag_SMBIOSTables*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_ACPI_OLD_RSDP:
return KernAux_Multiboot2_Tag_ACPIOldRSDP_is_valid(
(struct KernAux_Multiboot2_Tag_ACPIOldRSDP*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_ACPI_NEW_RSDP:
return KernAux_Multiboot2_Tag_ACPINewRSDP_is_valid(
(struct KernAux_Multiboot2_Tag_ACPINewRSDP*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_NETWORKING_INFO:
return KernAux_Multiboot2_Tag_NetworkingInfo_is_valid(
(struct KernAux_Multiboot2_Tag_NetworkingInfo*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_EFI_MEMORY_MAP:
return KernAux_Multiboot2_Tag_MemoryMap_is_valid(
(struct KernAux_Multiboot2_Tag_MemoryMap*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_EFI_BOOT_SERVICES_NOT_TERMINATED:
return KernAux_Multiboot2_Tag_EFIBootServicesNotTerminated_is_valid(
(struct KernAux_Multiboot2_Tag_EFIBootServicesNotTerminated*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_EFI_32BIT_IMAGE_HANDLE_PTR:
return KernAux_Multiboot2_Tag_EFI32bitImageHandlePtr_is_valid(
(struct KernAux_Multiboot2_Tag_EFI32bitImageHandlePtr*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_EFI_64BIT_IMAGE_HANDLE_PTR:
return KernAux_Multiboot2_Tag_EFI64bitImageHandlePtr_is_valid(
(struct KernAux_Multiboot2_Tag_EFI64bitImageHandlePtr*)tag_base
);
case KERNAUX_MULTIBOOT2_TAGTYPE_IMAGE_LOAD_BASE_PHYS_ADDR:
return KernAux_Multiboot2_Tag_ImageLoadBasePhysAddr_is_valid(
(struct KernAux_Multiboot2_Tag_ImageLoadBasePhysAddr*)tag_base
);
default:
return 0;
}
}
unsigned char KernAux_Multiboot2_Tag_None_is_valid(
const struct KernAux_Multiboot2_Tag_None *const tag
) {
return (
tag->base.type == KERNAUX_MULTIBOOT2_TAGTYPE_NONE &&
tag->base.size == 8
);
}
unsigned char KernAux_Multiboot2_Tag_BootCmdLine_is_valid(
const struct KernAux_Multiboot2_Tag_BootCmdLine *const tag
) {
unsigned int index = 1;
for (
const char *ptr = tag->cmdline;
*ptr && index < tag->base.size;
++ptr
) {
++index;
}
return (
tag->base.type == KERNAUX_MULTIBOOT2_TAGTYPE_BOOT_CMD_LINE &&
tag->base.size == 8 + index
);
}
unsigned char KernAux_Multiboot2_Tag_BootLoaderName_is_valid(
const struct KernAux_Multiboot2_Tag_BootLoaderName *const tag
) {
unsigned int index = 1;
for (
const char *ptr = tag->name;
*ptr && index < tag->base.size;
++ptr
) {
++index;
}
return (
tag->base.type == KERNAUX_MULTIBOOT2_TAGTYPE_BOOT_LOADER_NAME &&
tag->base.size == 8 + index
);
}
unsigned char KernAux_Multiboot2_Tag_Module_is_valid(
const struct KernAux_Multiboot2_Tag_Module *const tag
) {
unsigned int index = 1;
for (
const char *ptr = tag->cmdline;
*ptr && index < tag->base.size;
++ptr
) {
++index;
}
return (
tag->base.type == KERNAUX_MULTIBOOT2_TAGTYPE_MODULE &&
tag->base.size == 16 + index &&
tag->mod_start < tag->mod_end
);
}
unsigned char KernAux_Multiboot2_Tag_BasicMemoryInfo_is_valid(
const struct KernAux_Multiboot2_Tag_BasicMemoryInfo *const tag
) {
return (
tag->base.type == KERNAUX_MULTIBOOT2_TAGTYPE_BASIC_MEMORY_INFO &&
tag->base.size == 16
);
}
unsigned char KernAux_Multiboot2_Tag_BIOSBootDevice_is_valid(
const struct KernAux_Multiboot2_Tag_BIOSBootDevice *const tag
) {
return (
tag->base.type == KERNAUX_MULTIBOOT2_TAGTYPE_BIOS_BOOT_DEVICE &&
tag->base.size == 20
);
}
unsigned char KernAux_Multiboot2_Tag_MemoryMap_is_valid(
const struct KernAux_Multiboot2_Tag_MemoryMap *const tag
) {
return (
tag->base.type == KERNAUX_MULTIBOOT2_TAGTYPE_MEMORY_MAP &&
tag->base.size >= 16 &&
(tag->base.size - 16) % tag->entry_size == 0
);
}
unsigned char KernAux_Multiboot2_Tag_VBEInfo_is_valid(
const struct KernAux_Multiboot2_Tag_VBEInfo *const tag
) {
return (
tag->base.type == KERNAUX_MULTIBOOT2_TAGTYPE_VBE_INFO &&
tag->base.size == 784
);
}
unsigned char KernAux_Multiboot2_Tag_FramebufferInfo_is_valid(
const struct KernAux_Multiboot2_Tag_FramebufferInfo *const tag
) {
return (
tag->base.type == KERNAUX_MULTIBOOT2_TAGTYPE_FRAMEBUFFER_INFO &&
tag->base.size >= 31
);
}
unsigned char KernAux_Multiboot2_Tag_ELFSymbols_is_valid(
const struct KernAux_Multiboot2_Tag_ELFSymbols *const tag
) {
return (
tag->base.type == KERNAUX_MULTIBOOT2_TAGTYPE_ELF_SYMBOLS &&
tag->base.size >= 16 &&
(tag->base.size - 16) % tag->ent_size == 0
);
}
unsigned char KernAux_Multiboot2_Tag_APMTable_is_valid(
const struct KernAux_Multiboot2_Tag_APMTable *const tag
) {
return (
tag->base.type == KERNAUX_MULTIBOOT2_TAGTYPE_APM_TABLE &&
tag->base.size == 28
);
}
unsigned char KernAux_Multiboot2_Tag_EFI32bitSystemTablePtr_is_valid(
const struct KernAux_Multiboot2_Tag_EFI32bitSystemTablePtr *const tag
) {
return (
tag->base.type ==
KERNAUX_MULTIBOOT2_TAGTYPE_EFI_32BIT_SYSTEM_TABLE_PTR &&
tag->base.size == 12
);
}
unsigned char KernAux_Multiboot2_Tag_EFI64bitSystemTablePtr_is_valid(
const struct KernAux_Multiboot2_Tag_EFI64bitSystemTablePtr *const tag
) {
return (
tag->base.type ==
KERNAUX_MULTIBOOT2_TAGTYPE_EFI_64BIT_SYSTEM_TABLE_PTR &&
tag->base.size == 16
);
}
unsigned char KernAux_Multiboot2_Tag_SMBIOSTables_is_valid(
const struct KernAux_Multiboot2_Tag_SMBIOSTables *const tag
) {
return (
tag->base.type == KERNAUX_MULTIBOOT2_TAGTYPE_SMBIOS_TABLES &&
tag->base.size >= 16
);
}
unsigned char KernAux_Multiboot2_Tag_ACPIOldRSDP_is_valid(
const struct KernAux_Multiboot2_Tag_ACPIOldRSDP *const tag
) {
return (
tag->base.type == KERNAUX_MULTIBOOT2_TAGTYPE_ACPI_OLD_RSDP &&
tag->base.size >= 8
);
}
unsigned char KernAux_Multiboot2_Tag_ACPINewRSDP_is_valid(
const struct KernAux_Multiboot2_Tag_ACPINewRSDP *const tag
) {
return (
tag->base.type == KERNAUX_MULTIBOOT2_TAGTYPE_ACPI_NEW_RSDP &&
tag->base.size >= 8
);
}
unsigned char KernAux_Multiboot2_Tag_NetworkingInfo_is_valid(
const struct KernAux_Multiboot2_Tag_NetworkingInfo *const tag
) {
return (
tag->base.type == KERNAUX_MULTIBOOT2_TAGTYPE_NETWORKING_INFO &&
tag->base.size >= 8
);
}
unsigned char KernAux_Multiboot2_Tag_EFIMemoryMap_is_valid(
const struct KernAux_Multiboot2_Tag_EFIMemoryMap *const tag
) {
return (
tag->base.type == KERNAUX_MULTIBOOT2_TAGTYPE_EFI_MEMORY_MAP &&
tag->base.size >= 16
);
}
unsigned char KernAux_Multiboot2_Tag_EFIBootServicesNotTerminated_is_valid(
const struct KernAux_Multiboot2_Tag_EFIBootServicesNotTerminated *const tag
) {
return (
tag->base.type ==
KERNAUX_MULTIBOOT2_TAGTYPE_EFI_BOOT_SERVICES_NOT_TERMINATED &&
tag->base.size == 8
);
}
unsigned char KernAux_Multiboot2_Tag_EFI32bitImageHandlePtr_is_valid(
const struct KernAux_Multiboot2_Tag_EFI32bitImageHandlePtr *const tag
) {
return (
tag->base.type ==
KERNAUX_MULTIBOOT2_TAGTYPE_EFI_32BIT_IMAGE_HANDLE_PTR &&
tag->base.size == 12
);
}
unsigned char KernAux_Multiboot2_Tag_EFI64bitImageHandlePtr_is_valid(
const struct KernAux_Multiboot2_Tag_EFI64bitImageHandlePtr *const tag
) {
return (
tag->base.type ==
KERNAUX_MULTIBOOT2_TAGTYPE_EFI_64BIT_IMAGE_HANDLE_PTR &&
tag->base.size == 16
);
}
unsigned char KernAux_Multiboot2_Tag_ImageLoadBasePhysAddr_is_valid(
const struct KernAux_Multiboot2_Tag_ImageLoadBasePhysAddr *const tag
) {
return (
tag->base.type ==
KERNAUX_MULTIBOOT2_TAGTYPE_IMAGE_LOAD_BASE_PHYS_ADDR &&
tag->base.size == 12
);
}