diff mbox series

[pseudo] linkat: Fix AT_EMPTY_PATH handling

Message ID 20260717131943.3386262-1-richard.purdie@linuxfoundation.org
State New
Headers show
Series [pseudo] linkat: Fix AT_EMPTY_PATH handling | expand

Commit Message

Richard Purdie July 17, 2026, 1:19 p.m. UTC
Currently we don't cover the case where AT_EMPTY_PATH is set for atlink.
Update the code to handle this case in a similar way to the /proc/self
case which is similar.

This is used by some systemd tools which OE might run at rootfs time
such as hwdb generation.

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
 ports/unix/guts/linkat.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Comments

Paul Barker July 20, 2026, 10:37 a.m. UTC | #1
On Fri, 2026-07-17 at 14:19 +0100, Richard Purdie via
lists.yoctoproject.org wrote:
> Currently we don't cover the case where AT_EMPTY_PATH is set for atlink.

Typo: s/atlink/linkat/

> Update the code to handle this case in a similar way to the /proc/self
> case which is similar.
> 
> This is used by some systemd tools which OE might run at rootfs time
> such as hwdb generation.
> 
> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
> ---
>  ports/unix/guts/linkat.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/ports/unix/guts/linkat.c b/ports/unix/guts/linkat.c
> index 60fbf63..36ffc0f 100644
> --- a/ports/unix/guts/linkat.c
> +++ b/ports/unix/guts/linkat.c
> @@ -35,13 +35,18 @@
>  	}
>  #endif
>  	oldpath = oldname;
> -	if (pseudo_chroot_len && !strncmp(oldpath, pseudo_chroot, pseudo_chroot_len) &&
> +	if (oldpath && !*oldpath && pseudo_chroot_len && !strncmp(oldpath, pseudo_chroot, pseudo_chroot_len) &&

Should this be if (oldpath && *oldpath && ... ?

i.e. if oldpath is non-NULL and has non-zero length.

Best regards,
Richard Purdie July 20, 2026, 10:57 a.m. UTC | #2
On Mon, 2026-07-20 at 11:37 +0100, Paul Barker via lists.yoctoproject.org wrote:
> On Fri, 2026-07-17 at 14:19 +0100, Richard Purdie via
> lists.yoctoproject.org wrote:
> > Currently we don't cover the case where AT_EMPTY_PATH is set for atlink.
> 
> Typo: s/atlink/linkat/
> 
> > Update the code to handle this case in a similar way to the /proc/self
> > case which is similar.
> > 
> > This is used by some systemd tools which OE might run at rootfs time
> > such as hwdb generation.
> > 
> > Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
> > ---
> >  ports/unix/guts/linkat.c | 7 ++++++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> > 
> > diff --git a/ports/unix/guts/linkat.c b/ports/unix/guts/linkat.c
> > index 60fbf63..36ffc0f 100644
> > --- a/ports/unix/guts/linkat.c
> > +++ b/ports/unix/guts/linkat.c
> > @@ -35,13 +35,18 @@
> >  	}
> >  #endif
> >  	oldpath = oldname;
> > -	if (pseudo_chroot_len && !strncmp(oldpath, pseudo_chroot, pseudo_chroot_len) &&
> > +	if (oldpath && !*oldpath && pseudo_chroot_len && !strncmp(oldpath, pseudo_chroot, pseudo_chroot_len) &&
> 
> Should this be if (oldpath && *oldpath && ... ?
> 
> i.e. if oldpath is non-NULL and has non-zero length.

Well spotted, I've sent a v2, thanks.

Cheers,

Richard
diff mbox series

Patch

diff --git a/ports/unix/guts/linkat.c b/ports/unix/guts/linkat.c
index 60fbf63..36ffc0f 100644
--- a/ports/unix/guts/linkat.c
+++ b/ports/unix/guts/linkat.c
@@ -35,13 +35,18 @@ 
 	}
 #endif
 	oldpath = oldname;
-	if (pseudo_chroot_len && !strncmp(oldpath, pseudo_chroot, pseudo_chroot_len) &&
+	if (oldpath && !*oldpath && pseudo_chroot_len && !strncmp(oldpath, pseudo_chroot, pseudo_chroot_len) &&
 		oldpath[pseudo_chroot_len] == '/') {
 		oldpath += pseudo_chroot_len;
 	}
 
 	newpath = pseudo_root_path(__func__, __LINE__, newdirfd, newname, AT_SYMLINK_NOFOLLOW);
 
+	if ((!oldpath || !*oldpath) && (flags & AT_EMPTY_PATH)) {
+		tmpfile_fd = olddirfd;
+		// call actual link
+		rc = real_linkat(olddirfd, "", AT_FDCWD, newpath, flags);
+	} else
 	/* weird special case: if you link /proc/self/fd/N, you're supposed
 	 * to get a link to fd N. Used in conjunction with opening a directory
 	 * with O_TMPFILE in flags, which actually opens an already-deleted