From 8ef17919509e909746b0ad6465e9c6c952a3fe34 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 19 Jan 2025 14:59:13 +0100 Subject: [PATCH] hurd: Fix EINVAL error on linking to a slash-trailing path [BZ #32569] When the target path finishes with a slash, __file_name_split_at returns an empty file name. We can test for this to refuse doing the link. --- sysdeps/mach/hurd/bind.c | 8 ++++++-- sysdeps/mach/hurd/linkat.c | 6 +++++- sysdeps/mach/hurd/mknodat.c | 8 ++++++-- sysdeps/mach/hurd/symlinkat.c | 8 ++++++-- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/sysdeps/mach/hurd/bind.c b/sysdeps/mach/hurd/bind.c index f4cf5bd14e..bb408afcf6 100644 --- a/sysdeps/mach/hurd/bind.c +++ b/sysdeps/mach/hurd/bind.c @@ -47,8 +47,12 @@ __bind (int fd, __CONST_SOCKADDR_ARG addrarg, socklen_t len) if (dir == MACH_PORT_NULL) return -1; - /* Create a new, unlinked node in the target directory. */ - err = __dir_mkfile (dir, O_CREAT, 0666 & ~_hurd_umask, &node); + if (! *n) + /* Can't bind on the existing directory itself. */ + err = ENOTDIR; + else + /* Create a new, unlinked node in the target directory. */ + err = __dir_mkfile (dir, O_CREAT, 0666 & ~_hurd_umask, &node); if (! err) { diff --git a/sysdeps/mach/hurd/linkat.c b/sysdeps/mach/hurd/linkat.c index 75b4244f57..8f8e6c36fb 100644 --- a/sysdeps/mach/hurd/linkat.c +++ b/sysdeps/mach/hurd/linkat.c @@ -48,7 +48,11 @@ __linkat_common (int fromfd, const char *from, int tofd, const char *to, int at_ todir = __file_name_split_at (tofd, to, &toname); if (todir != MACH_PORT_NULL) { - err = __dir_link (todir, linknode, toname, 1); + if (! *toname) + /* Can't link to the existing directory itself. */ + err = ENOTDIR; + else + err = __dir_link (todir, linknode, toname, 1); __mach_port_deallocate (__mach_task_self (), todir); } __mach_port_deallocate (__mach_task_self (), linknode); diff --git a/sysdeps/mach/hurd/mknodat.c b/sysdeps/mach/hurd/mknodat.c index 13f2191766..c1fe3430d0 100644 --- a/sysdeps/mach/hurd/mknodat.c +++ b/sysdeps/mach/hurd/mknodat.c @@ -88,8 +88,12 @@ __mknodat (int fd, const char *path, mode_t mode, dev_t dev) if (dir == MACH_PORT_NULL) return -1; - /* Create a new, unlinked node in the target directory. */ - errnode = err = __dir_mkfile (dir, O_WRITE, (mode & ~S_IFMT) & ~_hurd_umask, &node); + if (! *name) + /* Can't link to the existing directory itself. */ + errnode = err = ENOTDIR; + else + /* Create a new, unlinked node in the target directory. */ + errnode = err = __dir_mkfile (dir, O_WRITE, (mode & ~S_IFMT) & ~_hurd_umask, &node); if (! err && translator != NULL) /* Set the node's translator to make it a device. */ diff --git a/sysdeps/mach/hurd/symlinkat.c b/sysdeps/mach/hurd/symlinkat.c index 8f72b2bea2..e7dfb673df 100644 --- a/sysdeps/mach/hurd/symlinkat.c +++ b/sysdeps/mach/hurd/symlinkat.c @@ -45,8 +45,12 @@ __symlinkat (const char *from, int fd, const char *to) if (dir == MACH_PORT_NULL) return -1; - /* Create a new, unlinked node in the target directory. */ - err = __dir_mkfile (dir, O_WRITE, 0777 & ~_hurd_umask, &node); + if (! *name) + /* Can't link to the existing directory itself. */ + err = ENOTDIR; + else + /* Create a new, unlinked node in the target directory. */ + err = __dir_mkfile (dir, O_WRITE, 0777 & ~_hurd_umask, &node); if (! err) {