* [PATCH iproute2 master] bpf: Fix race condition with map pinning
@ 2019-09-19 22:07 Joe Stringer
2019-09-19 23:25 ` Daniel Borkmann
2019-09-20 1:56 ` Joe Stringer
0 siblings, 2 replies; 3+ messages in thread
From: Joe Stringer @ 2019-09-19 22:07 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, daniel
If two processes attempt to invoke bpf_map_attach() at the same time,
then they will both create maps, then the first will successfully pin
the map to the filesystem and the second will not pin the map, but will
continue operating with a reference to its own copy of the map. As a
result, the sharing of the same map will be broken from the two programs
that were concurrently loaded via loaders using this library.
Fix this by adding a retry in the case where the pinning fails because
the map already exists on the filesystem. In that case, re-attempt
opening a fd to the map on the filesystem as it shows that another
program already created and pinned a map at that location.
Signed-off-by: Joe Stringer <joe@wand.net.nz>
---
lib/bpf.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/lib/bpf.c b/lib/bpf.c
index f64b58c3bb19..23eb8952cc28 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c
@@ -1625,7 +1625,9 @@ static int bpf_map_attach(const char *name, struct bpf_elf_ctx *ctx,
int *have_map_in_map)
{
int fd, ifindex, ret, map_inner_fd = 0;
+ bool retried = false;
+probe:
fd = bpf_probe_pinned(name, ctx, map->pinning);
if (fd > 0) {
ret = bpf_map_selfcheck_pinned(fd, map, ext,
@@ -1674,7 +1676,11 @@ static int bpf_map_attach(const char *name, struct bpf_elf_ctx *ctx,
}
ret = bpf_place_pinned(fd, name, ctx, map->pinning);
- if (ret < 0 && errno != EEXIST) {
+ if (ret < 0) {
+ if (!retried && errno == EEXIST) {
+ retried = true;
+ goto probe;
+ }
fprintf(stderr, "Could not pin %s map: %s\n", name,
strerror(errno));
close(fd);
--
2.20.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH iproute2 master] bpf: Fix race condition with map pinning
2019-09-19 22:07 [PATCH iproute2 master] bpf: Fix race condition with map pinning Joe Stringer
@ 2019-09-19 23:25 ` Daniel Borkmann
2019-09-20 1:56 ` Joe Stringer
1 sibling, 0 replies; 3+ messages in thread
From: Daniel Borkmann @ 2019-09-19 23:25 UTC (permalink / raw)
To: Joe Stringer; +Cc: Stephen Hemminger, netdev
On Thu, Sep 19, 2019 at 03:07:33PM -0700, Joe Stringer wrote:
> If two processes attempt to invoke bpf_map_attach() at the same time,
> then they will both create maps, then the first will successfully pin
> the map to the filesystem and the second will not pin the map, but will
> continue operating with a reference to its own copy of the map. As a
> result, the sharing of the same map will be broken from the two programs
> that were concurrently loaded via loaders using this library.
>
> Fix this by adding a retry in the case where the pinning fails because
> the map already exists on the filesystem. In that case, re-attempt
> opening a fd to the map on the filesystem as it shows that another
> program already created and pinned a map at that location.
>
> Signed-off-by: Joe Stringer <joe@wand.net.nz>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH iproute2 master] bpf: Fix race condition with map pinning
2019-09-19 22:07 [PATCH iproute2 master] bpf: Fix race condition with map pinning Joe Stringer
2019-09-19 23:25 ` Daniel Borkmann
@ 2019-09-20 1:56 ` Joe Stringer
1 sibling, 0 replies; 3+ messages in thread
From: Joe Stringer @ 2019-09-20 1:56 UTC (permalink / raw)
To: Joe Stringer; +Cc: Stephen Hemminger, netdev, Daniel Borkmann
On Thu, Sep 19, 2019 at 3:07 PM Joe Stringer <joe@wand.net.nz> wrote:
>
> If two processes attempt to invoke bpf_map_attach() at the same time,
> then they will both create maps, then the first will successfully pin
> the map to the filesystem and the second will not pin the map, but will
> continue operating with a reference to its own copy of the map. As a
> result, the sharing of the same map will be broken from the two programs
> that were concurrently loaded via loaders using this library.
>
> Fix this by adding a retry in the case where the pinning fails because
> the map already exists on the filesystem. In that case, re-attempt
> opening a fd to the map on the filesystem as it shows that another
> program already created and pinned a map at that location.
>
> Signed-off-by: Joe Stringer <joe@wand.net.nz>
> ---
> lib/bpf.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/lib/bpf.c b/lib/bpf.c
> index f64b58c3bb19..23eb8952cc28 100644
> --- a/lib/bpf.c
> +++ b/lib/bpf.c
> @@ -1625,7 +1625,9 @@ static int bpf_map_attach(const char *name, struct bpf_elf_ctx *ctx,
> int *have_map_in_map)
> {
> int fd, ifindex, ret, map_inner_fd = 0;
> + bool retried = false;
>
> +probe:
> fd = bpf_probe_pinned(name, ctx, map->pinning);
> if (fd > 0) {
> ret = bpf_map_selfcheck_pinned(fd, map, ext,
> @@ -1674,7 +1676,11 @@ static int bpf_map_attach(const char *name, struct bpf_elf_ctx *ctx,
> }
>
> ret = bpf_place_pinned(fd, name, ctx, map->pinning);
> - if (ret < 0 && errno != EEXIST) {
> + if (ret < 0) {
> + if (!retried && errno == EEXIST) {
> + retried = true;
> + goto probe;
> + }
Ah, forgot to close 'fd' before the jump in this retry case. Will fix
that up in v2.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2019-09-20 1:57 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-09-19 22:07 [PATCH iproute2 master] bpf: Fix race condition with map pinning Joe Stringer
2019-09-19 23:25 ` Daniel Borkmann
2019-09-20 1:56 ` Joe Stringer
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).