!91 校验elf来源是否可信

Merge pull request !91 from lihehe/code
This commit is contained in:
openharmony_ci
2024-01-06 07:14:33 +00:00
committed by Gitee
4 changed files with 44 additions and 31 deletions
+23 -1
View File
@@ -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) {
+3 -21
View File
@@ -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;
+15 -9
View File
@@ -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);
+3
View File
@@ -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);