[Bug libc/19866] mkstempat and mkdtempat

"adhemerval.zanella at linaro dot org via Glibc-bugs" <[email protected]> Thu, 18 Jun 2026 12:40:04 +0000
Newsgroups gmane.comp.lib.glibc.bugs
Message-ID <[email protected]/bugzilla/>
https://sourceware.org/bugzilla/show_bug.cgi?id=19866

Adhemerval Zanella <adhemerval.zanella at linaro dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |adhemerval.zanella at linaro dot o
                   |                            |rg

--- Comment #5 from Adhemerval Zanella <adhemerval.zanella at linaro dot org> ---
The mkstemp family indeed has a lot of potential pitfalls:

1. In-place mutation of the template, where makes string literals usage not
possible.
2. The randomness count is baked in the string and it can not be changed (users
can no ask for more).
3. O_CLOEXEC is not the default.
4. A lot of combinatorial variant: mkstemp -> mkostemp (flags) -> mkstemps
(suffix) -> mkostemps (both)
5. No mode parameter, the file is always created as 0600.
6. Suffix typing and positioning: the XXXXXX must sit at exactly
strlen(template) - suffixlen - 6 and mismatches are setups for EINVAL rather
than compile-time errors.
7. mkostemp accepts only O_APPEND/O_CLOEXEC/O_SYNC(-ish); anything else is
rejected, but the signature gives no hint.

I think a better alternative you a more broad interfaces without such issues:

Something like:

  /* Returns fd on success, -1 + errno on failure.
     Generates a leaf name <prefix><random*n_random><suffix> in dirfd. */
  int mkostempat (int dirfd,
                  const char *prefix,    /* no '/' allowed */
                  const char *suffix,    /* no '/' allowed; may be "" */
                  unsigned int n_random, /* entropy chars, 0 -> default 6 */
                  int oflags,            /* extra O_* OR'd into the create */
                  mode_t mode,           /* e.g. 0600 */
                  char *namebuf,         /* output, or NULL */
                  size_t namebuf_size);  /* bound; ERANGE/ENAMETOOLONG on
overflow */

* dirfd first, AT_FDCWD semantics (as other *at functions).
* namebuf/namebuf_size replaces the mutated template, killing the
string-literal footgun and the lifetime coupling. NULL namebuf means "I only
want the fd" (the common O_TMPFILE-adjacent case)
* prefix+suffix+n_random replaces the XXXXXX/suffixlen convention.
* O_CLOEXEC as the implicit default, with oflags for opt-out/extra flags.
* mode so 0600 is a default the caller can override atomically.

This does allow to be composable, so we can implement mkstemp family on top of
this. But it will require a bit more work.

I try to come up with an implementation for that so we can discuss on
libc-alpha.

-- 
You are receiving this mail because:
You are on the CC list for the bug.