diff --git a/glnx-fdio.c b/glnx-fdio.c index c8da35e8..09aa87f6 100644 --- a/glnx-fdio.c +++ b/glnx-fdio.c @@ -169,13 +169,12 @@ glnx_tmpfile_clear (GLnxTmpfile *tmpf) tmpf->initialized = FALSE; } -/* Allocate a temporary file, using Linux O_TMPFILE if available. +/* Allocate a temporary file, using Linux O_TMPFILE if available. The file mode + * will be 0600. + * * The result will be stored in @out_tmpf, which is caller allocated * so you can store it on the stack in common scenarios. * - * Note that with O_TMPFILE, the file mode will be `000`; you likely - * want to chmod it before calling glnx_link_tmpfile_at(). - * * The directory fd @dfd must live at least as long as the output @out_tmpf. */ gboolean @@ -185,6 +184,7 @@ glnx_open_tmpfile_linkable_at (int dfd, GLnxTmpfile *out_tmpf, GError **error) { + const guint mode = 0600; glnx_fd_close int fd = -1; int count; @@ -200,11 +200,16 @@ glnx_open_tmpfile_linkable_at (int dfd, * link_tmpfile() below to rename the result after writing the file * in full. */ #if defined(O_TMPFILE) && !defined(DISABLE_OTMPFILE) && !defined(ENABLE_WRPSEUDO_COMPAT) - fd = openat (dfd, subpath, O_TMPFILE|flags, 0600); + fd = openat (dfd, subpath, O_TMPFILE|flags, mode); if (fd == -1 && !(G_IN_SET(errno, ENOSYS, EISDIR, EOPNOTSUPP))) return glnx_throw_errno_prefix (error, "open(O_TMPFILE)"); if (fd != -1) { + /* Workaround for https://sourceware.org/bugzilla/show_bug.cgi?id=17523 + * See also https://github.com/ostreedev/ostree/issues/991 + */ + if (fchmod (fd, mode) < 0) + return glnx_throw_errno_prefix (error, "fchmod"); out_tmpf->initialized = TRUE; out_tmpf->src_dfd = dfd; /* Copied; caller must keep open */ out_tmpf->fd = glnx_steal_fd (&fd); @@ -221,7 +226,7 @@ glnx_open_tmpfile_linkable_at (int dfd, { glnx_gen_temp_name (tmp); - fd = openat (dfd, tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, 0600); + fd = openat (dfd, tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, mode); if (fd < 0) { if (errno == EEXIST) diff --git a/tests/test-libglnx-fdio.c b/tests/test-libglnx-fdio.c index 311e7f0f..cee7cb68 100644 --- a/tests/test-libglnx-fdio.c +++ b/tests/test-libglnx-fdio.c @@ -137,12 +137,36 @@ test_renameat2_exchange (void) g_assert_no_error (local_error); } +static void +test_tmpfile (void) +{ + g_autoptr(GError) local_error = NULL; + GError **error = &local_error; + g_auto(GLnxTmpfile) tmpf = { 0, }; + + if (!glnx_open_tmpfile_linkable_at (AT_FDCWD, ".", O_WRONLY|O_CLOEXEC, &tmpf, error)) + goto out; + + if (glnx_loop_write (tmpf.fd, "foo", strlen ("foo")) < 0) + { + (void)glnx_throw_errno_prefix (error, "write"); + goto out; + } + + if (glnx_link_tmpfile_at (&tmpf, GLNX_LINK_TMPFILE_NOREPLACE, AT_FDCWD, "foo", error)) + goto out; + + out: + g_assert_no_error (local_error); +} + int main (int argc, char **argv) { int ret; g_test_init (&argc, &argv, NULL); + g_test_add_func ("/tmpfile", test_tmpfile); g_test_add_func ("/renameat2-noreplace", test_renameat2_noreplace); g_test_add_func ("/renameat2-exchange", test_renameat2_exchange);