code_sign 适配6.6内核

Signed-off-by: cbl <caobaolong5@huawei.com>
This commit is contained in:
cbl
2024-09-06 15:35:11 +08:00
parent c3adf85085
commit dac3ee979b
3 changed files with 47 additions and 16 deletions
+21 -3
View File
@@ -4,14 +4,22 @@
*/
#include <asm/byteorder.h>
#include <linux/version.h>
#include <linux/fsverity.h>
#include <linux/slab.h>
#include "dsmm_developer.h"
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
#include <linux/pagemap.h>
#endif
#include "code_sign_elf.h"
#include "code_sign_log.h"
#include "verify_cert_chain.h"
#ifdef CONFIG_SECURITY_XPM
#include "dsmm_developer.h"
#endif
#define SIGN_HEAD_SIZE (sizeof(sign_head_t))
static void parse_sign_head(sign_head_t *out, char *ptr)
@@ -197,12 +205,20 @@ out:
int elf_file_enable_fs_verity(struct file *file)
{
#ifdef CONFIG_SECURITY_XPM
/* developer mode */
if (get_developer_mode_state() != STATE_ON) {
code_sign_log_info("developer mode off, elf not allowed to execute");
return -EINVAL;
}
#else
code_sign_log_info("developer mode off, elf not allowed to execute");
return -EINVAL;
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
mm_segment_t fs;
#endif
char *path_buf = kzalloc(PATH_MAX, GFP_KERNEL);
if (!path_buf) {
code_sign_log_error("alloc mem for path_buf failed");
@@ -245,10 +261,10 @@ int elf_file_enable_fs_verity(struct file *file)
err = -ENOMEM;
goto filp_close_out;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
fs = get_fs();
set_fs(KERNEL_DS);
#endif
ssize_t cnt = vfs_read(fp, sign_head_ptr, SIGN_HEAD_SIZE, &pos);
if (cnt != SIGN_HEAD_SIZE) {
code_sign_log_error("read sign head from file failed: return value %lu, expect %u bytes",
@@ -278,7 +294,9 @@ int elf_file_enable_fs_verity(struct file *file)
release_sign_head_out:
kfree(sign_head_ptr);
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
set_fs(fs);
#endif
filp_close_out:
filp_close(fp, NULL);
release_path_buf_out:
+19 -12
View File
@@ -8,11 +8,12 @@
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/compat.h>
#include <linux/version.h>
#include "avc.h"
#include "objsec.h"
#include "dsmm_developer.h"
#include "code_sign_ioctl.h"
#include "code_sign_log.h"
#define MAX_SIGNING_LENGTH 2048
DEFINE_SPINLOCK(cert_chain_tree_lock);
struct rb_root cert_chain_tree = RB_ROOT;
@@ -71,8 +72,11 @@ int code_sign_check_caller(char *caller)
u32 sid = current_sid(), context_len;
char *context = NULL;
int rc;
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
rc = security_sid_to_context(&selinux_state, sid, &context, &context_len);
#else
rc = security_sid_to_context(sid, &context, &context_len);
#endif
if (rc)
return -EINVAL;
@@ -180,11 +184,17 @@ int code_sign_avc_has_perm(u16 tclass, u32 requested)
struct av_decision avd;
u32 sid = current_sid();
int rc, rc2;
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
rc = avc_has_perm_noaudit(&selinux_state, sid, sid, tclass, requested,
AVC_STRICT, &avd);
rc2 = avc_audit(&selinux_state, sid, sid, tclass, requested, &avd, rc,
NULL, AVC_STRICT);
#else
rc = avc_has_perm_noaudit(sid, sid, tclass, requested,
AVC_STRICT, &avd);
rc2 = avc_audit(sid, sid, tclass, requested, &avd, rc,
NULL);
#endif
if (rc2)
return rc2;
@@ -207,7 +217,8 @@ int parse_cert_source(unsigned long args, struct cert_source **_source)
goto copy_source_failed;
}
if (info.path_len > CERT_CHAIN_PATH_LEN_MAX || info.issuer_length == 0 || info.signing_length == 0) {
if (info.path_len > CERT_CHAIN_PATH_LEN_MAX || info.issuer_length == 0 || info.signing_length == 0
|| info.issuer_length > MAX_SIGNING_LENGTH || info.signing_length > MAX_SIGNING_LENGTH) {
code_sign_log_error("invalid path len or subject or issuer");
ret = -EINVAL;
goto copy_source_failed;
@@ -288,10 +299,8 @@ long code_sign_ioctl(struct file *filp, unsigned int cmd, unsigned long args)
if (ret == 1) {
// developer cert
if (get_developer_mode_state() == STATE_ON) {
code_sign_log_debug("add developer cert");
ret = cert_chain_insert(&dev_cert_chain_tree, source);
}
code_sign_log_debug("add developer cert");
ret = cert_chain_insert(&dev_cert_chain_tree, source);
} else {
code_sign_log_debug("add release cert");
ret = cert_chain_insert(&cert_chain_tree, source);
@@ -314,10 +323,8 @@ long code_sign_ioctl(struct file *filp, unsigned int cmd, unsigned long args)
if (ret == 1) {
// developer cert
if (get_developer_mode_state() == STATE_ON) {
code_sign_log_debug("remove developer cert");
ret = cert_chain_remove(&dev_cert_chain_tree, source);
}
code_sign_log_debug("remove developer cert");
ret = cert_chain_remove(&dev_cert_chain_tree, source);
} else {
code_sign_log_debug("remove release cert");
ret = cert_chain_remove(&cert_chain_tree, source);
+7 -1
View File
@@ -6,15 +6,19 @@
#include <linux/cred.h>
#include <linux/key.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/verification.h>
#include <crypto/pkcs7.h>
#include "objsec.h"
#include "dsmm_developer.h"
#include "code_sign_ext.h"
#include "code_sign_ioctl.h"
#include "code_sign_log.h"
#include "verify_cert_chain.h"
#ifdef CONFIG_SECURITY_XPM
#include "dsmm_developer.h"
#endif
/*
* Find the key (X.509 certificate) to use to verify a PKCS#7 message. PKCS#7
* uses the issuer's name and the issuing certificate serial number for
@@ -144,11 +148,13 @@ void code_sign_verify_certchain(const void *raw_pkcs7, size_t pkcs7_len,
bool is_dev_mode = false;
#ifdef CONFIG_SECURITY_XPM
// developer mode && developer proc
if (get_developer_mode_state() == STATE_ON) {
code_sign_log_info("developer mode on");
is_dev_mode = true;
}
#endif
for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
/* Find the key for the signature if there is one */