summaryrefslogtreecommitdiff
path: root/hadoop-common-project
diff options
context:
space:
mode:
authorKihwal Lee <kihwal@apache.org>2018-05-29 14:30:29 -0500
committerKihwal Lee <kihwal@apache.org>2018-05-29 14:30:29 -0500
commit65e55097da2bb3f2fbdf9ba1946da25fe58bec98 (patch)
tree2c4a0c80d60a53fb5e829310ed86531f90689d10 /hadoop-common-project
parentd5708bbcdc86a18cb43f2243629d69dcdae702de (diff)
Additional check when unpacking archives. Contributed by Wilfred Spiegelenburg.
Diffstat (limited to 'hadoop-common-project')
-rw-r--r--hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/RunJar.java5
-rw-r--r--hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestRunJar.java36
2 files changed, 41 insertions, 0 deletions
diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/RunJar.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/RunJar.java
index 19b51ad692..678e4593df 100644
--- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/RunJar.java
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/RunJar.java
@@ -109,6 +109,7 @@ public class RunJar {
throws IOException {
try (JarFile jar = new JarFile(jarFile)) {
int numOfFailedLastModifiedSet = 0;
+ String targetDirPath = toDir.getCanonicalPath() + File.separator;
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
final JarEntry entry = entries.nextElement();
@@ -117,6 +118,10 @@ public class RunJar {
try (InputStream in = jar.getInputStream(entry)) {
File file = new File(toDir, entry.getName());
ensureDirectory(file.getParentFile());
+ if (!file.getCanonicalPath().startsWith(targetDirPath)) {
+ throw new IOException("expanding " + entry.getName()
+ + " would create file outside of " + toDir);
+ }
try (OutputStream out = new FileOutputStream(file)) {
IOUtils.copyBytes(in, out, BUFFER_SIZE);
}
diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestRunJar.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestRunJar.java
index 7b61b32d53..cb2cfa89c1 100644
--- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestRunJar.java
+++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestRunJar.java
@@ -20,12 +20,15 @@ package org.apache.hadoop.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
@@ -165,4 +168,37 @@ public class TestRunJar {
runJar.run(args);
// it should not throw an exception
}
+
+ @Test
+ public void testUnJar2() throws IOException {
+ // make a simple zip
+ File jarFile = new File(TEST_ROOT_DIR, TEST_JAR_NAME);
+ JarOutputStream jstream =
+ new JarOutputStream(new FileOutputStream(jarFile));
+ JarEntry je = new JarEntry("META-INF/MANIFEST.MF");
+ byte[] data = "Manifest-Version: 1.0\nCreated-By: 1.8.0_1 (Manual)"
+ .getBytes(StandardCharsets.UTF_8);
+ je.setSize(data.length);
+ jstream.putNextEntry(je);
+ jstream.write(data);
+ jstream.closeEntry();
+ je = new JarEntry("../outside.path");
+ data = "any data here".getBytes(StandardCharsets.UTF_8);
+ je.setSize(data.length);
+ jstream.putNextEntry(je);
+ jstream.write(data);
+ jstream.closeEntry();
+ jstream.close();
+
+ File unjarDir = getUnjarDir("unjar-path");
+
+ // Unjar everything
+ try {
+ RunJar.unJar(jarFile, unjarDir);
+ fail("unJar should throw IOException.");
+ } catch (IOException e) {
+ GenericTestUtils.assertExceptionContains(
+ "would create file outside of", e);
+ }
+ }
} \ No newline at end of file