[PATCH bpf-next] libbpf: fix errno is overwritten after being closed.

Xin Liu posted 1 patch 3 years, 3 months ago
tools/lib/bpf/libbpf_internal.h | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
[PATCH bpf-next] libbpf: fix errno is overwritten after being closed.
Posted by Xin Liu 3 years, 3 months ago
In the ensure_good_fd function, if the fcntl function succeeds but
the close function fails, ensure_good_fd returns a normal fd and
sets errno, which may cause users to misunderstand. The close
failure is not a serious problem, and the correct FD has been
handed over to the upper-layer application. Let's restore errno here.

Signed-off-by: Xin Liu <liuxin350@huawei.com>
---
 tools/lib/bpf/libbpf_internal.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
index 377642ff51fc..98333a6c38e9 100644
--- a/tools/lib/bpf/libbpf_internal.h
+++ b/tools/lib/bpf/libbpf_internal.h
@@ -543,10 +543,9 @@ static inline int ensure_good_fd(int fd)
 		fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
 		saved_errno = errno;
 		close(old_fd);
-		if (fd < 0) {
+		errno = saved_errno;
+		if (fd < 0)
 			pr_warn("failed to dup FD %d to FD > 2: %d\n", old_fd, -saved_errno);
-			errno = saved_errno;
-		}
 	}
 	return fd;
 }
-- 
2.33.0
Re: [PATCH bpf-next] libbpf: fix errno is overwritten after being closed.
Posted by Andrii Nakryiko 3 years, 3 months ago
On Fri, Dec 23, 2022 at 5:36 AM Xin Liu <liuxin350@huawei.com> wrote:
>
> In the ensure_good_fd function, if the fcntl function succeeds but
> the close function fails, ensure_good_fd returns a normal fd and
> sets errno, which may cause users to misunderstand. The close
> failure is not a serious problem, and the correct FD has been
> handed over to the upper-layer application. Let's restore errno here.
>
> Signed-off-by: Xin Liu <liuxin350@huawei.com>
> ---
>  tools/lib/bpf/libbpf_internal.h | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
> index 377642ff51fc..98333a6c38e9 100644
> --- a/tools/lib/bpf/libbpf_internal.h
> +++ b/tools/lib/bpf/libbpf_internal.h
> @@ -543,10 +543,9 @@ static inline int ensure_good_fd(int fd)
>                 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
>                 saved_errno = errno;
>                 close(old_fd);
> -               if (fd < 0) {
> +               errno = saved_errno;
> +               if (fd < 0)
>                         pr_warn("failed to dup FD %d to FD > 2: %d\n", old_fd, -saved_errno);
> -                       errno = saved_errno;

pr_warn calls into user-provided callback, which can clobber errno, so
`errno = saved_errno` should happen after pr_warn. With your change
there is even higher chance of errno clobbering.

Please send a follow up fix to unconditionally restore errno *after*
pr_warn, thanks.

> -               }
>         }
>         return fd;
>  }
> --
> 2.33.0
>
Re: [PATCH bpf-next] libbpf: fix errno is overwritten after being closed.
Posted by Alexei Starovoitov 3 years, 3 months ago
On Thu, Dec 29, 2022 at 1:44 PM Andrii Nakryiko
<andrii.nakryiko@gmail.com> wrote:
>
> On Fri, Dec 23, 2022 at 5:36 AM Xin Liu <liuxin350@huawei.com> wrote:
> >
> > In the ensure_good_fd function, if the fcntl function succeeds but
> > the close function fails, ensure_good_fd returns a normal fd and
> > sets errno, which may cause users to misunderstand. The close
> > failure is not a serious problem, and the correct FD has been
> > handed over to the upper-layer application. Let's restore errno here.
> >
> > Signed-off-by: Xin Liu <liuxin350@huawei.com>
> > ---
> >  tools/lib/bpf/libbpf_internal.h | 5 ++---
> >  1 file changed, 2 insertions(+), 3 deletions(-)
> >
> > diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
> > index 377642ff51fc..98333a6c38e9 100644
> > --- a/tools/lib/bpf/libbpf_internal.h
> > +++ b/tools/lib/bpf/libbpf_internal.h
> > @@ -543,10 +543,9 @@ static inline int ensure_good_fd(int fd)
> >                 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
> >                 saved_errno = errno;
> >                 close(old_fd);
> > -               if (fd < 0) {
> > +               errno = saved_errno;
> > +               if (fd < 0)
> >                         pr_warn("failed to dup FD %d to FD > 2: %d\n", old_fd, -saved_errno);
> > -                       errno = saved_errno;
>
> pr_warn calls into user-provided callback, which can clobber errno, so
> `errno = saved_errno` should happen after pr_warn. With your change
> there is even higher chance of errno clobbering.
>
> Please send a follow up fix to unconditionally restore errno *after*
> pr_warn, thanks.

Good point. I can follow up with one line fix too.
Re: [PATCH bpf-next] libbpf: fix errno is overwritten after being closed.
Posted by Andrii Nakryiko 3 years, 3 months ago
On Thu, Dec 29, 2022 at 1:49 PM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Thu, Dec 29, 2022 at 1:44 PM Andrii Nakryiko
> <andrii.nakryiko@gmail.com> wrote:
> >
> > On Fri, Dec 23, 2022 at 5:36 AM Xin Liu <liuxin350@huawei.com> wrote:
> > >
> > > In the ensure_good_fd function, if the fcntl function succeeds but
> > > the close function fails, ensure_good_fd returns a normal fd and
> > > sets errno, which may cause users to misunderstand. The close
> > > failure is not a serious problem, and the correct FD has been
> > > handed over to the upper-layer application. Let's restore errno here.
> > >
> > > Signed-off-by: Xin Liu <liuxin350@huawei.com>
> > > ---
> > >  tools/lib/bpf/libbpf_internal.h | 5 ++---
> > >  1 file changed, 2 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
> > > index 377642ff51fc..98333a6c38e9 100644
> > > --- a/tools/lib/bpf/libbpf_internal.h
> > > +++ b/tools/lib/bpf/libbpf_internal.h
> > > @@ -543,10 +543,9 @@ static inline int ensure_good_fd(int fd)
> > >                 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
> > >                 saved_errno = errno;
> > >                 close(old_fd);
> > > -               if (fd < 0) {
> > > +               errno = saved_errno;
> > > +               if (fd < 0)
> > >                         pr_warn("failed to dup FD %d to FD > 2: %d\n", old_fd, -saved_errno);
> > > -                       errno = saved_errno;
> >
> > pr_warn calls into user-provided callback, which can clobber errno, so
> > `errno = saved_errno` should happen after pr_warn. With your change
> > there is even higher chance of errno clobbering.
> >
> > Please send a follow up fix to unconditionally restore errno *after*
> > pr_warn, thanks.
>
> Good point. I can follow up with one line fix too.

that would be simplest, probably, thanks!
Re: [PATCH bpf-next] libbpf: fix errno is overwritten after being closed.
Posted by Alexei Starovoitov 3 years, 3 months ago
On Thu, Dec 29, 2022 at 3:21 PM Andrii Nakryiko
<andrii.nakryiko@gmail.com> wrote:
>
> On Thu, Dec 29, 2022 at 1:49 PM Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
> >
> > On Thu, Dec 29, 2022 at 1:44 PM Andrii Nakryiko
> > <andrii.nakryiko@gmail.com> wrote:
> > >
> > > On Fri, Dec 23, 2022 at 5:36 AM Xin Liu <liuxin350@huawei.com> wrote:
> > > >
> > > > In the ensure_good_fd function, if the fcntl function succeeds but
> > > > the close function fails, ensure_good_fd returns a normal fd and
> > > > sets errno, which may cause users to misunderstand. The close
> > > > failure is not a serious problem, and the correct FD has been
> > > > handed over to the upper-layer application. Let's restore errno here.
> > > >
> > > > Signed-off-by: Xin Liu <liuxin350@huawei.com>
> > > > ---
> > > >  tools/lib/bpf/libbpf_internal.h | 5 ++---
> > > >  1 file changed, 2 insertions(+), 3 deletions(-)
> > > >
> > > > diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
> > > > index 377642ff51fc..98333a6c38e9 100644
> > > > --- a/tools/lib/bpf/libbpf_internal.h
> > > > +++ b/tools/lib/bpf/libbpf_internal.h
> > > > @@ -543,10 +543,9 @@ static inline int ensure_good_fd(int fd)
> > > >                 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
> > > >                 saved_errno = errno;
> > > >                 close(old_fd);
> > > > -               if (fd < 0) {
> > > > +               errno = saved_errno;
> > > > +               if (fd < 0)
> > > >                         pr_warn("failed to dup FD %d to FD > 2: %d\n", old_fd, -saved_errno);
> > > > -                       errno = saved_errno;
> > >
> > > pr_warn calls into user-provided callback, which can clobber errno, so
> > > `errno = saved_errno` should happen after pr_warn. With your change
> > > there is even higher chance of errno clobbering.
> > >
> > > Please send a follow up fix to unconditionally restore errno *after*
> > > pr_warn, thanks.
> >
> > Good point. I can follow up with one line fix too.
>
> that would be simplest, probably, thanks!

Pushed trivial fix to bpf-next.
Re: [PATCH bpf-next] libbpf: fix errno is overwritten after being closed.
Posted by patchwork-bot+netdevbpf@kernel.org 3 years, 3 months ago
Hello:

This patch was applied to bpf/bpf-next.git (master)
by Alexei Starovoitov <ast@kernel.org>:

On Fri, 23 Dec 2022 21:36:18 +0800 you wrote:
> In the ensure_good_fd function, if the fcntl function succeeds but
> the close function fails, ensure_good_fd returns a normal fd and
> sets errno, which may cause users to misunderstand. The close
> failure is not a serious problem, and the correct FD has been
> handed over to the upper-layer application. Let's restore errno here.
> 
> Signed-off-by: Xin Liu <liuxin350@huawei.com>
> 
> [...]

Here is the summary with links:
  - [bpf-next] libbpf: fix errno is overwritten after being closed.
    https://git.kernel.org/bpf/bpf-next/c/07453245620c

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html