Add mkostempsat(3).

This is a variant of mkostemps() which takes a directory descriptor and
returns a descriptor for a tempfile relative to that directory.  Unlike
the other mktemp functions, mkostempsat() can be used in capability
mode.

Reviewed by:	cem
Discussed with:	brooks
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D21031
This commit is contained in:
markj 2019-07-29 19:02:16 +00:00
parent a1a1b09414
commit a4c47e1dde
5 changed files with 55 additions and 19 deletions

View File

@ -297,6 +297,7 @@ int mergesort_b(void *, size_t, size_t, int (^)(const void *, const void *));
#endif
int mkostemp(char *, int);
int mkostemps(char *, int, int);
int mkostempsat(int, char *, int, int);
void qsort_r(void *, size_t, size_t, void *,
int (*)(void *, const void *, const void *));
int radixsort(const unsigned char **, int, const unsigned char *,

View File

@ -63,7 +63,7 @@ MLINKS+=getc.3 fgetc.3 getc.3 getc_unlocked.3 getc.3 getchar.3 \
MLINKS+=getline.3 getdelim.3
MLINKS+=getwc.3 fgetwc.3 getwc.3 getwchar.3
MLINKS+=mktemp.3 mkdtemp.3 mktemp.3 mkstemp.3 mktemp.3 mkstemps.3 \
mktemp.3 mkostemp.3 mktemp.3 mkostemps.3
mktemp.3 mkostemp.3 mktemp.3 mkostemps.3 mktemp.3 mkostempsat.3
MLINKS+=open_memstream.3 open_wmemstream.3
MLINKS+=printf.3 asprintf.3 printf.3 dprintf.3 printf.3 fprintf.3 \
printf.3 snprintf.3 printf.3 sprintf.3 \

View File

@ -171,6 +171,10 @@ FBSD_1.5 {
gets_s;
};
FBSD_1.6 {
mkostempsat;
};
FBSDprivate_1.0 {
_flockfile;
_flockfile_debug_stub;

View File

@ -28,7 +28,7 @@
.\" @(#)mktemp.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
.Dd August 8, 2013
.Dd July 29, 2019
.Dt MKTEMP 3
.Os
.Sh NAME
@ -46,6 +46,8 @@
.Fn mkostemp "char *template" "int oflags"
.Ft int
.Fn mkostemps "char *template" "int suffixlen" "int oflags"
.Ft int
.Fn mkostempsat "int dfd" "char *template" "int suffixlen" "int oflags"
.Ft char *
.Fn mkdtemp "char *template"
.In unistd.h
@ -126,6 +128,21 @@ function
are told the length of the suffix string.
.Pp
The
.Fn mkostempsat
function acts the same as
.Fn mkostemps
but takes an additional directory descriptor as a parameter.
The temporary file is created relative to the corresponding
directory, or to the current working directory if the special
value
.Dv AT_FDCWD
is specified.
If the template path is an absolute path, the
.Fa dfd
parameter is ignored and the behavior is identical to
.Fn mkostemps .
.Pp
The
.Fn mkdtemp
function makes the same replacement to the template as in
.Fn mktemp
@ -262,9 +279,10 @@ and is not specified by
.St -p1003.1-2008 .
The
.Fn mkostemp ,
.Fn mkstemps
and
.Fn mkstemps ,
.Fn mkostemps
and
.Fn mkostempsat
functions do not conform to any standard.
.Sh HISTORY
A
@ -293,6 +311,10 @@ and
.Fn mkostemps
functions appeared in
.Fx 10.0 .
The
.Fn mkostempsat
function appeared in
.Fx 13.0 .
.Sh BUGS
This family of functions produces filenames which can be guessed,
though the risk is minimized when large numbers of
@ -308,10 +330,11 @@ and opening it for use
(later in the user application)
particularly dangerous from a security perspective.
Whenever it is possible,
.Fn mkstemp
or
.Fn mkstemp ,
.Fn mkostemp
should be used instead, since it does not have the race condition.
or
.Fn mkostempsat
should be used instead, since they do not have the race condition.
If
.Fn mkstemp
cannot be used, the filename created by

View File

@ -49,17 +49,25 @@ __FBSDID("$FreeBSD$");
char *_mktemp(char *);
static int _gettemp(char *, int *, int, int, int);
static int _gettemp(int, char *, int *, int, int, int);
static const unsigned char padchar[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
int
mkostempsat(int dfd, char *path, int slen, int oflags)
{
int fd;
return (_gettemp(dfd, path, &fd, 0, slen, oflags) ? fd : -1);
}
int
mkostemps(char *path, int slen, int oflags)
{
int fd;
return (_gettemp(path, &fd, 0, slen, oflags) ? fd : -1);
return (_gettemp(AT_FDCWD, path, &fd, 0, slen, oflags) ? fd : -1);
}
int
@ -67,7 +75,7 @@ mkstemps(char *path, int slen)
{
int fd;
return (_gettemp(path, &fd, 0, slen, 0) ? fd : -1);
return (_gettemp(AT_FDCWD, path, &fd, 0, slen, 0) ? fd : -1);
}
int
@ -75,7 +83,7 @@ mkostemp(char *path, int oflags)
{
int fd;
return (_gettemp(path, &fd, 0, 0, oflags) ? fd : -1);
return (_gettemp(AT_FDCWD, path, &fd, 0, 0, oflags) ? fd : -1);
}
int
@ -83,19 +91,19 @@ mkstemp(char *path)
{
int fd;
return (_gettemp(path, &fd, 0, 0, 0) ? fd : -1);
return (_gettemp(AT_FDCWD, path, &fd, 0, 0, 0) ? fd : -1);
}
char *
mkdtemp(char *path)
{
return (_gettemp(path, (int *)NULL, 1, 0, 0) ? path : (char *)NULL);
return (_gettemp(AT_FDCWD, path, (int *)NULL, 1, 0, 0) ? path : (char *)NULL);
}
char *
_mktemp(char *path)
{
return (_gettemp(path, (int *)NULL, 0, 0, 0) ? path : (char *)NULL);
return (_gettemp(AT_FDCWD, path, (int *)NULL, 0, 0, 0) ? path : (char *)NULL);
}
__warn_references(mktemp,
@ -108,7 +116,7 @@ mktemp(char *path)
}
static int
_gettemp(char *path, int *doopen, int domkdir, int slen, int oflags)
_gettemp(int dfd, char *path, int *doopen, int domkdir, int slen, int oflags)
{
char *start, *trv, *suffp, *carryp;
char *pad;
@ -155,7 +163,7 @@ _gettemp(char *path, int *doopen, int domkdir, int slen, int oflags)
for (; trv > path; --trv) {
if (*trv == '/') {
*trv = '\0';
rval = stat(path, &sbuf);
rval = fstatat(dfd, path, &sbuf, 0);
*trv = '/';
if (rval != 0)
return (0);
@ -168,11 +176,11 @@ _gettemp(char *path, int *doopen, int domkdir, int slen, int oflags)
}
}
oflags |= O_CREAT | O_EXCL | O_RDWR;
for (;;) {
if (doopen) {
if ((*doopen =
_open(path, O_CREAT|O_EXCL|O_RDWR|oflags, 0600)) >=
0)
*doopen = _openat(dfd, path, oflags, 0600);
if (*doopen >= 0)
return (1);
if (errno != EEXIST)
return (0);