Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions include/linux/filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,11 @@ static inline bool insn_is_cast_user(const struct bpf_insn *insn)
offsetof(TYPE, MEMBER); \
})

struct bpf_ksym_cache_entry {
unsigned long value;
char name[KSYM_NAME_LEN];
};

/* A struct sock_filter is architecture independent. */
struct compat_sock_fprog {
u16 len;
Expand Down Expand Up @@ -1381,6 +1386,9 @@ int __bpf_address_lookup(unsigned long addr, unsigned long *size,
bool is_bpf_text_address(unsigned long addr);
int bpf_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
char *sym);

int bpf_get_all_kallsyms(struct bpf_ksym_cache_entry **cache_ptr,
unsigned int *count_ptr);
struct bpf_prog *bpf_prog_ksym_find(unsigned long addr);

static inline int
Expand Down Expand Up @@ -1449,6 +1457,14 @@ static inline int bpf_get_kallsym(unsigned int symnum, unsigned long *value,
return -ERANGE;
}

static inline int bpf_get_all_kallsyms(struct bpf_ksym_cache_entry **cache_ptr,
unsigned int *count_ptr)
{
*cache_ptr = NULL;
*count_ptr = 0;
return 0;
}

static inline struct bpf_prog *bpf_prog_ksym_find(unsigned long addr)
{
return NULL;
Expand Down
46 changes: 46 additions & 0 deletions kernel/bpf/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,52 @@ int bpf_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
return ret;
}

int bpf_get_all_kallsyms(struct bpf_ksym_cache_entry **cache_ptr,
unsigned int *count_ptr)
{
struct bpf_ksym_cache_entry *cache;
struct bpf_ksym *ksym;
unsigned int count = 0;
unsigned int i = 0;

if (!bpf_jit_kallsyms_enabled()) {
*cache_ptr = NULL;
*count_ptr = 0;
return 0;
}

rcu_read_lock();
list_for_each_entry_rcu(ksym, &bpf_kallsyms, lnode)
count++;
rcu_read_unlock();

if (count == 0) {
*cache_ptr = NULL;
*count_ptr = 0;
return 0;
}

cache = kvmalloc_array(count, sizeof(*cache), GFP_KERNEL);
if (!cache)
return -ENOMEM;

rcu_read_lock();
list_for_each_entry_rcu(ksym, &bpf_kallsyms, lnode) {
if (i >= count) {
/* List grew since we counted, oh well */
break;
}
strscpy(cache[i].name, ksym->name, KSYM_NAME_LEN);
cache[i].value = ksym->start;
i++;
}
rcu_read_unlock();

*cache_ptr = cache;
*count_ptr = i;
return 0;
}

int bpf_jit_add_poke_descriptor(struct bpf_prog *prog,
struct bpf_jit_poke_descriptor *poke)
{
Expand Down
34 changes: 32 additions & 2 deletions kernel/kallsyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,8 @@ struct kallsym_iter {
char module_name[MODULE_NAME_LEN];
int exported;
int show_value;
struct bpf_ksym_cache_entry *bpf_cache;
unsigned int bpf_cache_count;
};

static int get_ksymbol_mod(struct kallsym_iter *iter)
Expand Down Expand Up @@ -603,11 +605,27 @@ static int get_ksymbol_ftrace_mod(struct kallsym_iter *iter)

static int get_ksymbol_bpf(struct kallsym_iter *iter)
{
unsigned int index = iter->pos - iter->pos_ftrace_mod_end;
int ret;

if (iter->bpf_cache) {
if (index >= iter->bpf_cache_count) {
iter->pos_bpf_end = iter->pos;
return 0;
}

strscpy(iter->module_name, "bpf", MODULE_NAME_LEN);
iter->exported = 0;
strscpy(iter->name, iter->bpf_cache[index].name, KSYM_NAME_LEN);
iter->value = iter->bpf_cache[index].value;
iter->type = BPF_SYM_ELF_TYPE;

return 1;
}

strscpy(iter->module_name, "bpf", MODULE_NAME_LEN);
iter->exported = 0;
ret = bpf_get_kallsym(iter->pos - iter->pos_ftrace_mod_end,
ret = bpf_get_kallsym(index,
&iter->value, &iter->type,
iter->name);
if (ret < 0) {
Expand Down Expand Up @@ -862,9 +880,21 @@ static int kallsyms_open(struct inode *inode, struct file *file)
* the result here at open time.
*/
iter->show_value = kallsyms_show_value(file->f_cred);

bpf_get_all_kallsyms(&iter->bpf_cache, &iter->bpf_cache_count);

return 0;
}

static int kallsyms_release(struct inode *inode, struct file *file)
{
struct seq_file *m = file->private_data;
struct kallsym_iter *iter = m->private;

kvfree(iter->bpf_cache);
return seq_release_private(inode, file);
}

#ifdef CONFIG_KGDB_KDB
const char *kdb_walk_kallsyms(loff_t *pos)
{
Expand All @@ -889,7 +919,7 @@ static const struct proc_ops kallsyms_proc_ops = {
.proc_open = kallsyms_open,
.proc_read = seq_read,
.proc_lseek = seq_lseek,
.proc_release = seq_release_private,
.proc_release = kallsyms_release,
};

static int __init kallsyms_init(void)
Expand Down