Re: [PATCH bpf-next v3 2/2] libbpf: Extend linker API to support in-memory ELF files

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Dec 11, 2024 at 8:40 AM Alastair Robertson <ajor@xxxxxxxx> wrote:
>
> The new_fd and add_fd functions correspond to the original new and
> add_file functions, but accept an FD instead of a file name. This
> gives API consumers the option of using anonymous files/memfds to
> avoid writing ELFs to disk.
>
> This new API will be useful for performing linking as part of
> bpftrace's JIT compilation.
>
> The add_buf function is a convenience wrapper that does the work of
> creating a memfd for the caller.
>
> Signed-off-by: Alastair Robertson <ajor@xxxxxxxx>
> ---
>  tools/lib/bpf/libbpf.h   |   5 ++
>  tools/lib/bpf/libbpf.map |   4 +
>  tools/lib/bpf/linker.c   | 163 ++++++++++++++++++++++++++++++++++-----
>  3 files changed, 152 insertions(+), 20 deletions(-)
>

There were a bunch of errno mishandling issues and a small memory
leak. I fixed all that up and landed in bpf-next.

> +int bpf_linker__add_file(struct bpf_linker *linker, const char *filename,
> +                        const struct bpf_linker_file_opts *opts)
> +{
> +       int fd, ret;
> +
> +       if (!OPTS_VALID(opts, bpf_linker_file_opts))
> +               return libbpf_err(-EINVAL);
> +
> +       if (!linker->elf)
> +               return libbpf_err(-EINVAL);
> +
> +       fd = open(filename, O_RDONLY | O_CLOEXEC);
> +       if (fd < 0) {
> +               pr_warn("failed to open file '%s': %s\n", filename, errstr(errno));
> +               return -errno;

same issue with errno clobbering, fixed, but please be careful with
errno, pretty much anything can clobber errno in libc, except free()
and maybe a few more APIs

> +       }
> +
> +       ret = bpf_linker_add_file(linker, fd, filename);
> +
> +       close(fd);
> +
> +       return ret;

this needed to be libbpf_err(ret), because close() can clobber errno,
added while applying

> +}
> +
> +int bpf_linker__add_fd(struct bpf_linker *linker, int fd,
> +                      const struct bpf_linker_file_opts *opts)
> +{
> +       char filename[32];
> +       int ret;
> +
> +       if (!OPTS_VALID(opts, bpf_linker_file_opts))
> +               return libbpf_err(-EINVAL);
> +
> +       if (!linker->elf)
> +               return libbpf_err(-EINVAL);
> +
> +       if (fd < 0)
> +               return libbpf_err(-EINVAL);
> +
> +       snprintf(filename, sizeof(filename), "fd:%d", fd);
> +
> +       ret = bpf_linker_add_file(linker, fd, filename);
> +
> +       return ret;

here as well

> +}
> +
> +int bpf_linker__add_buf(struct bpf_linker *linker, void *buf, size_t buf_sz,
> +                       const struct bpf_linker_file_opts *opts)
> +{
> +       char filename[32];
> +       int fd, written, ret;
> +
> +       if (!OPTS_VALID(opts, bpf_linker_file_opts))
> +               return libbpf_err(-EINVAL);
> +
> +       if (!linker->elf)
> +               return libbpf_err(-EINVAL);
> +
> +       snprintf(filename, sizeof(filename), "mem:%p+%zu", buf, buf_sz);
> +
> +       fd = memfd_create(filename, 0);
> +       if (fd < 0) {

and here

> +               pr_warn("failed to create memfd '%s': %s\n", filename, errstr(errno));
> +               return -errno;
> +       }
> +
> +       written = 0;
> +       while (written < buf_sz) {
> +               ret = write(fd, buf, buf_sz);
> +               if (ret < 0) {

and here

and also you were leaking memfd here, I added jump to close(fd)

> +                       pr_warn("failed to write '%s': %s\n", filename, errstr(errno));
> +                       return -errno;
> +               }
> +               written += ret;
> +       }
> +
> +       ret = bpf_linker_add_file(linker, fd, filename);
> +
> +       close(fd);
> +
> +       return ret;

and here


> +}
> +
>  static bool is_dwarf_sec_name(const char *name)
>  {
>         /* approximation, but the actual list is too long */
> @@ -2686,9 +2808,10 @@ int bpf_linker__finalize(struct bpf_linker *linker)
>         }
>
>         elf_end(linker->elf);
> -       close(linker->fd);
> -
>         linker->elf = NULL;
> +
> +       if (linker->fd_is_owned)
> +               close(linker->fd);
>         linker->fd = -1;
>
>         return 0;
> --
> 2.43.5
>





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux