1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
/* SPDX-License-Identifier: MIT
* Copyright (c) 2026 Leah Rowe <leah@libreboot.org>
*
* Hardened mktemp (mkhtemp!)
*
* WORK IN PROGRESS (proof of concept), or, v0.0000001
* DO NOT PUT THIS IN YOUR LINUX DISTRO YET.
*
* I will remove this notice when the code is mature, and
* probably contact several of your projects myself.
*
* See README. This is an ongoing project; no proper docs
* yet, and no manpage (yet!) - the code is documentation,
* while the specification that it implements evolves.
*/
#if defined(__linux__) && !defined(_GNU_SOURCE)
/* for openat2 on linux */
#define _GNU_SOURCE 1
#endif
#ifdef __OpenBSD__
#include <sys/param.h> /* pledge(2) */
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "include/common.h"
int
main(int argc, char *argv[])
{
#if defined (PATH_LEN) && \
(PATH_LEN) >= 256
size_t maxlen = PATH_LEN;
#else
size_t maxlen = 4096;
#endif
size_t len;
size_t tlen;
size_t xc = 0;
char *tmpdir = NULL;
char *template = NULL;
char *p;
char *s = NULL;
char *rp;
char resolved[maxlen];
char c;
int fd = -1;
int type = MKHTEMP_FILE;
int stfu = 0; /* -q option */
if (lbgetprogname(argv[0]) == NULL)
err_no_cleanup(stfu, errno, "could not set progname");
/* https://man.openbsd.org/pledge.2 */
#if defined(__OpenBSD__) && defined(OpenBSD)
#if (OpenBSD) >= 509
if (pledge("stdio flock rpath wpath cpath", NULL) == -1)
goto err_usage;
#endif
#endif
while ((c =
getopt(argc, argv, "qdp:")) != -1) {
switch (c) {
case 'd':
type = MKHTEMP_DIR;
break;
case 'p':
tmpdir = optarg;
break;
case 'q': /* don't print errors */
/* (exit status unchanged) */
stfu = 1;
break;
default:
goto err_usage;
}
}
if (optind < argc)
template = argv[optind];
if (optind + 1 < argc)
goto err_usage;
/* custom template e.g. foo.XXXXXXXXXXXXXXXXXXXXX */
if (template != NULL) {
if (slen(template, maxlen, &tlen) < 0)
err_no_cleanup(stfu, EINVAL,
"invalid template");
for (p = template + tlen;
p > template && *--p == 'X'; xc++);
if (xc < 3) /* the gnu mktemp errs on less than 3 */
err_no_cleanup(stfu, EINVAL,
"template must have 3 X or more on end (12+ advised");
}
/* user supplied -p PATH - WARNING:
* this permits symlinks, but only here,
* not in the library, so they are resolved
* here first, and *only here*. the mkhtemp
* library blocks them. be careful
* when using -p
*/
if (tmpdir != NULL) {
rp = realpath(tmpdir, resolved);
if (rp == NULL)
err_no_cleanup(stfu, errno, "%s", tmpdir);
tmpdir = resolved;
}
if (new_tmp_common(&fd, &s, type,
tmpdir, template) < 0)
err_no_cleanup(stfu, errno, "%s", s);
#if defined(__OpenBSD__) && defined(OpenBSD)
#if (OpenBSD) >= 509
if (pledge("stdio", NULL) == -1)
err_no_cleanup(stfu, errno, "pledge, exit");
#endif
#endif
if (s == NULL)
err_no_cleanup(stfu, EFAULT, "bad string initialisation");
if (*s == '\0')
err_no_cleanup(stfu, EFAULT, "empty string initialisation");
if (slen(s, maxlen, &len) < 0)
err_no_cleanup(stfu, EFAULT, "unterminated string initialisiert");
printf("%s\n", s);
return EXIT_SUCCESS;
err_usage:
err_no_cleanup(stfu, EINVAL,
"usage: %s [-d] [-p dir] [template]\n", getnvmprogname());
}/*
( >:3 )
/| |\
/ \ */
|