X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=21edd3ac2f38ab47e5c3453e626f4171ba557d72;hp=a6e86148d1bb49d9dfb421fc079bd814a55690c8;hb=c50e4f95d8cfcd21bde2b0d1ff24b4de8fef4976;hpb=a6afc4aeaa5018859f8c8a397001ee4e3794545e diff --git a/src/shared/util.c b/src/shared/util.c index a6e86148d..21edd3ac2 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -2337,7 +2337,7 @@ void rename_process(const char name[8]) { if (!saved_argv[i]) break; - memset(saved_argv[i], 0, strlen(saved_argv[i])); + memzero(saved_argv[i], strlen(saved_argv[i])); } } } @@ -3893,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; @@ -5792,7 +5792,7 @@ void* greedy_realloc0(void **p, size_t *allocated, size_t need) { return NULL; if (*allocated > prev) - memset(&q[prev], 0, *allocated - prev); + memzero(&q[prev], *allocated - prev); return q; } @@ -5838,20 +5838,6 @@ bool id128_is_valid(const char *s) { return true; } -void parse_user_at_host(char *arg, char **user, char **host) { - assert(arg); - assert(user); - assert(host); - - *host = strchr(arg, '@'); - if (*host == NULL) - *host = arg; - else { - *host[0]++ = '\0'; - *user = arg; - } -} - int split_pair(const char *s, const char *sep, char **l, char **r) { char *x, *a, *b; @@ -6093,57 +6079,20 @@ int getpeersec(int fd, char **ret) { return 0; } -int writev_safe(int fd, const struct iovec *w, int j) { - for (int i = 0; i < j; i++) { - size_t written = 0; - - while (written < w[i].iov_len) { - ssize_t r; - - r = write(fd, (char*) w[i].iov_base + written, w[i].iov_len - written); - if (r < 0 && errno != -EINTR) - return -errno; - - written += r; - } - } - - return 0; -} - +/* This is much like like mkostemp() but is subject to umask(). */ int mkostemp_safe(char *pattern, int flags) { - unsigned long tries = TMP_MAX; - char *s; - int r; + _cleanup_umask_ mode_t u; + int fd; assert(pattern); - /* This is much like like mkostemp() but avoids using any - * static variables, thus is async signal safe */ - - s = endswith(pattern, "XXXXXX"); - if (!s) - return -EINVAL; - - while (tries--) { - unsigned i; - int fd; + u = umask(077); - r = dev_urandom(s, 6); - if (r < 0) - return r; - - for (i = 0; i < 6; i++) - s[i] = ALPHANUMERICAL[(unsigned) s[i] % (sizeof(ALPHANUMERICAL)-1)]; - - fd = open(pattern, flags|O_EXCL|O_CREAT, S_IRUSR|S_IWUSR); - if (fd >= 0) - return fd; - if (!IN_SET(errno, EEXIST, EINTR)) - return -errno; - } + fd = mkostemp(pattern, flags); + if (fd < 0) + return -errno; - return -EEXIST; + return fd; } int open_tmpfile(const char *path, int flags) { @@ -6153,10 +6102,13 @@ int open_tmpfile(const char *path, int flags) { assert(path); #ifdef O_TMPFILE - fd = open(path, flags|O_TMPFILE|O_NOCTTY, S_IRUSR|S_IWUSR); + /* 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, flags); @@ -6166,3 +6118,21 @@ int open_tmpfile(const char *path, int flags) { unlink(p); return fd; } + +int fd_warn_permissions(const char *path, int fd) { + struct stat st; + + if (fstat(fd, &st) < 0) + return -errno; + + if (st.st_mode & 0111) + log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path); + + if (st.st_mode & 0002) + log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path); + + if (getpid() == 1 && (st.st_mode & 0044) != 0044) + log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path); + + return 0; +}