summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libc/stdlib/Makefile.inc8
-rw-r--r--src/lib/libc/stdlib/__mktemp4.c83
-rw-r--r--src/lib/libc/stdlib/mkdtemp.c33
-rw-r--r--src/lib/libc/stdlib/mkstemp.c64
-rw-r--r--src/lib/libc/stdlib/mktemp.c137
5 files changed, 195 insertions, 130 deletions
diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc
index fa4836f42b..f5e9a9fe4e 100644
--- a/src/lib/libc/stdlib/Makefile.inc
+++ b/src/lib/libc/stdlib/Makefile.inc
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile.inc,v 1.65 2024/01/19 16:30:28 millert Exp $ 1# $OpenBSD: Makefile.inc,v 1.66 2024/01/19 19:45:02 millert Exp $
2 2
3# stdlib sources 3# stdlib sources
4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/stdlib ${LIBCSRCDIR}/stdlib 4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/stdlib ${LIBCSRCDIR}/stdlib
@@ -6,9 +6,9 @@
6SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \ 6SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \
7 exit.c ecvt.c gcvt.c getenv.c getopt_long.c \ 7 exit.c ecvt.c gcvt.c getenv.c getopt_long.c \
8 getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c insque.c \ 8 getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c insque.c \
9 l64a.c llabs.c lldiv.c lsearch.c malloc.c mktemp.c reallocarray.c \ 9 l64a.c llabs.c lldiv.c lsearch.c malloc.c __mktemp4.c mkdtemp.c \
10 merge.c posix_pty.c qsort.c radixsort.c rand.c random.c \ 10 mkstemp.c mktemp.c reallocarray.c merge.c posix_pty.c qsort.c \
11 realpath.c remque.c setenv.c strtoimax.c \ 11 radixsort.c rand.c random.c realpath.c remque.c setenv.c strtoimax.c \
12 strtol.c strtoll.c strtonum.c strtoul.c strtoull.c strtoumax.c \ 12 strtol.c strtoll.c strtonum.c strtoul.c strtoull.c strtoumax.c \
13 system.c \ 13 system.c \
14 tfind.c thread_atexit.c tsearch.c \ 14 tfind.c thread_atexit.c tsearch.c \
diff --git a/src/lib/libc/stdlib/__mktemp4.c b/src/lib/libc/stdlib/__mktemp4.c
new file mode 100644
index 0000000000..4b4500018b
--- /dev/null
+++ b/src/lib/libc/stdlib/__mktemp4.c
@@ -0,0 +1,83 @@
1/* $OpenBSD: __mktemp4.c,v 1.1 2024/01/19 19:45:02 millert Exp $ */
2/*
3 * Copyright (c) 1996-1998, 2008 Theo de Raadt
4 * Copyright (c) 1997, 2008-2009, 2024 Todd C. Miller
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <errno.h>
20#include <limits.h>
21#include <stdlib.h>
22#include <string.h>
23
24#define TEMPCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
25#define NUM_CHARS (sizeof(TEMPCHARS) - 1)
26#define MIN_X 6
27
28#ifndef nitems
29#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
30#endif
31
32/*
33 * Internal driver for the mktemp(3) family of functions.
34 * The supplied callback does the actual work of testing or
35 * creating the file/directory.
36 */
37int
38__mktemp4(char *path, int slen, int flags, int (*cb)(const char *, int))
39{
40 char *start, *cp, *ep;
41 const char tempchars[] = TEMPCHARS;
42 unsigned int tries;
43 size_t len;
44 int ret;
45
46 len = strlen(path);
47 if (len < MIN_X || slen < 0 || (size_t)slen > len - MIN_X) {
48 errno = EINVAL;
49 return -1;
50 }
51 ep = path + len - slen;
52
53 for (start = ep; start > path && start[-1] == 'X'; start--)
54 ;
55 if (ep - start < MIN_X) {
56 errno = EINVAL;
57 return -1;
58 }
59
60 tries = INT_MAX;
61 do {
62 cp = start;
63 do {
64 unsigned short rbuf[16];
65 unsigned int i;
66
67 /*
68 * Avoid lots of arc4random() calls by using
69 * a buffer sized for up to 16 Xs at a time.
70 */
71 arc4random_buf(rbuf, sizeof(rbuf));
72 for (i = 0; i < nitems(rbuf) && cp != ep; i++)
73 *cp++ = tempchars[rbuf[i] % NUM_CHARS];
74 } while (cp != ep);
75
76 ret = cb(path, flags);
77 if (ret != -1 || errno != EEXIST)
78 return ret;
79 } while (--tries);
80
81 errno = EEXIST;
82 return -1;
83}
diff --git a/src/lib/libc/stdlib/mkdtemp.c b/src/lib/libc/stdlib/mkdtemp.c
new file mode 100644
index 0000000000..c33c3b4e8b
--- /dev/null
+++ b/src/lib/libc/stdlib/mkdtemp.c
@@ -0,0 +1,33 @@
1/* $OpenBSD: mkdtemp.c,v 1.1 2024/01/19 19:45:02 millert Exp $ */
2/*
3 * Copyright (c) 2024 Todd C. Miller
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/stat.h>
19#include <stdlib.h>
20
21static int
22mkdtemp_cb(const char *path, int flags)
23{
24 return mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR);
25}
26
27char *
28mkdtemp(char *path)
29{
30 if (__mktemp4(path, 0, 0, mkdtemp_cb) == 0)
31 return path;
32 return NULL;
33}
diff --git a/src/lib/libc/stdlib/mkstemp.c b/src/lib/libc/stdlib/mkstemp.c
new file mode 100644
index 0000000000..75a9d27d1a
--- /dev/null
+++ b/src/lib/libc/stdlib/mkstemp.c
@@ -0,0 +1,64 @@
1/* $OpenBSD: mkstemp.c,v 1.1 2024/01/19 19:45:02 millert Exp $ */
2/*
3 * Copyright (c) 2024 Todd C. Miller
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/stat.h>
19#include <errno.h>
20#include <fcntl.h>
21#include <stdlib.h>
22
23#define MKOSTEMP_FLAGS (O_APPEND | O_CLOEXEC | O_DSYNC | O_RSYNC | O_SYNC)
24
25static int
26mkstemp_cb(const char *path, int flags)
27{
28 flags |= O_CREAT | O_EXCL | O_RDWR;
29 return open(path, flags, S_IRUSR|S_IWUSR);
30}
31
32int
33mkostemps(char *path, int slen, int flags)
34{
35 if (flags & ~MKOSTEMP_FLAGS) {
36 errno = EINVAL;
37 return -1;
38 }
39 return __mktemp4(path, slen, flags, mkstemp_cb);
40}
41
42int
43mkostemp(char *path, int flags)
44{
45 if (flags & ~MKOSTEMP_FLAGS) {
46 errno = EINVAL;
47 return -1;
48 }
49 return __mktemp4(path, 0, flags, mkstemp_cb);
50}
51DEF_WEAK(mkostemp);
52
53int
54mkstemp(char *path)
55{
56 return __mktemp4(path, 0, 0, mkstemp_cb);
57}
58DEF_WEAK(mkstemp);
59
60int
61mkstemps(char *path, int slen)
62{
63 return __mktemp4(path, slen, 0, mkstemp_cb);
64}
diff --git a/src/lib/libc/stdlib/mktemp.c b/src/lib/libc/stdlib/mktemp.c
index 3b8bba7846..4dc06f74d1 100644
--- a/src/lib/libc/stdlib/mktemp.c
+++ b/src/lib/libc/stdlib/mktemp.c
@@ -1,7 +1,6 @@
1/* $OpenBSD: mktemp.c,v 1.1 2024/01/19 16:30:28 millert Exp $ */ 1/* $OpenBSD: mktemp.c,v 1.2 2024/01/19 19:45:02 millert Exp $ */
2/* 2/*
3 * Copyright (c) 1996-1998, 2008 Theo de Raadt 3 * Copyright (c) 2024 Todd C. Miller
4 * Copyright (c) 1997, 2008-2009 Todd C. Miller
5 * 4 *
6 * Permission to use, copy, modify, and distribute this software for any 5 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -16,106 +15,27 @@
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */ 16 */
18 17
19#include <sys/types.h>
20#include <sys/stat.h> 18#include <sys/stat.h>
21#include <errno.h> 19#include <errno.h>
22#include <fcntl.h>
23#include <limits.h>
24#include <stdio.h>
25#include <stdlib.h> 20#include <stdlib.h>
26#include <string.h>
27#include <ctype.h>
28#include <unistd.h>
29
30#define MKTEMP_NAME 0
31#define MKTEMP_FILE 1
32#define MKTEMP_DIR 2
33
34#define TEMPCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
35#define NUM_CHARS (sizeof(TEMPCHARS) - 1)
36#define MIN_X 6
37
38#define MKOTEMP_FLAGS (O_APPEND | O_CLOEXEC | O_DSYNC | O_RSYNC | O_SYNC)
39
40#ifndef nitems
41#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
42#endif
43 21
44static int 22static int
45mktemp_internal(char *path, int slen, int mode, int flags) 23mktemp_cb(const char *path, int flags)
46{ 24{
47 char *start, *cp, *ep;
48 const char tempchars[] = TEMPCHARS;
49 unsigned int tries;
50 struct stat sb; 25 struct stat sb;
51 size_t len;
52 int fd;
53
54 len = strlen(path);
55 if (len < MIN_X || slen < 0 || (size_t)slen > len - MIN_X) {
56 errno = EINVAL;
57 return(-1);
58 }
59 ep = path + len - slen;
60
61 for (start = ep; start > path && start[-1] == 'X'; start--)
62 ;
63 if (ep - start < MIN_X) {
64 errno = EINVAL;
65 return(-1);
66 }
67
68 if (flags & ~MKOTEMP_FLAGS) {
69 errno = EINVAL;
70 return(-1);
71 }
72 flags |= O_CREAT | O_EXCL | O_RDWR;
73 26
74 tries = INT_MAX; 27 if (lstat(path, &sb) == 0)
75 do { 28 errno = EEXIST;
76 cp = start; 29 return (errno == ENOENT ? 0 : -1);
77 do {
78 unsigned short rbuf[16];
79 unsigned int i;
80
81 /*
82 * Avoid lots of arc4random() calls by using
83 * a buffer sized for up to 16 Xs at a time.
84 */
85 arc4random_buf(rbuf, sizeof(rbuf));
86 for (i = 0; i < nitems(rbuf) && cp != ep; i++)
87 *cp++ = tempchars[rbuf[i] % NUM_CHARS];
88 } while (cp != ep);
89
90 switch (mode) {
91 case MKTEMP_NAME:
92 if (lstat(path, &sb) != 0)
93 return(errno == ENOENT ? 0 : -1);
94 break;
95 case MKTEMP_FILE:
96 fd = open(path, flags, S_IRUSR|S_IWUSR);
97 if (fd != -1 || errno != EEXIST)
98 return(fd);
99 break;
100 case MKTEMP_DIR:
101 if (mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR) == 0)
102 return(0);
103 if (errno != EEXIST)
104 return(-1);
105 break;
106 }
107 } while (--tries);
108
109 errno = EEXIST;
110 return(-1);
111} 30}
112 31
32/* Also called via tmpnam(3) and tempnam(3). */
113char * 33char *
114_mktemp(char *path) 34_mktemp(char *path)
115{ 35{
116 if (mktemp_internal(path, 0, MKTEMP_NAME, 0) == -1) 36 if (__mktemp4(path, 0, 0, mktemp_cb) == 0)
117 return(NULL); 37 return path;
118 return(path); 38 return NULL;
119} 39}
120 40
121__warn_references(mktemp, 41__warn_references(mktemp,
@@ -124,40 +44,5 @@ __warn_references(mktemp,
124char * 44char *
125mktemp(char *path) 45mktemp(char *path)
126{ 46{
127 return(_mktemp(path)); 47 return _mktemp(path);
128}
129
130int
131mkostemps(char *path, int slen, int flags)
132{
133 return(mktemp_internal(path, slen, MKTEMP_FILE, flags));
134}
135
136int
137mkstemp(char *path)
138{
139 return(mktemp_internal(path, 0, MKTEMP_FILE, 0));
140}
141DEF_WEAK(mkstemp);
142
143int
144mkostemp(char *path, int flags)
145{
146 return(mktemp_internal(path, 0, MKTEMP_FILE, flags));
147}
148DEF_WEAK(mkostemp);
149
150int
151mkstemps(char *path, int slen)
152{
153 return(mktemp_internal(path, slen, MKTEMP_FILE, 0));
154}
155
156char *
157mkdtemp(char *path)
158{
159 int error;
160
161 error = mktemp_internal(path, 0, MKTEMP_DIR, 0);
162 return(error ? NULL : path);
163} 48}