Skip to content

Commit 3443d27

Browse files
[Java Agent] Allow JRT protocol URLs in protection domain extraction (#19683)
* [Java Agent] Allow JRT protocol URLs in protection domain extraction Signed-off-by: rithin-pullela-aws <rithinp@amazon.com> * Add changelog Signed-off-by: rithin-pullela-aws <rithinp@amazon.com> * Use static imports Signed-off-by: rithin-pullela-aws <rithinp@amazon.com> * Add spotbugs dependency Signed-off-by: Owais Kazi <owaiskazi19@gmail.com> --------- Signed-off-by: rithin-pullela-aws <rithinp@amazon.com> Signed-off-by: Owais Kazi <owaiskazi19@gmail.com> Co-authored-by: Owais Kazi <owaiskazi19@gmail.com>
1 parent 3ffa49a commit 3443d27

File tree

4 files changed

+97
-0
lines changed

4 files changed

+97
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
3030
- Fix pull-based ingestion out-of-bounds offset scenarios and remove persisted offsets ([#19607](https://github.com/opensearch-project/OpenSearch/pull/19607))
3131
- [Star Tree] Fix sub-aggregator casting for search with profile=true ([19652](https://github.com/opensearch-project/OpenSearch/pull/19652))
3232
- Fix issue with updating core with a patch number other than 0 ([#19377](https://github.com/opensearch-project/OpenSearch/pull/19377))
33+
- [Java Agent] Allow JRT protocol URLs in protection domain extraction ([#19683](https://github.com/opensearch-project/OpenSearch/pull/19683))
3334

3435
### Dependencies
3536
- Update to Gradle 9.1 ([#19575](https://github.com/opensearch-project/OpenSearch/pull/19575))

libs/agent-sm/agent/src/main/java/org/opensearch/javaagent/StackCallerProtectionDomainChainExtractor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public Collection<ProtectionDomain> apply(Stream<StackFrame> frames) {
5454
.map(StackFrame::getDeclaringClass)
5555
.map(Class::getProtectionDomain)
5656
.filter(pd -> pd.getCodeSource() != null) // Filter out JDK classes
57+
.filter(pd -> !"jrt".equals(pd.getCodeSource().getLocation().getProtocol())) // Filter out codesources beginning with jrt:
5758
.collect(Collectors.toSet());
5859
}
5960
}

libs/agent-sm/agent/src/test/java/org/opensearch/javaagent/StackCallerProtectionDomainExtractorTests.java

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88

99
package org.opensearch.javaagent;
1010

11+
import org.junit.Assume;
1112
import org.junit.Test;
1213

14+
import java.lang.invoke.MethodType;
1315
import java.net.URI;
1416
import java.net.URISyntaxException;
1517
import java.nio.file.Path;
@@ -21,6 +23,7 @@
2123
import java.util.Set;
2224
import java.util.function.Supplier;
2325
import java.util.stream.Collectors;
26+
import java.util.stream.Stream;
2427

2528
import static org.hamcrest.MatcherAssert.assertThat;
2629
import static org.hamcrest.Matchers.containsInAnyOrder;
@@ -257,4 +260,92 @@ public void testAccessControllerUsingCheckedRunnableThrowsException() {
257260
org.opensearch.secure_sm.AccessController.doPrivilegedChecked(() -> { throw new IllegalArgumentException("Test exception"); });
258261
});
259262
}
263+
264+
private static final class FakeFrame implements StackWalker.StackFrame {
265+
private final Class<?> clazz;
266+
private final String method;
267+
268+
FakeFrame(Class<?> clazz, String method) {
269+
this.clazz = clazz;
270+
this.method = method;
271+
}
272+
273+
@Override
274+
public Class<?> getDeclaringClass() {
275+
return clazz;
276+
}
277+
278+
@Override
279+
public String getClassName() {
280+
return clazz.getName();
281+
}
282+
283+
@Override
284+
public String getMethodName() {
285+
return method;
286+
}
287+
288+
@Override
289+
public String getFileName() {
290+
return null;
291+
}
292+
293+
@Override
294+
public int getLineNumber() {
295+
return -1;
296+
}
297+
298+
@Override
299+
public boolean isNativeMethod() {
300+
return false;
301+
}
302+
303+
@Override
304+
public StackTraceElement toStackTraceElement() {
305+
return new StackTraceElement(getClassName(), getMethodName(), null, -1);
306+
}
307+
308+
// JDK 21 methods; stub minimally
309+
@Override
310+
public String getDescriptor() {
311+
return "()V";
312+
}
313+
314+
@Override
315+
public int getByteCodeIndex() {
316+
return -1;
317+
}
318+
319+
@Override
320+
public MethodType getMethodType() {
321+
return MethodType.methodType(void.class);
322+
}
323+
}
324+
325+
@Test
326+
public void testFiltersJrtProtocol() {
327+
// Guard: ensure HttpClient is truly from jrt:
328+
ProtectionDomain pd = java.net.http.HttpClient.class.getProtectionDomain();
329+
Assume.assumeTrue(
330+
pd != null
331+
&& pd.getCodeSource() != null
332+
&& pd.getCodeSource().getLocation() != null
333+
&& "jrt".equals(pd.getCodeSource().getLocation().getProtocol())
334+
);
335+
336+
StackWalker.StackFrame jrtFrame = new FakeFrame(java.net.http.HttpClient.class, "send");
337+
StackWalker.StackFrame fileFrame = new FakeFrame(StackCallerProtectionDomainExtractorTests.class, "helper");
338+
339+
Set<ProtectionDomain> pds = (Set<ProtectionDomain>) StackCallerProtectionDomainChainExtractor.INSTANCE.apply(
340+
Stream.of(jrtFrame, fileFrame)
341+
);
342+
343+
// Only the file: PD should remain
344+
assertEquals(1, pds.size());
345+
assertThat(
346+
pds.stream().map(x -> x.getCodeSource().getLocation().getProtocol()).collect(Collectors.toSet()),
347+
containsInAnyOrder("file")
348+
);
349+
}
350+
260351
}

libs/agent-sm/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,7 @@ base {
2020

2121
test.enabled = false
2222
testingConventions.enabled = false
23+
24+
dependencies {
25+
compileOnly "com.github.spotbugs:spotbugs-annotations:4.9.7"
26+
}

0 commit comments

Comments
 (0)