From: "Toke Høiland-Jørgensen" <toke@redhat.com>
To: Jesper Dangaard Brouer <brouer@redhat.com>,
David Ahern <dsahern@gmail.com>,
bpf@vger.kernel.org,
Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: Jesper Dangaard Brouer <brouer@redhat.com>,
netdev@vger.kernel.org, Daniel Borkmann <borkmann@iogearbox.net>,
Andrii Nakryiko <andrii.nakryiko@gmail.com>,
Lorenzo Bianconi <lorenzo@kernel.org>
Subject: Re: [PATCH bpf 1/3] bpf: syscall to start at file-descriptor 1
Date: Mon, 08 Jun 2020 20:28:03 +0200 [thread overview]
Message-ID: <875zc1cszw.fsf@toke.dk> (raw)
In-Reply-To: <159163507753.1967373.62249862728421448.stgit@firesoul>
Jesper Dangaard Brouer <brouer@redhat.com> writes:
> This patch change BPF syscall to avoid returning file descriptor value zero.
>
> As mentioned in cover letter, it is very impractical when extending kABI
> that the file-descriptor value 'zero' is valid, as this requires new fields
> must be initialised as minus-1. First step is to change the kernel such that
> BPF-syscall simply doesn't return value zero as a FD number.
>
> This patch achieves this by similar code to anon_inode_getfd(), with the
> exception of getting unused FD starting from 1. The kernel already supports
> starting from a specific FD value, as this is used by f_dupfd(). It seems
> simpler to replicate part of anon_inode_getfd() code and use this start from
> offset feature, instead of using f_dupfd() handling afterwards.
>
> Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
> ---
> fs/file.c | 2 +-
> include/linux/file.h | 1 +
> kernel/bpf/syscall.c | 38 ++++++++++++++++++++++++++++++++------
> 3 files changed, 34 insertions(+), 7 deletions(-)
>
> diff --git a/fs/file.c b/fs/file.c
> index abb8b7081d7a..122185cb7707 100644
> --- a/fs/file.c
> +++ b/fs/file.c
> @@ -535,7 +535,7 @@ int __alloc_fd(struct files_struct *files,
> return error;
> }
>
> -static int alloc_fd(unsigned start, unsigned flags)
> +int alloc_fd(unsigned start, unsigned flags)
Missing an EXPORT_SYMBOL() to go with this.
> {
> return __alloc_fd(current->files, start, rlimit(RLIMIT_NOFILE), flags);
> }
> diff --git a/include/linux/file.h b/include/linux/file.h
> index 122f80084a3e..927fb6c2582d 100644
> --- a/include/linux/file.h
> +++ b/include/linux/file.h
> @@ -85,6 +85,7 @@ extern int f_dupfd(unsigned int from, struct file *file, unsigned flags);
> extern int replace_fd(unsigned fd, struct file *file, unsigned flags);
> extern void set_close_on_exec(unsigned int fd, int flag);
> extern bool get_close_on_exec(unsigned int fd);
> +extern int alloc_fd(unsigned start, unsigned flags);
> extern int __get_unused_fd_flags(unsigned flags, unsigned long nofile);
> extern int get_unused_fd_flags(unsigned flags);
> extern void put_unused_fd(unsigned int fd);
> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index 4d530b1d5683..6eba236aacd1 100644
> --- a/kernel/bpf/syscall.c
> +++ b/kernel/bpf/syscall.c
> @@ -688,6 +688,32 @@ const struct file_operations bpf_map_fops = {
> .poll = bpf_map_poll,
> };
>
> +/* Code is similar to anon_inode_getfd(), except starts at FD 1 */
> +int bpf_anon_inode_getfd(const char *name, const struct file_operations *fops,
> + void *priv, int flags)
> +{
I think it's a little sad that we have to essentially re-implement
anon_inode_getfd(). I guess an alternative could be to add an extra
parameter to the existing function, either with a different name and a
wrapper function, or just change all the callers (by my count there are
only 13 call sites outside of BPF). Not sure if that is better, though?
> + int error, fd;
> + struct file *file;
> +
> + error = alloc_fd(1, flags);
> + if (error < 0)
> + return error;
> + fd = error;
> +
> + file = anon_inode_getfile(name, fops, priv, flags);
> + if (IS_ERR(file)) {
> + error = PTR_ERR(file);
> + goto err_put_unused_fd;
> + }
> + fd_install(fd, file);
> +
> + return fd;
> +
> +err_put_unused_fd:
> + put_unused_fd(fd);
> + return error;
> +}
> +
> int bpf_map_new_fd(struct bpf_map *map, int flags)
> {
> int ret;
> @@ -696,8 +722,8 @@ int bpf_map_new_fd(struct bpf_map *map, int flags)
> if (ret < 0)
> return ret;
>
> - return anon_inode_getfd("bpf-map", &bpf_map_fops, map,
> - flags | O_CLOEXEC);
> + return bpf_anon_inode_getfd("bpf-map", &bpf_map_fops, map,
> + flags | O_CLOEXEC);
> }
>
> int bpf_get_file_flag(int flags)
> @@ -1840,8 +1866,8 @@ int bpf_prog_new_fd(struct bpf_prog *prog)
> if (ret < 0)
> return ret;
>
> - return anon_inode_getfd("bpf-prog", &bpf_prog_fops, prog,
> - O_RDWR | O_CLOEXEC);
> + return bpf_anon_inode_getfd("bpf-prog", &bpf_prog_fops, prog,
> + O_RDWR | O_CLOEXEC);
> }
>
> static struct bpf_prog *____bpf_prog_get(struct fd f)
> @@ -2471,7 +2497,7 @@ int bpf_link_settle(struct bpf_link_primer *primer)
>
> int bpf_link_new_fd(struct bpf_link *link)
> {
> - return anon_inode_getfd("bpf-link", &bpf_link_fops, link, O_CLOEXEC);
> + return bpf_anon_inode_getfd("bpf-link", &bpf_link_fops, link, O_CLOEXEC);
> }
>
> struct bpf_link *bpf_link_get_from_fd(u32 ufd)
> @@ -4024,7 +4050,7 @@ static int bpf_enable_runtime_stats(void)
> return -EBUSY;
> }
>
> - fd = anon_inode_getfd("bpf-stats", &bpf_stats_fops, NULL, O_CLOEXEC);
> + fd = bpf_anon_inode_getfd("bpf-stats", &bpf_stats_fops, NULL, O_CLOEXEC);
> if (fd >= 0)
> static_key_slow_inc(&bpf_stats_enabled_key.key);
>
I guess you should also fix __btf_new_fd() in btf.c?
next prev parent reply other threads:[~2020-06-08 18:28 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-08 16:51 [PATCH bpf 0/3] bpf: avoid using/returning file descriptor value zero Jesper Dangaard Brouer
2020-06-08 16:51 ` [PATCH bpf 1/3] bpf: syscall to start at file-descriptor 1 Jesper Dangaard Brouer
2020-06-08 18:28 ` Toke Høiland-Jørgensen [this message]
2020-06-08 18:36 ` Andrii Nakryiko
2020-06-08 19:44 ` Jesper Dangaard Brouer
2020-06-08 20:05 ` Andrii Nakryiko
2020-06-08 19:00 ` kernel test robot
2020-06-08 19:00 ` kernel test robot
2020-06-08 19:55 ` kernel test robot
2020-06-08 19:55 ` kernel test robot
2020-06-08 19:55 ` [RFC PATCH] bpf: bpf_anon_inode_getfd() can be static kernel test robot
2020-06-08 19:55 ` kernel test robot
2020-06-08 20:39 ` [PATCH bpf 1/3] bpf: syscall to start at file-descriptor 1 kernel test robot
2020-06-08 20:39 ` kernel test robot
2020-06-08 20:42 ` kernel test robot
2020-06-08 20:42 ` kernel test robot
2020-06-08 16:51 ` [PATCH bpf 2/3] bpf: devmap adjust uapi for attach bpf program Jesper Dangaard Brouer
2020-06-08 18:30 ` Toke Høiland-Jørgensen
2020-06-08 16:51 ` [PATCH bpf 3/3] bpf: selftests and tools use struct bpf_devmap_val from uapi Jesper Dangaard Brouer
2020-06-09 1:34 ` [PATCH bpf 0/3] bpf: avoid using/returning file descriptor value zero Alexei Starovoitov
2020-06-09 9:55 ` Jesper Dangaard Brouer
2020-06-09 13:31 ` [PATCH bpf V2 0/2] bpf: adjust uapi for devmap prior to kernel release Jesper Dangaard Brouer
2020-06-09 13:31 ` [PATCH bpf V2 1/2] bpf: devmap adjust uapi for attach bpf program Jesper Dangaard Brouer
2020-06-09 13:47 ` David Ahern
2020-06-09 15:12 ` Jesper Dangaard Brouer
2020-06-09 13:31 ` [PATCH bpf V2 2/2] bpf: selftests and tools use struct bpf_devmap_val from uapi Jesper Dangaard Brouer
2020-06-09 19:03 ` [PATCH bpf V2 0/2] bpf: adjust uapi for devmap prior to kernel release Alexei Starovoitov
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=875zc1cszw.fsf@toke.dk \
--to=toke@redhat.com \
--cc=alexei.starovoitov@gmail.com \
--cc=andrii.nakryiko@gmail.com \
--cc=borkmann@iogearbox.net \
--cc=bpf@vger.kernel.org \
--cc=brouer@redhat.com \
--cc=dsahern@gmail.com \
--cc=lorenzo@kernel.org \
--cc=netdev@vger.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.