diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/CommandWithDestination.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/CommandWithDestination.java index 2fdde3fcdfb..4b8d3bc11ac 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/CommandWithDestination.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/CommandWithDestination.java @@ -238,7 +238,13 @@ abstract class CommandWithDestination extends FsCommand { e.setTargetPath(dstPath.toString()); throw e; } - if (dstPath.startsWith(srcPath+Path.SEPARATOR)) { + // When a path is normalized, all trailing slashes are removed + // except for the root + if(!srcPath.endsWith(Path.SEPARATOR)) { + srcPath += Path.SEPARATOR; + } + + if(dstPath.startsWith(srcPath)) { PathIOException e = new PathIOException(src.toString(), "is a subdirectory of itself"); e.setTargetPath(target.toString()); diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index 840f1ce1d31..2a5996662b0 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -1062,6 +1062,9 @@ Release 2.8.0 - UNRELEASED HDFS-9076. Log full path instead of inodeId in DFSClient #closeAllFilesBeingWritten() (Surendra Singh Lilhore via vinayakumarb) + HDFS-9123. Copying from the root to a subdirectory should be forbidden. + (Wei-Chiu Chuang via Yongjun Zhang) + Release 2.7.2 - UNRELEASED INCOMPATIBLE CHANGES diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSShell.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSShell.java index 624b8808a5b..e5a25a43d14 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSShell.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSShell.java @@ -1331,6 +1331,19 @@ public class TestDFSShell { e.getLocalizedMessage()); } assertEquals(0, val); + + // this should fail + args1[0] = "-cp"; + args1[1] = "/"; + args1[2] = "/test"; + val = 0; + try { + val = shell.run(args1); + } catch (Exception e) { + System.err.println("Exception raised from DFSShell.run " + + e.getLocalizedMessage()); + } + assertEquals(1, val); } // Verify -test -f negative case (missing file)