mirror of
https://github.com/openharmony/kernel_linux_common_modules.git
synced 2026-08-27 01:31:36 -04:00
check whether elf comes from trust source
Signed-off-by: lihehe <lihehao@huawei.com> Change-Id: I458ca1e44ac3c9342435a9c785c34186c1c635d8
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include "dsmm_developer.h"
|
||||
#include "code_sign_elf.h"
|
||||
#include "code_sign_log.h"
|
||||
#include "verify_cert_chain.h"
|
||||
|
||||
#define SIGN_HEAD_SIZE (sizeof(sign_head_t))
|
||||
|
||||
@@ -94,12 +95,28 @@ static int get_fsverity_desc(sign_block_t *sign_block, char *sign_data_ptr)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sign_block->fsverity_desc = (fs_verity_desc_t *) (sign_data_ptr + sign_block->code_signing_block_hdr.offset
|
||||
sign_block->fsverity_desc = (struct code_sign_descriptor *) (sign_data_ptr + sign_block->code_signing_block_hdr.offset
|
||||
+ sizeof(tl_header_t) + sign_block->merkle_tree_hdr.length
|
||||
+ sizeof(tl_header_t));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int validate_elf_source(const struct code_sign_descriptor *desc)
|
||||
{
|
||||
const u32 sig_size = le32_to_cpu(desc->sig_size);
|
||||
int ret = 0;
|
||||
|
||||
code_sign_verify_certchain(desc->signature, sig_size, NULL, &ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (ret <= DEBUG_CODE_START || ret >= DEBUG_CODE_END || ret == DEBUG_DEVELOPER_CODE) {
|
||||
code_sign_log_error("invalid elf source, type: %d", ret);
|
||||
return -EKEYREJECTED;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int enable_by_sign_head(struct file *fp, struct inode *inode, long long fsize, char *sign_head_ptr)
|
||||
{
|
||||
sign_block_t sign_block;
|
||||
@@ -154,6 +171,11 @@ static int enable_by_sign_head(struct file *fp, struct inode *inode, long long f
|
||||
if (err) /* -ETXTBSY */
|
||||
goto out_drop_write;
|
||||
|
||||
/* validate cert chain of elf signer */
|
||||
err = validate_elf_source(sign_block.fsverity_desc);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
/* fsverity_enable_with_descriptor in fs/verity/enable.c */
|
||||
err = fsverity_enable_with_descriptor(fp, (void *)(sign_block.fsverity_desc), sign_block.fsverity_desc_hdr.length);
|
||||
if (err) {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#define _CODE_SIGN_ELF_H
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/code_sign.h>
|
||||
|
||||
#define PAGE_SIZE_4K 12
|
||||
|
||||
@@ -36,7 +37,7 @@
|
||||
* | |hash alg (1 byte )| |
|
||||
* | |log2blocksize (1 byte )| |
|
||||
* | |salt size (1 byte )| |
|
||||
* | |signature size (4 bytes)| fs verity |
|
||||
* | |signature size (4 bytes)| code sign |
|
||||
* | |data size (8 bytes)| block |
|
||||
* | |root hash (64 bytes)| |
|
||||
* | |salt (32 bytes)| |
|
||||
@@ -85,7 +86,6 @@ typedef struct
|
||||
__u32 length;
|
||||
} tl_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__u32 type;
|
||||
@@ -93,24 +93,6 @@ typedef struct
|
||||
__u32 offset;
|
||||
} block_hdr_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__u8 version;
|
||||
__u8 hash_algorithm;
|
||||
__u8 log2_block_size;
|
||||
__u8 salt_size;
|
||||
__u32 signature_size;
|
||||
__u64 data_size;
|
||||
__u8 root_hash[64];
|
||||
__u8 salt[32];
|
||||
__u32 flags;
|
||||
__u32 reserved;
|
||||
__u64 tree_offset;
|
||||
__u8 reserved_buf[127];
|
||||
__u8 cs_version;
|
||||
char signature[];
|
||||
} fs_verity_desc_t;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct
|
||||
@@ -129,7 +111,7 @@ typedef struct
|
||||
tl_header_t merkle_tree_hdr;
|
||||
merkle_tree_t *merkle_tree;
|
||||
tl_header_t fsverity_desc_hdr;
|
||||
fs_verity_desc_t *fsverity_desc;
|
||||
struct code_sign_descriptor *fsverity_desc;
|
||||
|
||||
/* sign head */
|
||||
sign_head_t sign_head;
|
||||
|
||||
@@ -74,22 +74,28 @@ int code_sign_check_caller(char *caller)
|
||||
|
||||
rc = security_sid_to_context(&selinux_state, sid, &context, &context_len);
|
||||
if (rc)
|
||||
return rc;
|
||||
return -EINVAL;
|
||||
|
||||
code_sign_log_debug("sid=%d, context=%s", sid, context);
|
||||
if (strncmp(caller, context, strlen(caller)))
|
||||
if (!strncmp(caller, context, strlen(caller)))
|
||||
return 0;
|
||||
else
|
||||
return -EKEYREJECTED;
|
||||
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
int cert_chain_insert(struct rb_root *root, struct cert_source *cert)
|
||||
{
|
||||
// procs except key_enable are only allowed to insert developer_code
|
||||
if (!code_sign_check_caller(KEY_ENABLE_CTX) && !(cert->path_type == RELEASE_DEVELOPER_CODE
|
||||
|| cert->path_type == DEBUG_DEVELOPER_CODE)) {
|
||||
code_sign_log_error("no permission to insert code %d", cert->path_type);
|
||||
return -EKEYREJECTED;
|
||||
int ret = code_sign_check_caller(KEY_ENABLE_CTX);
|
||||
if (ret == -EINVAL) {
|
||||
code_sign_log_error("load SELinux context failed");
|
||||
return -EINVAL;
|
||||
} else if (ret == -EPERM) {
|
||||
// procs except key_enable are only allowed to insert developer_code
|
||||
if (!(cert->path_type == RELEASE_DEVELOPER_CODE
|
||||
|| cert->path_type == DEBUG_DEVELOPER_CODE)) {
|
||||
code_sign_log_error("no permission to insert code %d", cert->path_type);
|
||||
return -EPERM;
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock(&cert_chain_tree_lock);
|
||||
|
||||
@@ -66,6 +66,9 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
|
||||
static void set_file_ownerid(struct cs_info *cs_info, int path_type,
|
||||
struct pkcs7_signed_info *sinfo)
|
||||
{
|
||||
if (cs_info == NULL)
|
||||
return;
|
||||
|
||||
/* Mark a debug file as OWNERID_DEBUG */
|
||||
if((path_type > DEBUG_CODE_START) && (path_type < DEBUG_CODE_END)) {
|
||||
code_sign_set_ownerid(cs_info, FILE_OWNERID_DEBUG, NULL, 0);
|
||||
|
||||
Reference in New Issue
Block a user