fs-util,tmpfiles: fix error handling of fchmod_opath()

When 4dfaa528d4 was first commited its callers relied on `errno` instead of the
return value for error reporting. Which worked fine, since internally
under all conditions base were set — even if ugly and not inline with
our coding style. Things then got broken in
f8606626ed where suddenly additional
syscalls might end up being done in the function, thus corrupting `errno`.
This commit is contained in:
Lennart Poettering
2020-09-10 12:47:50 +02:00
parent bae66f4bda
commit dee00c1939
2 changed files with 18 additions and 10 deletions
+11 -6
View File
@@ -229,6 +229,7 @@ int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid) {
bool do_chown, do_chmod;
struct stat st;
int r;
/* Change ownership and access mode of the specified fd. Tries to do so safely, ensuring that at no
* point in time the access mode is above the old access mode under the old ownership or the new
@@ -259,18 +260,22 @@ int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid) {
if (do_chown && do_chmod) {
mode_t minimal = st.st_mode & mode; /* the subset of the old and the new mask */
if (((minimal ^ st.st_mode) & 07777) != 0)
if (fchmod_opath(fd, minimal & 07777) < 0)
return -errno;
if (((minimal ^ st.st_mode) & 07777) != 0) {
r = fchmod_opath(fd, minimal & 07777);
if (r < 0)
return r;
}
}
if (do_chown)
if (fchownat(fd, "", uid, gid, AT_EMPTY_PATH) < 0)
return -errno;
if (do_chmod)
if (fchmod_opath(fd, mode & 07777) < 0)
return -errno;
if (do_chmod) {
r = fchmod_opath(fd, mode & 07777);
if (r < 0)
return r;
}
return do_chown || do_chmod;
}