Skip to content

Commit efbb38f

Browse files
committed
feat: masking variants init
1 parent 23db21f commit efbb38f

3 files changed

Lines changed: 183 additions & 1 deletion

File tree

kernel/bpf/ir/kernpass/masking.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,5 @@ static bool check_run(int err)
8787
}
8888

8989
const struct custom_pass_cfg bpf_ir_kern_masking_pass =
90-
DEF_CUSTOM_PASS(DEF_FUNC_PASS(masking_pass, "masking_pass", false),
90+
DEF_CUSTOM_PASS(DEF_FUNC_PASS(masking_pass, "masking_all", false),
9191
check_run, NULL, NULL);
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
#include "linux/bpf_common.h"
3+
#include "linux/bpf_verifier.h"
4+
#include "linux/stddef.h"
5+
#include <linux/bpf_ir.h>
6+
#include "../../ir_kern.h"
7+
8+
#define CHECK_COND(cond) \
9+
if (!(cond)) { \
10+
return; \
11+
}
12+
13+
static void masking_pass(struct bpf_ir_env *env, struct ir_function *fun,
14+
void *param)
15+
{
16+
struct bpf_verifier_env *venv = env->venv;
17+
if (!venv) {
18+
RAISE_ERROR("Empty verifier env");
19+
}
20+
struct bpf_verifier_state *curstate = venv->cur_state;
21+
PRINT_LOG_INFO(env, "Verifier stuck on insn: %d\n", venv->insn_idx);
22+
if (env->verifier_err >= BPF_VERIFIER_ERR_41 &&
23+
env->verifier_err <= BPF_VERIFIER_ERR_44) {
24+
// memory range error
25+
// Should be a load/store instruction
26+
struct bpf_reg_state *regs =
27+
curstate->frame[curstate->curframe]->regs;
28+
struct bpf_insn raw_insn = env->insns[venv->insn_idx];
29+
PRINT_LOG_INFO(env, "raw instruction dst: %d, src: %d\n",
30+
raw_insn.dst_reg, raw_insn.src_reg);
31+
struct bpf_reg_state *src = &regs[raw_insn.src_reg];
32+
CHECK_COND(src->type == PTR_TO_MAP_VALUE);
33+
PRINT_LOG_INFO(env, "array size %d\n", src->map_ptr->value_size);
34+
if (BPF_CLASS(raw_insn.code) == BPF_LDX &&
35+
BPF_MODE(raw_insn.code) == BPF_MEM) {
36+
// Regular load
37+
// Add check to src
38+
struct ir_insn *insn = bpf_ir_find_ir_insn_by_rawpos(
39+
fun, venv->insn_idx);
40+
CHECK_COND(insn);
41+
// Found the IR instruction
42+
CHECK_COND(insn->op == IR_INSN_LOADRAW)
43+
// LOADRAW src
44+
struct ir_value v = insn->addr_val.value;
45+
46+
CHECK_COND(v.type == IR_VALUE_INSN);
47+
struct ir_insn *aluinsn = v.data.insn_d;
48+
CHECK_COND(bpf_ir_is_bin_alu(aluinsn));
49+
struct ir_value index;
50+
51+
if (aluinsn->values[0].data.insn_d->op ==
52+
IR_INSN_LOADIMM_EXTRA) {
53+
index = aluinsn->values[1];
54+
} else if (aluinsn->values[1].data.insn_d->op ==
55+
IR_INSN_LOADIMM_EXTRA) {
56+
index = aluinsn->values[0];
57+
} else {
58+
return;
59+
}
60+
struct ir_basic_block *err_bb =
61+
bpf_ir_create_bb(env, fun);
62+
bpf_ir_create_ret_insn_bb(env, err_bb,
63+
bpf_ir_value_const32(1),
64+
INSERT_BACK);
65+
struct ir_basic_block *old_bb = aluinsn->parent_bb;
66+
// Split before insn
67+
struct ir_basic_block *new_bb =
68+
bpf_ir_split_bb(env, fun, aluinsn, true);
69+
70+
u32 max_num = src->map_ptr->value_size -
71+
bpf_ir_sizeof_vr_type(
72+
insn->vr_type); // +1 will error!
73+
74+
bpf_ir_create_jbin_insn_bb(
75+
env, old_bb, index,
76+
bpf_ir_value_const32(max_num), new_bb, err_bb,
77+
IR_INSN_JGT, IR_ALU_64, INSERT_BACK);
78+
79+
bpf_ir_connect_bb(env, old_bb, err_bb);
80+
}
81+
}
82+
}
83+
84+
static bool check_run(int err)
85+
{
86+
return err >= BPF_VERIFIER_ERR_41 && err <= BPF_VERIFIER_ERR_44;
87+
}
88+
89+
const struct custom_pass_cfg bpf_ir_kern_masking_pass =
90+
DEF_CUSTOM_PASS(DEF_FUNC_PASS(masking_pass, "masking_dupload", false),
91+
check_run, NULL, NULL);
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
#include "linux/bpf_common.h"
3+
#include "linux/bpf_verifier.h"
4+
#include "linux/stddef.h"
5+
#include <linux/bpf_ir.h>
6+
#include "../../ir_kern.h"
7+
8+
#define CHECK_COND(cond) \
9+
if (!(cond)) { \
10+
return; \
11+
}
12+
13+
static void masking_pass(struct bpf_ir_env *env, struct ir_function *fun,
14+
void *param)
15+
{
16+
struct bpf_verifier_env *venv = env->venv;
17+
if (!venv) {
18+
RAISE_ERROR("Empty verifier env");
19+
}
20+
struct bpf_verifier_state *curstate = venv->cur_state;
21+
PRINT_LOG_INFO(env, "Verifier stuck on insn: %d\n", venv->insn_idx);
22+
if (env->verifier_err >= BPF_VERIFIER_ERR_41 &&
23+
env->verifier_err <= BPF_VERIFIER_ERR_44) {
24+
// memory range error
25+
// Should be a load/store instruction
26+
struct bpf_reg_state *regs =
27+
curstate->frame[curstate->curframe]->regs;
28+
struct bpf_insn raw_insn = env->insns[venv->insn_idx];
29+
PRINT_LOG_INFO(env, "raw instruction dst: %d, src: %d\n",
30+
raw_insn.dst_reg, raw_insn.src_reg);
31+
struct bpf_reg_state *src = &regs[raw_insn.src_reg];
32+
CHECK_COND(src->type == PTR_TO_MAP_VALUE);
33+
PRINT_LOG_INFO(env, "array size %d\n", src->map_ptr->value_size);
34+
if (BPF_CLASS(raw_insn.code) == BPF_LDX &&
35+
BPF_MODE(raw_insn.code) == BPF_MEM) {
36+
// Regular load
37+
// Add check to src
38+
struct ir_insn *insn = bpf_ir_find_ir_insn_by_rawpos(
39+
fun, venv->insn_idx);
40+
CHECK_COND(insn);
41+
// Found the IR instruction
42+
CHECK_COND(insn->op == IR_INSN_LOADRAW)
43+
// LOADRAW src
44+
struct ir_value v = insn->addr_val.value;
45+
46+
CHECK_COND(v.type == IR_VALUE_INSN);
47+
struct ir_insn *aluinsn = v.data.insn_d;
48+
CHECK_COND(bpf_ir_is_bin_alu(aluinsn));
49+
struct ir_value index;
50+
51+
if (aluinsn->values[0].data.insn_d->op ==
52+
IR_INSN_LOADIMM_EXTRA) {
53+
index = aluinsn->values[1];
54+
} else if (aluinsn->values[1].data.insn_d->op ==
55+
IR_INSN_LOADIMM_EXTRA) {
56+
index = aluinsn->values[0];
57+
} else {
58+
return;
59+
}
60+
struct ir_basic_block *err_bb =
61+
bpf_ir_create_bb(env, fun);
62+
bpf_ir_create_ret_insn_bb(env, err_bb,
63+
bpf_ir_value_const32(1),
64+
INSERT_BACK);
65+
struct ir_basic_block *old_bb = aluinsn->parent_bb;
66+
// Split before insn
67+
struct ir_basic_block *new_bb =
68+
bpf_ir_split_bb(env, fun, aluinsn, true);
69+
70+
u32 max_num = src->map_ptr->value_size -
71+
bpf_ir_sizeof_vr_type(
72+
insn->vr_type); // +1 will error!
73+
74+
bpf_ir_create_jbin_insn_bb(
75+
env, old_bb, index,
76+
bpf_ir_value_const32(max_num), new_bb, err_bb,
77+
IR_INSN_JGT, IR_ALU_64, INSERT_BACK);
78+
79+
bpf_ir_connect_bb(env, old_bb, err_bb);
80+
}
81+
}
82+
}
83+
84+
static bool check_run(int err)
85+
{
86+
return err >= BPF_VERIFIER_ERR_41 && err <= BPF_VERIFIER_ERR_44;
87+
}
88+
89+
const struct custom_pass_cfg bpf_ir_kern_masking_pass =
90+
DEF_CUSTOM_PASS(DEF_FUNC_PASS(masking_pass, "masking_puc", false),
91+
check_run, NULL, NULL);

0 commit comments

Comments
 (0)