Skip to content

Commit 796ce92

Browse files
committed
svm: migrate Log4ShellFeature to JVMCI reflection
1 parent c9f81cd commit 796ce92

File tree

1 file changed

+18
-20
lines changed

1 file changed

+18
-20
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/Log4ShellFeature.java

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,29 +26,33 @@
2626

2727
import java.io.IOException;
2828
import java.io.InputStream;
29-
import java.lang.reflect.Method;
3029
import java.net.URISyntaxException;
3130
import java.net.URL;
3231
import java.nio.file.FileSystem;
3332
import java.nio.file.FileSystems;
3433
import java.nio.file.Files;
3534
import java.nio.file.Path;
3635
import java.nio.file.Paths;
37-
import java.security.CodeSource;
38-
import java.security.ProtectionDomain;
3936
import java.util.HashSet;
4037
import java.util.Optional;
4138
import java.util.Properties;
4239
import java.util.Set;
4340
import java.util.stream.Stream;
4441

42+
import com.oracle.graal.pointsto.meta.AnalysisMethod;
43+
import com.oracle.graal.pointsto.meta.AnalysisType;
4544
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
4645
import com.oracle.svm.core.feature.InternalFeature;
4746
import com.oracle.svm.core.traits.BuiltinTraits.BuildtimeAccessOnly;
4847
import com.oracle.svm.core.traits.BuiltinTraits.NoLayeredCallbacks;
4948
import com.oracle.svm.core.traits.SingletonLayeredInstallationKind.Independent;
5049
import com.oracle.svm.core.traits.SingletonTraits;
50+
import com.oracle.svm.hosted.FeatureImpl.AfterAnalysisAccessImpl;
51+
import com.oracle.svm.util.JVMCIReflectionUtil;
5152
import com.oracle.svm.util.LogUtils;
53+
import com.oracle.svm.util.ResolvedJavaPackage;
54+
55+
import jdk.vm.ci.meta.ResolvedJavaType;
5256

5357
/**
5458
* A feature that detects whether a native image may be vulnerable to Log4Shell.
@@ -67,14 +71,8 @@ public class Log4ShellFeature implements InternalFeature {
6771
/* Different versions of log4j overload all these methods. */
6872
private static final Set<String> targetMethods = Set.of("debug", "error", "fatal", "info", "log", "trace", "warn");
6973

70-
private static Optional<String> getPomVersion(Class<?> log4jClass) {
71-
ProtectionDomain pd = log4jClass.getProtectionDomain();
72-
CodeSource cs = pd.getCodeSource();
73-
74-
if (cs == null) {
75-
return Optional.empty();
76-
}
77-
URL location = cs.getLocation();
74+
private static Optional<String> getPomVersion(ResolvedJavaType log4jClass) {
75+
URL location = JVMCIReflectionUtil.getOrigin(log4jClass);
7876
if (location == null) {
7977
return Optional.empty();
8078
}
@@ -148,20 +146,20 @@ private static boolean vulnerableLog4jTwo(String[] components) {
148146
return false;
149147
}
150148

151-
private AfterAnalysisAccess afterAnalysisAccess;
149+
private AfterAnalysisAccessImpl afterAnalysisAccess;
152150

153151
@Override
154152
public void afterAnalysis(AfterAnalysisAccess access) {
155-
this.afterAnalysisAccess = access;
153+
this.afterAnalysisAccess = (AfterAnalysisAccessImpl) access;
156154
}
157155

158156
public String getUserWarning() {
159-
Class<?> log4jClass = afterAnalysisAccess.findClassByName(log4jClassName);
157+
AnalysisType log4jClass = afterAnalysisAccess.findTypeByName(log4jClassName);
160158
if (log4jClass == null) {
161159
return null;
162160
}
163161

164-
Package log4jPackage = log4jClass.getPackage();
162+
ResolvedJavaPackage log4jPackage = JVMCIReflectionUtil.getPackage(log4jClass);
165163
String version = log4jPackage.getImplementationVersion();
166164

167165
if (version == null) {
@@ -186,21 +184,21 @@ public String getUserWarning() {
186184
Set<String> vulnerableMethods = new HashSet<>();
187185

188186
if (("1".equals(components[0]) && vulnerableLog4jOne(components)) || ("2".equals(components[0]) && vulnerableLog4jTwo(components))) {
189-
for (Method method : log4jClass.getMethods()) {
187+
for (AnalysisMethod method : log4jClass.getDeclaredMethods(false)) {
190188
String methodName = method.getName();
191-
if (targetMethods.contains(methodName) && (afterAnalysisAccess.isReachable(method) || (afterAnalysisAccess.reachableMethodOverrides(method).size() > 0))) {
192-
vulnerableMethods.add(method.getDeclaringClass().getName() + "." + method.getName());
189+
if (targetMethods.contains(methodName) && (afterAnalysisAccess.isReachable(method) || (!afterAnalysisAccess.reachableMethodOverrides(method).isEmpty()))) {
190+
vulnerableMethods.add(method.getDeclaringClass().toClassName() + "." + method.getName());
193191
}
194192
}
195193
}
196194

197-
if (vulnerableMethods.size() == 0) {
195+
if (vulnerableMethods.isEmpty()) {
198196
return null;
199197
}
200198

201199
StringBuilder renderedErrorMessage = new StringBuilder(String.format(log4jVulnerableErrorMessage));
202200
for (String method : vulnerableMethods) {
203-
renderedErrorMessage.append(System.lineSeparator() + " - " + method);
201+
renderedErrorMessage.append(System.lineSeparator()).append(" - ").append(method);
204202
}
205203
return renderedErrorMessage.toString();
206204
}

0 commit comments

Comments
 (0)