[JENKINS-56114] Correct behavior for Windows Server 2016 with Docker (#3914)

* [JENKINS-56114] Correct behavior for Windows Server 2016 with Docker
- also adjust the symlink escape hatch

* Correct missing space + retrigger build

* Improve performance with a check on the logger level

* Run the specific code only under Windows

* Rename the method as it's used only for Windows

(cherry picked from commit 5562b2fec6)
This commit is contained in:
Wadeck Follonier authored and Oliver Gondža committed 2019-03-18 09:35:48 +01:00
1 parent aad0d563d0
commit ff52beb5e2
2 files changed
+30 -4

No files matched your search

+25 -3
View File
@@ -132,6 +132,7 @@ import org.jenkinsci.remoting.RoleChecker;
import org.jenkinsci.remoting.RoleSensitive;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.Function;
import org.kohsuke.stapler.Stapler;
import static hudson.FilePath.TarCompression.GZIP;
@@ -3264,9 +3265,14 @@ public final class FilePath implements Serializable {
Path parentAbsolutePath = Util.fileToPath(parentFile.getAbsoluteFile());
Path parentRealPath;
try {
parentRealPath = parentAbsolutePath.toRealPath();
if (Functions.isWindows()) {
parentRealPath = this.windowsToRealPath(parentAbsolutePath);
} else {
parentRealPath = parentAbsolutePath.toRealPath();
}
}
catch(NoSuchFileException e) {
catch (NoSuchFileException e) {
LOGGER.log(Level.FINE, String.format("Cannot find the real path to the parentFile: %s", parentAbsolutePath), e);
return false;
}
@@ -3298,10 +3304,11 @@ public final class FilePath implements Serializable {
try{
Path child = currentFileAbsolutePath.toRealPath();
if (!child.startsWith(parentRealPath)) {
LOGGER.log(Level.FINE, "Child [{0}] does not start with parent [{1}] => not descendant", new Object[]{ child, parentRealPath });
return false;
}
} catch (NoSuchFileException e) {
// nonexistent file
// nonexistent file / Windows Server 2016 + MSFT docker
// in case this folder / file will be copied somewhere else,
// it becomes the responsibility of that system to check the isDescendant with the existing links
// we are not taking the parentRealPath to avoid possible problem
@@ -3324,6 +3331,21 @@ public final class FilePath implements Serializable {
}
return current;
}
private @Nonnull Path windowsToRealPath(@Nonnull Path path) throws IOException {
try {
return path.toRealPath();
}
catch (IOException e) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, String.format("relaxedToRealPath cannot use the regular toRealPath on %s, trying with toRealPath(LinkOption.NOFOLLOW_LINKS)", path), e);
}
}
// that's required for specific environment like Windows Server 2016, running MSFT docker
// where the root is a <SYMLINKD>
return path.toRealPath(LinkOption.NOFOLLOW_LINKS);
}
}
private static final SoloFilePathFilter UNRESTRICTED = SoloFilePathFilter.wrap(FilePathFilter.UNRESTRICTED);
@@ -546,7 +546,11 @@ public abstract class VirtualFile implements Comparable<VirtualFile>, Serializab
private boolean isIllegalSymlink() {
try {
return !this.isDescendant("");
String myPath = f.toPath().toRealPath().toString();
String rootPath = root.toPath().toRealPath().toString();
if (!myPath.equals(rootPath) && !myPath.startsWith(rootPath + File.separatorChar)) {
return true;
}
} catch (IOException x) {
Logger.getLogger(VirtualFile.class.getName()).log(Level.FINE, "could not determine symlink status of " + f, x);
} catch (InvalidPathException x2) {