On Thu, 25 Apr 2019 09:34:47 -0600, Todd C. Miller wrote:
> I think a better approach is to add an internal version of mkstemp(3)
> that takes a permission flag. We can then pass in DEFFILEMODE for
> the permission bits like stdio and avoid the umask and fchmod
> entirely.
Something like this for example.
- todd
Index: lib/libc/stdio/local.h
===================================================================
RCS file: /cvs/src/lib/libc/stdio/local.h,v
retrieving revision 1.25
diff -u -p -u -r1.25 local.h
--- lib/libc/stdio/local.h 23 May 2016 00:21:48 -0000 1.25
+++ lib/libc/stdio/local.h 25 Apr 2019 15:51:55 -0000
@@ -45,6 +45,7 @@
__BEGIN_HIDDEN_DECLS
void _cleanup(void);
int _fwalk(int (*)(FILE *));
+int _mktemp4(char *path, int slen, int flags, mode_t perm);
int __sflush(FILE *);
int __sflush_locked(FILE *);
FILE *__sfp(void);
Index: lib/libc/stdio/mktemp.c
===================================================================
RCS file: /cvs/src/lib/libc/stdio/mktemp.c,v
retrieving revision 1.39
diff -u -p -u -r1.39 mktemp.c
--- lib/libc/stdio/mktemp.c 28 Nov 2017 06:55:49 -0000 1.39
+++ lib/libc/stdio/mktemp.c 25 Apr 2019 15:53:53 -0000
@@ -41,15 +41,15 @@
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
-static int
-mktemp_internal(char *path, int slen, int mode, int flags)
+int
+_mktemp4(char *path, int slen, int flags, mode_t perm)
{
char *start, *cp, *ep;
const char tempchars[] = TEMPCHARS;
unsigned int tries;
struct stat sb;
size_t len;
- int fd;
+ int fd, mode;
len = strlen(path);
if (len < MIN_X || slen < 0 || (size_t)slen > len - MIN_X) {
@@ -71,6 +71,13 @@ mktemp_internal(char *path, int slen, in
}
flags |= O_CREAT | O_EXCL | O_RDWR;
+ if (perm == 0)
+ mode = MKTEMP_NAME;
+ else if (perm & S_IXUSR)
+ mode = MKTEMP_DIR;
+ else
+ mode = MKTEMP_FILE;
+
tries = INT_MAX;
do {
cp = start;
@@ -113,7 +120,7 @@ mktemp_internal(char *path, int slen, in
char *
_mktemp(char *path)
{
- if (mktemp_internal(path, 0, MKTEMP_NAME, 0) == -1)
+ if (_mktemp4(path, 0, 0, 0) == -1)
return(NULL);
return(path);
}
@@ -130,27 +137,27 @@ mktemp(char *path)
int
mkostemps(char *path, int slen, int flags)
{
- return(mktemp_internal(path, slen, MKTEMP_FILE, flags));
+ return(_mktemp4(path, slen, flags, S_IRUSR|S_IWUSR));
}
int
mkstemp(char *path)
{
- return(mktemp_internal(path, 0, MKTEMP_FILE, 0));
+ return(_mktemp4(path, 0, 0, S_IRUSR|S_IWUSR));
}
DEF_WEAK(mkstemp);
int
mkostemp(char *path, int flags)
{
- return(mktemp_internal(path, 0, MKTEMP_FILE, flags));
+ return(_mktemp4(path, 0, flags, S_IRUSR|S_IWUSR));
}
DEF_WEAK(mkostemp);
int
mkstemps(char *path, int slen)
{
- return(mktemp_internal(path, slen, MKTEMP_FILE, 0));
+ return(_mktemp4(path, slen, 0, S_IRUSR|S_IWUSR));
}
char *
@@ -158,6 +165,6 @@ mkdtemp(char *path)
{
int error;
- error = mktemp_internal(path, 0, MKTEMP_DIR, 0);
+ error = _mktemp4(path, 0, 0, S_IRUSR|S_IWUSR|S_IXUSR);
return(error ? NULL : path);
}
Index: lib/libc/stdio/tmpfile.c
===================================================================
RCS file: /cvs/src/lib/libc/stdio/tmpfile.c,v
retrieving revision 1.11
diff -u -p -u -r1.11 tmpfile.c
--- lib/libc/stdio/tmpfile.c 31 Aug 2015 02:53:57 -0000 1.11
+++ lib/libc/stdio/tmpfile.c 25 Apr 2019 15:52:26 -0000
@@ -56,15 +56,7 @@ tmpfile(void)
sigfillset(&set);
(void)sigprocmask(SIG_BLOCK, &set, &oset);
- fd = mkstemp(buf);
- if (fd != -1) {
- mode_t u;
-
- (void)unlink(buf);
- u = umask(0);
- (void)umask(u);
- (void)fchmod(fd, 0666 & ~u);
- }
+ fd = _mktemp4(buf, 0, 0, DEFFILEMODE);
(void)sigprocmask(SIG_SETMASK, &oset, NULL);