diff --git a/steam-runtime-tools/resolve-in-sysroot-internal.h b/steam-runtime-tools/resolve-in-sysroot-internal.h
index 5eb4fcef64a3204e3d614964d0058d4c64e8af22..7d47024e76d347b474ebdea332486d4dbc93a10f 100644
--- a/steam-runtime-tools/resolve-in-sysroot-internal.h
+++ b/steam-runtime-tools/resolve-in-sysroot-internal.h
@@ -32,6 +32,8 @@
  *  the path is a symlink, fail with %G_IO_ERROR_TOO_MANY_LINKS.
  * @SRT_RESOLVE_FLAGS_READABLE: Open the last component of the path
  *  for reading, instead of just as `O_PATH`.
+ * @SRT_RESOLVE_FLAGS_DIRECTORY: Open the last component of the path
+ *  for reading, and it must be a directory.
  * @SRT_RESOLVE_FLAGS_NONE: No special behaviour.
  *
  * Flags affecting how _srt_resolve_in_sysroot() behaves.
@@ -42,6 +44,7 @@ typedef enum
   SRT_RESOLVE_FLAGS_KEEP_FINAL_SYMLINK = (1 << 1),
   SRT_RESOLVE_FLAGS_REJECT_SYMLINKS = (1 << 2),
   SRT_RESOLVE_FLAGS_READABLE = (1 << 3),
+  SRT_RESOLVE_FLAGS_DIRECTORY = (1 << 4),
   SRT_RESOLVE_FLAGS_NONE = 0
 } SrtResolveFlags;
 
diff --git a/steam-runtime-tools/resolve-in-sysroot.c b/steam-runtime-tools/resolve-in-sysroot.c
index 28eaffbfcddd34c428d4aea1e313775edcc39a91..21965157ee34bc16262527ab77dfc6487fe2496e 100644
--- a/steam-runtime-tools/resolve-in-sysroot.c
+++ b/steam-runtime-tools/resolve-in-sysroot.c
@@ -303,15 +303,23 @@ _srt_resolve_in_sysroot (int sysroot,
         }
     }
 
-  if (flags & SRT_RESOLVE_FLAGS_READABLE)
+  if (flags & (SRT_RESOLVE_FLAGS_READABLE|SRT_RESOLVE_FLAGS_DIRECTORY))
     {
       g_autofree char *proc_fd_name = g_strdup_printf ("/proc/self/fd/%d",
                                                        g_array_index (fds, int,
                                                                       fds->len - 1));
       glnx_autofd int fd = -1;
 
-      if (!glnx_openat_rdonly (-1, proc_fd_name, TRUE, &fd, error))
-        return -1;
+      if (flags & SRT_RESOLVE_FLAGS_DIRECTORY)
+        {
+          if (!glnx_opendirat (-1, proc_fd_name, TRUE, &fd, error))
+            return -1;
+        }
+      else
+        {
+          if (!glnx_openat_rdonly (-1, proc_fd_name, TRUE, &fd, error))
+            return -1;
+        }
 
       if (real_path_out != NULL)
         *real_path_out = g_string_free (g_steal_pointer (&current_path), FALSE);
diff --git a/tests/pressure-vessel/resolve-in-sysroot.c b/tests/pressure-vessel/resolve-in-sysroot.c
index b7e1d850676b2b0fafee76ea1a76ea1873eacc44..bade3586d342b48abf63d1188f8a3992e5ada64d 100644
--- a/tests/pressure-vessel/resolve-in-sysroot.c
+++ b/tests/pressure-vessel/resolve-in-sysroot.c
@@ -110,6 +110,10 @@ test_resolve_in_sysroot (Fixture *f,
     "a/b/c/d/e",
     "a/b2/c2/d2/e2",
   };
+  static const char * const prepare_files[] =
+  {
+    "a/b/c/file",
+  };
   static const Symlink prepare_symlinks[] =
   {
     { "a/b/symlink_to_c", "c" },
@@ -137,6 +141,21 @@ test_resolve_in_sysroot (Fixture *f,
       { NULL, G_IO_ERROR_NOT_FOUND }
     },
     { { "a/b/c/d", SRT_RESOLVE_FLAGS_MKDIR_P }, { "a/b/c/d" } },
+    { { "a/b/c/d", SRT_RESOLVE_FLAGS_READABLE }, { "a/b/c/d" } },
+    { { "a/b/c/d", SRT_RESOLVE_FLAGS_DIRECTORY }, { "a/b/c/d" } },
+    {
+      { "a/b/c/d", SRT_RESOLVE_FLAGS_READABLE|SRT_RESOLVE_FLAGS_DIRECTORY },
+      { "a/b/c/d" }
+    },
+    { { "a/b/c/file", SRT_RESOLVE_FLAGS_READABLE }, { "a/b/c/file" } },
+    {
+      { "a/b/c/file", SRT_RESOLVE_FLAGS_DIRECTORY },
+      { NULL, G_IO_ERROR_NOT_DIRECTORY }
+    },
+    {
+      { "a/b/c/file", SRT_RESOLVE_FLAGS_READABLE|SRT_RESOLVE_FLAGS_DIRECTORY },
+      { NULL, G_IO_ERROR_NOT_DIRECTORY }
+    },
     { { "a/b///////.////./././///././c/d" }, { "a/b/c/d" } },
     { { "/a/b///////.////././../b2////././c2/d2" }, { "a/b2/c2/d2" } },
     { { "a/b/c/d/e/f" }, { NULL, G_IO_ERROR_NOT_FOUND } },
@@ -193,6 +212,16 @@ test_resolve_in_sysroot (Fixture *f,
       g_assert_no_error (error);
     }
 
+  for (i = 0; i < G_N_ELEMENTS (prepare_files); i++)
+    {
+      const char *it = prepare_files[i];
+
+      glnx_file_replace_contents_at (tmpdir.fd, it,
+                                     (guint8 *) "hello", 5,
+                                     0, NULL, &error);
+      g_assert_no_error (error);
+    }
+
   for (i = 0; i < G_N_ELEMENTS (prepare_symlinks); i++)
     {
       const Symlink *it = &prepare_symlinks[i];
@@ -221,6 +250,12 @@ test_resolve_in_sysroot (Fixture *f,
       if (it->call.flags & SRT_RESOLVE_FLAGS_REJECT_SYMLINKS)
         g_string_append (description, " (not following any symlink)");
 
+      if (it->call.flags & SRT_RESOLVE_FLAGS_DIRECTORY)
+        g_string_append (description, " (must be a directory)");
+
+      if (it->call.flags & SRT_RESOLVE_FLAGS_READABLE)
+        g_string_append (description, " (open for reading)");
+
       g_test_message ("%" G_GSIZE_FORMAT ": Resolving %s%s",
                       i, it->call.path, description->str);