[libglnx] glnx-dirfd: Add variants of glnx_mkdtempat() which open the directory



commit 6746e6f54d6d29066011bace3b7820e9ca240ac6
Author: Philip Withnall <withnall endlessm com>
Date:   Thu Apr 20 18:01:56 2017 +0100

    glnx-dirfd: Add variants of glnx_mkdtempat() which open the directory
    
    At the moment, it’s not possible for them to do this race-free (since
    openat(O_DIRECTORY | O_CREAT | O_EXCL) doesn’t work), but in future this
    could be possible. In any case, it’s a useful thing to want to do.
    
    Signed-off-by: Philip Withnall <withnall endlessm com>

 glnx-dirfd.c |   67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 glnx-dirfd.h |   11 +++++++++
 2 files changed, 78 insertions(+), 0 deletions(-)
---
diff --git a/glnx-dirfd.c b/glnx-dirfd.c
index 08d9007..8c43720 100644
--- a/glnx-dirfd.c
+++ b/glnx-dirfd.c
@@ -348,3 +348,70 @@ glnx_mkdtempat (int dfd,
                "mkstempat ran out of combinations to try.");
   return FALSE;
 }
+
+/**
+ * glnx_mkdtempat_open:
+ * @dfd: Directory FD
+ * @tmpl: (type filename): template directory name, last 6 characters will be replaced
+ * @mode: permissions to create the temporary directory with
+ * @out_dfd: (out caller-allocates): Return location for an FD for the new
+ *   temporary directory, or `-1` on error
+ * @error: Return location for a #GError, or %NULL
+ *
+ * Similar to glnx_mkdtempat(), except it will open the resulting temporary
+ * directory and return a directory FD to it.
+ *
+ * Returns: %TRUE on success, %FALSE otherwise
+ * Since: UNRELEASED
+ */
+gboolean
+glnx_mkdtempat_open (int      dfd,
+                     gchar   *tmpl,
+                     int      mode,
+                     int     *out_dfd,
+                     GError **error)
+{
+  /* FIXME: Ideally we could use openat(O_DIRECTORY | O_CREAT | O_EXCL) here
+   * to create and open the directory atomically, but that’s not supported by
+   * current kernel versions: http://www.openwall.com/lists/oss-security/2014/11/26/14
+   * (Tested on kernel 4.10.10-200.fc25.x86_64). For the moment, accept a
+   * TOCTTOU race here. */
+  *out_dfd = -1;
+
+  if (!glnx_mkdtempat (dfd, tmpl, mode, error))
+    return FALSE;
+
+  return glnx_opendirat (dfd, tmpl, FALSE, out_dfd, error);
+}
+
+/**
+ * glnx_mkdtempat_open_in_system:
+ * @tmpl: (type filename): template directory name, last 6 characters will be replaced
+ * @mode: permissions to create the temporary directory with
+ * @out_dfd: (out caller-allocates): Return location for an FD for the new
+ *   temporary directory, or `-1` on error
+ * @error: Return location for a #GError, or %NULL
+ *
+ * Similar to glnx_mkdtempat_open(), except it will use the system temporary
+ * directory (from g_get_tmp_dir()) as the parent directory to @tmpl.
+ *
+ * Returns: %TRUE on success, %FALSE otherwise
+ * Since: UNRELEASED
+ */
+gboolean
+glnx_mkdtempat_open_in_system (gchar   *tmpl,
+                               int      mode,
+                               int     *out_dfd,
+                               GError **error)
+{
+  glnx_fd_close int tmp_dfd = -1;
+
+  *out_dfd = -1;
+
+  if (!glnx_opendirat (-1, g_get_tmp_dir (), TRUE, &tmp_dfd, error))
+    return FALSE;
+
+  return glnx_mkdtempat_open (tmp_dfd, tmpl, mode, out_dfd, error);
+}
+
+
diff --git a/glnx-dirfd.h b/glnx-dirfd.h
index 3a76695..0cb79e6 100644
--- a/glnx-dirfd.h
+++ b/glnx-dirfd.h
@@ -88,4 +88,15 @@ gboolean glnx_mkdtempat (int dfd,
                          int mode,
                          GError **error);
 
+gboolean glnx_mkdtempat_open (int      dfd,
+                              gchar   *tmpl,
+                              int      mode,
+                              int     *out_dfd,
+                              GError **error);
+
+gboolean glnx_mkdtempat_open_in_system (gchar   *tmpl,
+                                        int      mode,
+                                        int     *out_dfd,
+                                        GError **error);
+
 G_END_DECLS


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]