Skip to content

Commit bbe9c29

Browse files
committed
HADOOP-19668 optimization: Use native subject inheritance if supported
1 parent b24614a commit bbe9c29

File tree

4 files changed

+65
-48
lines changed

4 files changed

+65
-48
lines changed

hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/SubjectUtil.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818

1919
package org.apache.hadoop.security.authentication.util;
2020

21+
import static org.junit.jupiter.api.Assertions.assertEquals;
22+
import static org.junit.jupiter.api.Assertions.assertNull;
23+
2124
import java.lang.invoke.MethodHandle;
2225
import java.lang.invoke.MethodHandles;
2326
import java.lang.invoke.MethodType;
@@ -56,6 +59,13 @@ public final class SubjectUtil {
5659
HAS_CALL_AS ? null : lookupDoAsThrowException();
5760
private static final MethodHandle CURRENT = lookupCurrent();
5861

62+
// copied from org.apache.hadoop.util.Shell to break circular dependency
63+
// "1.8"->8, "9"->9, "10"->10
64+
private static final int JAVA_SPEC_VER = Math.max(8,
65+
Integer.parseInt(System.getProperty("java.specification.version").split("\\.")[0]));
66+
67+
public static final boolean THREAD_INHERITS_SUBJECT = checkThreadInheritsSubject();
68+
5969
private static MethodHandle lookupCallAs() {
6070
MethodHandles.Lookup lookup = MethodHandles.lookup();
6171
try {
@@ -71,6 +81,23 @@ private static MethodHandle lookupCallAs() {
7181
}
7282
}
7383

84+
private static boolean checkThreadInheritsSubject() {
85+
86+
boolean securityManagerEnabled = true;
87+
try {
88+
SecurityManager sm = System.getSecurityManager();
89+
System.setSecurityManager(sm);
90+
} catch (UnsupportedOperationException e) {
91+
// JDK24+ always throws this, so we don't need to check for that
92+
// separately
93+
securityManagerEnabled = false;
94+
} catch (Throwable t) {
95+
// don't care
96+
}
97+
98+
return JAVA_SPEC_VER < 22 || securityManagerEnabled;
99+
}
100+
74101
private static MethodHandle lookupDoAs() {
75102
MethodHandles.Lookup lookup = MethodHandles.lookup();
76103
try {

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/Daemon.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ public class Daemon extends Thread {
4545

4646
@Override
4747
public final void start() {
48-
startSubject = SubjectUtil.current();
48+
if (!SubjectUtil.THREAD_INHERITS_SUBJECT) {
49+
startSubject = SubjectUtil.current();
50+
}
4951
super.start();
5052
}
5153

@@ -60,15 +62,19 @@ public void work() {
6062

6163
@Override
6264
public final void run() {
63-
SubjectUtil.doAs(startSubject, new PrivilegedAction<Void>() {
64-
65-
@Override
66-
public Void run() {
67-
work();
68-
return null;
69-
}
70-
71-
});
65+
if (!SubjectUtil.THREAD_INHERITS_SUBJECT) {
66+
SubjectUtil.doAs(startSubject, new PrivilegedAction<Void>() {
67+
68+
@Override
69+
public Void run() {
70+
work();
71+
return null;
72+
}
73+
74+
});
75+
} else {
76+
work();
77+
}
7278
}
7379

7480
{

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/concurrent/SubjectInheritingThread.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,9 @@ public SubjectInheritingThread(ThreadGroup group, Runnable target, String name)
161161
*/
162162
@Override
163163
public final void start() {
164-
startSubject = SubjectUtil.current();
164+
if (!SubjectUtil.THREAD_INHERITS_SUBJECT) {
165+
startSubject = SubjectUtil.current();
166+
}
165167
super.start();
166168
}
167169

@@ -181,14 +183,18 @@ public void work() {
181183
*/
182184
@Override
183185
public final void run() {
184-
SubjectUtil.doAs(startSubject, new PrivilegedAction<Void>() {
185-
186-
@Override
187-
public Void run() {
188-
work();
189-
return null;
190-
}
191-
192-
});
186+
if (!SubjectUtil.THREAD_INHERITS_SUBJECT) {
187+
SubjectUtil.doAs(startSubject, new PrivilegedAction<Void>() {
188+
189+
@Override
190+
public Void run() {
191+
work();
192+
return null;
193+
}
194+
195+
});
196+
} else {
197+
work();
198+
}
193199
}
194200
}

hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/concurrent/TestSubjectPropagation.java

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -146,22 +146,11 @@ public void run() {
146146
}
147147
});
148148

149-
boolean securityManagerEnabled = true;
150-
try {
151-
SecurityManager sm = System.getSecurityManager();
152-
System.setSecurityManager(sm);
153-
} catch (UnsupportedOperationException e) {
154-
// JDK24+ always throws this
155-
securityManagerEnabled = false;
156-
} catch (Throwable t) {
157-
// don't care
158-
}
159-
160-
if (Shell.isJavaVersionAtLeast(22) && !securityManagerEnabled) {
149+
if (SubjectUtil.THREAD_INHERITS_SUBJECT) {
150+
assertEquals(parentSubject, childSubject);
151+
} else {
161152
// This is the behaviour that breaks Hadoop authorization
162153
assertNull(childSubject);
163-
} else {
164-
assertEquals(parentSubject, childSubject);
165154
}
166155
}
167156

@@ -186,22 +175,11 @@ public void run() {
186175
}
187176
});
188177

189-
boolean securityManagerEnabled = true;
190-
try {
191-
SecurityManager sm = System.getSecurityManager();
192-
System.setSecurityManager(sm);
193-
} catch (UnsupportedOperationException e) {
194-
// JDK24+ always throws this
195-
securityManagerEnabled = false;
196-
} catch (Throwable t) {
197-
// don't care
198-
}
199-
200-
if (Shell.isJavaVersionAtLeast(22) && !securityManagerEnabled) {
178+
if (SubjectUtil.THREAD_INHERITS_SUBJECT) {
179+
assertEquals(parentSubject, childSubject);
180+
} else {
201181
// This is the behaviour that breaks Hadoop authorization
202182
assertNull(childSubject);
203-
} else {
204-
assertEquals(parentSubject, childSubject);
205183
}
206184
}
207185

0 commit comments

Comments
 (0)