Skip to content

Commit efd8b2d

Browse files
committed
Test with --sun-misc-unsafe-memory-access=deny
1 parent 567e737 commit efd8b2d

File tree

8 files changed

+105
-4
lines changed

8 files changed

+105
-4
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,13 @@ jobs:
7070

7171
- name: Set up gradle
7272
uses: gradle/actions/setup-gradle@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3
73+
7374
- name: Build
7475
run: >
7576
./gradlew build
7677
${{ matrix.coverage && 'jacocoTestReport' || '' }}
7778
-PtestJavaVersion=${{ matrix.test-java-version }}
79+
${{ matrix.test-java-version == 23 && '-PdenyUnsafe=true' || '' }}
7880
"-Porg.gradle.java.installations.paths=${{ steps.setup-java-test.outputs.path }}"
7981
"-Porg.gradle.java.installations.auto-download=false"
8082
env:

buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ dependencyCheck {
7070
}
7171

7272
val testJavaVersion = gradle.startParameter.projectProperties.get("testJavaVersion")?.let(JavaVersion::toVersion)
73+
val denyUnsafe = gradle.startParameter.projectProperties.get("denyUnsafe")?.toBoolean() ?: false
7374

7475
tasks {
7576
withType<JavaCompile>().configureEach {
@@ -114,6 +115,11 @@ tasks {
114115
)
115116
}
116117

118+
// Add JVM arguments when denyUnsafe property is set
119+
if (denyUnsafe) {
120+
jvmArgs("--sun-misc-unsafe-memory-access=deny")
121+
}
122+
117123
val defaultMaxRetries = if (System.getenv().containsKey("CI")) 2 else 0
118124
val maxTestRetries = gradle.startParameter.projectProperties["maxTestRetries"]?.toInt() ?: defaultMaxRetries
119125

exporters/common/build.gradle.kts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ testing {
7676
}
7777

7878
tasks {
79+
// Use custom Security Manager to prevent UnsafeUtil from accessing sun.misc.Unsafe
80+
withType<Test>().configureEach {
81+
val denyUnsafe = gradle.startParameter.projectProperties.get("denyUnsafe")?.toBoolean() ?: false
82+
if (denyUnsafe) {
83+
jvmArgs("-Djava.security.manager=io.opentelemetry.exporter.internal.unsafe.ProtobufWorkaroundSecurityManager")
84+
}
85+
}
7986
check {
8087
dependsOn(testing.suites)
8188
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.exporter.internal.unsafe;
7+
8+
import java.security.Permission;
9+
10+
public class ProtobufWorkaroundSecurityManager extends SecurityManager {
11+
12+
@Override
13+
public void checkPermission(Permission perm) {
14+
// Block access to sun.misc.Unsafe fields
15+
if (perm instanceof java.lang.reflect.ReflectPermission) {
16+
if ("suppressAccessChecks".equals(perm.getName())) {
17+
// Get the stack trace to see what's trying to access
18+
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
19+
for (StackTraceElement element : stack) {
20+
if (element.getClassName().contains("UnsafeUtil") &&
21+
element.getMethodName().contains("getUnsafe")) {
22+
throw new SecurityException("Access to sun.misc.Unsafe denied");
23+
}
24+
}
25+
}
26+
}
27+
// Allow everything else
28+
}
29+
30+
@Override
31+
public void checkPermission(Permission perm, Object context) {
32+
checkPermission(perm);
33+
}
34+
}

exporters/otlp/common/build.gradle.kts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ dependencies {
4141
jmhImplementation("io.grpc:grpc-netty")
4242
}
4343

44+
tasks.withType<Test>().configureEach {
45+
val denyUnsafe = gradle.startParameter.projectProperties.get("denyUnsafe")?.toBoolean() ?: false
46+
if (denyUnsafe) {
47+
// Use Security Manager to handle protobuf unsafe access
48+
jvmArgs("-Djava.security.manager=io.opentelemetry.exporter.internal.otlp.unsafe.ProtobufWorkaroundSecurityManager")
49+
}
50+
}
51+
4452
testing {
4553
suites {
4654
register<JvmTestSuite>("testIncubating") {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.exporter.internal.otlp.unsafe;
7+
8+
import java.security.Permission;
9+
10+
public class ProtobufWorkaroundSecurityManager extends SecurityManager {
11+
12+
@Override
13+
public void checkPermission(Permission perm) {
14+
// Block access to sun.misc.Unsafe fields
15+
if (perm instanceof java.lang.reflect.ReflectPermission) {
16+
if ("suppressAccessChecks".equals(perm.getName())) {
17+
// Get the stack trace to see what's trying to access
18+
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
19+
for (StackTraceElement element : stack) {
20+
if (element.getClassName().contains("UnsafeUtil") &&
21+
element.getMethodName().contains("getUnsafe")) {
22+
throw new SecurityException("Access to sun.misc.Unsafe denied");
23+
}
24+
}
25+
}
26+
}
27+
// Allow everything else
28+
}
29+
30+
@Override
31+
public void checkPermission(Permission perm, Object context) {
32+
checkPermission(perm);
33+
}
34+
}

opencensus-shim/build.gradle.kts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,11 @@ tasks.named<Test>("test") {
3030
// methods available.
3131
setForkEvery(1)
3232
maxParallelForks = 3
33+
34+
// OpenCensus uses LMAX Disruptor 3.4.2 which requires unsafe memory access
35+
// Override the global --sun-misc-unsafe-memory-access=deny setting for this module
36+
val denyUnsafe = gradle.startParameter.projectProperties.get("denyUnsafe")?.toBoolean() ?: false
37+
if (denyUnsafe) {
38+
jvmArgs("--sun-misc-unsafe-memory-access=allow")
39+
}
3340
}

sdk/trace-shaded-deps/src/test/java/io/opentelemetry/sdk/trace/internal/JcToolsTest.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void drain_ArrayBlockingQueue() {
4343
void drain_MessagePassingQueue() {
4444
// Arrange
4545
batch.add("Test3");
46-
Queue<String> queue = new MpscArrayQueue<>(10);
46+
Queue<String> queue = JcTools.newFixedSizeQueue(10);
4747
queue.add("Test1");
4848
queue.add("Test2");
4949

@@ -58,7 +58,7 @@ void drain_MessagePassingQueue() {
5858
@Test
5959
void drain_MaxBatch() {
6060
// Arrange
61-
Queue<String> queue = new MpscArrayQueue<>(10);
61+
Queue<String> queue = JcTools.newFixedSizeQueue(10);
6262
queue.add("Test1");
6363
queue.add("Test2");
6464

@@ -79,7 +79,10 @@ void newFixedSize_MpscQueue() {
7979
Queue<Object> objects = JcTools.newFixedSizeQueue(capacity);
8080

8181
// Assert
82-
assertThat(objects).isInstanceOf(MpscArrayQueue.class);
82+
assertThat(objects).satisfiesAnyOf(
83+
queue -> assertThat(queue).isInstanceOf(MpscArrayQueue.class),
84+
queue -> assertThat(queue).isInstanceOf(ArrayBlockingQueue.class)
85+
);
8386
}
8487

8588
@Test
@@ -92,7 +95,7 @@ void capacity_MpscQueue() {
9295
long queueSize = JcTools.capacity(queue);
9396

9497
// Assert
95-
assertThat(queueSize).isGreaterThan(capacity);
98+
assertThat(queueSize).isGreaterThanOrEqualTo(capacity);
9699
}
97100

98101
@Test

0 commit comments

Comments
 (0)