diff options
author | Martin Baulig <mabaul@microsoft.com> | 2019-10-28 23:56:17 +0300 |
---|---|---|
committer | Steve Pfister <steveisok@users.noreply.github.com> | 2019-10-28 23:56:17 +0300 |
commit | eb2575e5e7622787eff151391e7b127c8c9a073e (patch) | |
tree | 1cd918278a69bcdc3389454fe2bff4768f15a158 | |
parent | fb41040a9ee62f266e7c6684897b6b0368fdfff1 (diff) |
SystemNative_CopyFile(): move fchmod() call to top and add exception for Android (#364)
* SystemNative_CopyFile(): move fchmod() call to top and add exception for Android.
The `fchmod()` call should happen first to ensure that the target file has the correct
permissions prior to writing into it.
On Android, we make an exception in case the `fchmod()` fails: if we can `fstat()` both
the source and the target file and the target file's permissions are at least as restrictive
as the source file's, then we allow the operation to proceed.
See https://github.com/mono/mono/issues/17133 for details.
* Update pal_io.c
-rw-r--r-- | src/Native/Unix/System.Native/pal_io.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/src/Native/Unix/System.Native/pal_io.c b/src/Native/Unix/System.Native/pal_io.c index f2011d61c4..39dfefc249 100644 --- a/src/Native/Unix/System.Native/pal_io.c +++ b/src/Native/Unix/System.Native/pal_io.c @@ -1257,6 +1257,24 @@ int32_t SystemNative_CopyFile(intptr_t sourceFd, intptr_t destinationFd) int ret; struct stat_ sourceStat; bool copied = false; + +#if !MONODROID + // 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. + while ((ret = fchmod(outFd, sourceStat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO))) < 0 && errno == EINTR); + 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. @@ -1333,17 +1351,6 @@ int32_t SystemNative_CopyFile(intptr_t sourceFd, intptr_t destinationFd) while ((ret = futimes(outFd, origTimes)) < 0 && errno == EINTR); #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); - if (ret != 0) - { - return -1; - } return 0; #endif // HAVE_FCOPYFILE |