Commit 69dda13f authored by David S. Miller's avatar David S. Miller

Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf

Daniel Borkmann says:

====================
pull-request: bpf 2019-05-13

The following pull-request contains BPF updates for your *net* tree.

The main changes are:

1) Fix out of bounds backwards jumps due to a bug in dead code
   removal, from Daniel.

2) Fix libbpf users by detecting unsupported BTF kernel features
   and sanitize them before load, from Andrii.

3) Fix undefined behavior in narrow load handling of context
   fields, from Krzesimir.

4) Various BPF uapi header doc/man page fixes, from Quentin.

5) Misc .gitignore fixups to exclude built files, from Kelsey.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 3285a9aa e2f7fc0a
This diff is collapsed.
...@@ -338,7 +338,7 @@ int bpf_prog_calc_tag(struct bpf_prog *fp) ...@@ -338,7 +338,7 @@ int bpf_prog_calc_tag(struct bpf_prog *fp)
} }
static int bpf_adj_delta_to_imm(struct bpf_insn *insn, u32 pos, s32 end_old, static int bpf_adj_delta_to_imm(struct bpf_insn *insn, u32 pos, s32 end_old,
s32 end_new, u32 curr, const bool probe_pass) s32 end_new, s32 curr, const bool probe_pass)
{ {
const s64 imm_min = S32_MIN, imm_max = S32_MAX; const s64 imm_min = S32_MIN, imm_max = S32_MAX;
s32 delta = end_new - end_old; s32 delta = end_new - end_old;
...@@ -356,7 +356,7 @@ static int bpf_adj_delta_to_imm(struct bpf_insn *insn, u32 pos, s32 end_old, ...@@ -356,7 +356,7 @@ static int bpf_adj_delta_to_imm(struct bpf_insn *insn, u32 pos, s32 end_old,
} }
static int bpf_adj_delta_to_off(struct bpf_insn *insn, u32 pos, s32 end_old, static int bpf_adj_delta_to_off(struct bpf_insn *insn, u32 pos, s32 end_old,
s32 end_new, u32 curr, const bool probe_pass) s32 end_new, s32 curr, const bool probe_pass)
{ {
const s32 off_min = S16_MIN, off_max = S16_MAX; const s32 off_min = S16_MIN, off_max = S16_MAX;
s32 delta = end_new - end_old; s32 delta = end_new - end_old;
......
...@@ -7599,7 +7599,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) ...@@ -7599,7 +7599,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
insn->dst_reg, insn->dst_reg,
shift); shift);
insn_buf[cnt++] = BPF_ALU64_IMM(BPF_AND, insn->dst_reg, insn_buf[cnt++] = BPF_ALU64_IMM(BPF_AND, insn->dst_reg,
(1 << size * 8) - 1); (1ULL << size * 8) - 1);
} }
} }
......
#!/usr/bin/python3 #!/usr/bin/python3
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
# #
# Copyright (C) 2018 Netronome Systems, Inc. # Copyright (C) 2018-2019 Netronome Systems, Inc.
# In case user attempts to run with Python 2. # In case user attempts to run with Python 2.
from __future__ import print_function from __future__ import print_function
...@@ -39,7 +39,7 @@ class Helper(object): ...@@ -39,7 +39,7 @@ class Helper(object):
Break down helper function protocol into smaller chunks: return type, Break down helper function protocol into smaller chunks: return type,
name, distincts arguments. name, distincts arguments.
""" """
arg_re = re.compile('((const )?(struct )?(\w+|...))( (\**)(\w+))?$') arg_re = re.compile('((\w+ )*?(\w+|...))( (\**)(\w+))?$')
res = {} res = {}
proto_re = re.compile('(.+) (\**)(\w+)\(((([^,]+)(, )?){1,5})\)$') proto_re = re.compile('(.+) (\**)(\w+)\(((([^,]+)(, )?){1,5})\)$')
...@@ -54,8 +54,8 @@ class Helper(object): ...@@ -54,8 +54,8 @@ class Helper(object):
capture = arg_re.match(a) capture = arg_re.match(a)
res['args'].append({ res['args'].append({
'type' : capture.group(1), 'type' : capture.group(1),
'star' : capture.group(6), 'star' : capture.group(5),
'name' : capture.group(7) 'name' : capture.group(6)
}) })
return res return res
......
This diff is collapsed.
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "btf.h" #include "btf.h"
#include "str_error.h" #include "str_error.h"
#include "libbpf_util.h" #include "libbpf_util.h"
#include "libbpf_internal.h"
#ifndef EM_BPF #ifndef EM_BPF
#define EM_BPF 247 #define EM_BPF 247
...@@ -128,6 +129,10 @@ struct bpf_capabilities { ...@@ -128,6 +129,10 @@ struct bpf_capabilities {
__u32 name:1; __u32 name:1;
/* v5.2: kernel support for global data sections. */ /* v5.2: kernel support for global data sections. */
__u32 global_data:1; __u32 global_data:1;
/* BTF_KIND_FUNC and BTF_KIND_FUNC_PROTO support */
__u32 btf_func:1;
/* BTF_KIND_VAR and BTF_KIND_DATASEC support */
__u32 btf_datasec:1;
}; };
/* /*
...@@ -1021,6 +1026,74 @@ static bool section_have_execinstr(struct bpf_object *obj, int idx) ...@@ -1021,6 +1026,74 @@ static bool section_have_execinstr(struct bpf_object *obj, int idx)
return false; return false;
} }
static void bpf_object__sanitize_btf(struct bpf_object *obj)
{
bool has_datasec = obj->caps.btf_datasec;
bool has_func = obj->caps.btf_func;
struct btf *btf = obj->btf;
struct btf_type *t;
int i, j, vlen;
__u16 kind;
if (!obj->btf || (has_func && has_datasec))
return;
for (i = 1; i <= btf__get_nr_types(btf); i++) {
t = (struct btf_type *)btf__type_by_id(btf, i);
kind = BTF_INFO_KIND(t->info);
if (!has_datasec && kind == BTF_KIND_VAR) {
/* replace VAR with INT */
t->info = BTF_INFO_ENC(BTF_KIND_INT, 0, 0);
t->size = sizeof(int);
*(int *)(t+1) = BTF_INT_ENC(0, 0, 32);
} else if (!has_datasec && kind == BTF_KIND_DATASEC) {
/* replace DATASEC with STRUCT */
struct btf_var_secinfo *v = (void *)(t + 1);
struct btf_member *m = (void *)(t + 1);
struct btf_type *vt;
char *name;
name = (char *)btf__name_by_offset(btf, t->name_off);
while (*name) {
if (*name == '.')
*name = '_';
name++;
}
vlen = BTF_INFO_VLEN(t->info);
t->info = BTF_INFO_ENC(BTF_KIND_STRUCT, 0, vlen);
for (j = 0; j < vlen; j++, v++, m++) {
/* order of field assignments is important */
m->offset = v->offset * 8;
m->type = v->type;
/* preserve variable name as member name */
vt = (void *)btf__type_by_id(btf, v->type);
m->name_off = vt->name_off;
}
} else if (!has_func && kind == BTF_KIND_FUNC_PROTO) {
/* replace FUNC_PROTO with ENUM */
vlen = BTF_INFO_VLEN(t->info);
t->info = BTF_INFO_ENC(BTF_KIND_ENUM, 0, vlen);
t->size = sizeof(__u32); /* kernel enforced */
} else if (!has_func && kind == BTF_KIND_FUNC) {
/* replace FUNC with TYPEDEF */
t->info = BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0);
}
}
}
static void bpf_object__sanitize_btf_ext(struct bpf_object *obj)
{
if (!obj->btf_ext)
return;
if (!obj->caps.btf_func) {
btf_ext__free(obj->btf_ext);
obj->btf_ext = NULL;
}
}
static int bpf_object__elf_collect(struct bpf_object *obj, int flags) static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
{ {
Elf *elf = obj->efile.elf; Elf *elf = obj->efile.elf;
...@@ -1164,8 +1237,10 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags) ...@@ -1164,8 +1237,10 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
obj->btf = NULL; obj->btf = NULL;
} else { } else {
err = btf__finalize_data(obj, obj->btf); err = btf__finalize_data(obj, obj->btf);
if (!err) if (!err) {
bpf_object__sanitize_btf(obj);
err = btf__load(obj->btf); err = btf__load(obj->btf);
}
if (err) { if (err) {
pr_warning("Error finalizing and loading %s into kernel: %d. Ignored and continue.\n", pr_warning("Error finalizing and loading %s into kernel: %d. Ignored and continue.\n",
BTF_ELF_SEC, err); BTF_ELF_SEC, err);
...@@ -1187,6 +1262,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags) ...@@ -1187,6 +1262,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
BTF_EXT_ELF_SEC, BTF_EXT_ELF_SEC,
PTR_ERR(obj->btf_ext)); PTR_ERR(obj->btf_ext));
obj->btf_ext = NULL; obj->btf_ext = NULL;
} else {
bpf_object__sanitize_btf_ext(obj);
} }
} }
} }
...@@ -1556,12 +1633,63 @@ bpf_object__probe_global_data(struct bpf_object *obj) ...@@ -1556,12 +1633,63 @@ bpf_object__probe_global_data(struct bpf_object *obj)
return 0; return 0;
} }
static int bpf_object__probe_btf_func(struct bpf_object *obj)
{
const char strs[] = "\0int\0x\0a";
/* void x(int a) {} */
__u32 types[] = {
/* int */
BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
/* FUNC_PROTO */ /* [2] */
BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 1), 0),
BTF_PARAM_ENC(7, 1),
/* FUNC x */ /* [3] */
BTF_TYPE_ENC(5, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 0), 2),
};
int res;
res = libbpf__probe_raw_btf((char *)types, sizeof(types),
strs, sizeof(strs));
if (res < 0)
return res;
if (res > 0)
obj->caps.btf_func = 1;
return 0;
}
static int bpf_object__probe_btf_datasec(struct bpf_object *obj)
{
const char strs[] = "\0x\0.data";
/* static int a; */
__u32 types[] = {
/* int */
BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
/* VAR x */ /* [2] */
BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_VAR, 0, 0), 1),
BTF_VAR_STATIC,
/* DATASEC val */ /* [3] */
BTF_TYPE_ENC(3, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
BTF_VAR_SECINFO_ENC(2, 0, 4),
};
int res;
res = libbpf__probe_raw_btf((char *)types, sizeof(types),
strs, sizeof(strs));
if (res < 0)
return res;
if (res > 0)
obj->caps.btf_datasec = 1;
return 0;
}
static int static int
bpf_object__probe_caps(struct bpf_object *obj) bpf_object__probe_caps(struct bpf_object *obj)
{ {
int (*probe_fn[])(struct bpf_object *obj) = { int (*probe_fn[])(struct bpf_object *obj) = {
bpf_object__probe_name, bpf_object__probe_name,
bpf_object__probe_global_data, bpf_object__probe_global_data,
bpf_object__probe_btf_func,
bpf_object__probe_btf_datasec,
}; };
int i, ret; int i, ret;
......
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
/*
* Internal libbpf helpers.
*
* Copyright (c) 2019 Facebook
*/
#ifndef __LIBBPF_LIBBPF_INTERNAL_H
#define __LIBBPF_LIBBPF_INTERNAL_H
#define BTF_INFO_ENC(kind, kind_flag, vlen) \
((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
#define BTF_TYPE_ENC(name, info, size_or_type) (name), (info), (size_or_type)
#define BTF_INT_ENC(encoding, bits_offset, nr_bits) \
((encoding) << 24 | (bits_offset) << 16 | (nr_bits))
#define BTF_TYPE_INT_ENC(name, encoding, bits_offset, bits, sz) \
BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), sz), \
BTF_INT_ENC(encoding, bits_offset, bits)
#define BTF_MEMBER_ENC(name, type, bits_offset) (name), (type), (bits_offset)
#define BTF_PARAM_ENC(name, type) (name), (type)
#define BTF_VAR_SECINFO_ENC(type, offset, size) (type), (offset), (size)
int libbpf__probe_raw_btf(const char *raw_types, size_t types_len,
const char *str_sec, size_t str_len);
#endif /* __LIBBPF_LIBBPF_INTERNAL_H */
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "bpf.h" #include "bpf.h"
#include "libbpf.h" #include "libbpf.h"
#include "libbpf_internal.h"
static bool grep(const char *buffer, const char *pattern) static bool grep(const char *buffer, const char *pattern)
{ {
...@@ -132,21 +133,43 @@ bool bpf_probe_prog_type(enum bpf_prog_type prog_type, __u32 ifindex) ...@@ -132,21 +133,43 @@ bool bpf_probe_prog_type(enum bpf_prog_type prog_type, __u32 ifindex)
return errno != EINVAL && errno != EOPNOTSUPP; return errno != EINVAL && errno != EOPNOTSUPP;
} }
static int load_btf(void) int libbpf__probe_raw_btf(const char *raw_types, size_t types_len,
const char *str_sec, size_t str_len)
{ {
#define BTF_INFO_ENC(kind, kind_flag, vlen) \ struct btf_header hdr = {
((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN)) .magic = BTF_MAGIC,
#define BTF_TYPE_ENC(name, info, size_or_type) \ .version = BTF_VERSION,
(name), (info), (size_or_type) .hdr_len = sizeof(struct btf_header),
#define BTF_INT_ENC(encoding, bits_offset, nr_bits) \ .type_len = types_len,
((encoding) << 24 | (bits_offset) << 16 | (nr_bits)) .str_off = types_len,
#define BTF_TYPE_INT_ENC(name, encoding, bits_offset, bits, sz) \ .str_len = str_len,
BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), sz), \ };
BTF_INT_ENC(encoding, bits_offset, bits) int btf_fd, btf_len;
#define BTF_MEMBER_ENC(name, type, bits_offset) \ __u8 *raw_btf;
(name), (type), (bits_offset)
btf_len = hdr.hdr_len + hdr.type_len + hdr.str_len;
const char btf_str_sec[] = "\0bpf_spin_lock\0val\0cnt\0l"; raw_btf = malloc(btf_len);
if (!raw_btf)
return -ENOMEM;
memcpy(raw_btf, &hdr, sizeof(hdr));
memcpy(raw_btf + hdr.hdr_len, raw_types, hdr.type_len);
memcpy(raw_btf + hdr.hdr_len + hdr.type_len, str_sec, hdr.str_len);
btf_fd = bpf_load_btf(raw_btf, btf_len, NULL, 0, false);
if (btf_fd < 0) {
free(raw_btf);
return 0;
}
close(btf_fd);
free(raw_btf);
return 1;
}
static int load_sk_storage_btf(void)
{
const char strs[] = "\0bpf_spin_lock\0val\0cnt\0l";
/* struct bpf_spin_lock { /* struct bpf_spin_lock {
* int val; * int val;
* }; * };
...@@ -155,7 +178,7 @@ static int load_btf(void) ...@@ -155,7 +178,7 @@ static int load_btf(void)
* struct bpf_spin_lock l; * struct bpf_spin_lock l;
* }; * };
*/ */
__u32 btf_raw_types[] = { __u32 types[] = {
/* int */ /* int */
BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
/* struct bpf_spin_lock */ /* [2] */ /* struct bpf_spin_lock */ /* [2] */
...@@ -166,23 +189,9 @@ static int load_btf(void) ...@@ -166,23 +189,9 @@ static int load_btf(void)
BTF_MEMBER_ENC(19, 1, 0), /* int cnt; */ BTF_MEMBER_ENC(19, 1, 0), /* int cnt; */
BTF_MEMBER_ENC(23, 2, 32),/* struct bpf_spin_lock l; */ BTF_MEMBER_ENC(23, 2, 32),/* struct bpf_spin_lock l; */
}; };
struct btf_header btf_hdr = {
.magic = BTF_MAGIC,
.version = BTF_VERSION,
.hdr_len = sizeof(struct btf_header),
.type_len = sizeof(btf_raw_types),
.str_off = sizeof(btf_raw_types),
.str_len = sizeof(btf_str_sec),
};
__u8 raw_btf[sizeof(struct btf_header) + sizeof(btf_raw_types) +
sizeof(btf_str_sec)];
memcpy(raw_btf, &btf_hdr, sizeof(btf_hdr));
memcpy(raw_btf + sizeof(btf_hdr), btf_raw_types, sizeof(btf_raw_types));
memcpy(raw_btf + sizeof(btf_hdr) + sizeof(btf_raw_types),
btf_str_sec, sizeof(btf_str_sec));
return bpf_load_btf(raw_btf, sizeof(raw_btf), 0, 0, 0); return libbpf__probe_raw_btf((char *)types, sizeof(types),
strs, sizeof(strs));
} }
bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex) bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex)
...@@ -222,7 +231,7 @@ bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex) ...@@ -222,7 +231,7 @@ bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex)
value_size = 8; value_size = 8;
max_entries = 0; max_entries = 0;
map_flags = BPF_F_NO_PREALLOC; map_flags = BPF_F_NO_PREALLOC;
btf_fd = load_btf(); btf_fd = load_sk_storage_btf();
if (btf_fd < 0) if (btf_fd < 0)
return false; return false;
break; break;
......
...@@ -32,3 +32,5 @@ test_tcpnotify_user ...@@ -32,3 +32,5 @@ test_tcpnotify_user
test_libbpf test_libbpf
test_tcp_check_syncookie_user test_tcp_check_syncookie_user
alu32 alu32
libbpf.pc
libbpf.so.*
...@@ -178,3 +178,198 @@ ...@@ -178,3 +178,198 @@
.result_unpriv = REJECT, .result_unpriv = REJECT,
.result = ACCEPT, .result = ACCEPT,
}, },
{
"jump test 6",
.insns = {
BPF_MOV64_IMM(BPF_REG_0, 1),
BPF_MOV64_IMM(BPF_REG_1, 2),
BPF_JMP_IMM(BPF_JA, 0, 0, 2),
BPF_MOV64_IMM(BPF_REG_0, 2),
BPF_EXIT_INSN(),
BPF_JMP_REG(BPF_JNE, BPF_REG_0, BPF_REG_1, 16),
BPF_JMP_IMM(BPF_JA, 0, 0, 0),
BPF_JMP_IMM(BPF_JA, 0, 0, 0),
BPF_JMP_IMM(BPF_JA, 0, 0, 0),
BPF_JMP_IMM(BPF_JA, 0, 0, 0),
BPF_JMP_IMM(BPF_JA, 0, 0, 0),
BPF_JMP_IMM(BPF_JA, 0, 0, 0),
BPF_JMP_IMM(BPF_JA, 0, 0, 0),
BPF_JMP_IMM(BPF_JA, 0, 0, 0),
BPF_JMP_IMM(BPF_JA, 0, 0, 0),
BPF_JMP_IMM(BPF_JA, 0, 0, 0),
BPF_JMP_IMM(BPF_JA, 0, 0, 0),
BPF_JMP_IMM(BPF_JA, 0, 0, 0),
BPF_JMP_IMM(BPF_JA, 0, 0, 0),
BPF_JMP_IMM(BPF_JA, 0, 0, 0),
BPF_JMP_IMM(BPF_JA, 0, 0, 0),
BPF_JMP_IMM(BPF_JA, 0, 0, 0),
BPF_JMP_IMM(BPF_JA, 0, 0, -20),
},
.result = ACCEPT,
.retval = 2,
},
{
"jump test 7",
.insns = {
BPF_MOV64_IMM(BPF_REG_0, 1),
BPF_JMP_IMM(BPF_JA, 0, 0, 2),
BPF_MOV64_IMM(BPF_REG_0, 3),
BPF_EXIT_INSN(),
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 2, 16),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_JMP_IMM(BPF_JA, 0, 0, -20),
},
.result = ACCEPT,
.retval = 3,
},
{
"jump test 8",
.insns = {
BPF_MOV64_IMM(BPF_REG_0, 1),
BPF_MOV64_IMM(BPF_REG_1, 2),
BPF_JMP_IMM(BPF_JA, 0, 0, 2),
BPF_MOV64_IMM(BPF_REG_0, 3),
BPF_EXIT_INSN(),
BPF_JMP_REG(BPF_JNE, BPF_REG_0, BPF_REG_1, 16),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_JMP_IMM(BPF_JA, 0, 0, -20),
},
.result = ACCEPT,
.retval = 3,
},
{
"jump/call test 9",
.insns = {
BPF_MOV64_IMM(BPF_REG_0, 1),
BPF_JMP_IMM(BPF_JA, 0, 0, 2),
BPF_MOV64_IMM(BPF_REG_0, 3),
BPF_EXIT_INSN(),
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 2, 16),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -20),
BPF_EXIT_INSN(),
},
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
.result = REJECT,
.errstr = "jump out of range from insn 1 to 4",
},
{
"jump/call test 10",
.insns = {
BPF_MOV64_IMM(BPF_REG_0, 1),
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
BPF_MOV64_IMM(BPF_REG_0, 3),
BPF_EXIT_INSN(),
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 2, 16),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -20),
BPF_EXIT_INSN(),
},
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
.result = REJECT,
.errstr = "last insn is not an exit or jmp",
},
{
"jump/call test 11",
.insns = {
BPF_MOV64_IMM(BPF_REG_0, 1),
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
BPF_MOV64_IMM(BPF_REG_0, 3),
BPF_EXIT_INSN(),
BPF_MOV64_IMM(BPF_REG_0, 3),
BPF_EXIT_INSN(),
BPF_MOV64_IMM(BPF_REG_0, 1),
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 2, 26),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_MOV64_IMM(BPF_REG_0, 42),
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -31),
BPF_EXIT_INSN(),
},
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
.result = ACCEPT,
.retval = 3,
},
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment