tempname.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. /* Copyright (C) 1991-2021 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with the GNU C Library; if not, see
  13. <https://www.gnu.org/licenses/>. */
  14. #if !_LIBC
  15. # include <libc-config.h>
  16. # include "tempname.h"
  17. #endif
  18. #include <sys/types.h>
  19. #include <assert.h>
  20. #include <stdbool.h>
  21. #include <errno.h>
  22. #include <stdio.h>
  23. #ifndef P_tmpdir
  24. # define P_tmpdir "/tmp"
  25. #endif
  26. #ifndef TMP_MAX
  27. # define TMP_MAX 238328
  28. #endif
  29. #ifndef __GT_FILE
  30. # define __GT_FILE 0
  31. # define __GT_DIR 1
  32. # define __GT_NOCREATE 2
  33. #endif
  34. #if !_LIBC && (GT_FILE != __GT_FILE || GT_DIR != __GT_DIR \
  35. || GT_NOCREATE != __GT_NOCREATE)
  36. # error report this to bug-gnulib@gnu.org
  37. #endif
  38. #include <stddef.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <fcntl.h>
  42. #include <stdalign.h>
  43. #include <stdint.h>
  44. #include <sys/random.h>
  45. #include <sys/stat.h>
  46. #include <time.h>
  47. #if _LIBC
  48. # define struct_stat64 struct stat64
  49. # define __secure_getenv __libc_secure_getenv
  50. #else
  51. # define struct_stat64 struct stat
  52. # define __gen_tempname gen_tempname
  53. # define __mkdir mkdir
  54. # define __open open
  55. # define __lstat64(file, buf) lstat (file, buf)
  56. # define __stat64(file, buf) stat (file, buf)
  57. # define __getrandom getrandom
  58. # define __clock_gettime64 clock_gettime
  59. # define __timespec64 timespec
  60. #endif
  61. /* Use getrandom if it works, falling back on a 64-bit linear
  62. congruential generator that starts with Var's value
  63. mixed in with a clock's low-order bits if available. */
  64. typedef uint_fast64_t random_value;
  65. #define RANDOM_VALUE_MAX UINT_FAST64_MAX
  66. #define BASE_62_DIGITS 10 /* 62**10 < UINT_FAST64_MAX */
  67. #define BASE_62_POWER (62LL * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62)
  68. static random_value
  69. random_bits (random_value var, bool use_getrandom)
  70. {
  71. random_value r;
  72. /* Without GRND_NONBLOCK it can be blocked for minutes on some systems. */
  73. if (use_getrandom && __getrandom (&r, sizeof r, GRND_NONBLOCK) == sizeof r)
  74. return r;
  75. #if _LIBC || (defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME)
  76. /* Add entropy if getrandom did not work. */
  77. struct __timespec64 tv;
  78. __clock_gettime64 (CLOCK_MONOTONIC, &tv);
  79. var ^= tv.tv_nsec;
  80. #endif
  81. return 2862933555777941757 * var + 3037000493;
  82. }
  83. #if _LIBC
  84. /* Return nonzero if DIR is an existent directory. */
  85. static int
  86. direxists (const char *dir)
  87. {
  88. struct_stat64 buf;
  89. return __stat64 (dir, &buf) == 0 && S_ISDIR (buf.st_mode);
  90. }
  91. /* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is
  92. non-null and exists, uses it; otherwise uses the first of $TMPDIR,
  93. P_tmpdir, /tmp that exists. Copies into TMPL a template suitable
  94. for use with mk[s]temp. Will fail (-1) if DIR is non-null and
  95. doesn't exist, none of the searched dirs exists, or there's not
  96. enough space in TMPL. */
  97. int
  98. __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
  99. int try_tmpdir)
  100. {
  101. const char *d;
  102. size_t dlen, plen;
  103. if (!pfx || !pfx[0])
  104. {
  105. pfx = "file";
  106. plen = 4;
  107. }
  108. else
  109. {
  110. plen = strlen (pfx);
  111. if (plen > 5)
  112. plen = 5;
  113. }
  114. if (try_tmpdir)
  115. {
  116. d = __secure_getenv ("TMPDIR");
  117. if (d != NULL && direxists (d))
  118. dir = d;
  119. else if (dir != NULL && direxists (dir))
  120. /* nothing */ ;
  121. else
  122. dir = NULL;
  123. }
  124. if (dir == NULL)
  125. {
  126. if (direxists (P_tmpdir))
  127. dir = P_tmpdir;
  128. else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp"))
  129. dir = "/tmp";
  130. else
  131. {
  132. __set_errno (ENOENT);
  133. return -1;
  134. }
  135. }
  136. dlen = strlen (dir);
  137. while (dlen > 1 && dir[dlen - 1] == '/')
  138. dlen--; /* remove trailing slashes */
  139. /* check we have room for "${dir}/${pfx}XXXXXX\0" */
  140. if (tmpl_len < dlen + 1 + plen + 6 + 1)
  141. {
  142. __set_errno (EINVAL);
  143. return -1;
  144. }
  145. sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx);
  146. return 0;
  147. }
  148. #endif /* _LIBC */
  149. #if _LIBC
  150. static int try_tempname_len (char *, int, void *, int (*) (char *, void *),
  151. size_t);
  152. #endif
  153. static int
  154. try_file (char *tmpl, void *flags)
  155. {
  156. int *openflags = flags;
  157. return __open (tmpl,
  158. (*openflags & ~O_ACCMODE)
  159. | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
  160. }
  161. static int
  162. try_dir (char *tmpl, void *flags _GL_UNUSED)
  163. {
  164. return __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
  165. }
  166. static int
  167. try_nocreate (char *tmpl, void *flags _GL_UNUSED)
  168. {
  169. struct_stat64 st;
  170. if (__lstat64 (tmpl, &st) == 0 || errno == EOVERFLOW)
  171. __set_errno (EEXIST);
  172. return errno == ENOENT ? 0 : -1;
  173. }
  174. /* These are the characters used in temporary file names. */
  175. static const char letters[] =
  176. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  177. /* Generate a temporary file name based on TMPL. TMPL must match the
  178. rules for mk[s]temp (i.e., end in at least X_SUFFIX_LEN "X"s,
  179. possibly with a suffix).
  180. The name constructed does not exist at the time of the call to
  181. this function. TMPL is overwritten with the result.
  182. KIND may be one of:
  183. __GT_NOCREATE: simply verify that the name does not exist
  184. at the time of the call.
  185. __GT_FILE: create the file using open(O_CREAT|O_EXCL)
  186. and return a read-write fd. The file is mode 0600.
  187. __GT_DIR: create a directory, which will be mode 0700.
  188. We use a clever algorithm to get hard-to-predict names. */
  189. #ifdef _LIBC
  190. static
  191. #endif
  192. int
  193. gen_tempname_len (char *tmpl, int suffixlen, int flags, int kind,
  194. size_t x_suffix_len)
  195. {
  196. static int (*const tryfunc[]) (char *, void *) =
  197. {
  198. [__GT_FILE] = try_file,
  199. [__GT_DIR] = try_dir,
  200. [__GT_NOCREATE] = try_nocreate
  201. };
  202. return try_tempname_len (tmpl, suffixlen, &flags, tryfunc[kind],
  203. x_suffix_len);
  204. }
  205. #ifdef _LIBC
  206. static
  207. #endif
  208. int
  209. try_tempname_len (char *tmpl, int suffixlen, void *args,
  210. int (*tryfunc) (char *, void *), size_t x_suffix_len)
  211. {
  212. size_t len;
  213. char *XXXXXX;
  214. unsigned int count;
  215. int fd = -1;
  216. int save_errno = errno;
  217. /* A lower bound on the number of temporary files to attempt to
  218. generate. The maximum total number of temporary file names that
  219. can exist for a given template is 62**6. It should never be
  220. necessary to try all of these combinations. Instead if a reasonable
  221. number of names is tried (we define reasonable as 62**3) fail to
  222. give the system administrator the chance to remove the problems.
  223. This value requires that X_SUFFIX_LEN be at least 3. */
  224. #define ATTEMPTS_MIN (62 * 62 * 62)
  225. /* The number of times to attempt to generate a temporary file. To
  226. conform to POSIX, this must be no smaller than TMP_MAX. */
  227. #if ATTEMPTS_MIN < TMP_MAX
  228. unsigned int attempts = TMP_MAX;
  229. #else
  230. unsigned int attempts = ATTEMPTS_MIN;
  231. #endif
  232. /* A random variable. The initial value is used only the for fallback path
  233. on 'random_bits' on 'getrandom' failure. Its initial value tries to use
  234. some entropy from the ASLR and ignore possible bits from the stack
  235. alignment. */
  236. random_value v = ((uintptr_t) &v) / alignof (max_align_t);
  237. /* How many random base-62 digits can currently be extracted from V. */
  238. int vdigits = 0;
  239. /* Whether to consume entropy when acquiring random bits. On the
  240. first try it's worth the entropy cost with __GT_NOCREATE, which
  241. is inherently insecure and can use the entropy to make it a bit
  242. less secure. On the (rare) second and later attempts it might
  243. help against DoS attacks. */
  244. bool use_getrandom = tryfunc == try_nocreate;
  245. /* Least unfair value for V. If V is less than this, V can generate
  246. BASE_62_DIGITS digits fairly. Otherwise it might be biased. */
  247. random_value const unfair_min
  248. = RANDOM_VALUE_MAX - RANDOM_VALUE_MAX % BASE_62_POWER;
  249. len = strlen (tmpl);
  250. if (len < x_suffix_len + suffixlen
  251. || strspn (&tmpl[len - x_suffix_len - suffixlen], "X") < x_suffix_len)
  252. {
  253. __set_errno (EINVAL);
  254. return -1;
  255. }
  256. /* This is where the Xs start. */
  257. XXXXXX = &tmpl[len - x_suffix_len - suffixlen];
  258. for (count = 0; count < attempts; ++count)
  259. {
  260. for (size_t i = 0; i < x_suffix_len; i++)
  261. {
  262. if (vdigits == 0)
  263. {
  264. do
  265. {
  266. v = random_bits (v, use_getrandom);
  267. use_getrandom = true;
  268. }
  269. while (unfair_min <= v);
  270. vdigits = BASE_62_DIGITS;
  271. }
  272. XXXXXX[i] = letters[v % 62];
  273. v /= 62;
  274. vdigits--;
  275. }
  276. fd = tryfunc (tmpl, args);
  277. if (fd >= 0)
  278. {
  279. __set_errno (save_errno);
  280. return fd;
  281. }
  282. else if (errno != EEXIST)
  283. return -1;
  284. }
  285. /* We got out of the loop because we ran out of combinations to try. */
  286. __set_errno (EEXIST);
  287. return -1;
  288. }
  289. int
  290. __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
  291. {
  292. return gen_tempname_len (tmpl, suffixlen, flags, kind, 6);
  293. }
  294. #if !_LIBC
  295. int
  296. try_tempname (char *tmpl, int suffixlen, void *args,
  297. int (*tryfunc) (char *, void *))
  298. {
  299. return try_tempname_len (tmpl, suffixlen, args, tryfunc, 6);
  300. }
  301. #endif