From 4f1953a75dd3021fdbe1afccab6e761982edba36 Mon Sep 17 00:00:00 2001 From: yeyuning Date: Mon, 19 Aug 2024 15:51:56 +0800 Subject: [PATCH] skipping xpm check not elf file Signed-off-by: yeyuning Change-Id: I817b906944ae8de8af20ba22e9c8167ee3d781dd --- code_sign/code_sign_ext.c | 10 +++--- code_sign/code_sign_ioctl.c | 4 +-- xpm/validator/elf_code_segment_info.c | 49 ++++++++++++++++++++++++--- 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/code_sign/code_sign_ext.c b/code_sign/code_sign_ext.c index 4811b26..16abbaf 100644 --- a/code_sign/code_sign_ext.c +++ b/code_sign/code_sign_ext.c @@ -24,10 +24,12 @@ static inline int check_code_sign_descriptor(const struct inode *inode, if (!desc->cs_version) return 0; - - if (le64_to_cpu(desc->pgtypeinfo_off) > le64_to_cpu(desc->data_size) - le32_to_cpu(desc->pgtypeinfo_size)) { + + // when calc pgtypeinfo_size, trans bit size to byte size + u32 pgtypeinfo_size_bytes = le32_to_cpu(desc->pgtypeinfo_size) / 8; + if (le64_to_cpu(desc->pgtypeinfo_off) > le64_to_cpu(desc->data_size) - pgtypeinfo_size_bytes) { code_sign_log_error("Wrong offset: %llu (pgtypeinfo_off) > %llu (data_size) - %u (pgtypeinfo_size)", - le64_to_cpu(desc->pgtypeinfo_off), le64_to_cpu(desc->data_size), le32_to_cpu(desc->pgtypeinfo_size)); + le64_to_cpu(desc->pgtypeinfo_off), le64_to_cpu(desc->data_size), pgtypeinfo_size_bytes); return -EINVAL; } @@ -70,8 +72,8 @@ void code_sign_before_measurement(void *_desc, int *ret) struct code_sign_descriptor *desc = CAST_CODE_SIGN_DESC(_desc); if (desc->cs_version == 1) { - desc->cs_version = 0; *ret = desc->cs_version; + desc->cs_version = 0; } else { *ret = desc->cs_version; } diff --git a/code_sign/code_sign_ioctl.c b/code_sign/code_sign_ioctl.c index 16e640c..79f1238 100644 --- a/code_sign/code_sign_ioctl.c +++ b/code_sign/code_sign_ioctl.c @@ -213,7 +213,7 @@ int parse_cert_source(unsigned long args, struct cert_source **_source) goto copy_source_failed; } - source->subject = kzalloc(info.signing_length, GFP_KERNEL); + source->subject = kzalloc(info.signing_length + 1, GFP_KERNEL); if (!source->subject) { ret = -ENOMEM; goto copy_source_failed; @@ -225,7 +225,7 @@ int parse_cert_source(unsigned long args, struct cert_source **_source) goto copy_subject_failed; } - source->issuer = kzalloc(info.issuer_length, GFP_KERNEL); + source->issuer = kzalloc(info.issuer_length + 1, GFP_KERNEL); if (!source->issuer) { ret = -ENOMEM; goto copy_subject_failed; diff --git a/xpm/validator/elf_code_segment_info.c b/xpm/validator/elf_code_segment_info.c index dbbb1a0..385ad3c 100644 --- a/xpm/validator/elf_code_segment_info.c +++ b/xpm/validator/elf_code_segment_info.c @@ -225,7 +225,7 @@ static int get_elf64_info(struct elfhdr *elf_ehdr, struct elf_info *elf_info) return 0; } -static int elf_check_and_get_code_segment_offset(struct file *file, struct elf_info *elf_info) +static int elf_check_and_get_code_segment_offset(struct file *file, struct elf_info *elf_info, bool *skip) { uint16_t type; struct elfhdr *elf_ehdr = &elf_info->elf_ehdr; @@ -235,8 +235,11 @@ static int elf_check_and_get_code_segment_offset(struct file *file, struct elf_i if (ret < 0) return ret; - if (memcmp(elf_ehdr->e_ident, ELFMAG, SELFMAG) != 0) - return -ENOEXEC; + if (memcmp(elf_ehdr->e_ident, ELFMAG, SELFMAG) != 0) { + // when the file is not an ELF file, skip checking + *skip = true; + return 0; + } type = elf16_get_value(elf_ehdr, elf_ehdr->e_type); if (type != ET_EXEC && type != ET_DYN) @@ -287,16 +290,52 @@ static int find_elf_code_segment_info(const char *phdr_info, struct elf_info *el return 0; } +static int handle_skip_case(struct file *file, struct exec_file_signature_info **code_segment_info) { + struct exec_file_signature_info *tmp_info = NULL; + if (*code_segment_info == NULL) { + tmp_info = kzalloc(sizeof(struct exec_file_signature_info), GFP_KERNEL); + if (tmp_info == NULL) { + return -ENOMEM; + } + } else { + tmp_info = *code_segment_info; + } + + if (tmp_info->code_segments == NULL) { + tmp_info->code_segments = kzalloc(sizeof(struct exec_segment_info), GFP_KERNEL); + if (tmp_info->code_segments == NULL) { + if (*code_segment_info == NULL) { + kfree(tmp_info); + tmp_info = NULL; + } + return -ENOMEM; + } + tmp_info->code_segment_count = 1; + } + + tmp_info->code_segments[0].file_offset = 0; + tmp_info->code_segments[0].size = file_inode(file)->i_size; + + if (*code_segment_info == NULL) { + *code_segment_info = tmp_info; + } + return 0; +} + int parse_elf_code_segment_info(struct file *file, struct exec_file_signature_info **code_segment_info) { const char *phdr_info; struct elf_info elf_info = {0}; int ret; - - ret = elf_check_and_get_code_segment_offset(file, &elf_info); + bool skip = false; + ret = elf_check_and_get_code_segment_offset(file, &elf_info, &skip); if (ret < 0) return ret; + + if (skip) { + return handle_skip_case(file, code_segment_info); + } phdr_info = kzalloc(elf_info.e_phsize, GFP_KERNEL); if (phdr_info == NULL) -- Gitee