Skip to content

Unlimited index privileges cache can lead to OOM #126015

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
slobodanadamovic opened this issue Apr 1, 2025 · 2 comments
Open

Unlimited index privileges cache can lead to OOM #126015

slobodanadamovic opened this issue Apr 1, 2025 · 2 comments
Assignees
Labels
>bug :Security/Authorization Roles, Privileges, DLS/FLS, RBAC/ABAC Team:Security Meta label for security team

Comments

@slobodanadamovic
Copy link
Contributor

Elasticsearch Version

8.x

Installed Plugins

No response

Java Version

bundled

OS Version

all

Problem Description

Currently, the IndexPrivielge#CACHE is an unbounded ConcurrentHashMap. This can lead to a high memory consumption in clusters with many roles.

Local testing showed that roughly ~500 roles with random set of index privileges can lead to OOM errors with 500MB heap.

example stacktrace
java.lang.OutOfMemoryError: Java heap space
	at __randomizedtesting.SeedInfo.seed([FBD32FDE56DB2F8B:2AA7B1D3F0CEEE63]:0)
	at org.apache.lucene.util.ArrayUtil.growExact(ArrayUtil.java:320)
	at org.apache.lucene.util.ArrayUtil.growInRange(ArrayUtil.java:346)
	at org.apache.lucene.util.ArrayUtil.grow(ArrayUtil.java:354)
	at org.apache.lucene.internal.hppc.IntArrayList.ensureBufferSpace(IntArrayList.java:276)
	at org.apache.lucene.internal.hppc.IntArrayList.add(IntArrayList.java:76)
	at org.elasticsearch.lucene.util.automaton.MinimizationOperations.minimize(MinimizationOperations.java:155)
	at org.elasticsearch.xpack.core.security.support.Automatons.minimize(Automatons.java:297)
	at org.elasticsearch.xpack.core.security.support.Automatons.unionAndMinimize(Automatons.java:283)
	at org.elasticsearch.xpack.core.security.authz.privilege.IndexPrivilege.union(IndexPrivilege.java:467)
	at org.elasticsearch.xpack.core.security.authz.privilege.IndexPrivilege.combineIndexPrivileges(IndexPrivilege.java:435)
	at org.elasticsearch.xpack.core.security.authz.privilege.IndexPrivilege.resolve(IndexPrivilege.java:405)
	at org.elasticsearch.xpack.core.security.authz.privilege.IndexPrivilege.lambda$resolveBySelectorAccess$0(IndexPrivilege.java:347)
	at org.elasticsearch.xpack.core.security.authz.privilege.IndexPrivilege$$Lambda/0x000003f8003f3888.apply(Unknown Source)
	at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1756)
	at org.elasticsearch.xpack.core.security.authz.privilege.IndexPrivilege.resolveBySelectorAccess(IndexPrivilege.java:343)
	at org.elasticsearch.xpack.core.security.action.role.RoleDescriptorRequestValidator.validate(RoleDescriptorRequestValidator.java:53)
	at org.elasticsearch.xpack.core.security.action.role.RoleDescriptorRequestValidator.validate(RoleDescriptorRequestValidator.java:31)
	at org.elasticsearch.xpack.core.security.action.role.RoleDescriptorRequestValidatorTests.validateAndAssertSelectorNotAllowed(RoleDescriptorRequestValidatorTests.java:57)
	at org.elasticsearch.xpack.core.security.action.role.RoleDescriptorRequestValidatorTests.testSelectorsValidation(RoleDescriptorRequestValidatorTests.java:38)
	at java.base/java.lang.invoke.LambdaForm$DMH/0x000003f800000c00.invokeVirtual(LambdaForm$DMH)
	at java.base/java.lang.invoke.LambdaForm$MH/0x000003f800402800.invoke(LambdaForm$MH)
	at java.base/java.lang.invoke.Invokers$Holder.invokeExact_MT(Invokers$Holder)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(DirectMethodHandleAccessor.java:154)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at com.carrotsearch.randomizedtesting.RandomizedRunner.invoke(RandomizedRunner.java:1763)
	at com.carrotsearch.randomizedtesting.RandomizedRunner$8.evaluate(RandomizedRunner.java:946)
	at com.carrotsearch.randomizedtesting.RandomizedRunner$9.evaluate(RandomizedRunner.java:982)
	at com.carrotsearch.randomizedtesting.RandomizedRunner$10.evaluate(RandomizedRunner.java:996)
	at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
	at org.junit.rules.RunRules.evaluate(RunRules.java:20)
	at org.apache.lucene.tests.util.TestRuleSetupTeardownChained$1.evaluate(TestRuleSetupTeardownChained.java:48)

Steps to Reproduce

  1. Randomly create many roles

Logs (if relevant)

No response

@slobodanadamovic slobodanadamovic added >bug needs:triage Requires assignment of a team area label :Security/Authorization Roles, Privileges, DLS/FLS, RBAC/ABAC Team:Security Meta label for security team and removed needs:triage Requires assignment of a team area label labels Apr 1, 2025
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-security (Team:Security)

@StingNevermore
Copy link

I think we can use the Cache utility from Cache to limit memory usage. The specific approach would be: set a maximum entry limit of 1000 items, with estimated memory consumption around 1-2 MB. Additionally, for permission sets, 1000 entries represents a sufficiently large value. This configuration would help maintain overall system performance while using minimal memory, and also prevent potential OOM (Out-of-Memory) errors in extreme scenarios.No additional test cases need to be added for this change. We only need to ensure that all existing test cases pass successfully.

@ankit--sethi ankit--sethi self-assigned this May 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>bug :Security/Authorization Roles, Privileges, DLS/FLS, RBAC/ABAC Team:Security Meta label for security team
Projects
None yet
Development

No branches or pull requests

4 participants