Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4f73379

Browse files
Alexei Starovoitovborkmann
authored andcommitted
bpf: verbose jump offset overflow check
Larger programs may trigger 16-bit jump offset overflow check during instruction patching. Make this error verbose otherwise users cannot decipher error code without printks in the verifier. Signed-off-by: Alexei Starovoitov <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]>
1 parent 71dde68 commit 4f73379

File tree

2 files changed

+12
-6
lines changed

2 files changed

+12
-6
lines changed

kernel/bpf/core.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
438438
u32 insn_adj_cnt, insn_rest, insn_delta = len - 1;
439439
const u32 cnt_max = S16_MAX;
440440
struct bpf_prog *prog_adj;
441+
int err;
441442

442443
/* Since our patchlet doesn't expand the image, we're done. */
443444
if (insn_delta == 0) {
@@ -453,8 +454,8 @@ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
453454
* we afterwards may not fail anymore.
454455
*/
455456
if (insn_adj_cnt > cnt_max &&
456-
bpf_adj_branches(prog, off, off + 1, off + len, true))
457-
return NULL;
457+
(err = bpf_adj_branches(prog, off, off + 1, off + len, true)))
458+
return ERR_PTR(err);
458459

459460
/* Several new instructions need to be inserted. Make room
460461
* for them. Likely, there's no need for a new allocation as
@@ -463,7 +464,7 @@ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
463464
prog_adj = bpf_prog_realloc(prog, bpf_prog_size(insn_adj_cnt),
464465
GFP_USER);
465466
if (!prog_adj)
466-
return NULL;
467+
return ERR_PTR(-ENOMEM);
467468

468469
prog_adj->len = insn_adj_cnt;
469470

@@ -1096,13 +1097,13 @@ struct bpf_prog *bpf_jit_blind_constants(struct bpf_prog *prog)
10961097
continue;
10971098

10981099
tmp = bpf_patch_insn_single(clone, i, insn_buff, rewritten);
1099-
if (!tmp) {
1100+
if (IS_ERR(tmp)) {
11001101
/* Patching may have repointed aux->prog during
11011102
* realloc from the original one, so we need to
11021103
* fix it up here on error.
11031104
*/
11041105
bpf_jit_prog_release_other(prog, clone);
1105-
return ERR_PTR(-ENOMEM);
1106+
return tmp;
11061107
}
11071108

11081109
clone = tmp;

kernel/bpf/verifier.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6932,8 +6932,13 @@ static struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 of
69326932
struct bpf_prog *new_prog;
69336933

69346934
new_prog = bpf_patch_insn_single(env->prog, off, patch, len);
6935-
if (!new_prog)
6935+
if (IS_ERR(new_prog)) {
6936+
if (PTR_ERR(new_prog) == -ERANGE)
6937+
verbose(env,
6938+
"insn %d cannot be patched due to 16-bit range\n",
6939+
env->insn_aux_data[off].orig_idx);
69366940
return NULL;
6941+
}
69376942
if (adjust_insn_aux_data(env, new_prog->len, off, len))
69386943
return NULL;
69396944
adjust_subprog_starts(env, off, len);

0 commit comments

Comments
 (0)