X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=2b91ef8a8f9b203f71304c26bc50b420f5a52274;hp=f452431c6701a2ea56398de2c62116d7b513475b;hb=2d5bdf5bc0e4714d42e5999a4e37553a6bf83575;hpb=b89446bb33fbe6b9820efdbea62433657757a03f diff --git a/src/shared/util.c b/src/shared/util.c index f452431c6..2b91ef8a8 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -3835,12 +3835,13 @@ char* hostname_cleanup(char *s, bool lowercase) { } int pipe_eof(int fd) { - int r; struct pollfd pollfd = { .fd = fd, .events = POLLIN|POLLHUP, }; + int r; + r = poll(&pollfd, 1, 0); if (r < 0) return -errno; @@ -3892,7 +3893,7 @@ int fopen_temporary(const char *path, FILE **_f, char **_temp_path) { t[k] = '.'; stpcpy(stpcpy(t+k+1, fn), "XXXXXX"); - fd = mkostemp(t, O_WRONLY|O_CLOEXEC); + fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC); if (fd < 0) { free(t); return -errno; @@ -6111,25 +6112,35 @@ int writev_safe(int fd, const struct iovec *w, int j) { } int mkostemp_safe(char *pattern, int flags) { - char *s = pattern + strlen(pattern) - 6; - uint64_t tries = TMP_MAX; - int randfd, fd, i; + unsigned long tries = TMP_MAX; + char *s; + int r; + _cleanup_umask_ mode_t u; - assert(streq(s, "XXXXXX")); + assert(pattern); - randfd = open("/dev/urandom", O_RDONLY); - if (randfd < 0) - return -ENOSYS; + u = umask(077); + + /* This is much like like mkostemp() but avoids using any + * static variables, thus is async signal safe. Also, it's not + * subject to umask(). */ + + s = endswith(pattern, "XXXXXX"); + if (!s) + return -EINVAL; while (tries--) { - fd = read(randfd, s, 6); - if (fd == 0) - return -ENOSYS; + unsigned i; + int fd; + + r = dev_urandom(s, 6); + if (r < 0) + return r; for (i = 0; i < 6; i++) - s[i] = ALPHANUMERICAL[(unsigned) s[i] % strlen(ALPHANUMERICAL)]; + s[i] = ALPHANUMERICAL[(unsigned) s[i] % (sizeof(ALPHANUMERICAL)-1)]; - fd = open(pattern, flags|O_EXCL|O_CREAT, S_IRUSR|S_IWUSR); + fd = open(pattern, flags|O_EXCL|O_CREAT|O_NOCTTY|O_NOFOLLOW, S_IRUSR|S_IWUSR); if (fd >= 0) return fd; if (!IN_SET(errno, EEXIST, EINTR)) @@ -6140,17 +6151,22 @@ int mkostemp_safe(char *pattern, int flags) { } int open_tmpfile(const char *path, int flags) { - int fd; char *p; + int fd; + + assert(path); #ifdef O_TMPFILE + /* Try O_TMPFILE first, if it is supported */ fd = open(path, flags|O_TMPFILE, S_IRUSR|S_IWUSR); if (fd >= 0) return fd; #endif + + /* Fall back to unguessable name + unlinking */ p = strappenda(path, "/systemd-tmp-XXXXXX"); - fd = mkostemp_safe(p, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(p, flags); if (fd < 0) return fd;