You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2018/01/25 09:33:43 UTC
ignite git commit: ignite-6643 Marshalling improvements
Repository: ignite
Updated Branches:
refs/heads/master ce96e4f3e -> 340569b8f
ignite-6643 Marshalling improvements
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/340569b8
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/340569b8
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/340569b8
Branch: refs/heads/master
Commit: 340569b8f4e14a4cb61a9407ed2d9aa4a20bdf49
Parents: ce96e4f
Author: Andrey Gura <ag...@apache.org>
Authored: Mon Jan 22 22:41:54 2018 +0300
Committer: Andrey Gura <ag...@apache.org>
Committed: Thu Jan 25 12:29:47 2018 +0300
----------------------------------------------------------------------
.../apache/ignite/IgniteSystemProperties.java | 60 +----
.../org/apache/ignite/internal/ClassSet.java | 108 +++++++++
.../ignite/internal/GridKernalContextImpl.java | 6 +-
.../apache/ignite/internal/IgniteKernal.java | 107 ++++++++-
.../ignite/internal/MarshallerContextImpl.java | 33 ++-
.../GridClientOptimizedMarshaller.java | 4 +-
.../optimized/OptimizedMarshallerUtils.java | 4 -
.../optimized/OptimizedObjectInputStream.java | 5 +-
.../optimized/OptimizedObjectOutputStream.java | 3 +-
.../wal/reader/StandaloneGridKernalContext.java | 2 +-
.../platform/utils/PlatformUtils.java | 2 +-
.../rest/protocols/tcp/GridTcpRestParser.java | 15 +-
.../rest/protocols/tcp/GridTcpRestProtocol.java | 31 +--
.../ignite/internal/util/IgniteUtils.java | 15 ++
.../ignite/marshaller/MarshallerContext.java | 14 ++
.../ignite/marshaller/MarshallerUtils.java | 6 +
.../ignite/marshaller/jdk/JdkMarshaller.java | 20 +-
.../jdk/JdkMarshallerObjectInputStream.java | 9 +-
.../spi/discovery/tcp/TcpDiscoverySpi.java | 8 +-
.../org/apache/ignite/stream/StreamAdapter.java | 2 +-
.../ignite/stream/socket/SocketStreamer.java | 8 +-
.../test/config/class_list_exploit_excluded.txt | 18 ++
.../test/config/class_list_exploit_included.txt | 19 ++
.../apache/ignite/internal/ClassSetTest.java | 71 ++++++
.../MarshallerContextLockingSelfTest.java | 2 +-
...GridBinaryMarshallerCtxDisabledSelfTest.java | 12 +
.../cache/GridCacheEntryMemorySizeSelfTest.java | 11 +-
.../marshaller/MarshallerContextSelfTest.java | 10 +-
.../marshaller/MarshallerContextTestImpl.java | 2 +-
.../DiscoveryUnmarshalVulnerabilityTest.java | 180 +++++++++++++++
...ocketStreamerUnmarshalVulnerabilityTest.java | 222 +++++++++++++++++++
.../junits/GridTestKernalContext.java | 3 +-
.../ignite/testsuites/IgniteBasicTestSuite.java | 3 +
.../IgniteSpiDiscoverySelfTestSuite.java | 3 +
.../testsuites/IgniteStreamSelfTestSuite.java | 2 +
35 files changed, 894 insertions(+), 126 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
index 9cd031d..7761292 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
@@ -28,7 +28,6 @@ import org.apache.ignite.cluster.ClusterGroup;
import org.apache.ignite.configuration.DataStorageConfiguration;
import org.apache.ignite.internal.client.GridClient;
import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
-import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.stream.StreamTransformer;
import org.jetbrains.annotations.Nullable;
@@ -222,11 +221,6 @@ public final class IgniteSystemProperties {
public static final String IGNITE_MAX_COMPLETED_TX_COUNT = "IGNITE_MAX_COMPLETED_TX_COUNT";
/**
- * Concurrency level for all concurrent hash maps created by Ignite.
- */
- public static final String IGNITE_MAP_CONCURRENCY_LEVEL = "IGNITE_MAP_CONCURRENCY_LEVEL";
-
- /**
* Transactions that take more time, than value of this property, will be output to log
* with warning level. {@code 0} (default value) disables warning on slow transactions.
*/
@@ -320,13 +314,6 @@ public final class IgniteSystemProperties {
/** Ttl of removed cache entries (ms). */
public static final String IGNITE_CACHE_REMOVED_ENTRIES_TTL = "IGNITE_CACHE_REMOVED_ENTRIES_TTL";
- /** Maximum amount of concurrent updates per system thread in atomic caches in case of PRIMARY_SYNC or FULL_ASYNC
- * write synchronization mode. If this limit is exceeded then update will be performed with FULL_SYNC
- * synchronization mode. If value is {@code 0} then limit is unbounded.
- */
- public static final String IGNITE_ATOMIC_CACHE_MAX_CONCURRENT_DHT_UPDATES =
- "IGNITE_ATOMIC_CACHE_MAX_CONCURRENT_DHT_UPDATES";
-
/**
* Comma separated list of addresses in format "10.100.22.100:45000,10.100.22.101:45000".
* Makes sense only for {@link org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder}.
@@ -479,9 +466,6 @@ public final class IgniteSystemProperties {
/** Number of cache operation retries in case of topology exceptions. */
public static final String IGNITE_CACHE_RETRIES_COUNT = "IGNITE_CACHE_RETRIES_COUNT";
- /** Number of times pending cache objects will be dumped to the log in case of partition exchange timeout. */
- public static final String IGNITE_DUMP_PENDING_OBJECTS_THRESHOLD = "IGNITE_DUMP_PENDING_OBJECTS_THRESHOLD";
-
/** If this property is set to {@code true} then Ignite will log thread dump in case of partition exchange timeout. */
public static final String IGNITE_THREAD_DUMP_ON_EXCHANGE_TIMEOUT = "IGNITE_THREAD_DUMP_ON_EXCHANGE_TIMEOUT";
@@ -524,6 +508,12 @@ public final class IgniteSystemProperties {
public static final String IGNITE_BINARY_MARSHALLER_USE_STRING_SERIALIZATION_VER_2 =
"IGNITE_BINARY_MARSHALLER_USE_STRING_SERIALIZATION_VER_2";
+ /** Defines path to the file that contains list of classes allowed to safe deserialization.*/
+ public static final String IGNITE_MARSHALLER_WHITELIST = "IGNITE_MARSHALLER_WHITELIST";
+
+ /** Defines path to the file that contains list of classes disallowed to safe deserialization.*/
+ public static final String IGNITE_MARSHALLER_BLACKLIST = "IGNITE_MARSHALLER_BLACKLIST";
+
/**
* If set to {@code true}, then default selected keys set is used inside
* {@code GridNioServer} which lead to some extra garbage generation when
@@ -689,16 +679,7 @@ public final class IgniteSystemProperties {
*/
public static final String IGNITE_FORCE_START_JAVA7 = "IGNITE_FORCE_START_JAVA7";
- /** Returns true for system properties only avoiding sending sensitive information. */
- private static final IgnitePredicate<Map.Entry<String, String>> PROPS_FILTER = new IgnitePredicate<Map.Entry<String, String>>() {
- @Override public boolean apply(final Map.Entry<String, String> entry) {
- final String key = entry.getKey();
-
- return key.startsWith("java.") || key.startsWith("os.") || key.startsWith("user.");
- }
- };
-
- /**
+ /**
* When set to {@code true}, Ignite switches to compatibility mode with versions that don't
* support service security permissions. In this case security permissions will be ignored
* (if they set).
@@ -740,11 +721,6 @@ public final class IgniteSystemProperties {
public static final String IGNITE_ENABLE_FORCIBLE_NODE_KILL = "IGNITE_ENABLE_FORCIBLE_NODE_KILL";
/**
- *
- */
- public static final String IGNITE_WAL_ARCHIVE_COMPACT_SKIP_DELTA_RECORD = "IGNITE_WAL_ARCHIVE_COMPACT_SKIP_DELTA_RECORD";
-
- /**
* Tasks stealing will be started if tasks queue size per data-streamer thread exceeds this threshold.
* <p>
* Default value is {@code 4}.
@@ -1023,26 +999,4 @@ public final class IgniteSystemProperties {
return sysProps;
}
-
- /**
- * Does the same as {@link #snapshot()} but filters out
- * possible sensitive user data.
- *
- * @return Snapshot of system properties.
- */
- @SuppressWarnings("unchecked")
- public static Properties safeSnapshot() {
- final Properties props = snapshot();
-
- final Iterator<Map.Entry<Object, Object>> iter = props.entrySet().iterator();
-
- while (iter.hasNext()) {
- final Map.Entry entry = iter.next();
-
- if (!PROPS_FILTER.apply(entry))
- iter.remove();
- }
-
- return props;
- }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/ClassSet.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/ClassSet.java b/modules/core/src/main/java/org/apache/ignite/internal/ClassSet.java
new file mode 100644
index 0000000..400984d
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/ClassSet.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.IllegalFormatException;
+import java.util.Map;
+
+/**
+ * Set of classes represented as prefix tree.
+ * {@code *} symbol is allowed and indicates that all packages and classes are included.
+ */
+public class ClassSet {
+ /** Corresponds to {@code *} symbol. */
+ private static final Map<String, Node> ALL = Collections.emptyMap();
+
+ /** Root. */
+ private Node root = new Node();
+
+ /**
+ * Adds class name to the set.
+ *
+ * @param clsName Class name.
+ */
+ public void add(String clsName) {
+ String[] tokens = clsName.split("\\.");
+
+ Node cur = root;
+
+ for (int i = 0; i < tokens.length; i++) {
+ if (cur.children == ALL)
+ return;
+
+ if (tokens[i].equals("*")) {
+ if (i != tokens.length - 1)
+ throw new IllegalArgumentException("Incorrect class name format.");
+
+ cur.children = ALL;
+
+ return;
+ }
+
+ if (cur.children == null)
+ cur.children = new HashMap<>();
+
+ Node n = cur.children.get(tokens[i]);
+
+ if (n == null) {
+ n = new Node();
+
+ cur.children.put(tokens[i], n);
+ }
+
+ cur = n;
+ }
+ }
+
+ /**
+ * @param clsName Class name.
+ */
+ public boolean contains(String clsName) {
+ String[] tokens = clsName.split("\\.");
+
+ Node cur = root;
+
+ for (int i = 0; i < tokens.length; i++) {
+ if (cur.children == ALL)
+ return true;
+
+ if (cur.children == null)
+ return false;
+
+ Node n = cur.children.get(tokens[i]);
+
+ if (n == null)
+ return false;
+
+ if (i == tokens.length - 1)
+ return true;
+
+ cur = n;
+ }
+
+ return false;
+ }
+
+ /** */
+ private static class Node {
+ /** Children. */
+ private Map<String, Node> children;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
index 9a315e7..3f064fa 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
@@ -91,6 +91,7 @@ import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.X;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.plugin.PluginNotFoundException;
import org.apache.ignite.plugin.PluginProvider;
import org.apache.ignite.thread.IgniteStripedThreadPoolExecutor;
@@ -441,7 +442,8 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
ExecutorService qryExecSvc,
ExecutorService schemaExecSvc,
@Nullable Map<String, ? extends ExecutorService> customExecSvcs,
- List<PluginProvider> plugins
+ List<PluginProvider> plugins,
+ IgnitePredicate<String> clsFilter
) {
assert grid != null;
assert cfg != null;
@@ -467,7 +469,7 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
this.schemaExecSvc = schemaExecSvc;
this.customExecSvcs = customExecSvcs;
- marshCtx = new MarshallerContextImpl(plugins);
+ marshCtx = new MarshallerContextImpl(plugins, clsFilter);
try {
spring = SPRING.create(false);
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index 16698b5..3094963 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -17,10 +17,14 @@
package org.apache.ignite.internal;
+import java.io.BufferedReader;
import java.io.Externalizable;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.InvalidObjectException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
@@ -259,6 +263,8 @@ import static org.apache.ignite.internal.IgniteVersionUtils.VER;
import static org.apache.ignite.internal.IgniteVersionUtils.VER_STR;
import static org.apache.ignite.lifecycle.LifecycleEventType.AFTER_NODE_START;
import static org.apache.ignite.lifecycle.LifecycleEventType.BEFORE_NODE_START;
+import static org.apache.ignite.marshaller.MarshallerUtils.CLS_NAMES_FILE;
+import static org.apache.ignite.marshaller.MarshallerUtils.JDK_CLS_NAMES_FILE;
/**
* Ignite kernal.
@@ -834,7 +840,8 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
qryExecSvc,
schemaExecSvc,
customExecSvcs,
- plugins
+ plugins,
+ classNameFilter()
);
cfg.getMarshaller().setContext(ctx.marshallerContext());
@@ -1685,6 +1692,104 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
}
/**
+ * Returns class name filter for marshaller.
+ * @return Class name filter for marshaller.
+ */
+ private IgnitePredicate<String> classNameFilter() throws IgniteCheckedException {
+ ClassSet whiteList = classWhiteList();
+ ClassSet blackList = classBlackList();
+
+ return new IgnitePredicate<String>() {
+ @Override public boolean apply(String s) {
+ // Allows all primitive arrays and checks arrays' type.
+ if ((blackList != null || whiteList != null) && s.charAt(0) == '[') {
+ if (s.charAt(1) == 'L' && s.length() > 2)
+ s = s.substring(2, s.length() - 1);
+ else
+ return true;
+ }
+
+ return (blackList == null || !blackList.contains(s)) && (whiteList == null || whiteList.contains(s));
+ }
+ };
+ }
+
+ /**
+ * @return White list of classes.
+ */
+ private ClassSet classWhiteList() throws IgniteCheckedException {
+ ClassSet clsSet = null;
+
+ String fileName = IgniteSystemProperties.getString(IgniteSystemProperties.IGNITE_MARSHALLER_WHITELIST);
+
+ if (fileName != null) {
+ clsSet = new ClassSet();
+
+ addClassNames(JDK_CLS_NAMES_FILE, clsSet);
+ addClassNames(CLS_NAMES_FILE, clsSet);
+ addClassNames(fileName, clsSet);
+ }
+
+ return clsSet;
+ }
+
+ /**
+ * @return Black list of classes.
+ */
+ private ClassSet classBlackList() throws IgniteCheckedException {
+ ClassSet clsSet = null;
+
+ String blackListFileName = IgniteSystemProperties.getString(IgniteSystemProperties.IGNITE_MARSHALLER_BLACKLIST);
+
+ if (blackListFileName != null)
+ addClassNames(blackListFileName, clsSet = new ClassSet());
+
+ return clsSet;
+ }
+
+
+ /**
+ * Reads class names from resource referred by given system property name and returns set of classes.
+ * @param fileName File name containing list of classes.
+ * @param clsSet Class set for update.
+ * @return Set of classes.
+ */
+ private void addClassNames(String fileName, ClassSet clsSet) throws IgniteCheckedException {
+ InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileName);
+
+ if (is == null) {
+ try {
+ is = new FileInputStream(new File(fileName));
+ }
+ catch (FileNotFoundException e) {
+ throw new IgniteCheckedException("File " + fileName + " not found.");
+ }
+ }
+
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
+ String line;
+
+ for (int i = 1; (line = reader.readLine()) != null; i++) {
+ String s = line.trim();
+
+ if (!s.isEmpty() && s.charAt(0) != '#' && s.charAt(0) != '[') {
+ try {
+ clsSet.add(s);
+ }
+ catch (IllegalArgumentException e) {
+ throw new IgniteCheckedException("Exception occurred while reading list of classes" +
+ "[path=" + fileName + ", row=" + i + ", line=" + s + ']', e);
+ }
+ }
+ }
+ }
+ catch (IOException e) {
+ throw new IgniteCheckedException("Exception occurred while reading and creating list of classes " +
+ "[path=" + fileName + ']', e);
+ }
+ }
+
+ /**
* Add helper.
*
* @param helper Helper.
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java
index 08661a3..d82ab17 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java
@@ -50,25 +50,23 @@ import org.apache.ignite.internal.util.IgniteUtils;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.marshaller.MarshallerContext;
+import org.apache.ignite.marshaller.jdk.JdkMarshaller;
import org.apache.ignite.plugin.PluginProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jsr166.ConcurrentHashMap8;
import static org.apache.ignite.internal.MarshallerPlatformIds.JAVA_ID;
+import static org.apache.ignite.marshaller.MarshallerUtils.CLS_NAMES_FILE;
+import static org.apache.ignite.marshaller.MarshallerUtils.JDK_CLS_NAMES_FILE;
/**
* Marshaller context implementation.
*/
public class MarshallerContextImpl implements MarshallerContext {
/** */
- private static final String CLS_NAMES_FILE = "META-INF/classnames.properties";
-
- /** */
- private static final String JDK_CLS_NAMES_FILE = "META-INF/classnames-jdk.properties";
-
- /** */
private final Map<Integer, MappedName> sysTypesMap = new HashMap<>();
/** */
@@ -89,6 +87,12 @@ public class MarshallerContextImpl implements MarshallerContext {
/** */
private boolean clientNode;
+ /** Class name filter. */
+ private final IgnitePredicate<String> clsFilter;
+
+ /** JDK marshaller. */
+ private final JdkMarshaller jdkMarsh;
+
/**
* Marshaller mapping file store directory. {@code null} used for standard folder, in this case folder is calculated
* from work directory. Non null value may be used to setup custom directory from outside
@@ -100,7 +104,10 @@ public class MarshallerContextImpl implements MarshallerContext {
*
* @param plugins Plugins.
*/
- public MarshallerContextImpl(@Nullable Collection<PluginProvider> plugins) {
+ public MarshallerContextImpl(@Nullable Collection<PluginProvider> plugins, IgnitePredicate<String> clsFilter) {
+ this.clsFilter = clsFilter;
+ this.jdkMarsh = new JdkMarshaller(clsFilter);
+
initializeCaches();
try {
@@ -330,7 +337,7 @@ public class MarshallerContextImpl implements MarshallerContext {
if (clsName == null)
throw new ClassNotFoundException("Unknown type ID: " + typeId);
- return U.forName(clsName, ldr);
+ return U.forName(clsName, ldr, clsFilter);
}
/** {@inheritDoc} */
@@ -385,6 +392,16 @@ public class MarshallerContextImpl implements MarshallerContext {
return clsName;
}
+ /** {@inheritDoc} */
+ @Override public IgnitePredicate<String> classNameFilter() {
+ return clsFilter;
+ }
+
+ /** {@inheritDoc} */
+ @Override public JdkMarshaller jdkMarshaller() {
+ return jdkMarsh;
+ }
+
/**
* @param platformId Platform id.
* @param typeId Type id.
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java b/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
index 257b34c..2af1841 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
@@ -117,14 +117,14 @@ public class GridClientOptimizedMarshaller implements GridClientMarshaller {
private static class ClientMarshallerContext extends MarshallerContextImpl {
/** */
public ClientMarshallerContext() {
- super(null);
+ super(null, null);
}
/**
* @param plugins Plugins.
*/
public ClientMarshallerContext(@Nullable List<PluginProvider> plugins) {
- super(plugins);
+ super(plugins, null);
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerUtils.java
index f9a6df9..aa4bfd6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerUtils.java
@@ -33,7 +33,6 @@ import org.apache.ignite.IgniteException;
import org.apache.ignite.internal.util.GridUnsafe;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.marshaller.MarshallerContext;
-import org.apache.ignite.marshaller.jdk.JdkMarshaller;
import static org.apache.ignite.internal.MarshallerPlatformIds.JAVA_ID;
@@ -152,9 +151,6 @@ class OptimizedMarshallerUtils {
/** UTF-8 character name. */
static final Charset UTF_8 = Charset.forName("UTF-8");
- /** JDK marshaller. */
- static final JdkMarshaller JDK_MARSH = new JdkMarshaller();
-
static {
long mapOff;
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java
index 93a6f6f..0bd7cc0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java
@@ -70,7 +70,6 @@ import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshalle
import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.INT;
import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.INT_ARR;
import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.JDK;
-import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.JDK_MARSH;
import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.LINKED_HASH_MAP;
import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.LINKED_HASH_SET;
import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.LINKED_LIST;
@@ -227,7 +226,7 @@ class OptimizedObjectInputStream extends ObjectInputStream {
case JDK:
try {
- return JDK_MARSH.unmarshal(this, clsLdr);
+ return ctx.jdkMarshaller().unmarshal(this, clsLdr);
}
catch (IgniteCheckedException e) {
IOException ioEx = e.getCause(IOException.class);
@@ -338,7 +337,7 @@ class OptimizedObjectInputStream extends ObjectInputStream {
int typeId = readInt();
OptimizedClassDescriptor desc = typeId == 0 ?
- classDescriptor(clsMap, U.forName(readUTF(), clsLdr), ctx, mapper):
+ classDescriptor(clsMap, U.forName(readUTF(), clsLdr, ctx.classNameFilter()), ctx, mapper):
classDescriptor(clsMap, typeId, clsLdr, ctx, mapper);
curCls = desc.describedClass();
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectOutputStream.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectOutputStream.java b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectOutputStream.java
index 092d6a4..8a323a7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectOutputStream.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectOutputStream.java
@@ -47,7 +47,6 @@ import org.apache.ignite.marshaller.MarshallerContext;
import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.HANDLE;
import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.JDK;
-import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.JDK_MARSH;
import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.NULL;
import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.classDescriptor;
import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.getBoolean;
@@ -185,7 +184,7 @@ class OptimizedObjectOutputStream extends ObjectOutputStream {
writeByte(JDK);
try {
- JDK_MARSH.marshal(obj, this);
+ ctx.jdkMarshaller().marshal(obj, this);
}
catch (IgniteCheckedException e) {
IOException ioEx = e.getCause(IOException.class);
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
index 908d5b7..2c1d91e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
@@ -137,7 +137,7 @@ public class StandaloneGridKernalContext implements GridKernalContext {
throw new IllegalStateException("Must not fail on empty providers list.", e);
}
- this.marshallerCtx = new MarshallerContextImpl(null);
+ this.marshallerCtx = new MarshallerContextImpl(null, null);
this.cfg = prepareIgniteConfiguration();
// Fake folder provided to perform processor startup on empty folder.
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
index 2954a9e..12f70dd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
@@ -857,7 +857,7 @@ public class PlatformUtils {
BinaryMarshaller marsh = new BinaryMarshaller();
- marsh.setContext(new MarshallerContextImpl(null));
+ marsh.setContext(new MarshallerContextImpl(null, null));
ctx.configure(marsh, new IgniteConfiguration());
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestParser.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestParser.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestParser.java
index b4c8b7c..65eb3c3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestParser.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestParser.java
@@ -72,7 +72,7 @@ public class GridTcpRestParser implements GridNioParser {
private static final Charset UTF_8 = Charset.forName("UTF-8");
/** JDK marshaller. */
- private final Marshaller jdkMarshaller = new JdkMarshaller();
+ private final Marshaller marsh;
/** Router client flag. */
private final boolean routerClient;
@@ -81,7 +81,16 @@ public class GridTcpRestParser implements GridNioParser {
* @param routerClient Router client flag.
*/
public GridTcpRestParser(boolean routerClient) {
+ this(routerClient, new JdkMarshaller());
+ }
+
+ /**
+ * @param routerClient Router client flag.
+ * @param marsh Marshaller.
+ */
+ public GridTcpRestParser(boolean routerClient, Marshaller marsh) {
this.routerClient = routerClient;
+ this.marsh = marsh;
}
/** {@inheritDoc} */
@@ -735,7 +744,7 @@ public class GridTcpRestParser implements GridNioParser {
assert bytes != null;
if ((flags & SERIALIZED_FLAG) != 0)
- return U.unmarshal(jdkMarshaller, bytes, null);
+ return U.unmarshal(marsh, bytes, null);
int masked = flags & 0xff00;
@@ -817,7 +826,7 @@ public class GridTcpRestParser implements GridNioParser {
flags |= BYTE_ARR_FLAG;
}
else {
- U.marshal(jdkMarshaller, obj, out);
+ U.marshal(marsh, obj, out);
flags |= SERIALIZED_FLAG;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java
index df0e569..0049dbc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java
@@ -44,17 +44,12 @@ import org.apache.ignite.internal.util.nio.GridNioFilter;
import org.apache.ignite.internal.util.nio.GridNioParser;
import org.apache.ignite.internal.util.nio.GridNioServer;
import org.apache.ignite.internal.util.nio.GridNioServerListener;
-import org.apache.ignite.internal.util.nio.GridNioSession;
import org.apache.ignite.internal.util.nio.ssl.GridNioSslFilter;
import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.marshaller.Marshaller;
-import org.apache.ignite.marshaller.jdk.JdkMarshaller;
import org.apache.ignite.plugin.PluginProvider;
import org.apache.ignite.spi.IgnitePortProtocol;
import org.jetbrains.annotations.Nullable;
-import static org.apache.ignite.internal.util.nio.GridNioSessionMetaKey.MARSHALLER;
-
/**
* TCP binary protocol implementation.
*/
@@ -62,9 +57,6 @@ public class GridTcpRestProtocol extends GridRestProtocolAdapter {
/** Server. */
private GridNioServer<GridClientMessage> srv;
- /** JDK marshaller. */
- private final Marshaller jdkMarshaller = new JdkMarshaller();
-
/** NIO server listener. */
private GridTcpRestNioListener lsnr;
@@ -73,27 +65,6 @@ public class GridTcpRestProtocol extends GridRestProtocolAdapter {
super(ctx);
}
- /**
- * @return JDK marshaller.
- */
- Marshaller jdkMarshaller() {
- return jdkMarshaller;
- }
-
- /**
- * Returns marshaller.
- *
- * @param ses Session.
- * @return Marshaller.
- */
- GridClientMarshaller marshaller(GridNioSession ses) {
- GridClientMarshaller marsh = ses.meta(MARSHALLER.ordinal());
-
- assert marsh != null;
-
- return marsh;
- }
-
/** {@inheritDoc} */
@Override public String name() {
return "TCP binary";
@@ -110,7 +81,7 @@ public class GridTcpRestProtocol extends GridRestProtocolAdapter {
lsnr = new GridTcpRestNioListener(log, this, hnd, ctx);
- GridNioParser parser = new GridTcpRestParser(false);
+ GridNioParser parser = new GridTcpRestParser(false, ctx.marshallerContext().jdkMarshaller());
try {
host = resolveRestTcpHost(ctx.config());
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
index 0f6a41a..238030a 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
@@ -8532,6 +8532,18 @@ public abstract class IgniteUtils {
* @throws ClassNotFoundException If class not found.
*/
public static Class<?> forName(String clsName, @Nullable ClassLoader ldr) throws ClassNotFoundException {
+ return U.forName(clsName, ldr, null);
+ }
+
+ /**
+ * Gets class for provided name. Accepts primitive types names.
+ *
+ * @param clsName Class name.
+ * @param ldr Class loader.
+ * @return Class.
+ * @throws ClassNotFoundException If class not found.
+ */
+ public static Class<?> forName(String clsName, @Nullable ClassLoader ldr, IgnitePredicate<String> clsFilter) throws ClassNotFoundException {
assert clsName != null;
Class<?> cls = primitiveMap.get(clsName);
@@ -8558,6 +8570,9 @@ public abstract class IgniteUtils {
cls = ldrMap.get(clsName);
if (cls == null) {
+ if (clsFilter != null && !clsFilter.apply(clsName))
+ throw new RuntimeException("Deserialization of class " + clsName + " is disallowed.");
+
Class old = ldrMap.putIfAbsent(clsName, cls = Class.forName(clsName, true, ldr));
if (old != null)
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java b/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java
index 8d6cd77..987e999 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java
@@ -18,6 +18,8 @@
package org.apache.ignite.marshaller;
import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.marshaller.jdk.JdkMarshaller;
/**
* Marshaller context.
@@ -83,4 +85,16 @@ public interface MarshallerContext {
* @return {@code true} if the type is a system one, {@code false} otherwise.
*/
public boolean isSystemType(String typeName);
+
+ /**
+ * Returns class name filter.
+ *
+ * @return Class name filter.
+ */
+ public IgnitePredicate<String> classNameFilter();
+
+ /**
+ * Returns JDK marshaller instance.
+ */
+ public JdkMarshaller jdkMarshaller();
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java b/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java
index ad63702..bec1f57 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java
@@ -25,6 +25,12 @@ import org.jetbrains.annotations.Nullable;
* Utility marshaller methods.
*/
public class MarshallerUtils {
+ /** Jdk class names file. */
+ public static final String JDK_CLS_NAMES_FILE = "META-INF/classnames-jdk.properties";
+
+ /** Class names file. */
+ public static final String CLS_NAMES_FILE = "META-INF/classnames.properties";
+
/** Job sender node version. */
private static final ThreadLocal<IgniteProductVersion> JOB_SND_NODE_VER = new ThreadLocal<>();
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java b/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java
index 6759c40..ae4033b 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java
@@ -27,6 +27,7 @@ import org.apache.ignite.internal.util.io.GridByteArrayInputStream;
import org.apache.ignite.internal.util.io.GridByteArrayOutputStream;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.marshaller.AbstractNodeNameAwareMarshaller;
import org.jetbrains.annotations.Nullable;
@@ -67,6 +68,23 @@ import org.jetbrains.annotations.Nullable;
* For information about Spring framework visit <a href="http://www.springframework.org/">www.springframework.org</a>
*/
public class JdkMarshaller extends AbstractNodeNameAwareMarshaller {
+ /** Class name filter. */
+ private final IgnitePredicate<String> clsFilter;
+
+ /**
+ * Default constructor.
+ */
+ public JdkMarshaller() {
+ this(null);
+ }
+
+ /**
+ * @param clsFilter Class name filter.
+ */
+ public JdkMarshaller(IgnitePredicate<String> clsFilter) {
+ this.clsFilter = clsFilter;
+ }
+
/** {@inheritDoc} */
@Override protected void marshal0(@Nullable Object obj, OutputStream out) throws IgniteCheckedException {
assert out != null;
@@ -116,7 +134,7 @@ public class JdkMarshaller extends AbstractNodeNameAwareMarshaller {
ObjectInputStream objIn = null;
try {
- objIn = new JdkMarshallerObjectInputStream(new JdkMarshallerInputStreamWrapper(in), clsLdr);
+ objIn = new JdkMarshallerObjectInputStream(new JdkMarshallerInputStreamWrapper(in), clsLdr, clsFilter);
return (T)objIn.readObject();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java b/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java
index 03256e0..d9fdd3d 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgnitePredicate;
/**
* This class defines custom JDK object input stream.
@@ -30,17 +31,21 @@ class JdkMarshallerObjectInputStream extends ObjectInputStream {
/** */
private final ClassLoader clsLdr;
+ /** Class name filter. */
+ private final IgnitePredicate<String> clsFilter;
+
/**
* @param in Parent input stream.
* @param clsLdr Custom class loader.
* @throws IOException If initialization failed.
*/
- JdkMarshallerObjectInputStream(InputStream in, ClassLoader clsLdr) throws IOException {
+ JdkMarshallerObjectInputStream(InputStream in, ClassLoader clsLdr, IgnitePredicate<String> clsFilter) throws IOException {
super(in);
assert clsLdr != null;
this.clsLdr = clsLdr;
+ this.clsFilter = clsFilter;
enableResolveObject(true);
}
@@ -51,7 +56,7 @@ class JdkMarshallerObjectInputStream extends ObjectInputStream {
// Must have 'Class.forName()' instead of clsLoader.loadClass()
// due to weird ClassNotFoundExceptions for arrays of classes
// in certain cases.
- return U.forName(desc.getName(), clsLdr);
+ return U.forName(desc.getName(), clsLdr, clsFilter);
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
index 713bbab..51c5adf 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
@@ -55,6 +55,7 @@ import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.configuration.AddressResolver;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.IgniteInterruptedCheckedException;
+import org.apache.ignite.internal.IgniteKernal;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.X;
@@ -333,7 +334,7 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter implements DiscoverySpi {
protected volatile long gridStartTime;
/** Marshaller. */
- private final Marshaller marsh = new JdkMarshaller();
+ private Marshaller marsh;
/** Statistics. */
protected final TcpDiscoveryStatistics stats = new TcpDiscoveryStatistics();
@@ -551,6 +552,11 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter implements DiscoverySpi {
if (ignite != null) {
setLocalAddress(ignite.configuration().getLocalHost());
setAddressResolver(ignite.configuration().getAddressResolver());
+
+ if (ignite instanceof IgniteKernal) // IgniteMock instance can be injected from tests.
+ marsh = ((IgniteKernal)ignite).context().marshallerContext().jdkMarshaller();
+ else
+ marsh = new JdkMarshaller();
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/stream/StreamAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/stream/StreamAdapter.java b/modules/core/src/main/java/org/apache/ignite/stream/StreamAdapter.java
index 3f1dfad..49f0c15 100644
--- a/modules/core/src/main/java/org/apache/ignite/stream/StreamAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/stream/StreamAdapter.java
@@ -46,7 +46,7 @@ public abstract class StreamAdapter<T, K, V> {
private IgniteDataStreamer<K, V> stmr;
/** Ignite. */
- private Ignite ignite;
+ protected Ignite ignite;
/**
* Empty constructor.
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/stream/socket/SocketStreamer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/stream/socket/SocketStreamer.java b/modules/core/src/main/java/org/apache/ignite/stream/socket/SocketStreamer.java
index f45423b..1a68206 100644
--- a/modules/core/src/main/java/org/apache/ignite/stream/socket/SocketStreamer.java
+++ b/modules/core/src/main/java/org/apache/ignite/stream/socket/SocketStreamer.java
@@ -24,6 +24,7 @@ import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteDataStreamer;
import org.apache.ignite.IgniteException;
import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.internal.IgniteKernal;
import org.apache.ignite.internal.util.nio.GridBufferedParser;
import org.apache.ignite.internal.util.nio.GridDelimitedParser;
import org.apache.ignite.internal.util.nio.GridNioCodecFilter;
@@ -38,6 +39,7 @@ import org.apache.ignite.internal.util.typedef.internal.A;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.marshaller.Marshaller;
import org.apache.ignite.marshaller.MarshallerUtils;
+import org.apache.ignite.marshaller.jdk.JdkMarshaller;
import org.apache.ignite.stream.StreamAdapter;
import org.apache.ignite.stream.StreamTupleExtractor;
import org.jetbrains.annotations.Nullable;
@@ -217,7 +219,7 @@ public class SocketStreamer<T, K, V> extends StreamAdapter<T, K, V> {
/**
* Converts message to Java object using Jdk marshaller.
*/
- private static class DefaultConverter<T> implements SocketMessageConverter<T> {
+ private class DefaultConverter<T> implements SocketMessageConverter<T> {
/** Marshaller. */
private final Marshaller marsh;
@@ -227,7 +229,9 @@ public class SocketStreamer<T, K, V> extends StreamAdapter<T, K, V> {
* @param igniteInstanceName Ignite instance name.
*/
private DefaultConverter(@Nullable String igniteInstanceName) {
- marsh = MarshallerUtils.jdkMarshaller(igniteInstanceName);
+ marsh = new JdkMarshaller(((IgniteKernal)ignite).context().marshallerContext().classNameFilter());
+
+ MarshallerUtils.setNodeName(marsh, igniteInstanceName);
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/config/class_list_exploit_excluded.txt
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/class_list_exploit_excluded.txt b/modules/core/src/test/config/class_list_exploit_excluded.txt
new file mode 100644
index 0000000..d2657e8
--- /dev/null
+++ b/modules/core/src/test/config/class_list_exploit_excluded.txt
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Intentionally empty.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/config/class_list_exploit_included.txt
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/class_list_exploit_included.txt b/modules/core/src/test/config/class_list_exploit_included.txt
new file mode 100644
index 0000000..9a07d54
--- /dev/null
+++ b/modules/core/src/test/config/class_list_exploit_included.txt
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.apache.ignite.spi.discovery.tcp.DiscoveryUnmarshalVulnerabilityTest$Exploit
+org.apache.ignite.stream.socket.SocketStreamerUnmarshalVulnerabilityTest$Exploit
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/internal/ClassSetTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/ClassSetTest.java b/modules/core/src/test/java/org/apache/ignite/internal/ClassSetTest.java
new file mode 100644
index 0000000..c51957a
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/ClassSetTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link ClassSet} class.
+ */
+public class ClassSetTest extends TestCase {
+ /**
+ * @throws Exception If failed.
+ */
+ public void testAddAndContains() throws Exception {
+ ClassSet clsSet = new ClassSet();
+
+ clsSet.add("org.apache.ignite.Ignite");
+
+ assertTrue(clsSet.contains("org.apache.ignite.Ignite"));
+ assertFalse(clsSet.contains("org.apache.ignite.NotIgnite"));
+ assertFalse(clsSet.contains("org.apache.Ignite"));
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testAddWithMaskAndContains() throws Exception {
+ ClassSet clsSet = new ClassSet();
+
+ clsSet.add("org.apache.ignite.*");
+
+ assertTrue(clsSet.contains("org.apache.ignite.Ignite"));
+ assertTrue(clsSet.contains("org.apache.ignite.NotIgnite"));
+ assertFalse(clsSet.contains("org.apache.Ignite"));
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testReduceOnAddWithMask() throws Exception {
+ ClassSet clsSet = new ClassSet();
+
+ clsSet.add("org.apache.ignite.Ignite");
+ clsSet.add("org.apache.ignite.Ignition");
+
+ assertTrue(clsSet.contains("org.apache.ignite.Ignite"));
+ assertTrue(clsSet.contains("org.apache.ignite.Ignition"));
+ assertFalse(clsSet.contains("org.apache.ignite.NotIgnite"));
+
+ clsSet.add("org.apache.ignite.*");
+
+ assertTrue(clsSet.contains("org.apache.ignite.Ignite"));
+ assertTrue(clsSet.contains("org.apache.ignite.Ignition"));
+ assertTrue(clsSet.contains("org.apache.ignite.NotIgnite"));
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/internal/MarshallerContextLockingSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/MarshallerContextLockingSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/MarshallerContextLockingSelfTest.java
index 522b941..f31a56d 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/MarshallerContextLockingSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/MarshallerContextLockingSelfTest.java
@@ -140,7 +140,7 @@ public class MarshallerContextLockingSelfTest extends GridCommonAbstractTest {
public void executeTest(GridTestLog4jLogger log, GridKernalContext ctx) throws Exception {
counter.incrementAndGet();
- MarshallerContextImpl marshallerContext = new MarshallerContextImpl(null);
+ MarshallerContextImpl marshallerContext = new MarshallerContextImpl(null, null);
marshallerContext.onMarshallerProcessorStarted(ctx, null);
MarshallerMappingItem item = new MarshallerMappingItem(JAVA_ID, 1, String.class.getName());
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryMarshallerCtxDisabledSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryMarshallerCtxDisabledSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryMarshallerCtxDisabledSelfTest.java
index 35aa9b9..bb7c65d 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryMarshallerCtxDisabledSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryMarshallerCtxDisabledSelfTest.java
@@ -29,8 +29,10 @@ import org.apache.ignite.binary.BinaryWriter;
import org.apache.ignite.binary.Binarylizable;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.logger.NullLogger;
import org.apache.ignite.marshaller.MarshallerContext;
+import org.apache.ignite.marshaller.jdk.JdkMarshaller;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
/**
@@ -122,6 +124,16 @@ public class GridBinaryMarshallerCtxDisabledSelfTest extends GridCommonAbstractT
@Override public boolean isSystemType(String typeName) {
return false;
}
+
+ /** {@inheritDoc} */
+ @Override public IgnitePredicate<String> classNameFilter() {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public JdkMarshaller jdkMarshaller() {
+ return new JdkMarshaller();
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheEntryMemorySizeSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheEntryMemorySizeSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheEntryMemorySizeSelfTest.java
index f18afb2..8092d9f 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheEntryMemorySizeSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheEntryMemorySizeSelfTest.java
@@ -31,9 +31,10 @@ import org.apache.ignite.configuration.NearCacheConfiguration;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry;
import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.marshaller.Marshaller;
import org.apache.ignite.marshaller.MarshallerContext;
-import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
+import org.apache.ignite.marshaller.jdk.JdkMarshaller;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
@@ -166,6 +167,14 @@ public class GridCacheEntryMemorySizeSelfTest extends GridCommonAbstractTest {
@Override public boolean isSystemType(String typeName) {
return false;
}
+
+ @Override public IgnitePredicate<String> classNameFilter() {
+ return null;
+ }
+
+ @Override public JdkMarshaller jdkMarshaller() {
+ return new JdkMarshaller();
+ }
});
return marsh;
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java
index 9df56ec..da474df 100644
--- a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java
@@ -72,7 +72,7 @@ public class MarshallerContextSelfTest extends GridCommonAbstractTest {
* @throws Exception If failed.
*/
public void testClassName() throws Exception {
- MarshallerContextImpl marshCtx = new MarshallerContextImpl(null);
+ MarshallerContextImpl marshCtx = new MarshallerContextImpl(null, null);
marshCtx.onMarshallerProcessorStarted(ctx, null);
@@ -99,7 +99,7 @@ public class MarshallerContextSelfTest extends GridCommonAbstractTest {
public void testMultiplatformMappingsCollecting() throws Exception {
String nonJavaClassName = "random.platform.Mapping";
- MarshallerContextImpl marshCtx = new MarshallerContextImpl(null);
+ MarshallerContextImpl marshCtx = new MarshallerContextImpl(null, null);
marshCtx.onMarshallerProcessorStarted(ctx, null);
@@ -157,7 +157,7 @@ public class MarshallerContextSelfTest extends GridCommonAbstractTest {
*/
public void testOnUpdated() throws Exception {
File workDir = U.resolveWorkDirectory(U.defaultWorkDirectory(), "marshaller", false);
- MarshallerContextImpl ctx = new MarshallerContextImpl(null);
+ MarshallerContextImpl ctx = new MarshallerContextImpl(null, null);
ctx.onMarshallerProcessorStarted(this.ctx, null);
@@ -188,7 +188,7 @@ public class MarshallerContextSelfTest extends GridCommonAbstractTest {
* if platform ids passed to marshaller cache were not sequential (like 0, 2).
*/
public void testCacheStructure0() throws Exception {
- MarshallerContextImpl ctx = new MarshallerContextImpl(null);
+ MarshallerContextImpl ctx = new MarshallerContextImpl(null, null);
ctx.onMarshallerProcessorStarted(this.ctx, null);
@@ -221,7 +221,7 @@ public class MarshallerContextSelfTest extends GridCommonAbstractTest {
* if platform ids passed to marshaller context were sequential.
*/
public void testCacheStructure1() throws Exception {
- MarshallerContextImpl ctx = new MarshallerContextImpl(null);
+ MarshallerContextImpl ctx = new MarshallerContextImpl(null, null);
ctx.onMarshallerProcessorStarted(this.ctx, null);
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java
index 0a59bba..2d6383c 100644
--- a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java
+++ b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java
@@ -43,7 +43,7 @@ public class MarshallerContextTestImpl extends MarshallerContextImpl {
* @param excluded Excluded classes.
*/
public MarshallerContextTestImpl(@Nullable List<PluginProvider> plugins, Collection<String> excluded) {
- super(plugins);
+ super(plugins, null);
this.excluded = excluded;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/DiscoveryUnmarshalVulnerabilityTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/DiscoveryUnmarshalVulnerabilityTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/DiscoveryUnmarshalVulnerabilityTest.java
new file mode 100644
index 0000000..448c9af
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/DiscoveryUnmarshalVulnerabilityTest.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.spi.discovery.tcp;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.internal.util.lang.GridAbsPredicate;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.marshaller.jdk.JdkMarshaller;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHALLER_BLACKLIST;
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHALLER_WHITELIST;
+
+/**
+ * Tests for whitelist and blacklist ot avoiding deserialization vulnerability.
+ */
+public class DiscoveryUnmarshalVulnerabilityTest extends GridCommonAbstractTest {
+ /** Marshaller. */
+ private static final JdkMarshaller MARSH = new JdkMarshaller();
+
+ /** Shared value. */
+ private static final AtomicBoolean SHARED = new AtomicBoolean();
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTest() throws Exception {
+ super.beforeTest();
+
+ SHARED.set(false);
+
+ System.clearProperty(IGNITE_MARSHALLER_WHITELIST);
+ System.clearProperty(IGNITE_MARSHALLER_BLACKLIST);
+
+ IgniteUtils.clearClassCache();
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testNoLists() throws Exception {
+ testExploit(true);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testWhiteListIncluded() throws Exception {
+ String path = U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
+
+ System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
+
+ testExploit(true);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testWhiteListExcluded() throws Exception {
+ String path = U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_excluded.txt").getPath();
+
+ System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
+
+ testExploit(false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testBlackListIncluded() throws Exception {
+ String path = U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
+
+ System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+
+ testExploit(false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testBlackListExcluded() throws Exception {
+ String path = U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_excluded.txt").getPath();
+
+ System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+
+ testExploit(true);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testBothListIncluded() throws Exception {
+ String path = U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
+
+ System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
+ System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+
+ testExploit(false);
+ }
+
+ /**
+ * @param positive Positive.
+ */
+ private void testExploit(boolean positive) throws Exception {
+ try {
+ startGrid();
+
+ attack(marshal(new Exploit()));
+
+ boolean res = GridTestUtils.waitForCondition(new GridAbsPredicate() {
+ @Override public boolean apply() {
+ return SHARED.get();
+ }
+ }, 3000L);
+
+ if (positive)
+ assertTrue(res);
+ else
+ assertFalse(res);
+ }
+ finally {
+ stopAllGrids();
+ }
+ }
+
+ /**
+ * @param obj Object.
+ */
+ private static byte[] marshal(Object obj) throws IgniteCheckedException {
+ return MARSH.marshal(obj);
+ }
+
+ /**
+ * @param data Data.
+ */
+ private void attack(byte[] data) throws IOException {
+ InetAddress addr = InetAddress.getLoopbackAddress();
+
+ try (
+ Socket sock = new Socket(addr, 47500);
+ OutputStream oos = new BufferedOutputStream(sock.getOutputStream())
+ ) {
+ oos.write(U.IGNITE_HEADER);
+ oos.write(data);
+ }
+ }
+
+ /** */
+ private static class Exploit implements Serializable {
+ /**
+ * @param is Input stream.
+ */
+ private void readObject(ObjectInputStream is) throws ClassNotFoundException, IOException {
+ SHARED.set(true);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/stream/socket/SocketStreamerUnmarshalVulnerabilityTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/stream/socket/SocketStreamerUnmarshalVulnerabilityTest.java b/modules/core/src/test/java/org/apache/ignite/stream/socket/SocketStreamerUnmarshalVulnerabilityTest.java
new file mode 100644
index 0000000..dadc5b6
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/stream/socket/SocketStreamerUnmarshalVulnerabilityTest.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.stream.socket;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteDataStreamer;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.internal.util.lang.GridAbsPredicate;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteBiTuple;
+import org.apache.ignite.marshaller.Marshaller;
+import org.apache.ignite.marshaller.jdk.JdkMarshaller;
+import org.apache.ignite.stream.StreamSingleTupleExtractor;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHALLER_BLACKLIST;
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHALLER_WHITELIST;
+
+/**
+ * Tests for whitelist and blacklist ot avoiding deserialization vulnerability.
+ */
+public class SocketStreamerUnmarshalVulnerabilityTest extends GridCommonAbstractTest {
+ /** Shared value. */
+ private static final AtomicBoolean SHARED = new AtomicBoolean();
+
+ /** Port. */
+ private static int port;
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+ try (ServerSocket sock = new ServerSocket(0)) {
+ port = sock.getLocalPort();
+ }
+
+ IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+ cfg.setCacheConfiguration(defaultCacheConfiguration());
+
+ return cfg;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTest() throws Exception {
+ super.beforeTest();
+
+ SHARED.set(false);
+
+ System.clearProperty(IGNITE_MARSHALLER_WHITELIST);
+ System.clearProperty(IGNITE_MARSHALLER_BLACKLIST);
+
+ IgniteUtils.clearClassCache();
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testNoLists() throws Exception {
+ testExploit(true);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testWhiteListIncluded() throws Exception {
+ String path = U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
+
+ System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
+
+ testExploit(true);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testWhiteListExcluded() throws Exception {
+ String path = U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_excluded.txt").getPath();
+
+ System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
+
+ testExploit(false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testBlackListIncluded() throws Exception {
+ String path = U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
+
+ System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+
+ testExploit(false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testBlackListExcluded() throws Exception {
+ String path = U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_excluded.txt").getPath();
+
+ System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+
+ testExploit(true);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testBothListIncluded() throws Exception {
+ String path = U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
+
+ System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
+ System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+
+ testExploit(false);
+ }
+
+ /**
+ * @param positive Positive.
+ */
+ private void testExploit(boolean positive) throws Exception {
+ try {
+ Ignite ignite = startGrid();
+
+ SocketStreamer<Exploit, Integer, String> sockStmr = null;
+
+ try (IgniteDataStreamer<Integer, String> stmr = ignite.dataStreamer(DEFAULT_CACHE_NAME)) {
+ stmr.allowOverwrite(true);
+ stmr.autoFlushFrequency(10);
+
+ sockStmr = new SocketStreamer<>();
+
+ sockStmr.setIgnite(ignite);
+
+ sockStmr.setStreamer(stmr);
+
+ sockStmr.setPort(port);
+
+ sockStmr.setSingleTupleExtractor(new StreamSingleTupleExtractor<Exploit, Integer, String>() {
+ @Override public Map.Entry<Integer, String> extract(Exploit msg) {
+ return new IgniteBiTuple<>(1, "val");
+ }
+ });
+
+ sockStmr.start();
+
+ try (Socket sock = new Socket(InetAddress.getLocalHost(), port);
+ OutputStream os = new BufferedOutputStream(sock.getOutputStream())) {
+ Marshaller marsh = new JdkMarshaller();
+
+ byte[] msg = marsh.marshal(new Exploit());
+
+ os.write(msg.length >>> 24);
+ os.write(msg.length >>> 16);
+ os.write(msg.length >>> 8);
+ os.write(msg.length);
+
+ os.write(msg);
+ }
+ catch (IOException | IgniteCheckedException e) {
+ throw new IgniteException(e);
+ }
+
+ boolean res = GridTestUtils.waitForCondition(new GridAbsPredicate() {
+ @Override public boolean apply() {
+ return SHARED.get();
+ }
+ }, 3000L);
+
+ if (positive)
+ assertTrue(res);
+ else
+ assertFalse(res);
+ }
+ finally {
+ if (sockStmr != null)
+ sockStmr.stop();
+ }
+ }
+ finally {
+ stopAllGrids();
+ }
+ }
+
+ /** */
+ private static class Exploit implements Serializable {
+ /**
+ * @param is Input stream.
+ */
+ private void readObject(ObjectInputStream is) throws ClassNotFoundException, IOException {
+ SHARED.set(true);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java
index 6b39faa..5b85385 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java
@@ -78,7 +78,8 @@ public class GridTestKernalContext extends GridKernalContextImpl {
null,
null,
null,
- U.allPluginProviders()
+ U.allPluginProviders(),
+ null
);
GridTestUtils.setFieldValue(grid(), "cfg", config());
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
index 1b4e2da..9fee224 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
@@ -20,6 +20,7 @@ package org.apache.ignite.testsuites;
import java.util.Set;
import junit.framework.TestSuite;
import org.apache.ignite.GridSuppressedExceptionSelfTest;
+import org.apache.ignite.internal.ClassSetTest;
import org.apache.ignite.internal.ClusterGroupHostsSelfTest;
import org.apache.ignite.internal.ClusterGroupSelfTest;
import org.apache.ignite.internal.GridFailFastNodeFailureDetectionSelfTest;
@@ -191,6 +192,8 @@ public class IgniteBasicTestSuite extends TestSuite {
suite.addTestSuite(GridCleanerTest.class);
+ suite.addTestSuite(ClassSetTest.class);
+
return suite;
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java
index 626875c..6e51c36 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java
@@ -21,6 +21,7 @@ import junit.framework.TestSuite;
import org.apache.ignite.spi.GridTcpSpiForwardingSelfTest;
import org.apache.ignite.spi.discovery.AuthenticationRestartTest;
import org.apache.ignite.spi.discovery.IgniteDiscoveryCacheReuseSelfTest;
+import org.apache.ignite.spi.discovery.tcp.DiscoveryUnmarshalVulnerabilityTest;
import org.apache.ignite.spi.discovery.tcp.IgniteClientConnectTest;
import org.apache.ignite.spi.discovery.tcp.IgniteClientReconnectMassiveShutdownTest;
import org.apache.ignite.spi.discovery.tcp.TcpClientDiscoveryMarshallerCheckSelfTest;
@@ -111,6 +112,8 @@ public class IgniteSpiDiscoverySelfTestSuite extends TestSuite {
// Disco cache reuse.
suite.addTest(new TestSuite(IgniteDiscoveryCacheReuseSelfTest.class));
+ suite.addTest(new TestSuite(DiscoveryUnmarshalVulnerabilityTest.class));
+
return suite;
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteStreamSelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteStreamSelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteStreamSelfTestSuite.java
index d7c677c..9eac277 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteStreamSelfTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteStreamSelfTestSuite.java
@@ -19,6 +19,7 @@ package org.apache.ignite.testsuites;
import junit.framework.TestSuite;
import org.apache.ignite.stream.socket.SocketStreamerSelfTest;
+import org.apache.ignite.stream.socket.SocketStreamerUnmarshalVulnerabilityTest;
/**
* Stream test suite.
@@ -32,6 +33,7 @@ public class IgniteStreamSelfTestSuite extends TestSuite {
TestSuite suite = new TestSuite("Ignite Stream Test Suite");
suite.addTest(new TestSuite(SocketStreamerSelfTest.class));
+ suite.addTest(new TestSuite(SocketStreamerUnmarshalVulnerabilityTest.class));
return suite;
}