X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=b885a46e439fb3a5a197007b4ff90690fa0c074e;hb=249a98a8ff9f9a3da30e977d347c14487088f738;hp=693bb1d9a4b338d68bb2f911a778cf0bbc7b67af;hpb=6b1c671c3ab4a44ec18f3059e45f197fbe8502f3;p=elogind.git diff --git a/src/shared/util.c b/src/shared/util.c index 693bb1d9a..b885a46e4 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -3918,7 +3918,7 @@ bool path_is_safe(const char *p) { if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../")) return false; - if (strlen(p) > PATH_MAX) + if (strlen(p)+1 > PATH_MAX) return false; /* The following two checks are not really dangerous, but hey, they still are confusing */ @@ -4839,7 +4839,7 @@ int open_tmpfile(const char *path, int flags) { #ifdef O_TMPFILE /* Try O_TMPFILE first, if it is supported */ - fd = open(path, flags|O_TMPFILE, S_IRUSR|S_IWUSR); + fd = open(path, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR); if (fd >= 0) return fd; #endif @@ -5683,6 +5683,9 @@ int free_and_strdup(char **p, const char *s) { /* Replaces a string pointer with an strdup()ed new string, * possibly freeing the old one. */ + if (streq_ptr(*p, s)) + return 0; + if (s) { t = strdup(s); if (!t) @@ -5693,7 +5696,7 @@ int free_and_strdup(char **p, const char *s) { free(*p); *p = t; - return 0; + return 1; } int sethostname_idempotent(const char *s) { @@ -6001,128 +6004,6 @@ int read_attr_path(const char *p, unsigned *ret) { return read_attr_fd(fd, ret); } -int make_lock_file(const char *p, int operation, LockFile *ret) { - _cleanup_close_ int fd = -1; - _cleanup_free_ char *t = NULL; - int r; - - /* - * We use UNPOSIX locks if they are available. They have nice - * semantics, and are mostly compatible with NFS. However, - * they are only available on new kernels. When we detect we - * are running on an older kernel, then we fall back to good - * old BSD locks. They also have nice semantics, but are - * slightly problematic on NFS, where they are upgraded to - * POSIX locks, even though locally they are orthogonal to - * POSIX locks. - */ - - t = strdup(p); - if (!t) - return -ENOMEM; - - for (;;) { - struct flock fl = { - .l_type = (operation & ~LOCK_NB) == LOCK_EX ? F_WRLCK : F_RDLCK, - .l_whence = SEEK_SET, - }; - struct stat st; - - fd = open(p, O_CREAT|O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NOCTTY, 0600); - if (fd < 0) - return -errno; - - r = fcntl(fd, (operation & LOCK_NB) ? F_OFD_SETLK : F_OFD_SETLKW, &fl); - if (r < 0) { - - /* If the kernel is too old, use good old BSD locks */ - if (errno == EINVAL) - r = flock(fd, operation); - - if (r < 0) - return errno == EAGAIN ? -EBUSY : -errno; - } - - /* If we acquired the lock, let's check if the file - * still exists in the file system. If not, then the - * previous exclusive owner removed it and then closed - * it. In such a case our acquired lock is worthless, - * hence try again. */ - - r = fstat(fd, &st); - if (r < 0) - return -errno; - if (st.st_nlink > 0) - break; - - fd = safe_close(fd); - } - - ret->path = t; - ret->fd = fd; - ret->operation = operation; - - fd = -1; - t = NULL; - - return r; -} - -int make_lock_file_for(const char *p, int operation, LockFile *ret) { - const char *fn; - char *t; - - assert(p); - assert(ret); - - fn = basename(p); - if (!filename_is_valid(fn)) - return -EINVAL; - - t = newa(char, strlen(p) + 2 + 4 + 1); - stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), fn), ".lck"); - - return make_lock_file(t, operation, ret); -} - -void release_lock_file(LockFile *f) { - int r; - - if (!f) - return; - - if (f->path) { - - /* If we are the exclusive owner we can safely delete - * the lock file itself. If we are not the exclusive - * owner, we can try becoming it. */ - - if (f->fd >= 0 && - (f->operation & ~LOCK_NB) == LOCK_SH) { - static const struct flock fl = { - .l_type = F_WRLCK, - .l_whence = SEEK_SET, - }; - - r = fcntl(f->fd, F_OFD_SETLK, &fl); - if (r < 0 && errno == EINVAL) - r = flock(f->fd, LOCK_EX|LOCK_NB); - - if (r >= 0) - f->operation = LOCK_EX|LOCK_NB; - } - - if ((f->operation & ~LOCK_NB) == LOCK_EX) - unlink_noerrno(f->path); - - free(f->path); - f->path = NULL; - } - - f->fd = safe_close(f->fd); - f->operation = 0; -} - static size_t nul_length(const uint8_t *p, size_t sz) { size_t n = 0;