bpf: Update logging functions to work with BTF

* Based on 430e68d10b,
  77d2e05abd
  and a2a7d57010

Change-Id: I27e2c804726078646ca9beda31cbae2a745dfd47
Signed-off-by: Cyber Knight <cyberknight755@gmail.com>
This commit is contained in:
Tim Zimmermann 2023-10-15 14:57:14 +02:00 committed by Richard Raya
parent b1f30ebe50
commit d63ada96c2
3 changed files with 83 additions and 24 deletions

View File

@ -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,

View File

@ -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
View 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*)
}
}