bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH bpf] libbpf: sanitise map names before pinning
@ 2020-11-30 16:17 Toke Høiland-Jørgensen
  2020-12-02  0:39 ` Andrii Nakryiko
  0 siblings, 1 reply; 3+ messages in thread
From: Toke Høiland-Jørgensen @ 2020-11-30 16:17 UTC (permalink / raw)
  To: daniel, ast, andrii; +Cc: Toke Høiland-Jørgensen, bpf, netdev

When we added sanitising of map names before loading programs to libbpf, we
still allowed periods in the name. While the kernel will accept these for
the map names themselves, they are not allowed in file names when pinning
maps. This means that bpf_object__pin_maps() will fail if called on an
object that contains internal maps (such as sections .rodata).

Fix this by replacing periods with underscores when constructing map pin
paths. This only affects the paths generated by libbpf when
bpf_object__ping_maps() is called with a path argument. Any pin paths set
by bpf_map__set_pin_path() are unaffected, and it will still be up to the
caller to avoid invalid characters in those.

Fixes: 113e6b7e15e2 ("libbpf: Sanitise internal map names so they are not rejected by the kernel")
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
 tools/lib/bpf/libbpf.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 8d05132e1945..8a3b4713b356 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -7665,8 +7665,8 @@ int bpf_object__pin_maps(struct bpf_object *obj, const char *path)
 	}
 
 	bpf_object__for_each_map(map, obj) {
+		char buf[PATH_MAX], *s = buf;
 		char *pin_path = NULL;
-		char buf[PATH_MAX];
 
 		if (path) {
 			int len;
@@ -7680,6 +7680,8 @@ int bpf_object__pin_maps(struct bpf_object *obj, const char *path)
 				err = -ENAMETOOLONG;
 				goto err_unpin_maps;
 			}
+			while ((s = strstr(s, ".")))
+			    *s = '_';
 			pin_path = buf;
 		} else if (!map->pin_path) {
 			continue;
@@ -7712,8 +7714,8 @@ int bpf_object__unpin_maps(struct bpf_object *obj, const char *path)
 		return -ENOENT;
 
 	bpf_object__for_each_map(map, obj) {
+		char buf[PATH_MAX], *s = buf;
 		char *pin_path = NULL;
-		char buf[PATH_MAX];
 
 		if (path) {
 			int len;
@@ -7724,6 +7726,8 @@ int bpf_object__unpin_maps(struct bpf_object *obj, const char *path)
 				return -EINVAL;
 			else if (len >= PATH_MAX)
 				return -ENAMETOOLONG;
+			while ((s = strstr(s, ".")))
+			    *s = '_';
 			pin_path = buf;
 		} else if (!map->pin_path) {
 			continue;
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH bpf] libbpf: sanitise map names before pinning
  2020-11-30 16:17 [PATCH bpf] libbpf: sanitise map names before pinning Toke Høiland-Jørgensen
@ 2020-12-02  0:39 ` Andrii Nakryiko
  2020-12-02  9:55   ` Toke Høiland-Jørgensen
  0 siblings, 1 reply; 3+ messages in thread
From: Andrii Nakryiko @ 2020-12-02  0:39 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen
  Cc: Daniel Borkmann, Alexei Starovoitov, Andrii Nakryiko, bpf, Networking

On Mon, Nov 30, 2020 at 8:17 AM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>
> When we added sanitising of map names before loading programs to libbpf, we
> still allowed periods in the name. While the kernel will accept these for
> the map names themselves, they are not allowed in file names when pinning

That sounds like an unnecessary difference in kernel behavior. If the
kernel allows maps with '.' in the name, why not allow to pin it?
Should we fix that in the kernel?

> maps. This means that bpf_object__pin_maps() will fail if called on an
> object that contains internal maps (such as sections .rodata).
>
> Fix this by replacing periods with underscores when constructing map pin
> paths. This only affects the paths generated by libbpf when
> bpf_object__ping_maps() is called with a path argument. Any pin paths set
> by bpf_map__set_pin_path() are unaffected, and it will still be up to the
> caller to avoid invalid characters in those.
>
> Fixes: 113e6b7e15e2 ("libbpf: Sanitise internal map names so they are not rejected by the kernel")
> Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
> ---
>  tools/lib/bpf/libbpf.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index 8d05132e1945..8a3b4713b356 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -7665,8 +7665,8 @@ int bpf_object__pin_maps(struct bpf_object *obj, const char *path)
>         }
>
>         bpf_object__for_each_map(map, obj) {
> +               char buf[PATH_MAX], *s = buf;
>                 char *pin_path = NULL;
> -               char buf[PATH_MAX];
>
>                 if (path) {
>                         int len;
> @@ -7680,6 +7680,8 @@ int bpf_object__pin_maps(struct bpf_object *obj, const char *path)
>                                 err = -ENAMETOOLONG;
>                                 goto err_unpin_maps;
>                         }
> +                       while ((s = strstr(s, ".")))
> +                           *s = '_';

Let's extract this into a helper method?

>                         pin_path = buf;
>                 } else if (!map->pin_path) {
>                         continue;
> @@ -7712,8 +7714,8 @@ int bpf_object__unpin_maps(struct bpf_object *obj, const char *path)
>                 return -ENOENT;
>
>         bpf_object__for_each_map(map, obj) {
> +               char buf[PATH_MAX], *s = buf;
>                 char *pin_path = NULL;
> -               char buf[PATH_MAX];
>
>                 if (path) {
>                         int len;
> @@ -7724,6 +7726,8 @@ int bpf_object__unpin_maps(struct bpf_object *obj, const char *path)
>                                 return -EINVAL;
>                         else if (len >= PATH_MAX)
>                                 return -ENAMETOOLONG;
> +                       while ((s = strstr(s, ".")))
> +                           *s = '_';
>                         pin_path = buf;
>                 } else if (!map->pin_path) {
>                         continue;
> --
> 2.29.2
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH bpf] libbpf: sanitise map names before pinning
  2020-12-02  0:39 ` Andrii Nakryiko
@ 2020-12-02  9:55   ` Toke Høiland-Jørgensen
  0 siblings, 0 replies; 3+ messages in thread
From: Toke Høiland-Jørgensen @ 2020-12-02  9:55 UTC (permalink / raw)
  To: Andrii Nakryiko
  Cc: Daniel Borkmann, Alexei Starovoitov, Andrii Nakryiko, bpf, Networking

Andrii Nakryiko <andrii.nakryiko@gmail.com> writes:

> On Mon, Nov 30, 2020 at 8:17 AM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>>
>> When we added sanitising of map names before loading programs to libbpf, we
>> still allowed periods in the name. While the kernel will accept these for
>> the map names themselves, they are not allowed in file names when pinning
>
> That sounds like an unnecessary difference in kernel behavior. If the
> kernel allows maps with '.' in the name, why not allow to pin it?
> Should we fix that in the kernel?

Yeah, it is a bit odd. I always assumed the restriction in file names is
to prevent people from creating hidden (.-prefixed) files in bpffs? But
don't actually know for sure. Anyway, if that is the case we could still
allow periods in the middle of names.

I'm certainly not opposed to changing the kernel behaviour and I can
follow up with a patch for this if others agree; but we obviously still
need this for older kernels so I'll send a v2 with the helper method you
suggested below.

-Toke


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-12-02  9:57 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-30 16:17 [PATCH bpf] libbpf: sanitise map names before pinning Toke Høiland-Jørgensen
2020-12-02  0:39 ` Andrii Nakryiko
2020-12-02  9:55   ` Toke Høiland-Jørgensen

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).