-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tools: bpftool: detect sub-programs from the eBPF sequence
This patch detect all sub-programs from the eBPF sequence and keep the information in the new CFG data structure. The detection algorithm is basically the same as the one in verifier except we need to use insn->off instead of insn->imm to get the pc-relative call offset. Because verifier has modified insn->off/insn->imm during finishing the verification. Also, we don't need to do some sanity checks as verifier has done them. Signed-off-by: Jiong Wang <jiong.wang@netronome.com> Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
- Loading branch information
Jiong Wang
authored and
Alexei Starovoitov
committed
Mar 2, 2018
1 parent
73bb5b4
commit 8033175
Showing
2 changed files
with
190 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
/* | ||
* Copyright (C) 2018 Netronome Systems, Inc. | ||
* | ||
* This software is dual licensed under the GNU General License Version 2, | ||
* June 1991 as shown in the file COPYING in the top-level directory of this | ||
* source tree or the BSD 2-Clause License provided below. You have the | ||
* option to license this software under the complete terms of either license. | ||
* | ||
* The BSD 2-Clause License: | ||
* | ||
* Redistribution and use in source and binary forms, with or | ||
* without modification, are permitted provided that the following | ||
* conditions are met: | ||
* | ||
* 1. Redistributions of source code must retain the above | ||
* copyright notice, this list of conditions and the following | ||
* disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above | ||
* copyright notice, this list of conditions and the following | ||
* disclaimer in the documentation and/or other materials | ||
* provided with the distribution. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
* POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
|
||
#include <linux/list.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
#include "cfg.h" | ||
#include "main.h" | ||
|
||
struct cfg { | ||
struct list_head funcs; | ||
int func_num; | ||
}; | ||
|
||
struct func_node { | ||
struct list_head l; | ||
struct bpf_insn *start; | ||
struct bpf_insn *end; | ||
int idx; | ||
}; | ||
|
||
#define func_prev(func) list_prev_entry(func, l) | ||
#define func_next(func) list_next_entry(func, l) | ||
#define cfg_first_func(cfg) \ | ||
list_first_entry(&cfg->funcs, struct func_node, l) | ||
#define cfg_last_func(cfg) \ | ||
list_last_entry(&cfg->funcs, struct func_node, l) | ||
|
||
static struct func_node *cfg_append_func(struct cfg *cfg, struct bpf_insn *insn) | ||
{ | ||
struct func_node *new_func, *func; | ||
|
||
list_for_each_entry(func, &cfg->funcs, l) { | ||
if (func->start == insn) | ||
return func; | ||
else if (func->start > insn) | ||
break; | ||
} | ||
|
||
func = func_prev(func); | ||
new_func = calloc(1, sizeof(*new_func)); | ||
if (!new_func) { | ||
p_err("OOM when allocating FUNC node"); | ||
return NULL; | ||
} | ||
new_func->start = insn; | ||
new_func->idx = cfg->func_num; | ||
list_add(&new_func->l, &func->l); | ||
cfg->func_num++; | ||
|
||
return new_func; | ||
} | ||
|
||
static bool cfg_partition_funcs(struct cfg *cfg, struct bpf_insn *cur, | ||
struct bpf_insn *end) | ||
{ | ||
struct func_node *func, *last_func; | ||
|
||
func = cfg_append_func(cfg, cur); | ||
if (!func) | ||
return true; | ||
|
||
for (; cur < end; cur++) { | ||
if (cur->code != (BPF_JMP | BPF_CALL)) | ||
continue; | ||
if (cur->src_reg != BPF_PSEUDO_CALL) | ||
continue; | ||
func = cfg_append_func(cfg, cur + cur->off + 1); | ||
if (!func) | ||
return true; | ||
} | ||
|
||
last_func = cfg_last_func(cfg); | ||
last_func->end = end - 1; | ||
func = cfg_first_func(cfg); | ||
list_for_each_entry_from(func, &last_func->l, l) { | ||
func->end = func_next(func)->start - 1; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
static bool cfg_build(struct cfg *cfg, struct bpf_insn *insn, unsigned int len) | ||
{ | ||
int cnt = len / sizeof(*insn); | ||
|
||
INIT_LIST_HEAD(&cfg->funcs); | ||
|
||
return cfg_partition_funcs(cfg, insn, insn + cnt); | ||
} | ||
|
||
static void cfg_destroy(struct cfg *cfg) | ||
{ | ||
struct func_node *func, *func2; | ||
|
||
list_for_each_entry_safe(func, func2, &cfg->funcs, l) { | ||
list_del(&func->l); | ||
free(func); | ||
} | ||
} | ||
|
||
void dump_xlated_cfg(void *buf, unsigned int len) | ||
{ | ||
struct bpf_insn *insn = buf; | ||
struct cfg cfg; | ||
|
||
memset(&cfg, 0, sizeof(cfg)); | ||
if (cfg_build(&cfg, insn, len)) | ||
return; | ||
|
||
cfg_destroy(&cfg); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
/* | ||
* Copyright (C) 2018 Netronome Systems, Inc. | ||
* | ||
* This software is dual licensed under the GNU General License Version 2, | ||
* June 1991 as shown in the file COPYING in the top-level directory of this | ||
* source tree or the BSD 2-Clause License provided below. You have the | ||
* option to license this software under the complete terms of either license. | ||
* | ||
* The BSD 2-Clause License: | ||
* | ||
* Redistribution and use in source and binary forms, with or | ||
* without modification, are permitted provided that the following | ||
* conditions are met: | ||
* | ||
* 1. Redistributions of source code must retain the above | ||
* copyright notice, this list of conditions and the following | ||
* disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above | ||
* copyright notice, this list of conditions and the following | ||
* disclaimer in the documentation and/or other materials | ||
* provided with the distribution. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
* POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
|
||
#ifndef __BPF_TOOL_CFG_H | ||
#define __BPF_TOOL_CFG_H | ||
|
||
void dump_xlated_cfg(void *buf, unsigned int len); | ||
|
||
#endif /* __BPF_TOOL_CFG_H */ |