Hi,
There was a potentially confusing typo in the comments in my patch, so
I've attached a version with the typo fixed. Note that the code itself
was fine, the typo was just in the comments.
Cheers,
Cathy
On Wed, Nov 20, 2013 at 6:07 PM, Cathy Fitzpatrick <[email protected]> wrote:
> Hello,
>
> Currently the `svn patch` command changes the permissions on any file
> it patches to 600. This occurs because it creates a file under the
> system temporary directory for applying the patch, and then copies
> this file to the final destination. `apr_file_mktemp` sensibly assigns
> mode 600 to files created under the system temporary directory to
> avoid them being exposed to the entire system. So the result is that
> any file that `svn patch` patches ends up with 600 permissions rather
> than whatever it had before.
>
> Here is an example of the current behaviour (before my patch):
>
> [Cathy@localhost subversion]$ ls -la INSTALL
> -rw-rw-r--. 1 Cathy Cathy 63057 Nov 20 17:34 INSTALL
> [Cathy@localhost subversion]$ ./svn patch patch.diff
> U INSTALL
> [Cathy@localhost subversion]$ ls -la INSTALL
> -rw-------. 1 Cathy Cathy 63070 Nov 20 17:58 INSTALL
>
> Notice that applying the patch has changed the permissions of INSTALL.
>
> After my patch, we instead get the following:
>
> [Cathy@localhost subversion]$ ls -la INSTALL
> -rw-rw-r--. 1 Cathy Cathy 63057 Nov 20 17:59 INSTALL
> [Cathy@localhost subversion]$ ./svn patch patch.diff
> U INSTALL
> [Cathy@localhost subversion]$ ls -la INSTALL
> -rw-rw-r--. 1 Cathy Cathy 63070 Nov 20 17:59 INSTALL
>
> As expected, patching the file no longer alters its permissions.
>
>
> I have attached my patch to this email and it includes a log message.
>
> Regards,
>
> Cathy
[[[
svn patch: Don't change permissions of patched files
* subversion/libsvn_client/patch.c
(init_patch_target): Create temporary file for result of patch
under the working directory, rather than under the system
temporary directory. This is already how EOL translation
works (see `svn_subst_copy_and_translate4`) and has the
advantage that we can safely change permissions on the file
without potentially exposing the file to the entire system.
(install_patched_target): Make sure the final patched file has
the same permissions as the original file before patching.
Patch by: Cathy J. Fitzpatrick <[email protected]>
]]]
Index: subversion/libsvn_client/patch.c
===================================================================
--- subversion/libsvn_client/patch.c (revision 1543974)
+++ subversion/libsvn_client/patch.c (working copy)
@@ -1076,23 +1076,33 @@
* ### we should have kept the patch field in patch_target_t to be
* ### able to distinguish between 'what the patch says we should do'
* ### and 'what we can do with the given state of our WC'. */
if (patch->operation == svn_diff_op_added)
target->added = TRUE;
else if (patch->operation == svn_diff_op_deleted)
target->deleted = TRUE;
if (! target->is_symlink)
{
- /* Open a temporary file to write the patched result to. */
+ /* Open a temporary file to write the patched result to.
+ *
+ * Create the temporary file under the working directory (the same
+ * as EOL translation uses) so that it is safe to change its file
+ * permissions without exposing the file to the entire system, which
+ * could happen if the file were under the system temporary
+ * directory, rather than the working directory.
+ */
SVN_ERR(svn_io_open_unique_file3(&target->patched_file,
- &target->patched_path, NULL,
+ &target->patched_path,
+ svn_dirent_dirname(
+ wcroot_abspath,
+ scratch_pool),
remove_tempfiles ?
svn_io_file_del_on_pool_cleanup :
svn_io_file_del_none,
result_pool, scratch_pool));
/* Put the write callback in place. */
content->write = write_file;
content->write_baton = target->patched_file;
}
else
@@ -2564,20 +2574,27 @@
svn_boolean_t repair_eol;
/* Copy the patched file on top of the target file.
* Always expand keywords in the patched file, but repair EOL
* only if svn:eol-style dictates a particular style. */
repair_eol = (target->content->eol_style ==
svn_subst_eol_style_fixed ||
target->content->eol_style ==
svn_subst_eol_style_native);
+ /* Make sure the patched file has the same permissions as the
+ * original file. By design, `patched_path` will be under
+ * the working directory, so this does not introduce any
+ * security issues with temp files. */
+ SVN_ERR(svn_io_copy_perms(
+ target->local_abspath, target->patched_path, pool));
+
SVN_ERR(svn_subst_copy_and_translate4(
target->patched_path, target->local_abspath,
target->content->eol_str, repair_eol,
target->content->keywords,
TRUE /* expand */, FALSE /* special */,
ctx->cancel_func, ctx->cancel_baton, pool));
}
if (target->added || target->replaced)
{