From b9d2926df44a47116d2b0f56a16fc1b39e466dc2 Mon Sep 17 00:00:00 2001 From: Nail Samatov Date: Thu, 15 Aug 2019 20:15:40 +0300 Subject: Fix error occurring when SecurityManager is enabled It's expected that jgit should work without native git installation. In such case Security Manager can be configured to deny access to the files outside of git repository. JGit tries to find cygwin installation. If Security manager restricts access to some folders in PATH, it should be considered that those folders are absent for jgit. Also JGit tries to detect if symbolic links are supported by OS. If security manager forbids creation of symlinks, it should be assumed that symlinks aren't supported. Bug: 550115 Change-Id: Ic4b243cada604bc1090db6cc1cfd74f0fa324b98 Signed-off-by: Nail Samatov --- .../src/org/eclipse/jgit/internal/JGitText.java | 3 + org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java | 70 ++++++++++++++++++---- .../src/org/eclipse/jgit/util/FS_POSIX.java | 6 -- .../src/org/eclipse/jgit/util/FS_Win32.java | 33 ---------- 4 files changed, 61 insertions(+), 51 deletions(-) (limited to 'org.eclipse.jgit/src') diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java index 649f77724e..b80b7498b1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java @@ -648,6 +648,8 @@ public class JGitText extends TranslationBundle { /***/ public String readerIsRequired; /***/ public String readingObjectsFromLocalRepositoryFailed; /***/ public String readLastModifiedFailed; + /***/ public String readPipeIsNotAllowed; + /***/ public String readPipeIsNotAllowedRequiredPermission; /***/ public String readTimedOut; /***/ public String receivePackObjectTooLarge1; /***/ public String receivePackObjectTooLarge2; @@ -723,6 +725,7 @@ public class JGitText extends TranslationBundle { /***/ public String similarityScoreMustBeWithinBounds; /***/ public String sizeExceeds2GB; /***/ public String skipMustBeNonNegative; + /***/ public String skipNotAccessiblePath; /***/ public String smartHTTPPushDisabled; /***/ public String sourceDestinationMustMatch; /***/ public String sourceIsNotAWildcard; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java index 90305013f5..29519298c4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java @@ -64,6 +64,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.FileTime; +import java.security.AccessControlException; import java.security.AccessController; import java.security.PrivilegedAction; import java.text.MessageFormat; @@ -122,6 +123,8 @@ public abstract class FS { */ protected static final Entry[] NO_ENTRIES = {}; + private volatile Boolean supportSymlinks; + /** * This class creates FS instances. It will be overridden by a Java7 variant * if such can be detected in {@link #detect(Boolean)}. @@ -276,15 +279,19 @@ public abstract class FS { * @return FileStoreAttributes for the given path. */ public static FileStoreAttributes get(Path path) { - path = path.toAbsolutePath(); - Path dir = Files.isDirectory(path) ? path : path.getParent(); - FileStoreAttributes cached = attrCacheByPath.get(dir); - if (cached != null) { - return cached; + try { + path = path.toAbsolutePath(); + Path dir = Files.isDirectory(path) ? path : path.getParent(); + FileStoreAttributes cached = attrCacheByPath.get(dir); + if (cached != null) { + return cached; + } + FileStoreAttributes attrs = getFileStoreAttributes(dir); + attrCacheByPath.put(dir, attrs); + return attrs; + } catch (SecurityException e) { + return FALLBACK_FILESTORE_ATTRIBUTES; } - FileStoreAttributes attrs = getFileStoreAttributes(dir); - attrCacheByPath.put(dir, attrs); - return attrs; } private static FileStoreAttributes getFileStoreAttributes(Path dir) { @@ -813,7 +820,32 @@ public abstract class FS { * @since 3.0 */ public boolean supportsSymlinks() { - return false; + if (supportSymlinks == null) { + detectSymlinkSupport(); + } + return Boolean.TRUE.equals(supportSymlinks); + } + + private void detectSymlinkSupport() { + File tempFile = null; + try { + tempFile = File.createTempFile("tempsymlinktarget", ""); //$NON-NLS-1$ //$NON-NLS-2$ + File linkName = new File(tempFile.getParentFile(), "tempsymlink"); //$NON-NLS-1$ + createSymLink(linkName, tempFile.getPath()); + supportSymlinks = Boolean.TRUE; + linkName.delete(); + } catch (IOException | UnsupportedOperationException | SecurityException + | InternalError e) { + supportSymlinks = Boolean.FALSE; + } finally { + if (tempFile != null) { + try { + FileUtils.delete(tempFile); + } catch (IOException e) { + throw new RuntimeException(e); // panic + } + } + } } /** @@ -1067,9 +1099,16 @@ public abstract class FS { for (String p : path.split(File.pathSeparator)) { for (String command : lookFor) { - final File e = new File(p, command); - if (e.isFile()) - return e.getAbsoluteFile(); + final File file = new File(p, command); + try { + if (file.isFile()) { + return file.getAbsoluteFile(); + } + } catch (SecurityException e) { + LOG.warn(MessageFormat.format( + JGitText.get().skipNotAccessiblePath, + file.getPath())); + } } } return null; @@ -1172,6 +1211,13 @@ public abstract class FS { } } catch (IOException e) { LOG.error("Caught exception in FS.readPipe()", e); //$NON-NLS-1$ + } catch (AccessControlException e) { + LOG.warn(MessageFormat.format( + JGitText.get().readPipeIsNotAllowedRequiredPermission, + command, dir, e.getPermission())); + } catch (SecurityException e) { + LOG.warn(MessageFormat.format(JGitText.get().readPipeIsNotAllowed, + command, dir)); } if (debug) { LOG.debug("readpipe returns null"); //$NON-NLS-1$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java index a485389a9a..6a1eef2d66 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java @@ -285,12 +285,6 @@ public class FS_POSIX extends FS { return false; } - /** {@inheritDoc} */ - @Override - public boolean supportsSymlinks() { - return true; - } - /** {@inheritDoc} */ @Override public void setHidden(File path, boolean hidden) throws IOException { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java index 7fe80bb21a..1e64a38bb1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java @@ -74,8 +74,6 @@ import org.slf4j.LoggerFactory; public class FS_Win32 extends FS { private final static Logger LOG = LoggerFactory.getLogger(FS_Win32.class); - private volatile Boolean supportSymlinks; - /** * Constructor */ @@ -237,37 +235,6 @@ public class FS_Win32 extends FS { return proc; } - /** {@inheritDoc} */ - @Override - public boolean supportsSymlinks() { - if (supportSymlinks == null) { - detectSymlinkSupport(); - } - return Boolean.TRUE.equals(supportSymlinks); - } - - private void detectSymlinkSupport() { - File tempFile = null; - try { - tempFile = File.createTempFile("tempsymlinktarget", ""); //$NON-NLS-1$ //$NON-NLS-2$ - File linkName = new File(tempFile.getParentFile(), "tempsymlink"); //$NON-NLS-1$ - createSymLink(linkName, tempFile.getPath()); - supportSymlinks = Boolean.TRUE; - linkName.delete(); - } catch (IOException | UnsupportedOperationException - | InternalError e) { - supportSymlinks = Boolean.FALSE; - } finally { - if (tempFile != null) { - try { - FileUtils.delete(tempFile); - } catch (IOException e) { - throw new RuntimeException(e); // panic - } - } - } - } - /** {@inheritDoc} */ @Override public Attributes getAttributes(File path) { -- cgit v1.2.3