8327218: Add an ability to specify modules which should have native access enabled

Co-authored-by: Maurizio Cimadamore <mcimadamore@openjdk.org>
Reviewed-by: mcimadamore, erikj, alanb, ihse
This commit is contained in:
Jan Lahoda 2024-03-08 11:21:24 +00:00
parent d0d4912c3b
commit 27a03e0dc3
9 changed files with 123 additions and 26 deletions

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -91,3 +91,50 @@ PLATFORM_MODULES= \
PLATFORM_MODULES_windows= \
jdk.crypto.mscapi \
#
NATIVE_ACCESS_MODULES= \
java.base \
java.datatransfer \
java.desktop \
java.instrument \
java.logging \
java.management \
java.management.rmi \
java.naming \
java.net.http \
java.prefs \
java.rmi \
java.scripting \
java.se \
java.security.jgss \
java.security.sasl \
java.smartcardio \
java.sql \
java.sql.rowset \
java.transaction.xa \
java.xml \
java.xml.crypto \
jdk.accessibility \
jdk.charsets \
jdk.crypto.cryptoki \
jdk.dynalink \
jdk.httpserver \
jdk.incubator.vector \
jdk.internal.vm.ci \
jdk.jfr \
jdk.jsobject \
jdk.localedata \
jdk.management \
jdk.management.agent \
jdk.management.jfr \
jdk.naming.dns \
jdk.naming.rmi \
jdk.net \
jdk.nio.mapmode \
jdk.sctp \
jdk.security.auth \
jdk.security.jgss \
jdk.unsupported \
jdk.xml.dom \
jdk.zipfs \
#

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -48,6 +48,7 @@ public class GenModuleLoaderMap {
// default set of boot modules and ext modules
Stream<String> bootModules = Stream.empty();
Stream<String> platformModules = Stream.empty();
Stream<String> nativeAccessModules = Stream.empty();
Path outfile = null;
Path source = null;
for (int i=0; i < args.length; i++) {
@ -60,6 +61,9 @@ public class GenModuleLoaderMap {
} else if (option.equals("-platform")) {
String[] mns = arg.split(",");
platformModules = Stream.concat(platformModules, Arrays.stream(mns));
} else if (option.equals("-native-access")) {
String[] mns = arg.split(",");
nativeAccessModules = Stream.concat(nativeAccessModules, Arrays.stream(mns));
} else if (option.equals("-o")) {
outfile = Paths.get(arg);
} else {
@ -84,6 +88,8 @@ public class GenModuleLoaderMap {
line = patch(line, "@@BOOT_MODULE_NAMES@@", bootModules);
} else if (line.contains("@@PLATFORM_MODULE_NAMES@@")) {
line = patch(line, "@@PLATFORM_MODULE_NAMES@@", platformModules);
} else if (line.contains("@@NATIVE_ACCESS_MODULE_NAMES@@")) {
line = patch(line, "@@NATIVE_ACCESS_MODULE_NAMES@@", nativeAccessModules);
}
writer.println(line);
}

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -37,8 +37,9 @@ $(strip \
endef
BOOT_MODULES_LIST := $(call SubstComma, $(BOOT_MODULES))
PLATFORM_MODULES_LIST := $(call SubstComma, $(PLATFORM_MODULES))
NATIVE_ACCESS_MODULES_LIST := $(call SubstComma, $(NATIVE_ACCESS_MODULES))
VARDEPS_VALUE := $(BOOT_MODULES_LIST) $(PLATFORM_MODULES_LIST)
VARDEPS_VALUE := $(BOOT_MODULES_LIST) $(PLATFORM_MODULES_LIST) $(NATIVE_ACCESS_MODULES_LIST)
VARDEPS_FILE := $(call DependOnVariable, VARDEPS_VALUE)
############################################################################
@ -49,7 +50,9 @@ $(SUPPORT_OUTPUTDIR)/gensrc/java.base/jdk/internal/module/ModuleLoaderMap.java:
$(call MakeTargetDir)
$(RM) $@ $@.tmp
$(TOOL_GENCLASSLOADERMAP) -boot $(BOOT_MODULES_LIST) \
-platform $(PLATFORM_MODULES_LIST) -o $@.tmp $<
-platform $(PLATFORM_MODULES_LIST) \
-native-access $(NATIVE_ACCESS_MODULES_LIST) \
-o $@.tmp $<
$(MV) $@.tmp $@
TARGETS += $(SUPPORT_OUTPUTDIR)/gensrc/java.base/jdk/internal/module/ModuleLoaderMap.java

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -143,10 +143,6 @@ public final class Module implements AnnotatedElement {
String loc = Objects.toString(uri, null);
Object[] packages = descriptor.packages().toArray();
defineModule0(this, isOpen, vs, loc, packages);
if (loader == null || loader == ClassLoaders.platformClassLoader()) {
// boot/builtin modules are always native
implAddEnableNativeAccess();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -881,6 +881,24 @@ public final class ModuleLayer {
.findAny();
}
/**
* Updates the module with the given {@code name} in this layer
* to allow access to restricted methods.
*
* @param name the name of the module for which the native access
* should be enabled
* @return {@code true} iff the module is present in this layer,
* {@code false} otherwise
*/
boolean addEnableNativeAccess(String name) {
Module m = nameToModule.get(name);
if (m != null) {
m.implAddEnableNativeAccess();
return true;
} else {
return false;
}
}
/**
* Returns the {@code ClassLoader} for the module with the given name. If

View File

@ -2459,6 +2459,9 @@ public final class System {
public Module addEnableNativeAccess(Module m) {
return m.implAddEnableNativeAccess();
}
public boolean addEnableNativeAccess(ModuleLayer layer, String name) {
return layer.addEnableNativeAccess(name);
}
public void addEnableNativeAccessToAllUnnamed() {
Module.implAddEnableNativeAccessToAllUnnamed();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -269,6 +269,12 @@ public interface JavaLangAccess {
*/
Module addEnableNativeAccess(Module m);
/**
* Updates module named {@code name} in layer {@code layer} to allow access to restricted methods.
* Returns true iff the given module exists in the given layer.
*/
boolean addEnableNativeAccess(ModuleLayer layer, String name);
/**
* Updates all unnamed modules to allow access to restricted methods.
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -788,31 +788,38 @@ public final class ModuleBootstrap {
}
private static final boolean HAS_ENABLE_NATIVE_ACCESS_FLAG;
private static final Set<String> NATIVE_ACCESS_MODULES;
private static final Set<String> USER_NATIVE_ACCESS_MODULES;
private static final Set<String> JDK_NATIVE_ACCESS_MODULES;
public static boolean hasEnableNativeAccessFlag() {
return HAS_ENABLE_NATIVE_ACCESS_FLAG;
}
static {
NATIVE_ACCESS_MODULES = decodeEnableNativeAccess();
HAS_ENABLE_NATIVE_ACCESS_FLAG = !NATIVE_ACCESS_MODULES.isEmpty();
USER_NATIVE_ACCESS_MODULES = decodeEnableNativeAccess();
HAS_ENABLE_NATIVE_ACCESS_FLAG = !USER_NATIVE_ACCESS_MODULES.isEmpty();
JDK_NATIVE_ACCESS_MODULES = ModuleLoaderMap.nativeAccessModules();
}
/**
* Process the --enable-native-access option to grant access to restricted methods to selected modules.
* Grants native access to modules selected using the --enable-native-access
* command line option, and also to JDK modules that need the access.
*/
private static void addEnableNativeAccess(ModuleLayer layer) {
for (String name : NATIVE_ACCESS_MODULES) {
addEnableNativeAccess(layer, USER_NATIVE_ACCESS_MODULES, true);
addEnableNativeAccess(layer, JDK_NATIVE_ACCESS_MODULES, false);
}
/**
* Grants native access for the given modules in the given layer.
* Warns optionally about modules that were specified, but not present in the layer.
*/
private static void addEnableNativeAccess(ModuleLayer layer, Set<String> moduleNames, boolean shouldWarn) {
for (String name : moduleNames) {
if (name.equals("ALL-UNNAMED")) {
JLA.addEnableNativeAccessToAllUnnamed();
} else {
Optional<Module> module = layer.findModule(name);
if (module.isPresent()) {
JLA.addEnableNativeAccess(module.get());
} else {
warnUnknownModule(ENABLE_NATIVE_ACCESS, name);
}
} else if (!JLA.addEnableNativeAccess(layer, name) && shouldWarn) {
warnUnknownModule(ENABLE_NATIVE_ACCESS, name);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -110,6 +110,13 @@ public final class ModuleLoaderMap {
return Modules.platformModules;
}
/**
* Returns the names of the modules defined to the application loader which perform native access.
*/
public static Set<String> nativeAccessModules() {
return Modules.nativeAccessModules;
}
private static class Modules {
// list of boot modules is generated at build time.
private static final Set<String> bootModules =
@ -118,6 +125,10 @@ public final class ModuleLoaderMap {
// list of platform modules is generated at build time.
private static final Set<String> platformModules =
Set.of(new String[] { "@@PLATFORM_MODULE_NAMES@@" });
// list of jdk modules is generated at build time.
private static final Set<String> nativeAccessModules =
Set.of(new String[] { "@@NATIVE_ACCESS_MODULE_NAMES@@" });
}
/**