Skip to content

Commit b9989b5

Browse files
author
Alexei Starovoitov
committed
Merge branch 'Typeless/weak ksym for gen_loader + misc fixups'
Kumar Kartikeya says: ==================== Patches (1,2,3,6) add typeless and weak ksym support to gen_loader. It is follow up for the recent kfunc from modules series. The later patches (7,8) are misc fixes for selftests, and patch 4 for libbpf where we try to be careful to not end up with fds == 0, as libbpf assumes in various places that they are greater than 0. Patch 5 fixes up missing O_CLOEXEC in libbpf. Changelog: ---------- v4 -> v5 v4: https://lore.kernel.org/bpf/[email protected] * Address feedback from Andrii * Drop use of ensure_good_fd in unneeded call sites * Add sys_bpf_fd * Add _lskel suffix to all light skeletons and change all current selftests * Drop early break in close loop for sk_lookup * Fix other nits v3 -> v4 v3: https://lore.kernel.org/bpf/[email protected] * Remove gpl_only = true from bpf_kallsyms_lookup_name (Alexei) * Add bpf_dump_raw_ok check to ensure kptr_restrict isn't bypassed (Alexei) v2 -> v3 v2: https://lore.kernel.org/bpf/[email protected] * Address feedback from Song * Move ksym logging to separate helper to avoid code duplication * Move src_reg mask stuff to separate helper * Fix various other nits, add acks * __builtin_expect is used instead of likely to as skel_internal.h is included in isolation. v1 -> v2 v1: https://lore.kernel.org/bpf/[email protected] * Remove redundant OOM checks in emit_bpf_kallsyms_lookup_name * Use designated initializer for sk_lookup fd array (Jakub) * Do fd check for all fd returning low level APIs (Andrii, Alexei) * Make Fixes: tag quote commit message, use selftests/bpf prefix (Song, Andrii) * Split typeless and weak ksym support into separate patches, expand commit message (Song) * Fix duplication in selftests stemming from use of LSKELS_EXTRA (Song) ==================== Signed-off-by: Alexei Starovoitov <[email protected]>
2 parents 2895f48 + efadf2a commit b9989b5

30 files changed

+393
-159
lines changed

include/linux/bpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2110,6 +2110,7 @@ extern const struct bpf_func_proto bpf_for_each_map_elem_proto;
21102110
extern const struct bpf_func_proto bpf_btf_find_by_name_kind_proto;
21112111
extern const struct bpf_func_proto bpf_sk_setsockopt_proto;
21122112
extern const struct bpf_func_proto bpf_sk_getsockopt_proto;
2113+
extern const struct bpf_func_proto bpf_kallsyms_lookup_name_proto;
21132114

21142115
const struct bpf_func_proto *tracing_prog_func_proto(
21152116
enum bpf_func_id func_id, const struct bpf_prog *prog);

include/uapi/linux/bpf.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4923,6 +4923,21 @@ union bpf_attr {
49234923
* Dynamically cast a *sk* pointer to a *unix_sock* pointer.
49244924
* Return
49254925
* *sk* if casting is valid, or **NULL** otherwise.
4926+
*
4927+
* long bpf_kallsyms_lookup_name(const char *name, int name_sz, int flags, u64 *res)
4928+
* Description
4929+
* Get the address of a kernel symbol, returned in *res*. *res* is
4930+
* set to 0 if the symbol is not found.
4931+
* Return
4932+
* On success, zero. On error, a negative value.
4933+
*
4934+
* **-EINVAL** if *flags* is not zero.
4935+
*
4936+
* **-EINVAL** if string *name* is not the same size as *name_sz*.
4937+
*
4938+
* **-ENOENT** if symbol is not found.
4939+
*
4940+
* **-EPERM** if caller does not have permission to obtain kernel address.
49264941
*/
49274942
#define __BPF_FUNC_MAPPER(FN) \
49284943
FN(unspec), \
@@ -5104,6 +5119,7 @@ union bpf_attr {
51045119
FN(get_branch_snapshot), \
51055120
FN(trace_vprintk), \
51065121
FN(skc_to_unix_sock), \
5122+
FN(kallsyms_lookup_name), \
51075123
/* */
51085124

51095125
/* integer value in 'imm' field of BPF_CALL instruction selects which helper

kernel/bpf/syscall.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4781,6 +4781,31 @@ static const struct bpf_func_proto bpf_sys_close_proto = {
47814781
.arg1_type = ARG_ANYTHING,
47824782
};
47834783

4784+
BPF_CALL_4(bpf_kallsyms_lookup_name, const char *, name, int, name_sz, int, flags, u64 *, res)
4785+
{
4786+
if (flags)
4787+
return -EINVAL;
4788+
4789+
if (name_sz <= 1 || name[name_sz - 1])
4790+
return -EINVAL;
4791+
4792+
if (!bpf_dump_raw_ok(current_cred()))
4793+
return -EPERM;
4794+
4795+
*res = kallsyms_lookup_name(name);
4796+
return *res ? 0 : -ENOENT;
4797+
}
4798+
4799+
const struct bpf_func_proto bpf_kallsyms_lookup_name_proto = {
4800+
.func = bpf_kallsyms_lookup_name,
4801+
.gpl_only = false,
4802+
.ret_type = RET_INTEGER,
4803+
.arg1_type = ARG_PTR_TO_MEM,
4804+
.arg2_type = ARG_CONST_SIZE,
4805+
.arg3_type = ARG_ANYTHING,
4806+
.arg4_type = ARG_PTR_TO_LONG,
4807+
};
4808+
47844809
static const struct bpf_func_proto *
47854810
syscall_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
47864811
{
@@ -4791,6 +4816,8 @@ syscall_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
47914816
return &bpf_btf_find_by_name_kind_proto;
47924817
case BPF_FUNC_sys_close:
47934818
return &bpf_sys_close_proto;
4819+
case BPF_FUNC_kallsyms_lookup_name:
4820+
return &bpf_kallsyms_lookup_name_proto;
47944821
default:
47954822
return tracing_prog_func_proto(func_id, prog);
47964823
}

tools/include/uapi/linux/bpf.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4923,6 +4923,21 @@ union bpf_attr {
49234923
* Dynamically cast a *sk* pointer to a *unix_sock* pointer.
49244924
* Return
49254925
* *sk* if casting is valid, or **NULL** otherwise.
4926+
*
4927+
* long bpf_kallsyms_lookup_name(const char *name, int name_sz, int flags, u64 *res)
4928+
* Description
4929+
* Get the address of a kernel symbol, returned in *res*. *res* is
4930+
* set to 0 if the symbol is not found.
4931+
* Return
4932+
* On success, zero. On error, a negative value.
4933+
*
4934+
* **-EINVAL** if *flags* is not zero.
4935+
*
4936+
* **-EINVAL** if string *name* is not the same size as *name_sz*.
4937+
*
4938+
* **-ENOENT** if symbol is not found.
4939+
*
4940+
* **-EPERM** if caller does not have permission to obtain kernel address.
49264941
*/
49274942
#define __BPF_FUNC_MAPPER(FN) \
49284943
FN(unspec), \
@@ -5104,6 +5119,7 @@ union bpf_attr {
51045119
FN(get_branch_snapshot), \
51055120
FN(trace_vprintk), \
51065121
FN(skc_to_unix_sock), \
5122+
FN(kallsyms_lookup_name), \
51075123
/* */
51085124

51095125
/* integer value in 'imm' field of BPF_CALL instruction selects which helper

tools/lib/bpf/bpf.c

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,22 @@ static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
6565
return syscall(__NR_bpf, cmd, attr, size);
6666
}
6767

68+
static inline int sys_bpf_fd(enum bpf_cmd cmd, union bpf_attr *attr,
69+
unsigned int size)
70+
{
71+
int fd;
72+
73+
fd = sys_bpf(cmd, attr, size);
74+
return ensure_good_fd(fd);
75+
}
76+
6877
static inline int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size)
6978
{
7079
int retries = 5;
7180
int fd;
7281

7382
do {
74-
fd = sys_bpf(BPF_PROG_LOAD, attr, size);
83+
fd = sys_bpf_fd(BPF_PROG_LOAD, attr, size);
7584
} while (fd < 0 && errno == EAGAIN && retries-- > 0);
7685

7786
return fd;
@@ -104,7 +113,7 @@ int libbpf__bpf_create_map_xattr(const struct bpf_create_map_params *create_attr
104113
attr.inner_map_fd = create_attr->inner_map_fd;
105114
attr.map_extra = create_attr->map_extra;
106115

107-
fd = sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
116+
fd = sys_bpf_fd(BPF_MAP_CREATE, &attr, sizeof(attr));
108117
return libbpf_err_errno(fd);
109118
}
110119

@@ -206,7 +215,7 @@ int bpf_create_map_in_map_node(enum bpf_map_type map_type, const char *name,
206215
attr.numa_node = node;
207216
}
208217

209-
fd = sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
218+
fd = sys_bpf_fd(BPF_MAP_CREATE, &attr, sizeof(attr));
210219
return libbpf_err_errno(fd);
211220
}
212221

@@ -634,7 +643,7 @@ int bpf_obj_get(const char *pathname)
634643
memset(&attr, 0, sizeof(attr));
635644
attr.pathname = ptr_to_u64((void *)pathname);
636645

637-
fd = sys_bpf(BPF_OBJ_GET, &attr, sizeof(attr));
646+
fd = sys_bpf_fd(BPF_OBJ_GET, &attr, sizeof(attr));
638647
return libbpf_err_errno(fd);
639648
}
640649

@@ -745,7 +754,7 @@ int bpf_link_create(int prog_fd, int target_fd,
745754
break;
746755
}
747756
proceed:
748-
fd = sys_bpf(BPF_LINK_CREATE, &attr, sizeof(attr));
757+
fd = sys_bpf_fd(BPF_LINK_CREATE, &attr, sizeof(attr));
749758
return libbpf_err_errno(fd);
750759
}
751760

@@ -788,7 +797,7 @@ int bpf_iter_create(int link_fd)
788797
memset(&attr, 0, sizeof(attr));
789798
attr.iter_create.link_fd = link_fd;
790799

791-
fd = sys_bpf(BPF_ITER_CREATE, &attr, sizeof(attr));
800+
fd = sys_bpf_fd(BPF_ITER_CREATE, &attr, sizeof(attr));
792801
return libbpf_err_errno(fd);
793802
}
794803

@@ -946,7 +955,7 @@ int bpf_prog_get_fd_by_id(__u32 id)
946955
memset(&attr, 0, sizeof(attr));
947956
attr.prog_id = id;
948957

949-
fd = sys_bpf(BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr));
958+
fd = sys_bpf_fd(BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr));
950959
return libbpf_err_errno(fd);
951960
}
952961

@@ -958,7 +967,7 @@ int bpf_map_get_fd_by_id(__u32 id)
958967
memset(&attr, 0, sizeof(attr));
959968
attr.map_id = id;
960969

961-
fd = sys_bpf(BPF_MAP_GET_FD_BY_ID, &attr, sizeof(attr));
970+
fd = sys_bpf_fd(BPF_MAP_GET_FD_BY_ID, &attr, sizeof(attr));
962971
return libbpf_err_errno(fd);
963972
}
964973

@@ -970,7 +979,7 @@ int bpf_btf_get_fd_by_id(__u32 id)
970979
memset(&attr, 0, sizeof(attr));
971980
attr.btf_id = id;
972981

973-
fd = sys_bpf(BPF_BTF_GET_FD_BY_ID, &attr, sizeof(attr));
982+
fd = sys_bpf_fd(BPF_BTF_GET_FD_BY_ID, &attr, sizeof(attr));
974983
return libbpf_err_errno(fd);
975984
}
976985

@@ -982,7 +991,7 @@ int bpf_link_get_fd_by_id(__u32 id)
982991
memset(&attr, 0, sizeof(attr));
983992
attr.link_id = id;
984993

985-
fd = sys_bpf(BPF_LINK_GET_FD_BY_ID, &attr, sizeof(attr));
994+
fd = sys_bpf_fd(BPF_LINK_GET_FD_BY_ID, &attr, sizeof(attr));
986995
return libbpf_err_errno(fd);
987996
}
988997

@@ -1013,7 +1022,7 @@ int bpf_raw_tracepoint_open(const char *name, int prog_fd)
10131022
attr.raw_tracepoint.name = ptr_to_u64(name);
10141023
attr.raw_tracepoint.prog_fd = prog_fd;
10151024

1016-
fd = sys_bpf(BPF_RAW_TRACEPOINT_OPEN, &attr, sizeof(attr));
1025+
fd = sys_bpf_fd(BPF_RAW_TRACEPOINT_OPEN, &attr, sizeof(attr));
10171026
return libbpf_err_errno(fd);
10181027
}
10191028

@@ -1033,7 +1042,7 @@ int bpf_load_btf(const void *btf, __u32 btf_size, char *log_buf, __u32 log_buf_s
10331042
attr.btf_log_buf = ptr_to_u64(log_buf);
10341043
}
10351044

1036-
fd = sys_bpf(BPF_BTF_LOAD, &attr, sizeof(attr));
1045+
fd = sys_bpf_fd(BPF_BTF_LOAD, &attr, sizeof(attr));
10371046

10381047
if (fd < 0 && !do_log && log_buf && log_buf_size) {
10391048
do_log = true;
@@ -1075,7 +1084,7 @@ int bpf_enable_stats(enum bpf_stats_type type)
10751084
memset(&attr, 0, sizeof(attr));
10761085
attr.enable_stats.type = type;
10771086

1078-
fd = sys_bpf(BPF_ENABLE_STATS, &attr, sizeof(attr));
1087+
fd = sys_bpf_fd(BPF_ENABLE_STATS, &attr, sizeof(attr));
10791088
return libbpf_err_errno(fd);
10801089
}
10811090

tools/lib/bpf/bpf_gen_internal.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,19 @@ struct ksym_relo_desc {
88
int kind;
99
int insn_idx;
1010
bool is_weak;
11+
bool is_typeless;
1112
};
1213

1314
struct ksym_desc {
1415
const char *name;
1516
int ref;
1617
int kind;
17-
int off;
18+
union {
19+
/* used for kfunc */
20+
int off;
21+
/* used for typeless ksym */
22+
bool typeless;
23+
};
1824
int insn;
1925
};
2026

@@ -49,7 +55,7 @@ void bpf_gen__prog_load(struct bpf_gen *gen, struct bpf_prog_load_params *load_a
4955
void bpf_gen__map_update_elem(struct bpf_gen *gen, int map_idx, void *value, __u32 value_size);
5056
void bpf_gen__map_freeze(struct bpf_gen *gen, int map_idx);
5157
void bpf_gen__record_attach_target(struct bpf_gen *gen, const char *name, enum bpf_attach_type type);
52-
void bpf_gen__record_extern(struct bpf_gen *gen, const char *name, bool is_weak, int kind,
53-
int insn_idx);
58+
void bpf_gen__record_extern(struct bpf_gen *gen, const char *name, bool is_weak,
59+
bool is_typeless, int kind, int insn_idx);
5460

5561
#endif

tools/lib/bpf/btf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,7 @@ static struct btf *btf_parse_elf(const char *path, struct btf *base_btf,
897897
return ERR_PTR(-LIBBPF_ERRNO__LIBELF);
898898
}
899899

900-
fd = open(path, O_RDONLY);
900+
fd = open(path, O_RDONLY | O_CLOEXEC);
901901
if (fd < 0) {
902902
err = -errno;
903903
pr_warn("failed to open %s: %s\n", path, strerror(errno));

0 commit comments

Comments
 (0)