Skip to content

Commit 0b040e0

Browse files
Merge branch 'main' into fixChunkTest
2 parents 14ba99e + a1daddc commit 0b040e0

File tree

14 files changed

+592
-12
lines changed

14 files changed

+592
-12
lines changed

docs/reference/ingest/apis/simulate-ingest.asciidoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,8 @@ Definition of a mapping that will be merged into the index's mapping for validat
265265

266266
[[simulate-ingest-api-pre-existing-pipelines-ex]]
267267
===== Use pre-existing pipeline definitions
268-
In this example the index `index` has a default pipeline called `my-pipeline` and a final
269-
pipeline called `my-final-pipeline`. Since both documents are being ingested into `index`,
268+
In this example the index `my-index` has a default pipeline called `my-pipeline` and a final
269+
pipeline called `my-final-pipeline`. Since both documents are being ingested into `my-index`,
270270
both pipelines are executed using the pipeline definitions that are already in the system.
271271

272272
[source,console]

docs/reference/modules/indices/circuit_breaker.asciidoc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@
22
=== Circuit breaker settings
33
[[circuit-breaker-description]]
44
// tag::circuit-breaker-description-tag[]
5-
{es} contains multiple circuit breakers used to prevent operations from causing an OutOfMemoryError. Each breaker specifies a limit for how much memory it can use. Additionally, there is a parent-level breaker that specifies the total amount of memory that can be used across all breakers.
5+
{es} contains multiple circuit breakers used to prevent operations from using an excessive amount of memory. Each breaker tracks the memory
6+
used by certain operations and specifies a limit for how much memory it may track. Additionally, there
7+
is a parent-level breaker that specifies the total amount of memory that may be tracked across all breakers.
8+
9+
When a circuit breaker reaches its limit, {es} will reject further operations. See <<circuit-breaker-errors>> for information about errors
10+
raised by circuit breakers.
11+
12+
Circuit breakers do not track all memory usage in {es} and therefore provide only incomplete protection against excessive memory usage. If
13+
{es} uses too much memory then it may suffer from performance issues and nodes may even fail with an `OutOfMemoryError`. See
14+
<<high-jvm-memory-pressure>> for help with troubleshooting high heap usage.
615

716
Except where noted otherwise, these settings can be dynamically updated on a
817
live cluster with the <<cluster-update-settings,cluster-update-settings>> API.

libs/entitlement/tools/build.gradle

Whitespace-only changes.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
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+
plugins {
11+
id 'java'
12+
}
13+
14+
group = 'org.elasticsearch.entitlement.tools'
15+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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.entitlement.tools;
11+
12+
import java.io.IOException;
13+
import java.lang.module.ModuleDescriptor;
14+
import java.nio.file.FileSystem;
15+
import java.nio.file.Files;
16+
import java.util.HashMap;
17+
import java.util.Map;
18+
import java.util.Set;
19+
import java.util.stream.Collectors;
20+
21+
public class Utils {
22+
23+
public static Map<String, Set<String>> findModuleExports(FileSystem fs) throws IOException {
24+
var modulesExports = new HashMap<String, Set<String>>();
25+
try (var stream = Files.walk(fs.getPath("modules"))) {
26+
stream.filter(p -> p.getFileName().toString().equals("module-info.class")).forEach(x -> {
27+
try (var is = Files.newInputStream(x)) {
28+
var md = ModuleDescriptor.read(is);
29+
modulesExports.put(
30+
md.name(),
31+
md.exports()
32+
.stream()
33+
.filter(e -> e.isQualified() == false)
34+
.map(ModuleDescriptor.Exports::source)
35+
.collect(Collectors.toSet())
36+
);
37+
} catch (IOException e) {
38+
throw new RuntimeException(e);
39+
}
40+
});
41+
}
42+
return modulesExports;
43+
}
44+
45+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
plugins {
2+
id 'application'
3+
}
4+
5+
apply plugin: 'elasticsearch.build'
6+
apply plugin: 'elasticsearch.publish'
7+
8+
tasks.named("dependencyLicenses").configure {
9+
mapping from: /asm-.*/, to: 'asm'
10+
}
11+
12+
group = 'org.elasticsearch.entitlement.tools'
13+
14+
ext {
15+
javaMainClass = "org.elasticsearch.entitlement.tools.securitymanager.scanner.Main"
16+
}
17+
18+
application {
19+
mainClass.set(javaMainClass)
20+
applicationDefaultJvmArgs = [
21+
'--add-exports', 'java.base/sun.security.util=ALL-UNNAMED',
22+
'--add-opens', 'java.base/java.lang=ALL-UNNAMED',
23+
'--add-opens', 'java.base/java.net=ALL-UNNAMED',
24+
'--add-opens', 'java.base/java.net.spi=ALL-UNNAMED',
25+
'--add-opens', 'java.base/java.util.concurrent=ALL-UNNAMED',
26+
'--add-opens', 'java.base/javax.crypto=ALL-UNNAMED',
27+
'--add-opens', 'java.base/javax.security.auth=ALL-UNNAMED',
28+
'--add-opens', 'java.base/jdk.internal.logger=ALL-UNNAMED',
29+
'--add-opens', 'java.base/sun.nio.ch=ALL-UNNAMED',
30+
'--add-opens', 'jdk.management.jfr/jdk.management.jfr=ALL-UNNAMED',
31+
'--add-opens', 'java.logging/java.util.logging=ALL-UNNAMED',
32+
'--add-opens', 'java.logging/sun.util.logging.internal=ALL-UNNAMED',
33+
'--add-opens', 'java.naming/javax.naming.ldap.spi=ALL-UNNAMED',
34+
'--add-opens', 'java.rmi/sun.rmi.runtime=ALL-UNNAMED',
35+
'--add-opens', 'jdk.dynalink/jdk.dynalink=ALL-UNNAMED',
36+
'--add-opens', 'jdk.dynalink/jdk.dynalink.linker=ALL-UNNAMED',
37+
'--add-opens', 'java.desktop/sun.awt=ALL-UNNAMED',
38+
'--add-opens', 'java.sql.rowset/javax.sql.rowset.spi=ALL-UNNAMED',
39+
'--add-opens', 'java.sql/java.sql=ALL-UNNAMED',
40+
'--add-opens', 'java.xml.crypto/com.sun.org.apache.xml.internal.security.utils=ALL-UNNAMED'
41+
]
42+
}
43+
44+
repositories {
45+
mavenCentral()
46+
}
47+
48+
dependencies {
49+
compileOnly(project(':libs:core'))
50+
implementation 'org.ow2.asm:asm:9.7'
51+
implementation 'org.ow2.asm:asm-util:9.7'
52+
implementation(project(':libs:entitlement:tools:common'))
53+
}
54+
55+
tasks.named('forbiddenApisMain').configure {
56+
replaceSignatureFiles 'jdk-signatures'
57+
}
58+
59+
tasks.named("thirdPartyAudit").configure {
60+
ignoreMissingClasses()
61+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Copyright (c) 2012 France Télécom
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions
6+
are met:
7+
1. Redistributions of source code must retain the above copyright
8+
notice, this list of conditions and the following disclaimer.
9+
2. Redistributions in binary form must reproduce the above copyright
10+
notice, this list of conditions and the following disclaimer in the
11+
documentation and/or other materials provided with the distribution.
12+
3. Neither the name of the copyright holders nor the names of its
13+
contributors may be used to endorse or promote products derived from
14+
this software without specific prior written permission.
15+
16+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26+
THE POSSIBILITY OF SUCH DAMAGE.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
This tool scans the JDK on which it is running, looking for any location where `SecurityManager` is currently used, thus giving us a list of "entry points" inside the JDK where security checks are currently happening.
2+
3+
More in detail, the tool scans for calls to any `SecurityManager` method starting with `check` (e.g. `checkWrite`). The tool treats the generic `checkPermission` method a little bit differently: `checkPermission` accepts a generic `Permission` object, it tries to read the permission type and permission name to give more information about it, trying to match two patterns that are used frequently inside the JDK:
4+
5+
Pattern 1: private static permission field
6+
7+
```java
8+
private static final RuntimePermission INET_ADDRESS_RESOLVER_PERMISSION =
9+
new RuntimePermission("inetAddressResolverProvider");
10+
...
11+
sm.checkPermission(INET_ADDRESS_RESOLVER_PERMISSION);
12+
```
13+
Pattern 2: direct object creation
14+
15+
```java
16+
sm.checkPermission(new LinkPermission("symbolic"));
17+
```
18+
19+
The tool will recognize this pattern, and report the permission type and name alongside the `checkPermission` entry point (type `RuntimePermission` and name `inetAddressResolverProvider` in the first case, type `LinkPermission` and name `symbolic` in the second).
20+
21+
This allows to give more information (either a specific type like `LinkPermission`, or a specific name like `inetAddressResolverProvider`) to generic `checkPermission` to help in deciding how to classify the permission check. The 2 patterns work quite well and cover roughly 90% of the cases.
22+
23+
In order to run the tool, use:
24+
```shell
25+
./gradlew :libs:entitlement:tools:securitymanager-scanner:run
26+
```
27+
The output of the tool is a CSV file, with one line for each entry-point, columns separated by `TAB`
28+
29+
The columns are:
30+
1. Module name
31+
2. File name (from source root)
32+
3. Line number
33+
4. Fully qualified class name (ASM style, with `/` separators)
34+
5. Method name
35+
6. Method descriptor (ASM signature)
36+
6. Visibility (PUBLIC/PUBLIC-METHOD/PRIVATE)
37+
7. Check detail 1 (method name, or in case of checkPermission, permission name. Might be `MISSING`)
38+
8. Check detail 2 (in case of checkPermission, the argument type (`Permission` subtype). Might be `MISSING`)
39+
40+
Examples:
41+
```
42+
java.base sun/nio/ch/DatagramChannelImpl.java 1360 sun/nio/ch/DatagramChannelImpl connect (Ljava/net/SocketAddress;Z)Ljava/nio/channels/DatagramChannel; PRIVATE checkConnect
43+
```
44+
or
45+
```
46+
java.base java/net/ResponseCache.java 118 java/net/ResponseCache setDefault (Ljava/net/ResponseCache;)V PUBLIC setResponseCache java/net/NetPermission
47+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
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.entitlement.tools.securitymanager.scanner;
11+
12+
import org.elasticsearch.core.SuppressForbidden;
13+
import org.elasticsearch.entitlement.tools.Utils;
14+
import org.objectweb.asm.ClassReader;
15+
16+
import java.io.IOException;
17+
import java.net.URI;
18+
import java.nio.file.FileSystem;
19+
import java.nio.file.FileSystems;
20+
import java.nio.file.Files;
21+
import java.util.HashMap;
22+
import java.util.List;
23+
import java.util.Set;
24+
25+
public class Main {
26+
27+
static final Set<String> excludedModules = Set.of("java.desktop");
28+
29+
private static void identifySMChecksEntryPoints() throws IOException {
30+
31+
FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
32+
33+
var moduleExports = Utils.findModuleExports(fs);
34+
35+
var callers = new HashMap<String, List<SecurityCheckClassVisitor.CallerInfo>>();
36+
var visitor = new SecurityCheckClassVisitor(callers);
37+
38+
try (var stream = Files.walk(fs.getPath("modules"))) {
39+
stream.filter(x -> x.toString().endsWith(".class")).forEach(x -> {
40+
var moduleName = x.subpath(1, 2).toString();
41+
if (excludedModules.contains(moduleName) == false) {
42+
try {
43+
ClassReader cr = new ClassReader(Files.newInputStream(x));
44+
visitor.setCurrentModule(moduleName, moduleExports.get(moduleName));
45+
var path = x.getNameCount() > 3 ? x.subpath(2, x.getNameCount() - 1).toString() : "";
46+
visitor.setCurrentSourcePath(path);
47+
cr.accept(visitor, 0);
48+
} catch (IOException e) {
49+
throw new RuntimeException(e);
50+
}
51+
}
52+
});
53+
}
54+
55+
printToStdout(callers);
56+
}
57+
58+
@SuppressForbidden(reason = "This simple tool just prints to System.out")
59+
private static void printToStdout(HashMap<String, List<SecurityCheckClassVisitor.CallerInfo>> callers) {
60+
for (var kv : callers.entrySet()) {
61+
for (var e : kv.getValue()) {
62+
System.out.println(toString(kv.getKey(), e));
63+
}
64+
}
65+
}
66+
67+
private static final String SEPARATOR = "\t";
68+
69+
private static String toString(String calleeName, SecurityCheckClassVisitor.CallerInfo callerInfo) {
70+
var s = callerInfo.moduleName() + SEPARATOR + callerInfo.source() + SEPARATOR + callerInfo.line() + SEPARATOR + callerInfo
71+
.className() + SEPARATOR + callerInfo.methodName() + SEPARATOR + callerInfo.methodDescriptor() + SEPARATOR;
72+
73+
if (callerInfo.externalAccess().contains(SecurityCheckClassVisitor.ExternalAccess.METHOD)
74+
&& callerInfo.externalAccess().contains(SecurityCheckClassVisitor.ExternalAccess.CLASS)) {
75+
s += "PUBLIC";
76+
} else if (callerInfo.externalAccess().contains(SecurityCheckClassVisitor.ExternalAccess.METHOD)) {
77+
s += "PUBLIC-METHOD";
78+
} else {
79+
s += "PRIVATE";
80+
}
81+
82+
if (callerInfo.runtimePermissionType() != null) {
83+
s += SEPARATOR + callerInfo.runtimePermissionType();
84+
} else if (calleeName.equals("checkPermission")) {
85+
s += SEPARATOR + "MISSING"; // missing information
86+
} else {
87+
s += SEPARATOR + calleeName;
88+
}
89+
90+
if (callerInfo.permissionType() != null) {
91+
s += SEPARATOR + callerInfo.permissionType();
92+
} else if (calleeName.equals("checkPermission")) {
93+
s += SEPARATOR + "MISSING"; // missing information
94+
} else {
95+
s += SEPARATOR;
96+
}
97+
return s;
98+
}
99+
100+
public static void main(String[] args) throws IOException {
101+
identifySMChecksEntryPoints();
102+
}
103+
}

0 commit comments

Comments
 (0)