Skip to content

Commit ee74e56

Browse files
authored
[Backport 2.x] Add ThreadContextPermission for stashAndMergeHeaders and stashWithOrigin (opensearch-project#15049)
* Add ThreadContextPermission for stashAndMergeHeaders and stashWithOrigin (opensearch-project#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>
1 parent 1002c03 commit ee74e56

File tree

7 files changed

+54
-6
lines changed

7 files changed

+54
-6
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
99
- Add setting to ignore throttling nodes for allocation of unassigned primaries in remote restore ([#14991](https://github.com/opensearch-project/OpenSearch/pull/14991))
1010
- Add basic aggregation support for derived fields ([#14618](https://github.com/opensearch-project/OpenSearch/pull/14618))
1111
- Add ThreadContextPermission for markAsSystemContext and allow core to perform the method ([#15016](https://github.com/opensearch-project/OpenSearch/pull/15016))
12+
- Add ThreadContextPermission for stashAndMergeHeaders and stashWithOrigin ([#15039](https://github.com/opensearch-project/OpenSearch/pull/15039))
1213

1314
### Dependencies
1415
- Bump `org.apache.commons:commons-lang3` from 3.14.0 to 3.15.0 ([#14861](https://github.com/opensearch-project/OpenSearch/pull/14861))

server/src/main/java/org/opensearch/client/OriginSettingClient.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.opensearch.action.ActionType;
3737
import org.opensearch.action.support.ContextPreservingActionListener;
3838
import org.opensearch.common.util.concurrent.ThreadContext;
39+
import org.opensearch.common.util.concurrent.ThreadContextAccess;
3940
import org.opensearch.core.action.ActionListener;
4041
import org.opensearch.core.action.ActionResponse;
4142

@@ -65,7 +66,11 @@ protected <Request extends ActionRequest, Response extends ActionResponse> void
6566
ActionListener<Response> listener
6667
) {
6768
final Supplier<ThreadContext.StoredContext> supplier = in().threadPool().getThreadContext().newRestorableContext(false);
68-
try (ThreadContext.StoredContext ignore = in().threadPool().getThreadContext().stashWithOrigin(origin)) {
69+
try (
70+
ThreadContext.StoredContext ignore = ThreadContextAccess.doPrivileged(
71+
() -> in().threadPool().getThreadContext().stashWithOrigin(origin)
72+
)
73+
) {
6974
super.doExecute(action, request, new ContextPreservingActionListener<>(supplier, listener));
7075
}
7176
}

server/src/main/java/org/opensearch/client/support/AbstractClient.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@
410410
import org.opensearch.common.action.ActionFuture;
411411
import org.opensearch.common.settings.Settings;
412412
import org.opensearch.common.util.concurrent.ThreadContext;
413+
import org.opensearch.common.util.concurrent.ThreadContextAccess;
413414
import org.opensearch.core.action.ActionListener;
414415
import org.opensearch.core.action.ActionResponse;
415416
import org.opensearch.core.common.bytes.BytesReference;
@@ -2082,7 +2083,9 @@ protected <Request extends ActionRequest, Response extends ActionResponse> void
20822083
ActionListener<Response> listener
20832084
) {
20842085
ThreadContext threadContext = threadPool().getThreadContext();
2085-
try (ThreadContext.StoredContext ctx = threadContext.stashAndMergeHeaders(headers)) {
2086+
try (
2087+
ThreadContext.StoredContext ctx = ThreadContextAccess.doPrivileged(() -> threadContext.stashAndMergeHeaders(headers))
2088+
) {
20862089
super.doExecute(action, request, listener);
20872090
}
20882091
}

server/src/main/java/org/opensearch/common/util/concurrent/ThreadContext.java

+24
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ public final class ThreadContext implements Writeable {
118118
// thread context permissions
119119

120120
private static final Permission ACCESS_SYSTEM_THREAD_CONTEXT_PERMISSION = new ThreadContextPermission("markAsSystemContext");
121+
private static final Permission STASH_AND_MERGE_THREAD_CONTEXT_PERMISSION = new ThreadContextPermission("stashAndMergeHeaders");
122+
private static final Permission STASH_WITH_ORIGIN_THREAD_CONTEXT_PERMISSION = new ThreadContextPermission("stashWithOrigin");
121123

122124
private static final Logger logger = LogManager.getLogger(ThreadContext.class);
123125
private static final ThreadContextStruct DEFAULT_CONTEXT = new ThreadContextStruct();
@@ -215,6 +217,17 @@ public Writeable captureAsWriteable() {
215217
* if it can't find the task in memory.
216218
*/
217219
public StoredContext stashWithOrigin(String origin) {
220+
SecurityManager sm = System.getSecurityManager();
221+
if (sm != null) {
222+
try {
223+
sm.checkPermission(STASH_WITH_ORIGIN_THREAD_CONTEXT_PERMISSION);
224+
} catch (SecurityException ex) {
225+
deprecationLogger.deprecate(
226+
"stashWithOrigin",
227+
"Default access to stashWithOrigin will be removed in a future release. Permission to use stashWithOrigin must be explicitly granted."
228+
);
229+
}
230+
}
218231
final ThreadContext.StoredContext storedContext = stashContext();
219232
putTransient(ACTION_ORIGIN_TRANSIENT_NAME, origin);
220233
return storedContext;
@@ -226,6 +239,17 @@ public StoredContext stashWithOrigin(String origin) {
226239
* that are already existing are preserved unless they are defaults.
227240
*/
228241
public StoredContext stashAndMergeHeaders(Map<String, String> headers) {
242+
SecurityManager sm = System.getSecurityManager();
243+
if (sm != null) {
244+
try {
245+
sm.checkPermission(STASH_AND_MERGE_THREAD_CONTEXT_PERMISSION);
246+
} catch (SecurityException ex) {
247+
deprecationLogger.deprecate(
248+
"stashAndMergeHeaders",
249+
"Default access to stashAndMergeHeaders will be removed in a future release. Permission to use stashAndMergeHeaders must be explicitly granted."
250+
);
251+
}
252+
}
229253
final ThreadContextStruct context = threadLocal.get();
230254
Map<String, String> newHeader = new HashMap<>(headers);
231255
newHeader.putAll(context.requestHeaders);

server/src/main/resources/org/opensearch/bootstrap/security.policy

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ grant codeBase "${codebase.opensearch}" {
4949
// needed for SPI class loading
5050
permission java.lang.RuntimePermission "accessDeclaredMembers";
5151
permission org.opensearch.secure_sm.ThreadContextPermission "markAsSystemContext";
52+
permission org.opensearch.secure_sm.ThreadContextPermission "stashWithOrigin";
5253
};
5354

5455
//// Very special jar permissions:

server/src/main/resources/org/opensearch/bootstrap/test-framework.policy

+2
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,6 @@ grant {
148148
permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect";
149149
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
150150
permission org.opensearch.secure_sm.ThreadContextPermission "markAsSystemContext";
151+
permission org.opensearch.secure_sm.ThreadContextPermission "stashAndMergeHeaders";
152+
permission org.opensearch.secure_sm.ThreadContextPermission "stashWithOrigin";
151153
};

server/src/test/java/org/opensearch/common/util/concurrent/ThreadContextTests.java

+16-4
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ public void testStashWithOrigin() {
206206
}
207207

208208
assertNull(threadContext.getTransient(ThreadContext.ACTION_ORIGIN_TRANSIENT_NAME));
209-
try (ThreadContext.StoredContext storedContext = threadContext.stashWithOrigin(origin)) {
209+
try (ThreadContext.StoredContext storedContext = ThreadContextAccess.doPrivileged(() -> threadContext.stashWithOrigin(origin))) {
210210
assertEquals(origin, threadContext.getTransient(ThreadContext.ACTION_ORIGIN_TRANSIENT_NAME));
211211
assertNull(threadContext.getTransient("foo"));
212212
assertNull(threadContext.getTransient("bar"));
@@ -231,7 +231,7 @@ public void testStashAndMerge() {
231231
HashMap<String, String> toMerge = new HashMap<>();
232232
toMerge.put("foo", "baz");
233233
toMerge.put("simon", "says");
234-
try (ThreadContext.StoredContext ctx = threadContext.stashAndMergeHeaders(toMerge)) {
234+
try (ThreadContext.StoredContext ctx = ThreadContextAccess.doPrivileged(() -> threadContext.stashAndMergeHeaders(toMerge))) {
235235
assertEquals("bar", threadContext.getHeader("foo"));
236236
assertEquals("says", threadContext.getHeader("simon"));
237237
assertNull(threadContext.getTransient("ctx.foo"));
@@ -493,7 +493,13 @@ public void testStashAndMergeWithModifiedDefaults() {
493493
ThreadContext threadContext = new ThreadContext(build);
494494
HashMap<String, String> toMerge = new HashMap<>();
495495
toMerge.put("default", "2");
496-
try (ThreadContext.StoredContext ctx = threadContext.stashAndMergeHeaders(toMerge)) {
496+
ThreadContext finalThreadContext1 = threadContext;
497+
HashMap<String, String> finalToMerge1 = toMerge;
498+
try (
499+
ThreadContext.StoredContext ctx = ThreadContextAccess.doPrivileged(
500+
() -> finalThreadContext1.stashAndMergeHeaders(finalToMerge1)
501+
)
502+
) {
497503
assertEquals("2", threadContext.getHeader("default"));
498504
}
499505

@@ -502,7 +508,13 @@ public void testStashAndMergeWithModifiedDefaults() {
502508
threadContext.putHeader("default", "4");
503509
toMerge = new HashMap<>();
504510
toMerge.put("default", "2");
505-
try (ThreadContext.StoredContext ctx = threadContext.stashAndMergeHeaders(toMerge)) {
511+
ThreadContext finalThreadContext2 = threadContext;
512+
HashMap<String, String> finalToMerge2 = toMerge;
513+
try (
514+
ThreadContext.StoredContext ctx = ThreadContextAccess.doPrivileged(
515+
() -> finalThreadContext2.stashAndMergeHeaders(finalToMerge2)
516+
)
517+
) {
506518
assertEquals("4", threadContext.getHeader("default"));
507519
}
508520
}

0 commit comments

Comments
 (0)