util/nvmutil: hardened mkstemp

200 retries, not 100.

and open with O_NOFOLLOW and O_CLOEXEC

check X on mkstemp

support more than 6 X in mkstemp

make PATH_LEN 4096

1024 is a bit low

make default mkstemp length 4096

Signed-off-by: Leah Rowe <leah@libreboot.org>
This commit is contained in:
Leah Rowe
2026-03-19 08:07:47 +00:00
parent 4b35d9ac29
commit 50300f846f
2 changed files with 33 additions and 13 deletions

View File

@@ -35,7 +35,7 @@ int fchmod(int fd, mode_t mode);
#define MAX_CMD_LEN 50
#ifndef PATH_LEN
#define PATH_LEN 1024
#define PATH_LEN 4096
#endif
#define OFF_ERR 0
@@ -421,7 +421,7 @@ const char *getnvmprogname(void);
*/
char *new_tmpfile(int *fd, int local, const char *path);
int x_i_mkstemp(char *template);
int mkstemp_n(char *template);
char *x_c_tmpdir(void);
int close_on_eintr(int fd);
int fsync_on_eintr(int fd);

View File

@@ -310,7 +310,7 @@ new_tmpfile(int *fd, int local, const char *path)
dest[tmppath_len] = '\0';
fd_tmp = x_i_mkstemp(dest);
fd_tmp = mkstemp_n(dest);
if (fd_tmp == -1)
goto err_new_tmpfile;
@@ -421,36 +421,56 @@ x_c_tmpdir(void)
*/
int
x_i_mkstemp(char *template)
mkstemp_n(char *template)
{
int fd;
int i, j;
unsigned long i, j;
unsigned long len;
char *p;
char ch[] =
unsigned long xc = 0;
static char ch[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
unsigned long r;
unsigned long max_len =
#ifndef PATH_LEN
4096;
#else
(PATH_LEN);
#endif
len = xstrxlen(template, PATH_LEN);
len = xstrxlen(template, max_len);
/* find trailing XXXXXX */
if (len < 6)
if (len < 6) {
errno = EINVAL;
return -1;
}
p = template + len - 6;
p = template + len;
for (i = 0; i < 100; i++) {
while (p > template && p[-1] == 'X') {
--p;
++xc;
}
for (j = 0; j < 6; j++) {
if (xc < 6) {
errno = EINVAL;
return -1;
}
for (i = 0; i < 200; i++) {
for (j = 0; j < xc; j++) {
r = rlong();
p[j] = ch[(unsigned long)(r >> 1) % (sizeof(ch) - 1)];
}
fd = open(template, O_RDWR | O_CREAT | O_EXCL, 0600);
fd = open(template,
O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC, 0600);
if (fd >= 0)
return fd;