Skip to content

Commit

Permalink
[Backport 2.x] Add ThreadContextPermission for stashAndMergeHeaders a…
Browse files Browse the repository at this point in the history
…nd stashWithOrigin (#15049)

* Add ThreadContextPermission for stashAndMergeHeaders and stashWithOrigin (#15039)

* Add ThreadContextPermission for stashAndMergeHeaders and stashWithOrigin

Signed-off-by: Craig Perkins <cwperx@amazon.com>

* Add to CHANGELOG

Signed-off-by: Craig Perkins <cwperx@amazon.com>

* Use ThreadContextAccess

Signed-off-by: Craig Perkins <cwperx@amazon.com>

---------

Signed-off-by: Craig Perkins <cwperx@amazon.com>

* Add deprecationLogger

Signed-off-by: Craig Perkins <cwperx@amazon.com>

---------

Signed-off-by: Craig Perkins <cwperx@amazon.com>
  • Loading branch information
cwperks committed Jul 31, 2024
1 parent 1002c03 commit ee74e56
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Add setting to ignore throttling nodes for allocation of unassigned primaries in remote restore ([#14991](https://github.com/opensearch-project/OpenSearch/pull/14991))
- Add basic aggregation support for derived fields ([#14618](https://github.com/opensearch-project/OpenSearch/pull/14618))
- Add ThreadContextPermission for markAsSystemContext and allow core to perform the method ([#15016](https://github.com/opensearch-project/OpenSearch/pull/15016))
- Add ThreadContextPermission for stashAndMergeHeaders and stashWithOrigin ([#15039](https://github.com/opensearch-project/OpenSearch/pull/15039))

### Dependencies
- Bump `org.apache.commons:commons-lang3` from 3.14.0 to 3.15.0 ([#14861](https://github.com/opensearch-project/OpenSearch/pull/14861))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.opensearch.action.ActionType;
import org.opensearch.action.support.ContextPreservingActionListener;
import org.opensearch.common.util.concurrent.ThreadContext;
import org.opensearch.common.util.concurrent.ThreadContextAccess;
import org.opensearch.core.action.ActionListener;
import org.opensearch.core.action.ActionResponse;

Expand Down Expand Up @@ -65,7 +66,11 @@ protected <Request extends ActionRequest, Response extends ActionResponse> void
ActionListener<Response> listener
) {
final Supplier<ThreadContext.StoredContext> supplier = in().threadPool().getThreadContext().newRestorableContext(false);
try (ThreadContext.StoredContext ignore = in().threadPool().getThreadContext().stashWithOrigin(origin)) {
try (
ThreadContext.StoredContext ignore = ThreadContextAccess.doPrivileged(
() -> in().threadPool().getThreadContext().stashWithOrigin(origin)
)
) {
super.doExecute(action, request, new ContextPreservingActionListener<>(supplier, listener));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@
import org.opensearch.common.action.ActionFuture;
import org.opensearch.common.settings.Settings;
import org.opensearch.common.util.concurrent.ThreadContext;
import org.opensearch.common.util.concurrent.ThreadContextAccess;
import org.opensearch.core.action.ActionListener;
import org.opensearch.core.action.ActionResponse;
import org.opensearch.core.common.bytes.BytesReference;
Expand Down Expand Up @@ -2082,7 +2083,9 @@ protected <Request extends ActionRequest, Response extends ActionResponse> void
ActionListener<Response> listener
) {
ThreadContext threadContext = threadPool().getThreadContext();
try (ThreadContext.StoredContext ctx = threadContext.stashAndMergeHeaders(headers)) {
try (
ThreadContext.StoredContext ctx = ThreadContextAccess.doPrivileged(() -> threadContext.stashAndMergeHeaders(headers))
) {
super.doExecute(action, request, listener);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ public final class ThreadContext implements Writeable {
// thread context permissions

private static final Permission ACCESS_SYSTEM_THREAD_CONTEXT_PERMISSION = new ThreadContextPermission("markAsSystemContext");
private static final Permission STASH_AND_MERGE_THREAD_CONTEXT_PERMISSION = new ThreadContextPermission("stashAndMergeHeaders");
private static final Permission STASH_WITH_ORIGIN_THREAD_CONTEXT_PERMISSION = new ThreadContextPermission("stashWithOrigin");

private static final Logger logger = LogManager.getLogger(ThreadContext.class);
private static final ThreadContextStruct DEFAULT_CONTEXT = new ThreadContextStruct();
Expand Down Expand Up @@ -215,6 +217,17 @@ public Writeable captureAsWriteable() {
* if it can't find the task in memory.
*/
public StoredContext stashWithOrigin(String origin) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
try {
sm.checkPermission(STASH_WITH_ORIGIN_THREAD_CONTEXT_PERMISSION);
} catch (SecurityException ex) {
deprecationLogger.deprecate(
"stashWithOrigin",
"Default access to stashWithOrigin will be removed in a future release. Permission to use stashWithOrigin must be explicitly granted."
);
}
}
final ThreadContext.StoredContext storedContext = stashContext();
putTransient(ACTION_ORIGIN_TRANSIENT_NAME, origin);
return storedContext;
Expand All @@ -226,6 +239,17 @@ public StoredContext stashWithOrigin(String origin) {
* that are already existing are preserved unless they are defaults.
*/
public StoredContext stashAndMergeHeaders(Map<String, String> headers) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
try {
sm.checkPermission(STASH_AND_MERGE_THREAD_CONTEXT_PERMISSION);
} catch (SecurityException ex) {
deprecationLogger.deprecate(
"stashAndMergeHeaders",
"Default access to stashAndMergeHeaders will be removed in a future release. Permission to use stashAndMergeHeaders must be explicitly granted."
);
}
}
final ThreadContextStruct context = threadLocal.get();
Map<String, String> newHeader = new HashMap<>(headers);
newHeader.putAll(context.requestHeaders);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ grant codeBase "${codebase.opensearch}" {
// needed for SPI class loading
permission java.lang.RuntimePermission "accessDeclaredMembers";
permission org.opensearch.secure_sm.ThreadContextPermission "markAsSystemContext";
permission org.opensearch.secure_sm.ThreadContextPermission "stashWithOrigin";
};

//// Very special jar permissions:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,6 @@ grant {
permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect";
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
permission org.opensearch.secure_sm.ThreadContextPermission "markAsSystemContext";
permission org.opensearch.secure_sm.ThreadContextPermission "stashAndMergeHeaders";
permission org.opensearch.secure_sm.ThreadContextPermission "stashWithOrigin";
};
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ public void testStashWithOrigin() {
}

assertNull(threadContext.getTransient(ThreadContext.ACTION_ORIGIN_TRANSIENT_NAME));
try (ThreadContext.StoredContext storedContext = threadContext.stashWithOrigin(origin)) {
try (ThreadContext.StoredContext storedContext = ThreadContextAccess.doPrivileged(() -> threadContext.stashWithOrigin(origin))) {
assertEquals(origin, threadContext.getTransient(ThreadContext.ACTION_ORIGIN_TRANSIENT_NAME));
assertNull(threadContext.getTransient("foo"));
assertNull(threadContext.getTransient("bar"));
Expand All @@ -231,7 +231,7 @@ public void testStashAndMerge() {
HashMap<String, String> toMerge = new HashMap<>();
toMerge.put("foo", "baz");
toMerge.put("simon", "says");
try (ThreadContext.StoredContext ctx = threadContext.stashAndMergeHeaders(toMerge)) {
try (ThreadContext.StoredContext ctx = ThreadContextAccess.doPrivileged(() -> threadContext.stashAndMergeHeaders(toMerge))) {
assertEquals("bar", threadContext.getHeader("foo"));
assertEquals("says", threadContext.getHeader("simon"));
assertNull(threadContext.getTransient("ctx.foo"));
Expand Down Expand Up @@ -493,7 +493,13 @@ public void testStashAndMergeWithModifiedDefaults() {
ThreadContext threadContext = new ThreadContext(build);
HashMap<String, String> toMerge = new HashMap<>();
toMerge.put("default", "2");
try (ThreadContext.StoredContext ctx = threadContext.stashAndMergeHeaders(toMerge)) {
ThreadContext finalThreadContext1 = threadContext;
HashMap<String, String> finalToMerge1 = toMerge;
try (
ThreadContext.StoredContext ctx = ThreadContextAccess.doPrivileged(
() -> finalThreadContext1.stashAndMergeHeaders(finalToMerge1)
)
) {
assertEquals("2", threadContext.getHeader("default"));
}

Expand All @@ -502,7 +508,13 @@ public void testStashAndMergeWithModifiedDefaults() {
threadContext.putHeader("default", "4");
toMerge = new HashMap<>();
toMerge.put("default", "2");
try (ThreadContext.StoredContext ctx = threadContext.stashAndMergeHeaders(toMerge)) {
ThreadContext finalThreadContext2 = threadContext;
HashMap<String, String> finalToMerge2 = toMerge;
try (
ThreadContext.StoredContext ctx = ThreadContextAccess.doPrivileged(
() -> finalThreadContext2.stashAndMergeHeaders(finalToMerge2)
)
) {
assertEquals("4", threadContext.getHeader("default"));
}
}
Expand Down

0 comments on commit ee74e56

Please sign in to comment.