Skip to content

Commit 1174387

Browse files
authored
Merge branch 'main' into es-11331-streams-params-restriction
2 parents a98f1ea + 61382f3 commit 1174387

File tree

76 files changed

+1253
-559
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1253
-559
lines changed

.buildkite/pipelines/periodic.template.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ steps:
246246
image: family/elasticsearch-ubuntu-2404
247247
machineType: n2-standard-8
248248
buildDirectory: /dev/shm/bk
249-
if: build.branch =~ /^(main|\d+\.\d+|\d+\.x)$/
249+
if: build.branch =~ /^(main|\d+\.\d+|\d+\.x)$$/
250250
- label: check-branch-consistency
251251
command: .ci/scripts/run-gradle.sh branchConsistency
252252
timeout_in_minutes: 15

.buildkite/pipelines/periodic.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ steps:
684684
image: family/elasticsearch-ubuntu-2404
685685
machineType: n2-standard-8
686686
buildDirectory: /dev/shm/bk
687-
if: build.branch =~ /^(main|\d+\.\d+|\d+\.x)$/
687+
if: build.branch =~ /^(main|\d+\.\d+|\d+\.x)$$/
688688
- label: check-branch-consistency
689689
command: .ci/scripts/run-gradle.sh branchConsistency
690690
timeout_in_minutes: 15

build-tools-internal/src/main/resources/forbidden/jdk-signatures.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,29 @@ java.util.Collections#shuffle(java.util.List) @ Use java.util.Collections#shuffl
102102

103103
@defaultMessage Avoid creating FilePermission objects directly, but use FilePermissionUtils instead
104104
java.io.FilePermission#<init>(java.lang.String,java.lang.String)
105+
106+
@defaultMessage DocumentBuilderFactory should not be used directly. Use XmlUtils#getHardenedDocumentBuilder(java.lang.String[]) instead.
107+
javax.xml.parsers.DocumentBuilderFactory#newInstance()
108+
javax.xml.parsers.DocumentBuilderFactory#newInstance(java.lang.String, java.lang.ClassLoader)
109+
javax.xml.parsers.DocumentBuilderFactory#newDefaultNSInstance()
110+
javax.xml.parsers.DocumentBuilderFactory#newNSInstance()
111+
javax.xml.parsers.DocumentBuilderFactory#newNSInstance(java.lang.String, java.lang.ClassLoader)
112+
113+
@defaultMessage TransformerFactory should not be used directly. Use XmlUtils#getHardenedXMLTransformer() instead.
114+
javax.xml.transform.TransformerFactory#newInstance()
115+
javax.xml.transform.TransformerFactory#newInstance(java.lang.String, java.lang.ClassLoader)
116+
117+
@defaultMessage SAXParserFactory should not be used directly. Use XmlUtils#getHardenedSaxParser() instead
118+
javax.xml.parsers.SAXParserFactory#newInstance()
119+
javax.xml.parsers.SAXParserFactory#newInstance(java.lang.String, java.lang.ClassLoader)
120+
javax.xml.parsers.SAXParserFactory#newDefaultNSInstance()
121+
javax.xml.parsers.SAXParserFactory#newNSInstance()
122+
javax.xml.parsers.SAXParserFactory#newNSInstance(java.lang.String, java.lang.ClassLoader)
123+
124+
@defaultMessage SchemaValidator should not be used directly. Use XmlUtils#getHardenedSchemaValidator() instead
125+
javax.xml.validation.SchemaFactory#newDefaultInstance()
126+
javax.xml.validation.SchemaFactory#newInstance(java.lang.String)
127+
javax.xml.validation.SchemaFactory#newInstance(java.lang.String, java.lang.String, java.lang.ClassLoader)
128+
129+
@defaultMessage Validator should not be used directly. Use XmlUtils#getHardenedValidator() instead
130+
javax.xml.validation.Schema#newValidator()

docs/changelog/133718.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 133718
2+
summary: Remove upper limit for chunking settings
3+
area: Machine Learning
4+
type: enhancement
5+
issues: []

libs/core/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
module org.elasticsearch.base {
1313
requires static jsr305;
1414
requires org.elasticsearch.logging;
15+
requires java.xml;
1516

1617
exports org.elasticsearch.core;
1718
exports org.elasticsearch.jdk;
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.core;
11+
12+
import org.elasticsearch.logging.LogManager;
13+
import org.elasticsearch.logging.Logger;
14+
import org.xml.sax.SAXException;
15+
import org.xml.sax.SAXNotRecognizedException;
16+
import org.xml.sax.SAXNotSupportedException;
17+
import org.xml.sax.SAXParseException;
18+
19+
import javax.xml.XMLConstants;
20+
import javax.xml.parsers.DocumentBuilder;
21+
import javax.xml.parsers.DocumentBuilderFactory;
22+
import javax.xml.parsers.ParserConfigurationException;
23+
import javax.xml.parsers.SAXParserFactory;
24+
import javax.xml.transform.Transformer;
25+
import javax.xml.transform.TransformerConfigurationException;
26+
import javax.xml.transform.TransformerException;
27+
import javax.xml.transform.TransformerFactory;
28+
import javax.xml.validation.Schema;
29+
import javax.xml.validation.SchemaFactory;
30+
import javax.xml.validation.Validator;
31+
32+
public class XmlUtils {
33+
34+
private static final Logger LOGGER = LogManager.getLogger(XmlUtils.class);
35+
36+
/**
37+
* Constructs a DocumentBuilder with all the necessary features for it to be secure
38+
*
39+
* @throws ParserConfigurationException if one of the features can't be set on the DocumentBuilderFactory
40+
*/
41+
public static DocumentBuilder getHardenedBuilder(String[] schemaFiles) throws ParserConfigurationException {
42+
final DocumentBuilderFactory dbf = getHardenedBuilderFactory();
43+
dbf.setNamespaceAware(true);
44+
// Ensure that Schema Validation is enabled for the factory
45+
dbf.setValidating(true);
46+
// This is required, otherwise schema validation causes signature invalidation
47+
dbf.setFeature("http://apache.org/xml/features/validation/schema/normalized-value", false);
48+
// Make sure that URL schema namespaces are not resolved/downloaded from URLs we do not control
49+
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "file,jar");
50+
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "file,jar");
51+
// We ship our own xsd files for schema validation since we do not trust anyone else.
52+
dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource", schemaFiles);
53+
DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
54+
documentBuilder.setErrorHandler(new ErrorHandler());
55+
return documentBuilder;
56+
}
57+
58+
/**
59+
* Returns a DocumentBuilderFactory pre-configured to be secure
60+
*/
61+
@SuppressForbidden(reason = "This is the only allowed way to construct a DocumentBuilder")
62+
public static DocumentBuilderFactory getHardenedBuilderFactory() throws ParserConfigurationException {
63+
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
64+
// Disallow internal and external entity expansion
65+
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
66+
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
67+
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
68+
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
69+
dbf.setFeature("http://xml.org/sax/features/validation", true);
70+
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
71+
dbf.setIgnoringComments(true);
72+
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
73+
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
74+
dbf.setFeature("http://apache.org/xml/features/honour-all-schemaLocations", true);
75+
// Ensure we do not resolve XIncludes. Defaults to false, but set it explicitly to be future-proof
76+
dbf.setXIncludeAware(false);
77+
// Ensure we do not expand entity reference nodes
78+
dbf.setExpandEntityReferences(false);
79+
// Further limit danger from denial of service attacks
80+
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
81+
dbf.setAttribute("http://apache.org/xml/features/validation/schema", true);
82+
dbf.setAttribute("http://apache.org/xml/features/validation/schema-full-checking", true);
83+
dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", XMLConstants.W3C_XML_SCHEMA_NS_URI);
84+
85+
return dbf;
86+
}
87+
88+
/**
89+
* Constructs a Transformer configured to be secure
90+
*/
91+
@SuppressForbidden(reason = "This is the only allowed way to construct a Transformer")
92+
public static Transformer getHardenedXMLTransformer() throws TransformerConfigurationException {
93+
final TransformerFactory tfactory = TransformerFactory.newInstance();
94+
tfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
95+
tfactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
96+
tfactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
97+
tfactory.setAttribute("indent-number", 2);
98+
Transformer transformer = tfactory.newTransformer();
99+
transformer.setErrorListener(new ErrorListener());
100+
return transformer;
101+
}
102+
103+
/**
104+
* Returns a SchemaFactory configured to be secure
105+
*/
106+
@SuppressForbidden(reason = "This is the only allowed way to construct a SchemaFactory")
107+
public static SchemaFactory getHardenedSchemaFactory() throws SAXNotSupportedException, SAXNotRecognizedException {
108+
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
109+
schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
110+
schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
111+
return schemaFactory;
112+
}
113+
114+
/**
115+
* Constructs a Validator configured to be secure
116+
*/
117+
@SuppressForbidden(reason = "This is the only allowed way to construct a Validator")
118+
public static Validator getHardenedValidator(Schema schema) throws SAXNotSupportedException, SAXNotRecognizedException {
119+
Validator validator = schema.newValidator();
120+
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
121+
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
122+
return validator;
123+
}
124+
125+
@SuppressForbidden(reason = "This is the only allowed way to construct a SAXParser")
126+
public static SAXParserFactory getHardenedSaxParserFactory() throws SAXNotSupportedException, SAXNotRecognizedException,
127+
ParserConfigurationException {
128+
var saxParserFactory = SAXParserFactory.newInstance();
129+
130+
saxParserFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
131+
saxParserFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
132+
saxParserFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
133+
saxParserFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
134+
saxParserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
135+
136+
return saxParserFactory;
137+
}
138+
139+
private static class ErrorHandler implements org.xml.sax.ErrorHandler {
140+
/**
141+
* Enabling schema validation with `setValidating(true)` in our
142+
* DocumentBuilderFactory requires that we provide our own
143+
* ErrorHandler implementation
144+
*
145+
* @throws SAXException If the document we attempt to parse is not valid according to the specified schema.
146+
*/
147+
@Override
148+
public void warning(SAXParseException e) throws SAXException {
149+
LOGGER.debug("XML Parser error ", e);
150+
throw e;
151+
}
152+
153+
@Override
154+
public void error(SAXParseException e) throws SAXException {
155+
LOGGER.debug("XML Parser error ", e);
156+
throw e;
157+
}
158+
159+
@Override
160+
public void fatalError(SAXParseException e) throws SAXException {
161+
LOGGER.debug("XML Parser error ", e);
162+
throw e;
163+
}
164+
}
165+
166+
private static class ErrorListener implements javax.xml.transform.ErrorListener {
167+
168+
@Override
169+
public void warning(TransformerException e) throws TransformerException {
170+
LOGGER.debug("XML transformation error", e);
171+
throw e;
172+
}
173+
174+
@Override
175+
public void error(TransformerException e) throws TransformerException {
176+
LOGGER.debug("XML transformation error", e);
177+
throw e;
178+
}
179+
180+
@Override
181+
public void fatalError(TransformerException e) throws TransformerException {
182+
LOGGER.debug("XML transformation error", e);
183+
throw e;
184+
}
185+
}
186+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright Elasticsearch B.V., and/or licensed to Elasticsearch B.V.
3+
* under one or more license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*
19+
* This file is based on a modification of https://github.com/open-telemetry/opentelemetry-java which is licensed under the Apache 2.0 License.
20+
*/
21+
22+
package org.elasticsearch.exponentialhistogram;
23+
24+
/**
25+
* Basic implementation for {@link ExponentialHistogram} with common functionality.
26+
*/
27+
public abstract class AbstractExponentialHistogram implements ExponentialHistogram {
28+
29+
@Override
30+
public long valueCount() {
31+
return zeroBucket().count() + negativeBuckets().valueCount() + positiveBuckets().valueCount();
32+
}
33+
34+
@Override
35+
public int hashCode() {
36+
return ExponentialHistogram.hashCode(this);
37+
}
38+
39+
@Override
40+
public boolean equals(Object obj) {
41+
if (this == obj) {
42+
return true;
43+
}
44+
if (obj instanceof ExponentialHistogram) {
45+
return ExponentialHistogram.equals(this, (ExponentialHistogram) obj);
46+
}
47+
return false;
48+
}
49+
}

libs/exponential-histogram/src/main/java/org/elasticsearch/exponentialhistogram/EmptyExponentialHistogram.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
import java.util.OptionalLong;
2525

26-
class EmptyExponentialHistogram implements ReleasableExponentialHistogram {
26+
class EmptyExponentialHistogram extends AbstractExponentialHistogram implements ReleasableExponentialHistogram {
2727

2828
static final EmptyExponentialHistogram INSTANCE = new EmptyExponentialHistogram();
2929

libs/exponential-histogram/src/main/java/org/elasticsearch/exponentialhistogram/ExponentialHistogram.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,14 @@ public interface ExponentialHistogram extends Accountable {
102102
*/
103103
double sum();
104104

105+
/**
106+
* Returns the number of values represented by this histogram.
107+
* In other words, this is the sum of the counts of all buckets including the zero bucket.
108+
*
109+
* @return the value count, guaranteed to be zero for empty histograms
110+
*/
111+
long valueCount();
112+
105113
/**
106114
* Returns minimum of all values represented by this histogram.
107115
*
@@ -132,6 +140,60 @@ interface Buckets {
132140

133141
}
134142

143+
/**
144+
* Value-based equality for exponential histograms.
145+
* @param a the first histogram (can be null)
146+
* @param b the second histogram (can be null)
147+
* @return true, if both histograms are equal
148+
*/
149+
static boolean equals(ExponentialHistogram a, ExponentialHistogram b) {
150+
if (a == b) return true;
151+
if (a == null) return false;
152+
if (b == null) return false;
153+
154+
return a.scale() == b.scale()
155+
&& a.sum() == b.sum()
156+
&& equalsIncludingNaN(a.min(), b.min())
157+
&& a.zeroBucket().equals(b.zeroBucket())
158+
&& bucketIteratorsEqual(a.negativeBuckets().iterator(), b.negativeBuckets().iterator())
159+
&& bucketIteratorsEqual(a.positiveBuckets().iterator(), b.positiveBuckets().iterator());
160+
}
161+
162+
private static boolean equalsIncludingNaN(double a, double b) {
163+
return (a == b) || (Double.isNaN(a) && Double.isNaN(b));
164+
}
165+
166+
private static boolean bucketIteratorsEqual(BucketIterator a, BucketIterator b) {
167+
if (a.scale() != b.scale()) {
168+
return false;
169+
}
170+
while (a.hasNext() && b.hasNext()) {
171+
if (a.peekIndex() != b.peekIndex() || a.peekCount() != b.peekCount()) {
172+
return false;
173+
}
174+
a.advance();
175+
b.advance();
176+
}
177+
return a.hasNext() == b.hasNext();
178+
}
179+
180+
/**
181+
* Default hash code implementation to be used with {@link #equals(ExponentialHistogram, ExponentialHistogram)}.
182+
* @param histogram the histogram to hash
183+
* @return the hash code
184+
*/
185+
static int hashCode(ExponentialHistogram histogram) {
186+
int hash = histogram.scale();
187+
hash = 31 * hash + Double.hashCode(histogram.sum());
188+
hash = 31 * hash + Long.hashCode(histogram.valueCount());
189+
hash = 31 * hash + Double.hashCode(histogram.min());
190+
hash = 31 * hash + histogram.zeroBucket().hashCode();
191+
// we intentionally don't include the hash of the buckets here, because that is likely expensive to compute
192+
// instead, we assume that the value count and sum are a good enough approximation in most cases to minimize collisions
193+
// the value count is typically available as a cached value and doesn't involve iterating over all buckets
194+
return hash;
195+
}
196+
135197
static ExponentialHistogram empty() {
136198
return EmptyExponentialHistogram.INSTANCE;
137199
}

0 commit comments

Comments
 (0)