Skip to content

Commit

Permalink
[JENKINS-56114] Correct behavior for Windows Server 2016 with Docker (j…
Browse files Browse the repository at this point in the history
…enkinsci#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
  • Loading branch information
Wadeck authored and anish-dangi-wdc committed Mar 12, 2019
1 parent ee0a1e2 commit 8b075cd
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
28 changes: 25 additions & 3 deletions core/src/main/java/hudson/FilePath.java
Expand Up @@ -132,6 +132,7 @@
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;
Expand Down Expand Up @@ -3262,9 +3263,14 @@ public Boolean invoke(@Nonnull File parentFile, @Nonnull VirtualChannel channel)
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;
}

Expand Down Expand Up @@ -3296,10 +3302,11 @@ public Boolean invoke(@Nonnull File parentFile, @Nonnull VirtualChannel channel)
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
Expand All @@ -3322,6 +3329,21 @@ public Boolean invoke(@Nonnull File parentFile, @Nonnull VirtualChannel channel)
}
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);
Expand Down
6 changes: 5 additions & 1 deletion core/src/main/java/jenkins/util/VirtualFile.java
Expand Up @@ -544,7 +544,11 @@ public Collection<String> list(String includes, String excludes, boolean useDefa

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) {
Expand Down

0 comments on commit 8b075cd

Please sign in to comment.