HADOOP-9043. Disallow in winutils creating symlinks with forwards slashes. Contributed by Chris Nauroth.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1478577 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
6cec97be4b
commit
1c762c01c4
|
@ -540,6 +540,9 @@ Trunk (Unreleased)
|
|||
HADOOP-9532. HADOOP_CLIENT_OPTS is appended twice by Windows cmd scripts.
|
||||
(Chris Nauroth via suresh)
|
||||
|
||||
HADOOP-9043. Disallow in winutils creating symlinks with forwards slashes.
|
||||
(Chris Nauroth via suresh)
|
||||
|
||||
Release 2.0.5-beta - UNRELEASED
|
||||
|
||||
INCOMPATIBLE CHANGES
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package org.apache.hadoop.fs.local;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
@ -90,8 +91,8 @@ public class RawLocalFs extends DelegateToFileSystem {
|
|||
// NB: Use createSymbolicLink in java.nio.file.Path once available
|
||||
try {
|
||||
Shell.execCommand(Shell.getSymlinkCommand(
|
||||
getPathWithoutSchemeAndAuthority(target),
|
||||
getPathWithoutSchemeAndAuthority(link)));
|
||||
getPathWithoutSchemeAndAuthority(target).getPath(),
|
||||
getPathWithoutSchemeAndAuthority(link).getPath()));
|
||||
} catch (IOException x) {
|
||||
throw new IOException("Unable to create symlink: "+x.getMessage());
|
||||
}
|
||||
|
@ -175,12 +176,12 @@ public class RawLocalFs extends DelegateToFileSystem {
|
|||
throw new AssertionError();
|
||||
}
|
||||
|
||||
private static String getPathWithoutSchemeAndAuthority(Path path) {
|
||||
// This code depends on Path.toString() to remove the leading slash before
|
||||
// the drive specification on Windows.
|
||||
private static File getPathWithoutSchemeAndAuthority(Path path) {
|
||||
Path newPath = path.isUriPathAbsolute() ?
|
||||
new Path(null, null, path.toUri().getPath()) :
|
||||
path;
|
||||
return newPath.toString();
|
||||
|
||||
// Path.toString() removes leading slash before drive spec on Windows.
|
||||
return new File(newPath.toString());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,17 @@ int Symlink(__in int argc, __in_ecount(argc) wchar_t *argv[])
|
|||
goto SymlinkEnd;
|
||||
}
|
||||
|
||||
if (wcschr(longLinkName, L'/') != NULL || wcschr(longFileName, L'/') != NULL)
|
||||
{
|
||||
// Reject forward-slash separated paths as they result in unusable symlinks.
|
||||
//
|
||||
fwprintf(stderr,
|
||||
L"Rejecting forward-slash separated path which would result in an "
|
||||
L"unusable symlink: link = %s, target = %s\n", longLinkName, longFileName);
|
||||
ret = FAILURE;
|
||||
goto SymlinkEnd;
|
||||
}
|
||||
|
||||
// Check if the the process's access token has the privilege to create
|
||||
// symbolic links. Without this step, the call to CreateSymbolicLink() from
|
||||
// users have the privilege to create symbolic links will still succeed.
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.apache.hadoop.fs.Path;
|
|||
import org.apache.hadoop.fs.FileUtil;
|
||||
import static org.apache.hadoop.fs.FileContextTestHelper.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
import org.junit.Test;
|
||||
import org.junit.Before;
|
||||
|
||||
|
@ -66,6 +67,43 @@ public class TestLocalFSFileContextSymlink extends FileContextSymlinkBaseTest {
|
|||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testCreateDanglingLink() throws IOException {
|
||||
// Dangling symlinks are not supported on Windows local file system.
|
||||
assumeTrue(!Path.WINDOWS);
|
||||
super.testCreateDanglingLink();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testCreateFileViaDanglingLinkParent() throws IOException {
|
||||
assumeTrue(!Path.WINDOWS);
|
||||
super.testCreateFileViaDanglingLinkParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testOpenResolvesLinks() throws IOException {
|
||||
assumeTrue(!Path.WINDOWS);
|
||||
super.testOpenResolvesLinks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testRecursiveLinks() throws IOException {
|
||||
assumeTrue(!Path.WINDOWS);
|
||||
super.testRecursiveLinks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testRenameDirToDanglingSymlink() throws IOException {
|
||||
assumeTrue(!Path.WINDOWS);
|
||||
super.testRenameDirToDanglingSymlink();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testStatDanglingLink() throws IOException {
|
||||
assumeTrue(!Path.WINDOWS);
|
||||
super.testStatDanglingLink();
|
||||
}
|
||||
|
||||
@Test
|
||||
/** lstat a non-existant file using a partially qualified path */
|
||||
public void testDanglingLinkFilePartQual() throws IOException {
|
||||
|
@ -87,6 +125,7 @@ public class TestLocalFSFileContextSymlink extends FileContextSymlinkBaseTest {
|
|||
@Test
|
||||
/** Stat and lstat a dangling link */
|
||||
public void testDanglingLink() throws IOException {
|
||||
assumeTrue(!Path.WINDOWS);
|
||||
Path fileAbs = new Path(testBaseDir1()+"/file");
|
||||
Path fileQual = new Path(testURI().toString(), fileAbs);
|
||||
Path link = new Path(testBaseDir1()+"/linkToFile");
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.apache.hadoop.util;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
@ -44,6 +45,8 @@ public class TestWinUtils {
|
|||
|
||||
@Before
|
||||
public void setUp() {
|
||||
// Not supported on non-Windows platforms
|
||||
assumeTrue(Shell.WINDOWS);
|
||||
TEST_DIR.mkdirs();
|
||||
}
|
||||
|
||||
|
@ -70,11 +73,6 @@ public class TestWinUtils {
|
|||
|
||||
@Test (timeout = 30000)
|
||||
public void testLs() throws IOException {
|
||||
if (!Shell.WINDOWS) {
|
||||
// Not supported on non-Windows platforms
|
||||
return;
|
||||
}
|
||||
|
||||
final String content = "6bytes";
|
||||
final int contentSize = content.length();
|
||||
File testFile = new File(TEST_DIR, "file1");
|
||||
|
@ -104,11 +102,6 @@ public class TestWinUtils {
|
|||
|
||||
@Test (timeout = 30000)
|
||||
public void testGroups() throws IOException {
|
||||
if (!Shell.WINDOWS) {
|
||||
// Not supported on non-Windows platforms
|
||||
return;
|
||||
}
|
||||
|
||||
String currentUser = System.getProperty("user.name");
|
||||
|
||||
// Verify that groups command returns information about the current user
|
||||
|
@ -229,11 +222,6 @@ public class TestWinUtils {
|
|||
|
||||
@Test (timeout = 30000)
|
||||
public void testBasicChmod() throws IOException {
|
||||
if (!Shell.WINDOWS) {
|
||||
// Not supported on non-Windows platforms
|
||||
return;
|
||||
}
|
||||
|
||||
// - Create a file.
|
||||
// - Change mode to 377 so owner does not have read permission.
|
||||
// - Verify the owner truly does not have the permissions to read.
|
||||
|
@ -285,11 +273,6 @@ public class TestWinUtils {
|
|||
|
||||
@Test (timeout = 30000)
|
||||
public void testChmod() throws IOException {
|
||||
if (!Shell.WINDOWS) {
|
||||
// Not supported on non-Windows platforms
|
||||
return;
|
||||
}
|
||||
|
||||
testChmodInternal("7", "-------rwx");
|
||||
testChmodInternal("70", "----rwx---");
|
||||
testChmodInternal("u-x,g+r,o=g", "-rw-r--r--");
|
||||
|
@ -322,11 +305,6 @@ public class TestWinUtils {
|
|||
|
||||
@Test (timeout = 30000)
|
||||
public void testChown() throws IOException {
|
||||
if (!Shell.WINDOWS) {
|
||||
// Not supported on non-Windows platforms
|
||||
return;
|
||||
}
|
||||
|
||||
File a = new File(TEST_DIR, "a");
|
||||
assertTrue(a.createNewFile());
|
||||
String username = System.getProperty("user.name");
|
||||
|
@ -349,4 +327,36 @@ public class TestWinUtils {
|
|||
assertTrue(a.delete());
|
||||
assertFalse(a.exists());
|
||||
}
|
||||
|
||||
@Test (timeout = 30000)
|
||||
public void testSymlinkRejectsForwardSlashesInLink() throws IOException {
|
||||
File newFile = new File(TEST_DIR, "file");
|
||||
assertTrue(newFile.createNewFile());
|
||||
String target = newFile.getPath();
|
||||
String link = new File(TEST_DIR, "link").getPath().replaceAll("\\\\", "/");
|
||||
try {
|
||||
Shell.execCommand(Shell.WINUTILS, "symlink", link, target);
|
||||
fail(String.format("did not receive expected failure creating symlink "
|
||||
+ "with forward slashes in link: link = %s, target = %s", link, target));
|
||||
} catch (IOException e) {
|
||||
LOG.info(
|
||||
"Expected: Failed to create symlink with forward slashes in target");
|
||||
}
|
||||
}
|
||||
|
||||
@Test (timeout = 30000)
|
||||
public void testSymlinkRejectsForwardSlashesInTarget() throws IOException {
|
||||
File newFile = new File(TEST_DIR, "file");
|
||||
assertTrue(newFile.createNewFile());
|
||||
String target = newFile.getPath().replaceAll("\\\\", "/");
|
||||
String link = new File(TEST_DIR, "link").getPath();
|
||||
try {
|
||||
Shell.execCommand(Shell.WINUTILS, "symlink", link, target);
|
||||
fail(String.format("did not receive expected failure creating symlink "
|
||||
+ "with forward slashes in target: link = %s, target = %s", link, target));
|
||||
} catch (IOException e) {
|
||||
LOG.info(
|
||||
"Expected: Failed to create symlink with forward slashes in target");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue