Skip to content

Commit aab5873

Browse files
committed
SOLR-18058: Tweak "allowPath" checks to avoid NPEs
1 parent b15d107 commit aab5873

10 files changed

Lines changed: 57 additions & 7 deletions

File tree

solr/core/src/java/org/apache/solr/core/CoreContainer.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import java.io.IOException;
3939
import java.lang.invoke.MethodHandles;
4040
import java.nio.file.Path;
41-
import java.nio.file.Paths;
4241
import java.text.SimpleDateFormat;
4342
import java.util.Arrays;
4443
import java.util.Collections;
@@ -447,6 +446,7 @@ public CoreContainer(NodeConfig config, CoresLocator locator, boolean asyncSolrC
447446
SolrPaths.AllowPathBuilder allowPathBuilder = new SolrPaths.AllowPathBuilder();
448447
allowPathBuilder.addPath(cfg.getSolrHome());
449448
allowPathBuilder.addPath(cfg.getCoreRootDirectory());
449+
allowPathBuilder.addPath(cfg.getConfigSetBaseDirectory());
450450
if (cfg.getSolrDataHome() != null) {
451451
allowPathBuilder.addPath(cfg.getSolrDataHome());
452452
}
@@ -1593,6 +1593,10 @@ public SolrCore create(
15931593
log.warn(msg);
15941594
throw new SolrException(ErrorCode.CONFLICT, msg);
15951595
}
1596+
1597+
// Validate 'instancePath' prior to instantiating CoreDescriptor, as CD construction attempts
1598+
// to read properties from 'instancePath'
1599+
assertPathAllowed(instancePath);
15961600
CoreDescriptor cd =
15971601
new CoreDescriptor(
15981602
coreName, instancePath, parameters, getContainerProperties(), getZkController());
@@ -1607,8 +1611,7 @@ public SolrCore create(
16071611
}
16081612

16091613
// Validate paths are relative to known locations to avoid path traversal
1610-
assertPathAllowed(cd.getInstanceDir());
1611-
assertPathAllowed(Paths.get(cd.getDataDir()));
1614+
assertPathAllowed(Path.of(cd.getDataDir()));
16121615

16131616
boolean preExistingZkEntry = false;
16141617
try {
@@ -1679,6 +1682,8 @@ public SolrCore create(
16791682
}
16801683
}
16811684

1685+
public static final String ALLOW_PATHS_SYSPROP = "solr.allowPaths";
1686+
16821687
/**
16831688
* Checks that the given path is relative to SOLR_HOME, SOLR_DATA_HOME, coreRootDirectory or one
16841689
* of the paths specified in solr.xml's allowPaths element. Delegates to {@link

solr/core/src/java/org/apache/solr/core/FileSystemConfigSetService.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,21 @@ public class FileSystemConfigSetService extends ConfigSetService {
5656
public static final String METADATA_FILE = ".metadata.json";
5757

5858
private final Path configSetBase;
59+
// TODO currently it's not really possible to check paths against allowPaths without a
60+
// CoreContainer reference, see SOLR-18059
61+
private final CoreContainer cc;
5962

6063
public FileSystemConfigSetService(CoreContainer cc) {
6164
super(cc.getResourceLoader(), cc.getConfig().hasSchemaCache());
65+
66+
this.cc = cc;
6267
this.configSetBase = cc.getConfig().getConfigSetBaseDirectory();
6368
}
6469

6570
/** Testing purpose */
6671
protected FileSystemConfigSetService(Path configSetBase) {
6772
super(null, false);
73+
this.cc = null;
6874
this.configSetBase = configSetBase;
6975
}
7076

@@ -317,6 +323,13 @@ protected Path locateInstanceDir(CoreDescriptor cd) {
317323
String configSet = cd.getConfigSet();
318324
if (configSet == null) return cd.getInstanceDir();
319325
Path configSetDirectory = configSetBase.resolve(configSet);
326+
327+
// CoreContainer only null in testing scenarios - bit of a hack, but will go away with
328+
// SOLR-18059
329+
if (cc != null) {
330+
cc.assertPathAllowed(configSetDirectory);
331+
}
332+
320333
if (!Files.isDirectory(configSetDirectory))
321334
throw new SolrException(
322335
SolrException.ErrorCode.SERVER_ERROR,

solr/core/src/java/org/apache/solr/core/SolrPaths.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ public AllowPathBuilder addPath(String path) {
126126
* (not supported as a {@link Path} on Windows), see {@link #addPath(String)}.
127127
*/
128128
public AllowPathBuilder addPath(Path path) {
129+
if (path == null) {
130+
return this;
131+
}
132+
129133
if (paths != ALL_PATHS) {
130134
if (path.equals(ALL_PATH)) {
131135
paths = ALL_PATHS;

solr/core/src/test/org/apache/solr/response/TestPrometheusResponseWriter.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
*/
1717
package org.apache.solr.response;
1818

19+
import static org.apache.solr.core.CoreContainer.ALLOW_PATHS_SYSPROP;
20+
1921
import com.codahale.metrics.Counter;
2022
import com.codahale.metrics.Gauge;
2123
import com.codahale.metrics.Meter;
@@ -33,6 +35,7 @@
3335
import org.apache.solr.client.solrj.impl.NoOpResponseParser;
3436
import org.apache.solr.client.solrj.request.QueryRequest;
3537
import org.apache.solr.common.params.ModifiableSolrParams;
38+
import org.apache.solr.common.util.EnvUtils;
3639
import org.apache.solr.common.util.NamedList;
3740
import org.apache.solr.metrics.SolrMetricManager;
3841
import org.apache.solr.util.ExternalPaths;
@@ -53,6 +56,7 @@ public class TestPrometheusResponseWriter extends SolrTestCaseJ4 {
5356
public static void beforeClass() throws Exception {
5457
SharedMetricRegistries.clear();
5558

59+
EnvUtils.setProperty(ALLOW_PATHS_SYSPROP, ExternalPaths.SERVER_HOME);
5660
solrClientTestRule.startSolr(LuceneTestCase.createTempDir());
5761
solrClientTestRule.newCollection().withConfigSet(ExternalPaths.DEFAULT_CONFIGSET).create();
5862
var cc = solrClientTestRule.getCoreContainer();

solr/core/src/test/org/apache/solr/search/TestThinCache.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
*/
1717
package org.apache.solr.search;
1818

19+
import static org.apache.solr.core.CoreContainer.ALLOW_PATHS_SYSPROP;
20+
1921
import java.nio.file.Files;
2022
import java.nio.file.Path;
2123
import java.util.Collections;
@@ -39,6 +41,9 @@ public class TestThinCache extends SolrTestCaseJ4 {
3941
@ClassRule public static EmbeddedSolrServerTestRule solrRule = new EmbeddedSolrServerTestRule();
4042
public static final String SOLR_NODE_LEVEL_CACHE_XML =
4143
"<solr>\n"
44+
+ " <str name=\"allowPaths\">${"
45+
+ ALLOW_PATHS_SYSPROP
46+
+ ":}</str>"
4247
+ " <caches>\n"
4348
+ " <cache name='myNodeLevelCache'\n"
4449
+ " size='10'\n"
@@ -55,11 +60,12 @@ public class TestThinCache extends SolrTestCaseJ4 {
5560
@BeforeClass
5661
public static void setupSolrHome() throws Exception {
5762
Path home = createTempDir("home");
63+
Path configSet = createTempDir("configSet");
64+
System.setProperty(ALLOW_PATHS_SYSPROP, configSet.toAbsolutePath().toString());
5865
Files.writeString(home.resolve("solr.xml"), SOLR_NODE_LEVEL_CACHE_XML);
5966

6067
solrRule.startSolr(home);
6168

62-
Path configSet = createTempDir("configSet");
6369
copyMinConf(configSet.toFile());
6470
// insert a special filterCache configuration
6571
Path solrConfig = configSet.resolve("conf/solrconfig.xml");

solr/core/src/test/org/apache/solr/servlet/HideStackTraceTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
*/
1717
package org.apache.solr.servlet;
1818

19+
import static org.apache.solr.core.CoreContainer.ALLOW_PATHS_SYSPROP;
20+
1921
import java.io.IOException;
2022
import java.nio.file.Files;
2123
import java.nio.file.Path;
@@ -26,6 +28,7 @@
2628
import org.apache.solr.SolrTestCaseJ4;
2729
import org.apache.solr.SolrTestCaseJ4.SuppressSSL;
2830
import org.apache.solr.client.solrj.impl.HttpClientUtil;
31+
import org.apache.solr.common.util.EnvUtils;
2932
import org.apache.solr.handler.component.ResponseBuilder;
3033
import org.apache.solr.handler.component.SearchComponent;
3134
import org.apache.solr.util.SolrJettyTestRule;
@@ -47,6 +50,8 @@ public static void setupSolrHome() throws Exception {
4750

4851
Path configSet = createTempDir("configSet");
4952
copyMinConf(configSet.toFile());
53+
EnvUtils.setProperty(ALLOW_PATHS_SYSPROP, configSet.toAbsolutePath().toString());
54+
5055
// insert a special filterCache configuration
5156
Path solrConfig = configSet.resolve("conf/solrconfig.xml");
5257
Files.writeString(

solr/prometheus-exporter/src/test/org/apache/solr/prometheus/scraper/SolrStandaloneScraperBasicAuthTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,13 @@ public class SolrStandaloneScraperBasicAuthTest extends SolrTestCaseJ4 {
7171
public static void setupSolrHome() throws Exception {
7272
Path solrHome = LuceneTestCase.createTempDir();
7373
Files.write(solrHome.resolve("security.json"), securityJson.getBytes(StandardCharsets.UTF_8));
74-
solrRule.startSolr(solrHome);
7574

7675
Path configSet = LuceneTestCase.createTempDir();
7776
SolrStandaloneScraperTest.createConf(configSet);
77+
System.setProperty("solr.allowPaths", configSet.toAbsolutePath().toString());
78+
79+
solrRule.startSolr(solrHome);
80+
7881
solrRule
7982
.newCollection()
8083
.withConfigSet(configSet.toString())

solr/prometheus-exporter/src/test/org/apache/solr/prometheus/scraper/SolrStandaloneScraperTest.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,12 @@ public class SolrStandaloneScraperTest extends SolrTestCaseJ4 {
5454

5555
@BeforeClass
5656
public static void setupBeforeClass() throws Exception {
57-
solrRule.startSolr(LuceneTestCase.createTempDir());
58-
5957
Path configSet = LuceneTestCase.createTempDir();
6058
createConf(configSet);
59+
System.setProperty("solr.allowPaths", configSet.toAbsolutePath().toString());
60+
61+
solrRule.startSolr(LuceneTestCase.createTempDir());
62+
6163
solrRule.newCollection().withConfigSet(configSet.toString()).create();
6264

6365
PrometheusExporterSettings settings = PrometheusExporterSettings.builder().build();

solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientProxyTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
*/
1717
package org.apache.solr.client.solrj.impl;
1818

19+
import static org.apache.solr.core.CoreContainer.ALLOW_PATHS_SYSPROP;
20+
1921
import com.carrotsearch.randomizedtesting.RandomizedTest;
2022
import java.util.Arrays;
2123
import java.util.Objects;
@@ -26,6 +28,7 @@
2628
import org.apache.solr.client.solrj.SolrQuery;
2729
import org.apache.solr.client.solrj.cloud.SocketProxy;
2830
import org.apache.solr.common.SolrInputDocument;
31+
import org.apache.solr.common.util.EnvUtils;
2932
import org.apache.solr.embedded.JettyConfig;
3033
import org.apache.solr.util.ExternalPaths;
3134
import org.apache.solr.util.SolrJettyTestRule;
@@ -44,6 +47,8 @@ public class Http2SolrClientProxyTest extends SolrTestCaseJ4 {
4447
public static void beforeTest() throws Exception {
4548
RandomizedTest.assumeFalse(sslConfig.isSSLMode());
4649

50+
EnvUtils.setProperty(
51+
ALLOW_PATHS_SYSPROP, ExternalPaths.SERVER_HOME); // Needed for configset location
4752
solrClientTestRule.enableProxy();
4853
solrClientTestRule.startSolr(createTempDir(), new Properties(), JettyConfig.builder().build());
4954
// Actually only need extremely minimal configSet but just use the default

solr/test-framework/src/java/org/apache/solr/util/EmbeddedSolrServerTestRule.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919
import java.nio.file.Files;
2020
import java.nio.file.Path;
2121
import java.util.Properties;
22+
import java.util.Set;
2223
import org.apache.lucene.tests.util.LuceneTestCase;
2324
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
2425
import org.apache.solr.core.CoreContainer;
2526
import org.apache.solr.core.NodeConfig;
27+
import org.apache.solr.core.SolrPaths;
2628
import org.apache.solr.core.SolrXmlConfig;
2729
import org.apache.solr.update.UpdateShardHandlerConfig;
2830

@@ -87,6 +89,7 @@ public NodeConfig.NodeConfigBuilder newNodeConfigBuilder(Path solrHome) {
8789

8890
return new NodeConfig.NodeConfigBuilder("testNode", solrHome)
8991
.setUpdateShardHandlerConfig(UpdateShardHandlerConfig.TEST_DEFAULT)
92+
.setAllowPaths(Set.of(SolrPaths.ALL_PATH))
9093
.setCoreRootDirectory(LuceneTestCase.createTempDir("cores").toString());
9194
}
9295

0 commit comments

Comments
 (0)