Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8073061

(fs) Files.copy(foo, bar, REPLACE_EXISTING) deletes bar even if foo is not readable

XMLWordPrintable

    • b17
    • x86, x86_64
    • linux, linux_ubuntu, os_x
    • Verified

        FULL PRODUCT VERSION :


        ADDITIONAL OS VERSION INFORMATION :
        Ubuntu 14.10, x86_64

        A DESCRIPTION OF THE PROBLEM :
        /tmp/x $ cat Test.java
        import java.io.IOException;
        import java.nio.file.Files;
        import java.nio.file.Path;
        import java.nio.file.Paths;
        import java.nio.file.StandardCopyOption;

        public class Test
        {
            public static void main(final String... args)
                throws IOException
            {
                final Path a = Paths.get("a");
                final Path b = Paths.get("b");
            
                Files.copy(a, b, StandardCopyOption.REPLACE_EXISTING);
            }
        }
        /tmp/x $ ls
        Test.java
        /tmp/x $ touch a b
        /tmp/x $ chmod 0 a
        /tmp/x $ cp a b
        cp: cannot open ‘a’ for reading: Permission denied
        /tmp/x $ javac Test.java
        /tmp/x $ java Test
        Exception in thread "main" java.nio.file.AccessDeniedException: a
        at sun.nio.fs.UnixException.translateToIOException(UnixException.java:84)
        at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
        at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
        at sun.nio.fs.UnixCopyFile.copyFile(UnixCopyFile.java:230)
        at sun.nio.fs.UnixCopyFile.copy(UnixCopyFile.java:581)
        at sun.nio.fs.UnixFileSystemProvider.copy(UnixFileSystemProvider.java:253)
        at java.nio.file.Files.copy(Files.java:1274)
        at Test.main(Test.java:15)
        /tmp/x $ ls
        a Test.class Test.java
        /tmp/x $


        The rundown is pretty simple:

        * I purposefully set file "a" so that I cannot read from it;
        * I invoke the cp command to copy the contents of "a" to "b": it fails: however, "b" is left intact;
        * I now try and invoke Files.copy(), specifying that I want to replace the destination;
        * "a" fails to be read and the exception is correctly reported (AccessDeniedException);
        * BUT... b is GONE.

        Now, thanks to Michael Rasmussen (michael.rasmussen@zeroturnaround.com), I have two more pieces of information:

        * this bug DOES NOT happens on Windows;
        * it seems to be isolated to a specific section of code in the UnixFileSystemProvider and not limited to Linux. Original link was:

        http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/tip/src/java.base/unix/classes/sun/nio/fs/UnixCopyFile.java#l556

        This means that the provider only checks for the destination file's existence; however, it fails to check _beforehand_ that the source path from which to copy is readable at all.

        Note that here both the source and destination (the "victim" as I like to call it) are regular files; I have not checked the behavior in the following cases:

        * the source is a directory;
        * the destination is an empty directory (though, from the code, it seems obvious that it will be rmdir()ed; however I fail to see what exception would be thrown if the directory were not empty).


        ADDITIONAL REGRESSION INFORMATION:
        Unsure; I have only stumbled upon this bug a few hours ago; however it is pretty critical.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Just adapt the bug text to your own Unix system

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        The destination file is not deleted; or, if it is an empty directory, it is not removed
        ACTUAL -
        the destination file is removed

        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        The expected one, see bug report

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        See test case.
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        None...

              bpb Brian Burkhalter
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

                Created:
                Updated:
                Resolved: