BPF List
 help / color / mirror / Atom feed
From: Christian Brauner <brauner@kernel.org>
To: Andrii Nakryiko <andrii@kernel.org>
Cc: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net,
	martin.lau@kernel.org, cyphar@cyphar.com, lennart@poettering.net
Subject: Re: [PATCH bpf-next 1/3] bpf: support O_PATH FDs in BPF_OBJ_PIN and BPF_OBJ_GET commands
Date: Tue, 16 May 2023 11:07:44 +0200	[thread overview]
Message-ID: <20230516-briefe-blutzellen-0432957bdd15@brauner> (raw)
In-Reply-To: <20230516001348.286414-2-andrii@kernel.org>

On Mon, May 15, 2023 at 05:13:46PM -0700, Andrii Nakryiko wrote:
> Current UAPI of BPF_OBJ_PIN and BPF_OBJ_GET commands of bpf() syscall
> forces users to specify pinning location as a string-based absolute or
> relative (to current working directory) path. This has various
> implications related to security (e.g., symlink-based attacks), forces
> BPF FS to be exposed in the file system, which can cause races with
> other applications.
> 
> One of the feedbacks we got from folks working with containers heavily
> was that inability to use purely FD-based location specification was an
> unfortunate limitation and hindrance for BPF_OBJ_PIN and BPF_OBJ_GET
> commands. This patch closes this oversight, adding path_fd field to

Cool!

> BPF_OBJ_PIN and BPF_OBJ_GET UAPI, following conventions established by
> *at() syscalls for dirfd + pathname combinations.
> 
> This now allows interesting possibilities like working with detached BPF
> FS mount (e.g., to perform multiple pinnings without running a risk of
> someone interfering with them), and generally making pinning/getting
> more secure and not prone to any races and/or security attacks.
> 
> This is demonstrated by a selftest added in subsequent patch that takes
> advantage of new mount APIs (fsopen, fsconfig, fsmount) to demonstrate
> creating detached BPF FS mount, pinning, and then getting BPF map out of
> it, all while never exposing this private instance of BPF FS to outside
> worlds.
> 
> Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
> ---
>  include/linux/bpf.h            |  4 ++--
>  include/uapi/linux/bpf.h       |  5 +++++
>  kernel/bpf/inode.c             | 16 ++++++++--------
>  kernel/bpf/syscall.c           |  8 +++++---
>  tools/include/uapi/linux/bpf.h |  5 +++++
>  5 files changed, 25 insertions(+), 13 deletions(-)
> 
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 36e4b2d8cca2..f58895830ada 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -2077,8 +2077,8 @@ struct file *bpf_link_new_file(struct bpf_link *link, int *reserved_fd);
>  struct bpf_link *bpf_link_get_from_fd(u32 ufd);
>  struct bpf_link *bpf_link_get_curr_or_next(u32 *id);
>  
> -int bpf_obj_pin_user(u32 ufd, const char __user *pathname);
> -int bpf_obj_get_user(const char __user *pathname, int flags);
> +int bpf_obj_pin_user(u32 ufd, int path_fd, const char __user *pathname);
> +int bpf_obj_get_user(int path_fd, const char __user *pathname, int flags);
>  
>  #define BPF_ITER_FUNC_PREFIX "bpf_iter_"
>  #define DEFINE_BPF_ITER_FUNC(target, args...)			\
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index 1bb11a6ee667..db2870a52ce0 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -1420,6 +1420,11 @@ union bpf_attr {
>  		__aligned_u64	pathname;
>  		__u32		bpf_fd;
>  		__u32		file_flags;
> +		/* same as dirfd in openat() syscall; see openat(2)
> +		 * manpage for details of dirfd/path_fd and pathname semantics;
> +		 * zero path_fd implies AT_FDCWD behavior
> +		 */
> +		__u32		path_fd;
>  	};

So 0 is a valid file descriptor and can trivially be created and made to
refer to any file. Is this a conscious decision to have a zero value
imply AT_FDCWD and have you done this somewhere else in bpf already?
Because that's contrary to how any file descriptor based apis work.

How this is usually solved for extensible structs is to have a flag
field that raises a flag to indicate that the fd fiel is set and thus 0
can be used as a valid value.

The way you're doing it right now is very counterintuitive to userspace
and pretty much guaranteed to cause subtle bugs.

  parent reply	other threads:[~2023-05-16  9:07 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-16  0:13 [PATCH bpf-next 0/3] Add O_PATH-based BPF_OBJ_PIN and BPF_OBJ_GET support Andrii Nakryiko
2023-05-16  0:13 ` [PATCH bpf-next 1/3] bpf: support O_PATH FDs in BPF_OBJ_PIN and BPF_OBJ_GET commands Andrii Nakryiko
2023-05-16  8:52   ` Jiri Olsa
2023-05-16 18:02     ` Andrii Nakryiko
2023-05-16  9:07   ` Christian Brauner [this message]
2023-05-16 18:02     ` Andrii Nakryiko
2023-05-17  9:11       ` fd == 0 means AT_FDCWD " Christian Brauner
2023-05-17 12:05         ` Christoph Hellwig
2023-05-17 16:17           ` Alexei Starovoitov
2023-05-17 21:48             ` Alexei Starovoitov
2023-05-18  8:38             ` Christian Brauner
2023-05-18 14:30               ` Theodore Ts'o
2023-05-18 16:25               ` Alexei Starovoitov
2023-05-18 16:33                 ` Matthew Wilcox
2023-05-18 17:22                   ` Christian Brauner
2023-05-18 17:20                 ` Christian Brauner
2023-05-18 17:33                   ` Linus Torvalds
2023-05-18 18:21                     ` Christian Brauner
2023-05-18 18:26                   ` Alexei Starovoitov
2023-05-18 18:57                     ` Linus Torvalds
2023-05-19  4:44                       ` Alexei Starovoitov
2023-05-19  8:13                         ` Christian Brauner
2023-05-19 14:27                           ` Theodore Ts'o
2023-05-19 17:51                         ` Linus Torvalds
2023-05-23  7:49                         ` Lennart Poettering
2023-05-23 17:25                           ` Andrii Nakryiko
2023-08-26  4:27                         ` Al Viro
2023-05-18 21:56         ` Andrii Nakryiko
2023-05-16  0:13 ` [PATCH bpf-next 2/3] libbpf: add opts-based bpf_obj_pin() API and add support for path_fd Andrii Nakryiko
2023-05-16  0:13 ` [PATCH bpf-next 3/3] selftests/bpf: add path_fd-based BPF_OBJ_PIN and BPF_OBJ_GET tests Andrii Nakryiko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230516-briefe-blutzellen-0432957bdd15@brauner \
    --to=brauner@kernel.org \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=cyphar@cyphar.com \
    --cc=daniel@iogearbox.net \
    --cc=lennart@poettering.net \
    --cc=martin.lau@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox