Skip to content

Conversation

phananh1010
Copy link
Owner

@phananh1010 phananh1010 commented Oct 7, 2025

Single commit with tree=135d74b33ba9f1ce2b0e61fa5fb2a39a3763c688^{tree}, parent=41fea9d8a715b1e2ffb668c3cf54c6c9645f0331. Exact snapshot of upstream PR head. No conflict resolution attempted.

Summary by CodeRabbit

  • Bug Fixes
    • Tightened entitlement policy to avoid unintended trust of certain system packages, improving security and stability.
    • Expanded desktop environment permissions to allow safe thread management, enhancing compatibility with desktop-related operations.
  • Refactor
    • Strengthened module scope resolution for more predictable behavior across different runtime setups.
  • Tests
    • Added coverage for image/PDF stream initialization to prevent regressions in related functionality.

BASE=41fea9d8a715b1e2ffb668c3cf54c6c9645f0331
HEAD=135d74b33ba9f1ce2b0e61fa5fb2a39a3763c688
Branch=main
Copy link

coderabbitai bot commented Oct 7, 2025

Walkthrough

Expands desktop entitlements to include ManageThreads. Broadens visibility of constants/fields in PolicyManager. Adds a new unit test instantiating MemoryCacheImageInputStream. Refactors TestScopeResolver from record to class, introduces excluded system package scope computation and lookups, and updates APIs to use PolicyScope. Adjusts TestPolicyManager trust logic to exclude those system packages.

Changes

Cohort / File(s) Summary of Changes
Desktop entitlement update
libs/entitlement/.../bootstrap/HardcodedEntitlements.java
Adds ManageThreadsEntitlement to java.desktop scope alongside LoadNativeLibrariesEntitlement; adds TODO comment.
PolicyManager visibility adjustments
libs/entitlement/.../runtime/policy/PolicyManager.java
Makes MODULES_EXCLUDED_FROM_SYSTEM_MODULES public; makes ComponentKind.componentName public; no logic changes.
New test for image input stream instantiation
libs/entitlement/src/test/java/.../bootstrap/HardcodedEntitlementsTests.java
Adds test class with method constructing MemoryCacheImageInputStream over UTF-8 bytes; no assertions.
Test scope resolver refactor and API shift
test/framework/src/main/java/org/elasticsearch/bootstrap/TestScopeResolver.java
Converts record to class; introduces excluded system package scope cache and lookup; updates getScope to consult excluded system packages when CodeSource is null; replaces PolicyManager.PolicyScope with PolicyScope across API; updates factory to return Function<Class<?>, PolicyScope>.
Trust logic guard for excluded system packages
test/framework/src/main/java/.../entitlement/runtime/policy/TestPolicyManager.java
Updates isTrustedSystemClass to return false for classes within excluded system package scopes via TestScopeResolver lookup.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor T as Test/Caller
  participant TSR as TestScopeResolver
  participant JRT as Java Modules
  participant PM as PolicyScope

  Note over TSR: Initialization phase
  TSR->>JRT: ModuleFinder.ofSystem() / ModuleLayer.boot()
  JRT-->>TSR: System modules & packages
  TSR->>TSR: Build excludedSystemPackageScopes (from MODULES_EXCLUDED_FROM_SYSTEM_MODULES)

  Note over T,TSR: Scope resolution
  T->>TSR: getScope(callerClass)
  TSR->>TSR: Resolve CodeSource
  alt CodeSource is null
    TSR->>TSR: getExcludedSystemPackageScope(callerClass)
    alt Found excluded system package
      TSR-->>T: PolicyScope (excluded system package)
    else Not found
      TSR-->>T: PolicyScope.unknown(location)
    end
  else CodeSource present
    TSR-->>T: PolicyScope.server(...) or .plugin(...), or .unknown(...)
  end
Loading
sequenceDiagram
  autonumber
  actor C as RequestingClass
  participant TPM as TestPolicyManager
  participant TSR as TestScopeResolver

  C->>TPM: isTrustedSystemClass(requestingClass)
  TPM->>TSR: getExcludedSystemPackageScope(requestingClass)
  alt Scope is non-null (excluded)
    TPM-->>C: false (not trusted)
  else Scope is null
    TPM-->>C: prior trust logic (unchanged)
  end
  Note over TPM: New guard enforces exclusion for specific system packages
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

I nibble threads with desktop ease,
And map the scopes among the trees;
From records turned to classes stout,
I sniff which modules to keep out.
Trust is trimmed with gentle care—
Hop, hop! Our tests now breathe fresh air. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title Check ⚠️ Warning The title emphasizes that this is a mirror of an upstream PR for AI review rather than summarizing the substantive entitlement and policy-related code changes present in the snapshot, so it does not clearly convey what modifications the pull request actually introduces. Please revise the title to succinctly reflect the main code changes (for example, mentioning the addition of ManageThreadsEntitlement and the PolicyScope refactoring in TestScopeResolver) so that reviewers immediately understand the core updates from upstream PR elastic#134454.
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch eval/pr-134454-diff

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 41fea9d and c1e1a88.

📒 Files selected for processing (5)
  • libs/entitlement/src/main/java/org/elasticsearch/entitlement/bootstrap/HardcodedEntitlements.java (1 hunks)
  • libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/PolicyManager.java (2 hunks)
  • libs/entitlement/src/test/java/org/elasticsearch/entitlement/bootstrap/HardcodedEntitlementsTests.java (1 hunks)
  • test/framework/src/main/java/org/elasticsearch/bootstrap/TestScopeResolver.java (4 hunks)
  • test/framework/src/main/java/org/elasticsearch/entitlement/runtime/policy/TestPolicyManager.java (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
test/framework/src/main/java/org/elasticsearch/entitlement/runtime/policy/TestPolicyManager.java (1)
test/framework/src/main/java/org/elasticsearch/bootstrap/TestScopeResolver.java (1)
  • TestScopeResolver (35-160)
test/framework/src/main/java/org/elasticsearch/bootstrap/TestScopeResolver.java (1)
libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/PolicyManager.java (1)
  • PolicyManager (50-398)
🔇 Additional comments (5)
libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/PolicyManager.java (2)

57-58: Public visibility for excluded system modules constant looks good

Needed for test/framework lookups; aligns with usage in TestScopeResolver.


97-101: Expose ComponentKind.componentName

Public field enables constructing PolicyScope outside the package. No behavioral risk.

test/framework/src/main/java/org/elasticsearch/bootstrap/TestScopeResolver.java (1)

94-134: Resolver wiring and PolicyScope usage look correct

Plugin/server scopes built as expected; jar URL handling preserved.

test/framework/src/main/java/org/elasticsearch/entitlement/runtime/policy/TestPolicyManager.java (1)

101-107: Correctly guard excluded system packages from being trusted

Aligns trust check with excluded-system scope computation.

libs/entitlement/src/main/java/org/elasticsearch/entitlement/bootstrap/HardcodedEntitlements.java (1)

117-123: Add ManageThreads to java.desktop is appropriate

Scoped to java.desktop; satisfies Disposer needs alongside native libs.

Comment on lines +30 to +32
public void testTikaPDF() {
new MemoryCacheImageInputStream(new ByteArrayInputStream("test test".getBytes(UTF_8)));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Close the stream (try-with-resources) to avoid resource leaks

Also consider a minimal assertion to exercise the instance.

Apply:

-    public void testTikaPDF() {
-        new MemoryCacheImageInputStream(new ByteArrayInputStream("test test".getBytes(UTF_8)));
-    }
+    public void testTikaPDF() throws Exception {
+        try (var in = new MemoryCacheImageInputStream(new ByteArrayInputStream("test test".getBytes(UTF_8)))) {
+            assertNotNull(in);
+        }
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public void testTikaPDF() {
new MemoryCacheImageInputStream(new ByteArrayInputStream("test test".getBytes(UTF_8)));
}
public void testTikaPDF() throws Exception {
try (var in = new MemoryCacheImageInputStream(new ByteArrayInputStream("test test".getBytes(UTF_8)))) {
assertNotNull(in);
}
}
🤖 Prompt for AI Agents
In
libs/entitlement/src/test/java/org/elasticsearch/entitlement/bootstrap/HardcodedEntitlementsTests.java
around lines 30-32, the MemoryCacheImageInputStream is created without being
closed and there is no assertion; change the test to open the
ByteArrayInputStream and MemoryCacheImageInputStream in a try-with-resources
block to ensure both are closed, read or call a simple method on the
MemoryCacheImageInputStream (e.g., read() or available()) to exercise the
instance, and add a minimal assertion (e.g., assertThat(value,
is(expectedNonNegativeOrNotMinusOne))) to validate the read/available result.

Comment on lines +45 to +64
private static Map<String, PolicyScope> computeExcludedSystemPackageScopes() {
// Within any one module layer, module names are unique, so we just need the names
Set<String> systemModuleNames = ModuleFinder.ofSystem()
.findAll()
.stream()
.map(ref -> ref.descriptor().name())
.filter(MODULES_EXCLUDED_FROM_SYSTEM_MODULES::contains)
.collect(toSet());

Map<String, PolicyScope> result = new TreeMap<>();
ModuleLayer.boot().modules().stream().filter(m -> systemModuleNames.contains(m.getName())).forEach(m -> {
ModuleDescriptor desc = m.getDescriptor();
if (desc != null) {
desc.packages().forEach(pkg ->
// Our component identification logic returns SERVER for these
result.put(pkg, new PolicyScope(SERVER, SERVER.componentName, m.getName())));
}
});
return result;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Return an unmodifiable map to prevent accidental mutation

Compute once, then freeze the result to avoid accidental writes.

Apply:

-    private static Map<String, PolicyScope> computeExcludedSystemPackageScopes() {
+    private static Map<String, PolicyScope> computeExcludedSystemPackageScopes() {
         ...
-        return result;
+        return Map.copyOf(result);
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private static Map<String, PolicyScope> computeExcludedSystemPackageScopes() {
// Within any one module layer, module names are unique, so we just need the names
Set<String> systemModuleNames = ModuleFinder.ofSystem()
.findAll()
.stream()
.map(ref -> ref.descriptor().name())
.filter(MODULES_EXCLUDED_FROM_SYSTEM_MODULES::contains)
.collect(toSet());
Map<String, PolicyScope> result = new TreeMap<>();
ModuleLayer.boot().modules().stream().filter(m -> systemModuleNames.contains(m.getName())).forEach(m -> {
ModuleDescriptor desc = m.getDescriptor();
if (desc != null) {
desc.packages().forEach(pkg ->
// Our component identification logic returns SERVER for these
result.put(pkg, new PolicyScope(SERVER, SERVER.componentName, m.getName())));
}
});
return result;
}
private static Map<String, PolicyScope> computeExcludedSystemPackageScopes() {
// Within any one module layer, module names are unique, so we just need the names
Set<String> systemModuleNames = ModuleFinder.ofSystem()
.findAll()
.stream()
.map(ref -> ref.descriptor().name())
.filter(MODULES_EXCLUDED_FROM_SYSTEM_MODULES::contains)
.collect(toSet());
Map<String, PolicyScope> result = new TreeMap<>();
ModuleLayer.boot().modules().stream()
.filter(m -> systemModuleNames.contains(m.getName()))
.forEach(m -> {
ModuleDescriptor desc = m.getDescriptor();
if (desc != null) {
desc.packages().forEach(pkg ->
// Our component identification logic returns SERVER for these
result.put(pkg, new PolicyScope(SERVER, SERVER.componentName, m.getName()))
);
}
});
return Map.copyOf(result);
}
🤖 Prompt for AI Agents
In
test/framework/src/main/java/org/elasticsearch/bootstrap/TestScopeResolver.java
around lines 45-64, the method currently returns a mutable TreeMap; change it to
return an unmodifiable map to prevent accidental mutation by wrapping the result
before returning (e.g., Collections.unmodifiableMap(result) or
Map.copyOf(result)) so the computed map is frozen when returned.

Comment on lines +70 to +76
PolicyScope getScope(Class<?> callerClass) {
var callerCodeSource = callerClass.getProtectionDomain().getCodeSource();
assert callerCodeSource != null;
if (callerCodeSource == null) {
// This only happens for JDK classes. Furthermore, for trivially allowed modules, we shouldn't even get here.
// Hence, this must be an excluded system module, so check for that.
return requireNonNull(getExcludedSystemPackageScope(callerClass));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Avoid potential NPE on non-excluded JDK classes

Edge-case: if this is ever called for a JDK class not in the excluded set, requireNonNull will throw. Prefer a safe fallback.

Apply:

-            return requireNonNull(getExcludedSystemPackageScope(callerClass));
+            var scope = getExcludedSystemPackageScope(callerClass);
+            return scope != null ? scope : PolicyScope.unknown(callerClass.getModule().getName());

Alternatively, throw with a clear message:

-            return requireNonNull(getExcludedSystemPackageScope(callerClass));
+            return java.util.Objects.requireNonNull(
+                getExcludedSystemPackageScope(callerClass),
+                "Missing excluded-system package scope for " + callerClass.getName()
+            );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
PolicyScope getScope(Class<?> callerClass) {
var callerCodeSource = callerClass.getProtectionDomain().getCodeSource();
assert callerCodeSource != null;
if (callerCodeSource == null) {
// This only happens for JDK classes. Furthermore, for trivially allowed modules, we shouldn't even get here.
// Hence, this must be an excluded system module, so check for that.
return requireNonNull(getExcludedSystemPackageScope(callerClass));
}
PolicyScope getScope(Class<?> callerClass) {
var callerCodeSource = callerClass.getProtectionDomain().getCodeSource();
if (callerCodeSource == null) {
// This only happens for JDK classes. Furthermore, for trivially allowed modules, we shouldn't even get here.
// Hence, this must be an excluded system module, so check for that.
var scope = getExcludedSystemPackageScope(callerClass);
return scope != null
? scope
: PolicyScope.unknown(callerClass.getModule().getName());
}
}
🤖 Prompt for AI Agents
In
test/framework/src/main/java/org/elasticsearch/bootstrap/TestScopeResolver.java
around lines 70 to 76, avoid using
requireNonNull(getExcludedSystemPackageScope(callerClass)) because if a JDK
class that is not in the excluded set reaches this point it will cause an NPE;
instead capture the result into a local variable, check it for null, and if null
throw an IllegalStateException with a clear message that includes the
callerClass name (or alternatively return an explicit safe default PolicyScope
if that is more appropriate for your design).

@phananh1010 phananh1010 closed this Oct 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant