Skip to content
This repository has been archived by the owner on Aug 8, 2024. It is now read-only.

Put fchmod back to the top in SystemNative_CopyFile and only ignore when it fails on android #367

Merged
merged 2 commits into from
Oct 29, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 22 additions & 19 deletions src/Native/Unix/System.Native/pal_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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'.
Expand Down Expand Up @@ -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
}
Expand Down