Explorar o código

fix failure of fchmodat to report EOPNOTSUPP in the race path

in the case where a non-symlink file was replaced by a symlink during
the fchmodat operation with AT_SYMLINK_NOFOLLOW, mode change on the
new symlink target was successfully suppressed, but the error was not
reported. instead, fchmodat simply returned 0.

(cherry picked from commit 61b1d102129990f6e903c6ddcf46c7d79d1a1e99)

(conflicts from commit dd5f50da6f6c3df5647e922e47f8568a8896a752)
Rich Felker %!s(int64=10) %!d(string=hai) anos
pai
achega
d670873b7e
Modificáronse 1 ficheiros con 5 adicións e 2 borrados
  1. 5 2
      src/stat/fchmodat.c

+ 5 - 2
src/stat/fchmodat.c

@@ -28,8 +28,11 @@ int fchmodat(int fd, const char *path, mode_t mode, int flag)
 	}
 
 	__procfdname(proc, fd2);
-	if (!(ret = __syscall(SYS_stat, proc, &st)) && !S_ISLNK(st.st_mode))
-		ret = __syscall(SYS_chmod, proc, mode);
+	ret = __syscall(SYS_fstatat, AT_FDCWD, proc, &st, 0);
+	if (!ret) {
+		if (S_ISLNK(st.st_mode)) ret = -EOPNOTSUPP;
+		else ret = __syscall(SYS_fchmodat, AT_FDCWD, proc, mode);
+	}
 
 	__syscall(SYS_close, fd2);
 	return __syscall_ret(ret);