Skip to content

Commit

Permalink
fdio: Ensure O_TMPFILE is mode 0600
Browse files Browse the repository at this point in the history
Work around an older glibc bug.
  • Loading branch information
cgwalters committed Jul 10, 2017
1 parent a37e672 commit 452c371
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
17 changes: 11 additions & 6 deletions glnx-fdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;

Expand All @@ -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);
Expand All @@ -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)
Expand Down
24 changes: 24 additions & 0 deletions tests/test-libglnx-fdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 452c371

Please sign in to comment.