diff --git a/subprojects/libglnx/glnx-fdio.c b/subprojects/libglnx/glnx-fdio.c
index 98732051aef02e5e7a697149c7ea19926a602191..3d9f9a759415ba1c15eb9807cf036d52f55dbd6d 100644
--- a/subprojects/libglnx/glnx-fdio.c
+++ b/subprojects/libglnx/glnx-fdio.c
@@ -321,6 +321,8 @@ glnx_open_anonymous_tmpfile (int          flags,
                                            error);
 }
 
+static const char proc_self_fd_slash[] = "/proc/self/fd/";
+
 /* Use this after calling glnx_open_tmpfile_linkable_at() to give
  * the file its final name (link into place).
  */
@@ -367,8 +369,8 @@ glnx_link_tmpfile_at (GLnxTmpfile *tmpf,
   else
     {
       /* This case we have O_TMPFILE, so our reference to it is via /proc/self/fd */
-      char proc_fd_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(tmpf->fd) + 1];
-      snprintf (proc_fd_path, sizeof (proc_fd_path), "/proc/self/fd/%i", tmpf->fd);
+      char proc_fd_path[sizeof (proc_self_fd_slash) + DECIMAL_STR_MAX(tmpf->fd)];
+      snprintf (proc_fd_path, sizeof (proc_fd_path), "%s%i", proc_self_fd_slash, tmpf->fd);
 
       if (replace)
         {
@@ -455,8 +457,8 @@ glnx_tmpfile_reopen_rdonly (GLnxTmpfile *tmpf,
   else
     {
       /* This case we have O_TMPFILE, so our reference to it is via /proc/self/fd */
-      char proc_fd_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(tmpf->fd) + 1];
-      snprintf (proc_fd_path, sizeof (proc_fd_path), "/proc/self/fd/%i", tmpf->fd);
+      char proc_fd_path[sizeof (proc_self_fd_slash) + DECIMAL_STR_MAX(tmpf->fd)];
+      snprintf (proc_fd_path, sizeof (proc_fd_path), "%s%i", proc_self_fd_slash, tmpf->fd);
 
       if (!glnx_openat_rdonly (AT_FDCWD, proc_fd_path, TRUE, &rdonly_fd, error))
         return FALSE;
diff --git a/subprojects/libglnx/glnx-shutil.c b/subprojects/libglnx/glnx-shutil.c
index 5ebe7f8886e02a95886a0814378c1fa15d51dd16..5a6fd7cecc81ae419eb0d98705fde9d032434978 100644
--- a/subprojects/libglnx/glnx-shutil.c
+++ b/subprojects/libglnx/glnx-shutil.c
@@ -149,12 +149,10 @@ mkdir_p_at_internal (int              dfd,
  again:
   if (mkdirat (dfd, path, mode) == -1)
     {
-      if (errno == ENOENT)
+      if (errno == ENOENT && !did_recurse)
         {
           char *lastslash;
 
-          g_assert (!did_recurse);
-
           lastslash = strrchr (path, '/');
           if (lastslash == NULL)
             {
diff --git a/subprojects/libglnx/meson_options.txt b/subprojects/libglnx/meson_options.txt
index 1028017fb9ecfdfe36c9b109a5412ac55a5602d0..e90011144df53423d609aeff5a6ea860e27bb604 100644
--- a/subprojects/libglnx/meson_options.txt
+++ b/subprojects/libglnx/meson_options.txt
@@ -5,5 +5,5 @@ option(
   'tests',
   type : 'boolean',
   description : 'build and run unit tests',
-  value : 'true',
+  value : true,
 )
diff --git a/subprojects/libglnx/tests/test-libglnx-shutil.c b/subprojects/libglnx/tests/test-libglnx-shutil.c
index 28b34abe0f3bdd8ac19f3e469ed0598f8677889c..98e424aa0487ffaaa0a47b55c4efc44c316a7812 100644
--- a/subprojects/libglnx/tests/test-libglnx-shutil.c
+++ b/subprojects/libglnx/tests/test-libglnx-shutil.c
@@ -1,6 +1,7 @@
 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
  *
- * Copyright © 2017 Endless OS Foundation LLC
+ * Copyright © 2017-2019 Endless OS Foundation LLC
+ * Copyright © 2024 Collabora Ltd.
  * SPDX-License-Identifier: LGPL-2.0-or-later
  *
  * This library is free software; you can redistribute it and/or
@@ -29,9 +30,47 @@
 
 #include "libglnx-testlib.h"
 
+static void
+test_mkdir_p_parent_unsuitable (void)
+{
+  _GLNX_TEST_SCOPED_TEMP_DIR;
+  _GLNX_TEST_DECLARE_ERROR(local_error, error);
+  glnx_autofd int dfd = -1;
+
+  if (!glnx_ensure_dir (AT_FDCWD, "test", 0755, error))
+    return;
+  if (!glnx_opendirat (AT_FDCWD, "test", FALSE, &dfd, error))
+    return;
+
+  if (!glnx_file_replace_contents_at (dfd, "file",
+                                      (const guint8 *) "", 0,
+                                      GLNX_FILE_REPLACE_NODATASYNC,
+                                      NULL, error))
+    return;
+
+  if (symlinkat ("nosuchtarget", dfd, "link") < 0)
+    {
+      glnx_throw_errno_prefix (error, "symlinkat");
+      return;
+    }
+
+  glnx_shutil_mkdir_p_at (dfd, "file/baz", 0755, NULL, error);
+  g_test_message ("mkdir %s -> %s", "file/baz",
+                  local_error ? local_error->message : "success");
+  g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY);
+  g_clear_error (&local_error);
+
+  glnx_shutil_mkdir_p_at (dfd, "link/baz", 0755, NULL, error);
+  g_test_message ("mkdir %s -> %s", "link/baz",
+                  local_error ? local_error->message : "success");
+  g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
+  g_clear_error (&local_error);
+}
+
 static void
 test_mkdir_p_enoent (void)
 {
+  _GLNX_TEST_SCOPED_TEMP_DIR;
   _GLNX_TEST_DECLARE_ERROR(local_error, error);
   glnx_autofd int dfd = -1;
 
@@ -57,6 +96,7 @@ main (int    argc,
   g_test_init (&argc, &argv, NULL);
 
   g_test_add_func ("/mkdir-p/enoent", test_mkdir_p_enoent);
+  g_test_add_func ("/mkdir-p/parent-unsuitable", test_mkdir_p_parent_unsuitable);
 
   ret = g_test_run();