dm_verify

参考https://cloud.tencent.com/developer/article/1054088

static int verity_verify_io(struct dm_verity_io *io) { bool is_zero; struct dm_verity *v = io->v; struct bvec_iter start; unsigned b; struct crypto_wait wait; struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size); for (b = 0; b < io->n_blocks; b++) { int r; sector_t cur_block = io->block + b; struct ahash_request *req = verity_io_hash_req(v, io); if (v->validated_blocks && likely(test_bit(cur_block, v->validated_blocks))) { verity_bv_skip_block(v, io, &io->iter); continue; } r = verity_hash_for_block(v, io, cur_block, verity_io_want_digest(v, io), &is_zero); if (unlikely(r < 0)) return r; if (is_zero) { /* * If we expect a zero block, don't validate, just * return zeros. */ r = verity_for_bv_block(v, io, &io->iter, verity_bv_zero); if (unlikely(r < 0)) return r; continue; } r = verity_hash_init(v, req, &wait); if (unlikely(r < 0)) return r; start = io->iter; r = verity_for_io_block(v, io, &io->iter, &wait); if (unlikely(r < 0)) return r; r = verity_hash_final(v, req, verity_io_real_digest(v, io), &wait); if (unlikely(r < 0)) return r; if (likely(memcmp(verity_io_real_digest(v, io), verity_io_want_digest(v, io), v->digest_size) == 0)) { if (v->validated_blocks) set_bit(cur_block, v->validated_blocks); continue; } else if (verity_fec_decode(v, io, DM_VERITY_BLOCK_TYPE_DATA, cur_block, NULL, &start) == 0) continue; else { if (bio->bi_status) { /* * Error correction failed; Just return error */ return -EIO; } if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA, cur_block)) return -EIO; } } return 0; } 这里面怎么修改
08-14
static int LoadDmDeviceTable(int fd, const char *devName, DmVerityTarget *target) { int rc; errno_t err; char *parasBuf = NULL; size_t parasTotalSize; struct dm_ioctl *io = NULL; struct dm_target_spec *ts = NULL; char *paras = NULL; FS_DM_RETURN_ERR_IF_NULL(target); FS_DM_RETURN_ERR_IF_NULL(target->paras); parasTotalSize = DM_ALIGN(sizeof(*io) + sizeof(*ts) + target->paras_len + 1); parasBuf = calloc(1, parasTotalSize); if (parasBuf == NULL) { BEGET_LOGE("error, calloc dm table fail"); return -1; } io = (struct dm_ioctl *)parasBuf; ts = (struct dm_target_spec *)(parasBuf + sizeof(*io)); paras = parasBuf + sizeof(*io) + sizeof((*ts)); do { rc = InitDmIo(io, devName); if (rc != 0) { BEGET_LOGE("error 0x%x, init dm io", rc); break; } io->data_size = parasTotalSize; io->data_start = sizeof(*io); io->target_count = 1; // io->flags |= DM_READONLY_FLAG; ts->status = 0; ts->sector_start = target->start; ts->length = target->length; err = strcpy_s(ts->target_type, sizeof(ts->target_type), "verity"); if (err != EOK) { rc = -1; BEGET_LOGE("error 0x%x, cp target type", err); break; } err = strcpy_s(paras, target->paras_len + 1, target->paras); if (err != EOK) { rc = -1; BEGET_LOGE("error 0x%x, cp target paras", err); break; } ts->next = parasTotalSize - sizeof(*io); rc = ioctl(fd, DM_TABLE_LOAD, io); if (rc != 0) { BEGET_LOGE("error 0x%x, DM_TABLE_LOAD failed for %s", rc, devName); break; } } while (0); free(parasBuf); return rc; } static int ActiveDmDevice(int fd, const char *devName) { int rc; struct dm_ioctl io; rc = InitDmIo(&io, devName); if (rc != 0) { return rc; } // io.flags |= DM_READONLY_FLAG; rc = ioctl(fd, DM_DEV_SUSPEND, &io); if (rc != 0) { BEGET_LOGE("error, DM_TABLE_SUSPEND for %s, ret=%d", devName, rc); return rc; } return 0; } 注释以后有没有什么影响
08-14
<think>嗯,用户想了解dm-verify和AVB(Android Verified Boot)的关系以及它们的用法。首先,我需要确定这两个概念各自的定义和作用,然后再看看它们是如何在Android系统中协同工作的。 首先,AVB是Android Verified Boot的缩写,主要用于启动验证,确保设备启动链中每个阶段的固件都是经过验证的,没有被篡改。根据引用[1]中的内容,AVB 2.0的设计中,hashtree验证错误是由HLOS(High-Level Operating System,即Android系统)而不是引导加载程序(bootloader)检测的。这说明AVB在验证过程中涉及到不同的阶段,可能在系统启动的不同环节进行验证。 然后是dm-verify,这是Linux设备映射器(Device Mapper)的一个模块,用于在块设备层进行实时验证。dm-verify通常用于验证整个分区的完整性和真实性,比如系统分区或vendor分区。根据已有的知识,dm-verify会在系统运行时对每个数据块进行验证,确保其未被篡改,这可能与AVB的验证阶段不同,AVB更多是在启动时验证,而dm-verify是在运行时持续验证。 接下来需要理清两者的关系。根据Android文档,AVB和dm-verify可以结合使用。AVB在启动阶段验证内核和initramfs等组件,而dm-verify则在系统启动后对系统分区进行实时验证。引用[2]中提到了启动参数的设置,包括root分区的PARTUUID和文件系统类型,这可能与dm-verify在挂载根文件系统时的验证有关。例如,在启动参数中设置dm-verify相关的参数,确保根文件系统在挂载时进行验证。 在实现方式上,AVB可能通过bootloader传递验证信息给内核,比如通过cmdline参数,而dm-verify则利用这些参数在内核层面进行验证。例如,AVB可能会在启动时生成一个哈希树(hashtree),并将该信息写入vbmeta结构体中,内核在启动时会读取这些信息,并通过dm-verify模块进行持续的验证。 关于具体用法,用户可能需要配置AVB的vbmeta结构体,生成相应的签名,并在设备的分区布局中包含vbmeta分区。同时,在内核配置中启用dm-verify的支持,并在设备树或启动参数中指定验证相关的参数,如dm="..."。这样,在系统启动时,AVB会验证boot和vbmeta分区,而dm-verify在挂载系统分区时进行实时验证。 可能需要注意的问题包括两者的验证阶段不同,AVB在启动早期,而dm-verify在运行时,因此它们的错误处理机制可能不同。例如,引用[1]提到AVB的hashtree_error_mode参数控制如何处理验证错误,而dm-verify可能在内核层面触发不同的错误处理机制,比如重启或进入安全模式。 用户可能的应用场景包括需要高安全性的Android设备,确保从启动到系统运行的每个阶段都经过验证,防止恶意软件或未经授权的修改。此外,了解如何配置和调试这些验证机制,对于系统开发者和安全工程师来说非常重要。 相关问题方面,用户可能还想知道如何配置AVB和dm-verify的具体步骤,如何处理验证失败的情况,以及两者在性能上的影响。此外,可能对如何生成和签名vbmeta镜像,如何集成到系统镜像中,以及如何调试验证过程中的问题感兴趣。</think>### dm-verify与AVB的关系及实现分析 #### 1. **基本概念** - **AVB (Android Verified Boot)**:用于验证启动链的完整性,从bootloader到系统分区的每个阶段均需验证签名[^1]。其核心通过`vbmeta`分区存储哈希值和签名。 - **dm-verify**:Linux内核中的设备映射器模块,用于在块设备层实时验证数据完整性,常与AVB配合保护系统分区[^2]。 #### 2. **协作机制** - **启动阶段**:AVB验证`boot.img`和`vbmeta`分区的签名,确保引导组件可信。 - **运行时验证**:系统启动后,dm-verify通过`vbmeta`中的哈希树(hashtree)实时校验`/system`或`/vendor`分区的每个数据块。 #### 3. **实现配置** ##### AVB配置步骤: 1. 生成密钥对并签名分区镜像: ```bash avbtool make_vbmeta_image --output vbmeta.img --include_descriptors_from_image boot.img ``` 2. 将`vbmeta.img`刷入设备独立分区,并在bootloader中启用AVB验证。 ##### dm-verify启用方法: 在内核配置中启用`CONFIG_DM_VERITY`,并通过启动参数传递验证参数: ``` dm="1 vroot none ro 1, 0 253:0 verity 1 PARTUUID=xxxx... PARTUUID=xxxx... 4096 4096 512 512 sha256 hashtree_hex salt_hex" ``` 参数解析: - `PARTUUID`:指定待验证分区及哈希树所在分区。 - `sha256`:哈希算法类型。 #### 4. **错误处理** - **AVB**:通过`hashtree_error_mode`定义验证失败行为(如`AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE`)[^1]。 - **dm-verify**:触发I/O错误,可能导致挂载失败或内核panic。 #### 5. **典型应用场景** - 防止Rootkit篡改系统分区。 - 满足Android兼容性要求(如GMS认证设备必须启用AVB)。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值