diff options
author | Martin Baulig <mabaul@microsoft.com> | 2019-10-29 20:10:31 +0300 |
---|---|---|
committer | Martin Baulig <mabaul@microsoft.com> | 2019-10-29 20:17:48 +0300 |
commit | 82e3cdb19cab91a0a88db896c1e2cc43f0afb23c (patch) | |
tree | 254ef4d43559d7bb5b4caeeba955e92b4dc8bbb7 | |
parent | 11501bfb54371d0a4a6de8ecfab1438708c2dea1 (diff) |
Put fchmod back to the top in SystemNative_CopyFile and only ignore when it fails on android.
-rw-r--r-- | src/Native/Unix/System.Native/pal_io.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/src/Native/Unix/System.Native/pal_io.c b/src/Native/Unix/System.Native/pal_io.c index dc5e9e825a..37a9b417b8 100644 --- a/src/Native/Unix/System.Native/pal_io.c +++ b/src/Native/Unix/System.Native/pal_io.c @@ -1257,7 +1257,27 @@ int32_t SystemNative_CopyFile(intptr_t sourceFd, intptr_t destinationFd) int ret; struct stat_ sourceStat; bool copied = false; - + + // First, stat the source file. + while ((ret = fstat_(inFd, &sourceStat)) < 0 && errno == EINTR); + if (ret != 0) + { + // If we can't stat() it, then we likely don't have permission to read it. + return -1; + } + + // Then copy permissions. This fchmod() needs to happen prior to writing anything into + // the file to avoid possiblyleaking any private data. + while ((ret = fchmod(outFd, sourceStat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO))) < 0 && errno == EINTR); +#if !TARGET_ANDROID + // On Android, we are not allowed to modify permissions, but the copy should still succeed; + // see https://github.com/mono/mono/issues/17133 for details. + if (ret != 0) + { + return -1; + } +#endif + #if HAVE_SENDFILE_4 // If sendfile is available (Linux), try to use it, as the whole copy // can be performed in the kernel, without lots of unnecessary copying. @@ -1267,6 +1287,7 @@ int32_t SystemNative_CopyFile(intptr_t sourceFd, intptr_t destinationFd) return -1; } + // On 32-bit, if you use 64-bit offsets, the last argument of `sendfile' will be a // `size_t' a 32-bit integer while the `st_size' field of the stat structure will be off64_t. // So `size' will have to be `uint64_t'. In all other cases, it will be `size_t'. @@ -1334,24 +1355,6 @@ int32_t SystemNative_CopyFile(intptr_t sourceFd, intptr_t destinationFd) #endif } - if (ret != 0) - { - return -1; - } - - // Then copy permissions. - while ((ret = fchmod(outFd, sourceStat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO))) < 0 && errno == EINTR); - -// We are ignoring the error on Android because in the case of external storage we are not allowed -// to modify permissions, but the copy should still succeed. -// https://github.com/mono/mono/issues/17133 -#if !TARGET_ANDROID - if (ret != 0) - { - return -1; - } -#endif - return 0; #endif // HAVE_FCOPYFILE } |