Browse Source
The default threads from the ForkJoinPool run without any privileges when a SecurityManager is installed, leading to SecurityExceptions when trying to create the probe file even if the application otherwise has write privileges in the directory. Use a dedicated ThreadPoolExecutor using daemon threads instead. Bug: 551690 Change-Id: Id5376f09f0d7da5ceea367e1f0dfc70f823d62d3 Signed-off-by: Alex Jitianu <alex_jitianu@sync.ro> Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>stable-5.8
Alex Jitianu
5 years ago
committed by
Matthias Sohn
2 changed files with 169 additions and 4 deletions
@ -0,0 +1,132 @@
|
||||
/* |
||||
* Copyright (c) 2019 Alex Jitianu <alex_jitianu@sync.ro> and others |
||||
* |
||||
* This program and the accompanying materials are made available under the |
||||
* terms of the Eclipse Distribution License v. 1.0 which is available at |
||||
* https://www.eclipse.org/org/documents/edl-v10.php.
|
||||
* |
||||
* SPDX-License-Identifier: BSD-3-Clause |
||||
*/ |
||||
package org.eclipse.jgit.api; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
import static org.junit.Assert.assertFalse; |
||||
import static org.junit.Assert.assertTrue; |
||||
|
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
import java.io.StringWriter; |
||||
import java.nio.file.Files; |
||||
import java.nio.file.Path; |
||||
import java.security.Policy; |
||||
import java.util.Collections; |
||||
|
||||
import org.apache.log4j.Logger; |
||||
import org.apache.log4j.PatternLayout; |
||||
import org.apache.log4j.WriterAppender; |
||||
import org.eclipse.jgit.junit.RepositoryTestCase; |
||||
import org.eclipse.jgit.util.FileUtils; |
||||
import org.junit.After; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* Tests that using a SecurityManager does not result in errors logged. |
||||
*/ |
||||
public class SecurityManagerMissingPermissionsTest extends RepositoryTestCase { |
||||
|
||||
/** |
||||
* Collects all logging sent to the logging system. |
||||
*/ |
||||
private final StringWriter errorOutputWriter = new StringWriter(); |
||||
|
||||
/** |
||||
* Appender to intercept all logging sent to the logging system. |
||||
*/ |
||||
private WriterAppender appender; |
||||
|
||||
private SecurityManager originalSecurityManager; |
||||
|
||||
@Override |
||||
@Before |
||||
public void setUp() throws Exception { |
||||
originalSecurityManager = System.getSecurityManager(); |
||||
|
||||
appender = new WriterAppender( |
||||
new PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN), |
||||
errorOutputWriter); |
||||
|
||||
Logger.getRootLogger().addAppender(appender); |
||||
|
||||
refreshPolicyAllPermission(Policy.getPolicy()); |
||||
System.setSecurityManager(new SecurityManager()); |
||||
super.setUp(); |
||||
} |
||||
|
||||
/** |
||||
* If a SecurityManager is active a lot of {@link java.io.FilePermission} |
||||
* errors are thrown and logged while initializing a repository. |
||||
* |
||||
* @throws Exception |
||||
*/ |
||||
@Test |
||||
public void testCreateNewRepos_MissingPermissions() throws Exception { |
||||
File wcTree = new File(getTemporaryDirectory(), |
||||
"CreateNewRepositoryTest_testCreateNewRepos"); |
||||
|
||||
File marker = new File(getTemporaryDirectory(), "marker"); |
||||
Files.write(marker.toPath(), Collections.singletonList("Can write")); |
||||
assertTrue("Can write in test directory", marker.isFile()); |
||||
FileUtils.delete(marker); |
||||
assertFalse("Can delete in test direcory", marker.exists()); |
||||
|
||||
Git git = Git.init().setBare(false) |
||||
.setDirectory(new File(wcTree.getAbsolutePath())).call(); |
||||
|
||||
addRepoToClose(git.getRepository()); |
||||
|
||||
assertEquals("", errorOutputWriter.toString()); |
||||
} |
||||
|
||||
@Override |
||||
@After |
||||
public void tearDown() throws Exception { |
||||
System.setSecurityManager(originalSecurityManager); |
||||
Logger.getRootLogger().removeAppender(appender); |
||||
super.tearDown(); |
||||
} |
||||
|
||||
/** |
||||
* Refresh the Java Security Policy. |
||||
* |
||||
* @param policy |
||||
* the policy object |
||||
* |
||||
* @throws IOException |
||||
* if the temporary file that contains the policy could not be |
||||
* created |
||||
*/ |
||||
private static void refreshPolicyAllPermission(Policy policy) |
||||
throws IOException { |
||||
// Starting with an all permissions policy.
|
||||
String policyString = "grant { permission java.security.AllPermission; };"; |
||||
|
||||
// Do not use TemporaryFilesFactory, it will create a dependency cycle
|
||||
Path policyFile = Files.createTempFile("testpolicy", ".txt"); |
||||
|
||||
try { |
||||
Files.write(policyFile, Collections.singletonList(policyString)); |
||||
System.setProperty("java.security.policy", |
||||
policyFile.toUri().toURL().toString()); |
||||
policy.refresh(); |
||||
} finally { |
||||
try { |
||||
Files.delete(policyFile); |
||||
} catch (IOException e) { |
||||
// Do not log; the test tests for no logging having occurred
|
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue