* [PATCH 0/6] Add _opts variant for bpf_*_get_fd_by_id()
@ 2022-10-04 11:48 Roberto Sassu
2022-10-04 11:48 ` [PATCH 1/6] libbpf: Fix LIBBPF_1.0.0 declaration in libbpf.map Roberto Sassu
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Roberto Sassu @ 2022-10-04 11:48 UTC (permalink / raw)
To: ast, daniel, andrii, martin.lau, song, yhs, john.fastabend,
kpsingh, sdf, haoluo, jolsa, mykolal, shuah
Cc: bpf, linux-kselftest, linux-kernel, Roberto Sassu
From: Roberto Sassu <roberto.sassu@huawei.com>
Add the _opts variant for bpf_*_get_fd_by_id() functions, to be able to
pass to the kernel more options, when requesting a fd of an eBPF object to
the kernel.
Pass the options through a newly introduced structure, bpf_get_fd_opts,
which currently contains open_flags (the other two members are for
compatibility and for padding).
open_flags allows the caller to request specific permissions to access a
map (e.g. read-only). This is useful for example in the situation where a
map is write-protected.
Besides patches 2-6, which introduce the new variants and the data
structure, patch 1 fixes the LIBBPF_1.0.0 declaration in libbpf.map.
Roberto Sassu (6):
libbpf: Fix LIBBPF_1.0.0 declaration in libbpf.map
libbpf: Define bpf_get_fd_opts and introduce
bpf_map_get_fd_by_id_opts()
libbpf: Introduce bpf_prog_get_fd_by_id_opts()
libbpf: Introduce bpf_btf_get_fd_by_id_opts()
libbpf: Introduce bpf_link_get_fd_by_id_opts()
selftests/bpf: Add tests for _opts variants of bpf_*_get_fd_by_id()
tools/lib/bpf/bpf.c | 47 +++++++++-
tools/lib/bpf/bpf.h | 16 ++++
tools/lib/bpf/libbpf.map | 6 +-
.../bpf/prog_tests/libbpf_get_fd_opts.c | 88 +++++++++++++++++++
.../bpf/progs/test_libbpf_get_fd_opts.c | 36 ++++++++
5 files changed, 188 insertions(+), 5 deletions(-)
create mode 100644 tools/testing/selftests/bpf/prog_tests/libbpf_get_fd_opts.c
create mode 100644 tools/testing/selftests/bpf/progs/test_libbpf_get_fd_opts.c
--
2.25.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/6] libbpf: Fix LIBBPF_1.0.0 declaration in libbpf.map
2022-10-04 11:48 [PATCH 0/6] Add _opts variant for bpf_*_get_fd_by_id() Roberto Sassu
@ 2022-10-04 11:48 ` Roberto Sassu
2022-10-04 11:48 ` [PATCH 2/6] libbpf: Define bpf_get_fd_opts and introduce bpf_map_get_fd_by_id_opts() Roberto Sassu
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2022-10-04 11:48 UTC (permalink / raw)
To: ast, daniel, andrii, martin.lau, song, yhs, john.fastabend,
kpsingh, sdf, haoluo, jolsa, mykolal, shuah
Cc: bpf, linux-kselftest, linux-kernel, Roberto Sassu, stable
From: Roberto Sassu <roberto.sassu@huawei.com>
Add the missing LIBBPF_0.8.0 at the end of the LIBBPF_1.0.0 declaration,
similarly to other version declarations.
Cc: stable@vger.kernel.org # 5.19.x
Fixes: e2371b1632b1c ("libbpf: start 1.0 development cycle")
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
tools/lib/bpf/libbpf.map | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index c1d6aa7c82b6..04fab9f1fdd7 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -367,7 +367,7 @@ LIBBPF_1.0.0 {
libbpf_bpf_map_type_str;
libbpf_bpf_prog_type_str;
perf_buffer__buffer;
-};
+} LIBBPF_0.8.0;
LIBBPF_1.1.0 {
global:
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/6] libbpf: Define bpf_get_fd_opts and introduce bpf_map_get_fd_by_id_opts()
2022-10-04 11:48 [PATCH 0/6] Add _opts variant for bpf_*_get_fd_by_id() Roberto Sassu
2022-10-04 11:48 ` [PATCH 1/6] libbpf: Fix LIBBPF_1.0.0 declaration in libbpf.map Roberto Sassu
@ 2022-10-04 11:48 ` Roberto Sassu
2022-10-04 11:48 ` [PATCH 3/6] libbpf: Introduce bpf_prog_get_fd_by_id_opts() Roberto Sassu
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2022-10-04 11:48 UTC (permalink / raw)
To: ast, daniel, andrii, martin.lau, song, yhs, john.fastabend,
kpsingh, sdf, haoluo, jolsa, mykolal, shuah
Cc: bpf, linux-kselftest, linux-kernel, Roberto Sassu
From: Roberto Sassu <roberto.sassu@huawei.com>
Define a new data structure called bpf_get_fd_opts, with the member
open_flags, to be used by callers of the _opts variants of
bpf_*_get_fd_by_id() to specify the permissions needed for the file
descriptor to be obtained.
Also, introduce bpf_map_get_fd_by_id_opts(), to let the caller pass a
bpf_get_fd_opts structure.
Finally, keep the existing bpf_map_get_fd_by_id(), and call
bpf_map_get_fd_by_id_opts() with NULL as opts argument, to request
read-write permissions (current behavior).
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
tools/lib/bpf/bpf.c | 12 +++++++++++-
tools/lib/bpf/bpf.h | 10 ++++++++++
tools/lib/bpf/libbpf.map | 1 +
3 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 1d49a0352836..4b03063edf1d 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -948,19 +948,29 @@ int bpf_prog_get_fd_by_id(__u32 id)
return libbpf_err_errno(fd);
}
-int bpf_map_get_fd_by_id(__u32 id)
+int bpf_map_get_fd_by_id_opts(__u32 id,
+ const struct bpf_get_fd_opts *opts)
{
const size_t attr_sz = offsetofend(union bpf_attr, open_flags);
union bpf_attr attr;
int fd;
+ if (!OPTS_VALID(opts, bpf_get_fd_opts))
+ return libbpf_err(-EINVAL);
+
memset(&attr, 0, attr_sz);
attr.map_id = id;
+ attr.open_flags = OPTS_GET(opts, open_flags, 0);
fd = sys_bpf_fd(BPF_MAP_GET_FD_BY_ID, &attr, attr_sz);
return libbpf_err_errno(fd);
}
+int bpf_map_get_fd_by_id(__u32 id)
+{
+ return bpf_map_get_fd_by_id_opts(id, NULL);
+}
+
int bpf_btf_get_fd_by_id(__u32 id)
{
const size_t attr_sz = offsetofend(union bpf_attr, open_flags);
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 9c50beabdd14..c60eda3c88ad 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -365,7 +365,17 @@ LIBBPF_API int bpf_prog_get_next_id(__u32 start_id, __u32 *next_id);
LIBBPF_API int bpf_map_get_next_id(__u32 start_id, __u32 *next_id);
LIBBPF_API int bpf_btf_get_next_id(__u32 start_id, __u32 *next_id);
LIBBPF_API int bpf_link_get_next_id(__u32 start_id, __u32 *next_id);
+
+struct bpf_get_fd_opts {
+ size_t sz; /* size of this struct for forward/backward compatibility */
+ __u32 open_flags; /* permissions requested for the operation on fd */
+ size_t :0;
+};
+#define bpf_get_fd_opts__last_field open_flags
+
LIBBPF_API int bpf_prog_get_fd_by_id(__u32 id);
+LIBBPF_API int bpf_map_get_fd_by_id_opts(__u32 id,
+ const struct bpf_get_fd_opts *opts);
LIBBPF_API int bpf_map_get_fd_by_id(__u32 id);
LIBBPF_API int bpf_btf_get_fd_by_id(__u32 id);
LIBBPF_API int bpf_link_get_fd_by_id(__u32 id);
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index 04fab9f1fdd7..2e665b21d84f 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -371,6 +371,7 @@ LIBBPF_1.0.0 {
LIBBPF_1.1.0 {
global:
+ bpf_map_get_fd_by_id_opts;
user_ring_buffer__discard;
user_ring_buffer__free;
user_ring_buffer__new;
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/6] libbpf: Introduce bpf_prog_get_fd_by_id_opts()
2022-10-04 11:48 [PATCH 0/6] Add _opts variant for bpf_*_get_fd_by_id() Roberto Sassu
2022-10-04 11:48 ` [PATCH 1/6] libbpf: Fix LIBBPF_1.0.0 declaration in libbpf.map Roberto Sassu
2022-10-04 11:48 ` [PATCH 2/6] libbpf: Define bpf_get_fd_opts and introduce bpf_map_get_fd_by_id_opts() Roberto Sassu
@ 2022-10-04 11:48 ` Roberto Sassu
2022-10-04 11:48 ` [PATCH 4/6] libbpf: Introduce bpf_btf_get_fd_by_id_opts() Roberto Sassu
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2022-10-04 11:48 UTC (permalink / raw)
To: ast, daniel, andrii, martin.lau, song, yhs, john.fastabend,
kpsingh, sdf, haoluo, jolsa, mykolal, shuah
Cc: bpf, linux-kselftest, linux-kernel, Roberto Sassu
From: Roberto Sassu <roberto.sassu@huawei.com>
Introduce bpf_prog_get_fd_by_id_opts(), for symmetry with
bpf_map_get_fd_by_id_opts(), to let the caller pass the newly introduced
data structure bpf_get_fd_opts. Keep the existing bpf_prog_get_fd_by_id(),
and call bpf_prog_get_fd_by_id_opts() with NULL as opts argument, to
prevent setting open_flags.
Currently, the kernel does not support non-zero open_flags for
bpf_prog_get_fd_by_id_opts(), and a call with them will result in an error
returned by the bpf() system call. The caller should always pass zero
open_flags.
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
tools/lib/bpf/bpf.c | 11 ++++++++++-
tools/lib/bpf/bpf.h | 2 ++
tools/lib/bpf/libbpf.map | 1 +
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 4b03063edf1d..92464c2d1da7 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -935,19 +935,28 @@ int bpf_link_get_next_id(__u32 start_id, __u32 *next_id)
return bpf_obj_get_next_id(start_id, next_id, BPF_LINK_GET_NEXT_ID);
}
-int bpf_prog_get_fd_by_id(__u32 id)
+int bpf_prog_get_fd_by_id_opts(__u32 id, const struct bpf_get_fd_opts *opts)
{
const size_t attr_sz = offsetofend(union bpf_attr, open_flags);
union bpf_attr attr;
int fd;
+ if (!OPTS_VALID(opts, bpf_get_fd_opts))
+ return libbpf_err(-EINVAL);
+
memset(&attr, 0, attr_sz);
attr.prog_id = id;
+ attr.open_flags = OPTS_GET(opts, open_flags, 0);
fd = sys_bpf_fd(BPF_PROG_GET_FD_BY_ID, &attr, attr_sz);
return libbpf_err_errno(fd);
}
+int bpf_prog_get_fd_by_id(__u32 id)
+{
+ return bpf_prog_get_fd_by_id_opts(id, NULL);
+}
+
int bpf_map_get_fd_by_id_opts(__u32 id,
const struct bpf_get_fd_opts *opts)
{
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index c60eda3c88ad..595d342fb7f9 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -373,6 +373,8 @@ struct bpf_get_fd_opts {
};
#define bpf_get_fd_opts__last_field open_flags
+LIBBPF_API int bpf_prog_get_fd_by_id_opts(__u32 id,
+ const struct bpf_get_fd_opts *opts);
LIBBPF_API int bpf_prog_get_fd_by_id(__u32 id);
LIBBPF_API int bpf_map_get_fd_by_id_opts(__u32 id,
const struct bpf_get_fd_opts *opts);
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index 2e665b21d84f..c3604eaa220d 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -372,6 +372,7 @@ LIBBPF_1.0.0 {
LIBBPF_1.1.0 {
global:
bpf_map_get_fd_by_id_opts;
+ bpf_prog_get_fd_by_id_opts;
user_ring_buffer__discard;
user_ring_buffer__free;
user_ring_buffer__new;
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 4/6] libbpf: Introduce bpf_btf_get_fd_by_id_opts()
2022-10-04 11:48 [PATCH 0/6] Add _opts variant for bpf_*_get_fd_by_id() Roberto Sassu
` (2 preceding siblings ...)
2022-10-04 11:48 ` [PATCH 3/6] libbpf: Introduce bpf_prog_get_fd_by_id_opts() Roberto Sassu
@ 2022-10-04 11:48 ` Roberto Sassu
2022-10-04 11:48 ` [PATCH 5/6] libbpf: Introduce bpf_link_get_fd_by_id_opts() Roberto Sassu
2022-10-04 11:48 ` [PATCH 6/6] selftests/bpf: Add tests for _opts variants of bpf_*_get_fd_by_id() Roberto Sassu
5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2022-10-04 11:48 UTC (permalink / raw)
To: ast, daniel, andrii, martin.lau, song, yhs, john.fastabend,
kpsingh, sdf, haoluo, jolsa, mykolal, shuah
Cc: bpf, linux-kselftest, linux-kernel, Roberto Sassu
From: Roberto Sassu <roberto.sassu@huawei.com>
Introduce bpf_btf_get_fd_by_id_opts(), for symmetry with
bpf_map_get_fd_by_id_opts(), to let the caller pass the newly introduced
data structure bpf_get_fd_opts. Keep the existing bpf_btf_get_fd_by_id(),
and call bpf_btf_get_fd_by_id_opts() with NULL as opts argument, to prevent
setting open_flags.
Currently, the kernel does not support non-zero open_flags for
bpf_btf_get_fd_by_id_opts(), and a call with them will result in an error
returned by the bpf() system call. The caller should always pass zero
open_flags.
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
tools/lib/bpf/bpf.c | 12 +++++++++++-
tools/lib/bpf/bpf.h | 2 ++
tools/lib/bpf/libbpf.map | 1 +
3 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 92464c2d1da7..f43e8c8afbd3 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -980,19 +980,29 @@ int bpf_map_get_fd_by_id(__u32 id)
return bpf_map_get_fd_by_id_opts(id, NULL);
}
-int bpf_btf_get_fd_by_id(__u32 id)
+int bpf_btf_get_fd_by_id_opts(__u32 id,
+ const struct bpf_get_fd_opts *opts)
{
const size_t attr_sz = offsetofend(union bpf_attr, open_flags);
union bpf_attr attr;
int fd;
+ if (!OPTS_VALID(opts, bpf_get_fd_opts))
+ return libbpf_err(-EINVAL);
+
memset(&attr, 0, attr_sz);
attr.btf_id = id;
+ attr.open_flags = OPTS_GET(opts, open_flags, 0);
fd = sys_bpf_fd(BPF_BTF_GET_FD_BY_ID, &attr, attr_sz);
return libbpf_err_errno(fd);
}
+int bpf_btf_get_fd_by_id(__u32 id)
+{
+ return bpf_btf_get_fd_by_id_opts(id, NULL);
+}
+
int bpf_link_get_fd_by_id(__u32 id)
{
const size_t attr_sz = offsetofend(union bpf_attr, open_flags);
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 595d342fb7f9..559af0b84299 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -379,6 +379,8 @@ LIBBPF_API int bpf_prog_get_fd_by_id(__u32 id);
LIBBPF_API int bpf_map_get_fd_by_id_opts(__u32 id,
const struct bpf_get_fd_opts *opts);
LIBBPF_API int bpf_map_get_fd_by_id(__u32 id);
+LIBBPF_API int bpf_btf_get_fd_by_id_opts(__u32 id,
+ const struct bpf_get_fd_opts *opts);
LIBBPF_API int bpf_btf_get_fd_by_id(__u32 id);
LIBBPF_API int bpf_link_get_fd_by_id(__u32 id);
LIBBPF_API int bpf_obj_get_info_by_fd(int bpf_fd, void *info, __u32 *info_len);
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index c3604eaa220d..7011d5eec67b 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -371,6 +371,7 @@ LIBBPF_1.0.0 {
LIBBPF_1.1.0 {
global:
+ bpf_btf_get_fd_by_id_opts;
bpf_map_get_fd_by_id_opts;
bpf_prog_get_fd_by_id_opts;
user_ring_buffer__discard;
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 5/6] libbpf: Introduce bpf_link_get_fd_by_id_opts()
2022-10-04 11:48 [PATCH 0/6] Add _opts variant for bpf_*_get_fd_by_id() Roberto Sassu
` (3 preceding siblings ...)
2022-10-04 11:48 ` [PATCH 4/6] libbpf: Introduce bpf_btf_get_fd_by_id_opts() Roberto Sassu
@ 2022-10-04 11:48 ` Roberto Sassu
2022-10-04 11:48 ` [PATCH 6/6] selftests/bpf: Add tests for _opts variants of bpf_*_get_fd_by_id() Roberto Sassu
5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2022-10-04 11:48 UTC (permalink / raw)
To: ast, daniel, andrii, martin.lau, song, yhs, john.fastabend,
kpsingh, sdf, haoluo, jolsa, mykolal, shuah
Cc: bpf, linux-kselftest, linux-kernel, Roberto Sassu
From: Roberto Sassu <roberto.sassu@huawei.com>
Introduce bpf_link_get_fd_by_id_opts(), for symmetry with
bpf_map_get_fd_by_id_opts(), to let the caller pass the newly introduced
data structure bpf_get_fd_opts. Keep the existing bpf_link_get_fd_by_id(),
and call bpf_link_get_fd_by_id_opts() with NULL as opts argument, to
prevent setting open_flags.
Currently, the kernel does not support non-zero open_flags for
bpf_link_get_fd_by_id_opts(), and a call with them will result in an error
returned by the bpf() system call. The caller should always pass zero
open_flags.
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
tools/lib/bpf/bpf.c | 12 +++++++++++-
tools/lib/bpf/bpf.h | 2 ++
tools/lib/bpf/libbpf.map | 1 +
3 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index f43e8c8afbd3..f3d89a2bdb50 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -1003,19 +1003,29 @@ int bpf_btf_get_fd_by_id(__u32 id)
return bpf_btf_get_fd_by_id_opts(id, NULL);
}
-int bpf_link_get_fd_by_id(__u32 id)
+int bpf_link_get_fd_by_id_opts(__u32 id,
+ const struct bpf_get_fd_opts *opts)
{
const size_t attr_sz = offsetofend(union bpf_attr, open_flags);
union bpf_attr attr;
int fd;
+ if (!OPTS_VALID(opts, bpf_get_fd_opts))
+ return libbpf_err(-EINVAL);
+
memset(&attr, 0, attr_sz);
attr.link_id = id;
+ attr.open_flags = OPTS_GET(opts, open_flags, 0);
fd = sys_bpf_fd(BPF_LINK_GET_FD_BY_ID, &attr, attr_sz);
return libbpf_err_errno(fd);
}
+int bpf_link_get_fd_by_id(__u32 id)
+{
+ return bpf_link_get_fd_by_id_opts(id, NULL);
+}
+
int bpf_obj_get_info_by_fd(int bpf_fd, void *info, __u32 *info_len)
{
const size_t attr_sz = offsetofend(union bpf_attr, info);
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 559af0b84299..834809d74c82 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -382,6 +382,8 @@ LIBBPF_API int bpf_map_get_fd_by_id(__u32 id);
LIBBPF_API int bpf_btf_get_fd_by_id_opts(__u32 id,
const struct bpf_get_fd_opts *opts);
LIBBPF_API int bpf_btf_get_fd_by_id(__u32 id);
+LIBBPF_API int bpf_link_get_fd_by_id_opts(__u32 id,
+ const struct bpf_get_fd_opts *opts);
LIBBPF_API int bpf_link_get_fd_by_id(__u32 id);
LIBBPF_API int bpf_obj_get_info_by_fd(int bpf_fd, void *info, __u32 *info_len);
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index 7011d5eec67b..71bf5691a689 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -372,6 +372,7 @@ LIBBPF_1.0.0 {
LIBBPF_1.1.0 {
global:
bpf_btf_get_fd_by_id_opts;
+ bpf_link_get_fd_by_id_opts;
bpf_map_get_fd_by_id_opts;
bpf_prog_get_fd_by_id_opts;
user_ring_buffer__discard;
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 6/6] selftests/bpf: Add tests for _opts variants of bpf_*_get_fd_by_id()
2022-10-04 11:48 [PATCH 0/6] Add _opts variant for bpf_*_get_fd_by_id() Roberto Sassu
` (4 preceding siblings ...)
2022-10-04 11:48 ` [PATCH 5/6] libbpf: Introduce bpf_link_get_fd_by_id_opts() Roberto Sassu
@ 2022-10-04 11:48 ` Roberto Sassu
5 siblings, 0 replies; 7+ messages in thread
From: Roberto Sassu @ 2022-10-04 11:48 UTC (permalink / raw)
To: ast, daniel, andrii, martin.lau, song, yhs, john.fastabend,
kpsingh, sdf, haoluo, jolsa, mykolal, shuah
Cc: bpf, linux-kselftest, linux-kernel, Roberto Sassu
From: Roberto Sassu <roberto.sassu@huawei.com>
Introduce the data_input map, write-protected with a small eBPF program
implementing the lsm/bpf_map hook.
Then, ensure that bpf_map_get_fd_by_id() and bpf_map_get_fd_by_id_opts()
with NULL opts don't succeed due to requesting read-write access to the
write-protected map. Also, ensure that bpf_map_get_fd_by_id_opts() with
open_flags in opts set to BPF_F_RDONLY instead succeeds.
After obtaining a read-only fd, ensure that only map lookup succeeds and
not update. Ensure that update works only with the read-write fd obtained
at program loading time, when the write protection was not yet enabled.
Finally, ensure that the other _opts variants of bpf_*_get_fd_by_id() don't
work if the BPF_F_RDONLY flag is set in opts (due to the kernel not
handling the open_flags member of bpf_attr).
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
.../bpf/prog_tests/libbpf_get_fd_opts.c | 88 +++++++++++++++++++
.../bpf/progs/test_libbpf_get_fd_opts.c | 36 ++++++++
2 files changed, 124 insertions(+)
create mode 100644 tools/testing/selftests/bpf/prog_tests/libbpf_get_fd_opts.c
create mode 100644 tools/testing/selftests/bpf/progs/test_libbpf_get_fd_opts.c
diff --git a/tools/testing/selftests/bpf/prog_tests/libbpf_get_fd_opts.c b/tools/testing/selftests/bpf/prog_tests/libbpf_get_fd_opts.c
new file mode 100644
index 000000000000..2d4ba8f80d55
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/libbpf_get_fd_opts.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Copyright (C) 2022 Huawei Technologies Duesseldorf GmbH
+ *
+ * Author: Roberto Sassu <roberto.sassu@huawei.com>
+ */
+
+#include <test_progs.h>
+
+#include "test_libbpf_get_fd_opts.skel.h"
+
+void test_libbpf_get_fd_opts(void)
+{
+ struct test_libbpf_get_fd_opts *skel;
+ struct bpf_map_info info_m = { 0 };
+ __u32 len = sizeof(info_m), value;
+ struct bpf_map *map;
+ int ret, zero = 0, fd = -1;
+
+ DECLARE_LIBBPF_OPTS(bpf_get_fd_opts, fd_opts_rdonly,
+ .open_flags = BPF_F_RDONLY,
+ );
+
+ skel = test_libbpf_get_fd_opts__open_and_load();
+ if (!ASSERT_OK_PTR(skel, "test_libbpf_get_fd_opts__open_and_load"))
+ return;
+
+ ret = test_libbpf_get_fd_opts__attach(skel);
+ if (!ASSERT_OK(ret, "test_libbpf_get_fd_opts__attach"))
+ goto close_prog;
+
+ map = bpf_object__find_map_by_name(skel->obj, "data_input");
+ if (!ASSERT_OK_PTR(map, "bpf_object__find_map_by_name"))
+ goto close_prog;
+
+ ret = bpf_obj_get_info_by_fd(bpf_map__fd(map), &info_m, &len);
+ if (!ASSERT_OK(ret, "bpf_obj_get_info_by_fd"))
+ goto close_prog;
+
+ fd = bpf_map_get_fd_by_id(info_m.id);
+ if (!ASSERT_LT(fd, 0, "bpf_map_get_fd_by_id"))
+ goto close_prog;
+
+ fd = bpf_map_get_fd_by_id_opts(info_m.id, NULL);
+ if (!ASSERT_LT(fd, 0, "bpf_map_get_fd_by_id_opts"))
+ goto close_prog;
+
+ fd = bpf_map_get_fd_by_id_opts(info_m.id, &fd_opts_rdonly);
+ if (!ASSERT_GE(fd, 0, "bpf_map_get_fd_by_id_opts"))
+ goto close_prog;
+
+ /* Map lookup should work with read-only fd. */
+ ret = bpf_map_lookup_elem(fd, &zero, &value);
+ if (!ASSERT_OK(ret, "bpf_map_lookup_elem"))
+ goto close_prog;
+
+ if (!ASSERT_EQ(value, 0, "map value mismatch"))
+ goto close_prog;
+
+ /* Map update should not work with read-only fd. */
+ ret = bpf_map_update_elem(fd, &zero, &len, BPF_ANY);
+ if (!ASSERT_LT(ret, 0, "bpf_map_update_elem"))
+ goto close_prog;
+
+ /* Map update should work with read-write fd. */
+ ret = bpf_map_update_elem(bpf_map__fd(map), &zero, &len, BPF_ANY);
+ if (!ASSERT_OK(ret, "bpf_map_update_elem"))
+ goto close_prog;
+
+ /* Prog get fd with opts set should not work (no kernel support). */
+ ret = bpf_prog_get_fd_by_id_opts(0, &fd_opts_rdonly);
+ if (!ASSERT_EQ(ret, -EINVAL, "bpf_prog_get_fd_by_id_opts"))
+ goto close_prog;
+
+ /* Link get fd with opts set should not work (no kernel support). */
+ ret = bpf_link_get_fd_by_id_opts(0, &fd_opts_rdonly);
+ if (!ASSERT_EQ(ret, -EINVAL, "bpf_link_get_fd_by_id_opts"))
+ goto close_prog;
+
+ /* BTF get fd with opts set should not work (no kernel support). */
+ ret = bpf_btf_get_fd_by_id_opts(0, &fd_opts_rdonly);
+ ASSERT_EQ(ret, -EINVAL, "bpf_btf_get_fd_by_id_opts");
+
+close_prog:
+ close(fd);
+ test_libbpf_get_fd_opts__destroy(skel);
+}
diff --git a/tools/testing/selftests/bpf/progs/test_libbpf_get_fd_opts.c b/tools/testing/selftests/bpf/progs/test_libbpf_get_fd_opts.c
new file mode 100644
index 000000000000..f5ac5f3e8919
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/test_libbpf_get_fd_opts.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Copyright (C) 2022 Huawei Technologies Duesseldorf GmbH
+ *
+ * Author: Roberto Sassu <roberto.sassu@huawei.com>
+ */
+
+#include "vmlinux.h"
+#include <errno.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+/* From include/linux/mm.h. */
+#define FMODE_WRITE 0x2
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, __u32);
+} data_input SEC(".maps");
+
+char _license[] SEC("license") = "GPL";
+
+SEC("lsm/bpf_map")
+int BPF_PROG(check_access, struct bpf_map *map, fmode_t fmode)
+{
+ if (map != (struct bpf_map *)&data_input)
+ return 0;
+
+ if (fmode & FMODE_WRITE)
+ return -EACCES;
+
+ return 0;
+}
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2022-10-04 11:50 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-04 11:48 [PATCH 0/6] Add _opts variant for bpf_*_get_fd_by_id() Roberto Sassu
2022-10-04 11:48 ` [PATCH 1/6] libbpf: Fix LIBBPF_1.0.0 declaration in libbpf.map Roberto Sassu
2022-10-04 11:48 ` [PATCH 2/6] libbpf: Define bpf_get_fd_opts and introduce bpf_map_get_fd_by_id_opts() Roberto Sassu
2022-10-04 11:48 ` [PATCH 3/6] libbpf: Introduce bpf_prog_get_fd_by_id_opts() Roberto Sassu
2022-10-04 11:48 ` [PATCH 4/6] libbpf: Introduce bpf_btf_get_fd_by_id_opts() Roberto Sassu
2022-10-04 11:48 ` [PATCH 5/6] libbpf: Introduce bpf_link_get_fd_by_id_opts() Roberto Sassu
2022-10-04 11:48 ` [PATCH 6/6] selftests/bpf: Add tests for _opts variants of bpf_*_get_fd_by_id() Roberto Sassu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).