mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
bpf: Update logging functions to work with BTF
* Based on430e68d10b
,77d2e05abd
anda2a7d57010
Change-Id: I27e2c804726078646ca9beda31cbae2a745dfd47 Signed-off-by: Cyber Knight <cyberknight755@gmail.com>
This commit is contained in:
parent
b1f30ebe50
commit
d63ada96c2
@ -136,9 +136,11 @@ struct bpf_insn_aux_data {
|
||||
|
||||
#define MAX_USED_MAPS 64 /* max number of maps accessed by one eBPF program */
|
||||
|
||||
#define BPF_VERIFIER_TMP_LOG_SIZE 1024
|
||||
|
||||
struct bpf_verifier_log {
|
||||
u32 level;
|
||||
char *kbuf;
|
||||
char kbuf[BPF_VERIFIER_TMP_LOG_SIZE];
|
||||
char __user *ubuf;
|
||||
u32 len_used;
|
||||
u32 len_total;
|
||||
@ -149,6 +151,17 @@ static inline bool bpf_verifier_log_full(const struct bpf_verifier_log *log)
|
||||
return log->len_used >= log->len_total - 1;
|
||||
}
|
||||
|
||||
static inline bool bpf_verifier_log_needed(const struct bpf_verifier_log *log)
|
||||
{
|
||||
return log->level && log->ubuf && !bpf_verifier_log_full(log);
|
||||
}
|
||||
|
||||
__printf(2, 3) void bpf_verifier_log_write(struct bpf_verifier_log *log,
|
||||
const char *fmt, ...);
|
||||
|
||||
void bpf_verifier_vlog(struct bpf_verifier_log *log, const char *fmt,
|
||||
va_list args);
|
||||
|
||||
struct bpf_verifier_env;
|
||||
struct bpf_ext_analyzer_ops {
|
||||
int (*insn_hook)(struct bpf_verifier_env *env,
|
||||
|
@ -160,21 +160,55 @@ static struct bpf_verifier_log verifier_log;
|
||||
|
||||
static DEFINE_MUTEX(bpf_verifier_lock);
|
||||
|
||||
/* log_level controls verbosity level of eBPF verifier.
|
||||
* verbose() is used to dump the verification trace to the log, so the user
|
||||
* can figure out what's wrong with the program
|
||||
*/
|
||||
static __printf(1, 2) void verbose(const char *fmt, ...)
|
||||
void bpf_verifier_vlog(struct bpf_verifier_log *log,
|
||||
const char *fmt, va_list args)
|
||||
{
|
||||
unsigned int n;
|
||||
|
||||
n = vscnprintf(log->kbuf, BPF_VERIFIER_TMP_LOG_SIZE, fmt, args);
|
||||
|
||||
WARN_ONCE(n >= BPF_VERIFIER_TMP_LOG_SIZE - 1,
|
||||
"verifier log line truncated - local buffer too short\n");
|
||||
|
||||
n = min(log->len_total - log->len_used - 1, n);
|
||||
log->kbuf[n] = '\0';
|
||||
|
||||
if (!copy_to_user(log->ubuf + log->len_used, log->kbuf, n + 1))
|
||||
log->len_used += n;
|
||||
else
|
||||
log->ubuf = NULL;
|
||||
}
|
||||
|
||||
/* log_level controls verbosity level of eBPF verifier.
|
||||
* bpf_verifier_log_write() is used to dump the verification trace to the log,
|
||||
* so the user can figure out what's wrong with the program
|
||||
*/
|
||||
__printf(2, 3) void bpf_verifier_log_write(struct bpf_verifier_log *log,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
struct bpf_verifier_log *log = &verifier_log;
|
||||
va_list args;
|
||||
|
||||
if (!log->level || bpf_verifier_log_full(log))
|
||||
if (!bpf_verifier_log_needed(log))
|
||||
return;
|
||||
|
||||
va_start(args, fmt);
|
||||
log->len_used += vscnprintf(log->kbuf + log->len_used,
|
||||
log->len_total - log->len_used, fmt, args);
|
||||
bpf_verifier_vlog(log, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bpf_verifier_log_write);
|
||||
/* Historically bpf_verifier_log_write was called verbose, but the name was too
|
||||
* generic for symbol export. The function was renamed, but not the calls in
|
||||
* the verifier to avoid complicating backports. Hence the alias below.
|
||||
*/
|
||||
static __printf(1, 2) void verbose(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (!bpf_verifier_log_needed(&verifier_log))
|
||||
return;
|
||||
|
||||
va_start(args, fmt);
|
||||
bpf_verifier_vlog(&verifier_log, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
@ -5118,9 +5152,6 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr)
|
||||
goto err_unlock;
|
||||
|
||||
ret = -ENOMEM;
|
||||
log->kbuf = vmalloc(log->len_total);
|
||||
if (!log->kbuf)
|
||||
goto err_unlock;
|
||||
} else {
|
||||
log->level = 0;
|
||||
}
|
||||
@ -5167,17 +5198,12 @@ skip_full_check:
|
||||
ret = fixup_bpf_calls(env);
|
||||
|
||||
if (log->level && bpf_verifier_log_full(log)) {
|
||||
BUG_ON(log->len_used >= log->len_total);
|
||||
/* verifier log exceeded user supplied buffer */
|
||||
ret = -ENOSPC;
|
||||
/* fall through to return what was recorded */
|
||||
}
|
||||
|
||||
/* copy verifier log back to user space including trailing zero */
|
||||
if (log->level && copy_to_user(log->ubuf, log->kbuf,
|
||||
log->len_used + 1) != 0) {
|
||||
if (log->level && !log->ubuf) {
|
||||
ret = -EFAULT;
|
||||
goto free_log_buf;
|
||||
goto err_release_maps;
|
||||
}
|
||||
|
||||
if (ret == 0 && env->used_map_cnt) {
|
||||
@ -5188,7 +5214,7 @@ skip_full_check:
|
||||
|
||||
if (!env->prog->aux->used_maps) {
|
||||
ret = -ENOMEM;
|
||||
goto free_log_buf;
|
||||
goto err_release_maps;
|
||||
}
|
||||
|
||||
memcpy(env->prog->aux->used_maps, env->used_maps,
|
||||
@ -5201,9 +5227,7 @@ skip_full_check:
|
||||
convert_pseudo_ld_imm64(env);
|
||||
}
|
||||
|
||||
free_log_buf:
|
||||
if (log->level)
|
||||
vfree(log->kbuf);
|
||||
err_release_maps:
|
||||
if (!env->prog->aux->used_maps)
|
||||
/* if we didn't copy map pointers into bpf_prog_info, release
|
||||
* them now. Otherwise free_used_maps() will release them.
|
||||
|
22
scripts/module-lto.lds
Normal file
22
scripts/module-lto.lds
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
SECTIONS {
|
||||
/DISCARD/ : {
|
||||
*(.eh_frame)
|
||||
}
|
||||
.bss : {
|
||||
*(.bss .bss.[0-9a-zA-Z_]*)
|
||||
*(.bss..L*)
|
||||
}
|
||||
.data : {
|
||||
*(.data .data.[0-9a-zA-Z_]*)
|
||||
*(.data..L*)
|
||||
}
|
||||
.rodata : {
|
||||
*(.rodata .rodata.[0-9a-zA-Z_]*)
|
||||
*(.rodata..L*)
|
||||
}
|
||||
.text : ALIGN((1 << 12)) {
|
||||
*(.text.__cfi_check)
|
||||
*(.text .text.[0-9a-zA-Z_]* .text..L.cfi*)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user