Skip to content

Restrict apm agent entitlements to the system classloader unnamed module#120546

Merged
jdconrad merged 17 commits intoelastic:mainfrom
jdconrad:scriptmodule
Jan 28, 2025
Merged

Restrict apm agent entitlements to the system classloader unnamed module#120546
jdconrad merged 17 commits intoelastic:mainfrom
jdconrad:scriptmodule

Conversation

@jdconrad
Copy link
Contributor

@jdconrad jdconrad commented Jan 21, 2025

This change closes a hole where we assumed any check against an unnamed-module from any classloader was for one of our apm agent. This was not the case and made it so scripts could in theory have the same entitlements as apm agent. Instead we now check to see if a class in an unnamed module is part of the system classloader to ensure it's actually for the apm agent.

Relates to ES-10192

@jdconrad jdconrad added >bug :Core/Infra/Plugins Plugin API and infrastructure auto-backport Automatically create backport pull requests when merged v9.0.0 v8.18.0 labels Jan 21, 2025
@elasticsearchmachine elasticsearchmachine added the Team:Core/Infra Meta label for core/infra team label Jan 21, 2025
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra (Team:Core/Infra)

@elasticsearchmachine
Copy link
Collaborator

Hi @jdconrad, I've created a changelog YAML for you.

@jdconrad jdconrad changed the title Restrict agent entitlements to the system classloader unnamed module Jan 21, 2025
Copy link
Member

@rjernst rjernst left a comment

Choose a reason for hiding this comment

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

Looks good, a couple suggestions


private static PolicyManager policyManagerWithEntitlementsModule(Module entitlementsModule) {
return new PolicyManager(createEmptyTestServerPolicy(), List.of(), Map.of(), c -> "test", entitlementsModule);
private static PolicyManager policyManagerWithEntitlementsModule(Module agentsModule, Module entitlementsModule) {
Copy link
Member

Choose a reason for hiding this comment

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

nit, the method name is no longer accurate. Could this just be policyManager(...) now?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.


var policyManager = policyManagerWithEntitlementsModule(entitlementsClass.getModule());
var policyManager = policyManagerWithEntitlementsModule(
ClassLoader.getSystemClassLoader().getUnnamedModule(),
Copy link
Member

Choose a reason for hiding this comment

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

Instead of relying on the real classloader, can we create a test class in its own loader, similar to the above makeClassInItsOwnModule above? Then we can test that class gets the right policy when another class in an unnamed module does not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a test for a test agents module.

List.of(),
Map.of("plugin1", createPluginPolicy("plugin.module")),
c -> "plugin1",
NO_ENTITLEMENTS_MODULE,
Copy link
Member

Choose a reason for hiding this comment

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

Rather than reuse NO_ENTITLEMENTS_MODULE, can we create a test specific agents module?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

@ldematte
Copy link
Contributor

Looks good to me too, but ++ on all of Ryan's comments above

@jdconrad
Copy link
Contributor Author

@rjernst @ldematte Thank you for the reviews! I have updated this PR based on the feedback.

@jdconrad
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/part-2

Copy link
Contributor

@ldematte ldematte left a comment

Choose a reason for hiding this comment

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

LGTM; I'd add one additional test, but that's up to you

ModuleEntitlements agentsEntitlements = policyManager.getEntitlements(agentsClass);
assertThat(agentsEntitlements.hasEntitlement(CreateClassLoaderEntitlement.class), is(true));
ModuleEntitlements notAgentsEntitlements = policyManager.getEntitlements(notAgentsClass);
assertThat(notAgentsEntitlements.hasEntitlement(CreateClassLoaderEntitlement.class), is(false));
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I'd like a check that uses two unnamed modules, to show that using named/unnamed is no longer a factor.
It should be simple, create 2 classloaders, load 2 classes (even the same) with them, and use classloader.getUnnamedModule() to pass to PolicyManager fot the agent module for one of the 2.
Even if it's the "same" class, one should pass, the other should not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a good idea! I will add this.

@jdconrad jdconrad requested a review from a team as a code owner January 27, 2025 19:37
<method v="2" />
</configuration>
</component>
</component> No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you mean to commit this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, sigh.

@jdconrad jdconrad merged commit 343ec0b into elastic:main Jan 28, 2025
21 checks passed
jdconrad added a commit to jdconrad/elasticsearch that referenced this pull request Jan 28, 2025
…le (elastic#120546)

This change closes a hole where we assumed any check against an unnamed-module from any 
classloader was for one of our apm agent. This was not the case and made it so scripts could in theory 
have the same entitlements as apm agent. Instead we now check to see if a class is part of the apm 
package in an unnamed module to ensure it's actually for the apm agent.

Relates to ES-10192
@elasticsearchmachine
Copy link
Collaborator

💚 Backport successful

Status Branch Result
8.x
elasticsearchmachine pushed a commit that referenced this pull request Jan 28, 2025
…le (#120546) (#121054)

This change closes a hole where we assumed any check against an unnamed-module from any 
classloader was for one of our apm agent. This was not the case and made it so scripts could in theory 
have the same entitlements as apm agent. Instead we now check to see if a class is part of the apm 
package in an unnamed module to ensure it's actually for the apm agent.

Relates to ES-10192
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-backport Automatically create backport pull requests when merged >bug :Core/Infra/Plugins Plugin API and infrastructure Team:Core/Infra Meta label for core/infra team v8.18.0 v9.0.0

5 participants