You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by go...@apache.org on 2017/11/15 18:57:37 UTC
[geode] 02/02: Whitelist: Work with older versions of Java 8
This is an automated email from the ASF dual-hosted git repository.
gosullivan pushed a commit to branch whitelist_wip
in repository https://gitbox.apache.org/repos/asf/geode.git
commit 731ac2b4206615fb6bdaa54db371c7f8b7956fd4
Author: Galen O'Sullivan <go...@pivotal.io>
AuthorDate: Wed Nov 15 10:55:23 2017 -0800
Whitelist: Work with older versions of Java 8
and achieve this by moving references to ObjectInputFilter out of
InternalDataSerializer.
Signed-off-by: Dan Smith <ds...@pivotal.io>
---
.../geode/internal/EmptyInputStreamFilter.java | 24 +++
.../apache/geode/internal/InputStreamFilter.java | 21 +++
.../geode/internal/InternalDataSerializer.java | 176 ++++++++-------------
.../internal/ObjectInputStreamFilterWrapper.java | 92 +++++++++++
...alDataSerializerSerializationWhitelistTest.java | 12 ++
5 files changed, 211 insertions(+), 114 deletions(-)
diff --git a/geode-core/src/main/java/org/apache/geode/internal/EmptyInputStreamFilter.java b/geode-core/src/main/java/org/apache/geode/internal/EmptyInputStreamFilter.java
new file mode 100644
index 0000000..82369a0
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/EmptyInputStreamFilter.java
@@ -0,0 +1,24 @@
+/*
+ * 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.geode.internal;
+
+import java.io.ObjectInputStream;
+
+public class EmptyInputStreamFilter implements InputStreamFilter {
+ @Override
+ public void setFilterOn(ObjectInputStream ois) {
+ // Do nothing, this is the case where we don't filter.
+ }
+}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/InputStreamFilter.java b/geode-core/src/main/java/org/apache/geode/internal/InputStreamFilter.java
new file mode 100644
index 0000000..19d4102
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/InputStreamFilter.java
@@ -0,0 +1,21 @@
+/*
+ * 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.geode.internal;
+
+import java.io.ObjectInputStream;
+
+public interface InputStreamFilter {
+ void setFilterOn(ObjectInputStream ois);
+}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/InternalDataSerializer.java b/geode-core/src/main/java/org/apache/geode/internal/InternalDataSerializer.java
index 71a802a..969ece4 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/InternalDataSerializer.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/InternalDataSerializer.java
@@ -14,7 +14,60 @@
*/
package org.apache.geode.internal;
+import java.io.BufferedReader;
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.EOFException;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.NotSerializableException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.io.UTFDataFormatException;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.URL;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Stack;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.UUID;
+import java.util.Vector;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+
import org.apache.commons.lang.StringUtils;
+import org.apache.logging.log4j.Logger;
+
import org.apache.geode.CancelException;
import org.apache.geode.CanonicalInstantiator;
import org.apache.geode.DataSerializable;
@@ -24,7 +77,6 @@ import org.apache.geode.GemFireIOException;
import org.apache.geode.GemFireRethrowable;
import org.apache.geode.Instantiator;
import org.apache.geode.InternalGemFireError;
-import org.apache.geode.InternalGemFireException;
import org.apache.geode.SerializationException;
import org.apache.geode.SystemFailure;
import org.apache.geode.ToDataException;
@@ -70,59 +122,6 @@ import org.apache.geode.pdx.internal.PdxReaderImpl;
import org.apache.geode.pdx.internal.PdxType;
import org.apache.geode.pdx.internal.PdxWriterImpl;
import org.apache.geode.pdx.internal.TypeRegistry;
-import org.apache.logging.log4j.Logger;
-import sun.misc.ObjectInputFilter;
-
-import java.io.BufferedReader;
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.EOFException;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.NotSerializableException;
-import java.io.ObjectInput;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutput;
-import java.io.ObjectOutputStream;
-import java.io.ObjectStreamClass;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.io.UTFDataFormatException;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Proxy;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.net.InetAddress;
-import java.net.URL;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Properties;
-import java.util.Set;
-import java.util.Stack;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.UUID;
-import java.util.Vector;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.TimeUnit;
/**
* Contains static methods for data serializing instances of internal GemFire classes. It also
@@ -151,13 +150,12 @@ public abstract class InternalDataSerializer extends DataSerializer implements D
+ ";";
- private static ObjectInputFilter defaultSerializationFilter =
- ObjectInputFilter.Config.createFilter("**");
+ private static InputStreamFilter defaultSerializationFilter = new EmptyInputStreamFilter();
/**
* A deserialization filter for ObjectInputStreams
*/
- private static ObjectInputFilter serializationFilter = defaultSerializationFilter;
+ private static InputStreamFilter serializationFilter = defaultSerializationFilter;
private static final String serializationVersionTxt =
System.getProperty(DistributionConfig.GEMFIRE_PREFIX + "serializationVersion");
@@ -226,8 +224,9 @@ public abstract class InternalDataSerializer extends DataSerializer implements D
throw new GemFireConfigException(
"A serialization filter has been specified but this version of Java does not support serialization filters - sun.misc.ObjectInputFilter is not available");
}
- createSerializationFilter(SANCTIONED_SERIALIZABLES_DEPENDENCIES_PATTERN
- + distributionConfig.getSerializableObjectFilter() + ";!*", services);
+ serializationFilter =
+ new ObjectInputStreamFilterWrapper(SANCTIONED_SERIALIZABLES_DEPENDENCIES_PATTERN
+ + distributionConfig.getSerializableObjectFilter() + ";!*", services);
} else {
clearSerializationFilter();
}
@@ -237,59 +236,11 @@ public abstract class InternalDataSerializer extends DataSerializer implements D
serializationFilter = defaultSerializationFilter;
}
- private static void createSerializationFilter(String serializationFilterSpec,
- Collection<DistributedSystemService> services) {
-
- Set<String> sanctionedClasses = new HashSet<>(500);
- for (DistributedSystemService service : services) {
- try {
- sanctionedClasses.addAll(service.getSerializationWhitelist());
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- try {
- URL sanctionedSerializables = ClassPathLoader.getLatest()
- .getResource(InternalDataSerializer.class, "sanctionedSerializables.txt");
- Collection<String> coreClassNames = loadClassNames(sanctionedSerializables);
- sanctionedClasses.addAll(coreClassNames);
- } catch (IOException e) {
- throw new InternalGemFireException(
- "unable to read sanctionedSerializables.txt to form a serialization white-list", e);
- }
-
- logger.debug("setting a serialization filter containing {}", serializationFilterSpec);
-
- final ObjectInputFilter userFilter =
- ObjectInputFilter.Config.createFilter(serializationFilterSpec);
- serializationFilter = filterInfo -> {
- if (filterInfo.serialClass() == null) {
- return userFilter.checkInput(filterInfo);
- }
-
- String className = filterInfo.serialClass().getName();
- if (filterInfo.serialClass().isArray()) {
- className = filterInfo.serialClass().getComponentType().getName();
- }
- if (sanctionedClasses.contains(className)) {
- return ObjectInputFilter.Status.ALLOWED;
- // return ObjectInputFilter.Status.UNDECIDED;
- } else {
- ObjectInputFilter.Status status = userFilter.checkInput(filterInfo);
- if (status == ObjectInputFilter.Status.REJECTED) {
- logger.warn("Serialization filter is rejecting class {}", className);
- }
- return status;
- }
- };
-
- // global filter - if we enable this it will affect all ObjectInputStreams
- // ObjectInputFilter.Config.setSerialFilter(serializationFilter);
- }
/**
- * Loads the class names from sanctionedSerializables.txt, a file that is also maintained for
- * backward-compatibility testing with AnalyzeSerializablesJUnitTest
+ * {@link DistributedSystemService}s that need to whitelist Serializable objects can use this to
+ * read them from a file and then return them via
+ * {@link DistributedSystemService#getSerializationWhitelist}
*/
public static Collection<String> loadClassNames(URL sanctionedSerializables) throws IOException {
Collection<String> result = new ArrayList(1000);
@@ -2966,10 +2917,7 @@ public abstract class InternalDataSerializer extends DataSerializer implements D
}
ObjectInput ois = new DSObjectInputStream(stream);
- if (serializationFilter != null) {
- ObjectInputFilter.Config.setObjectInputFilter((ObjectInputStream) ois,
- serializationFilter);
- }
+ serializationFilter.setFilterOn((ObjectInputStream) ois);
if (stream instanceof VersionedDataStream) {
Version v = ((VersionedDataStream) stream).getVersion();
if (v != null && v != Version.CURRENT) {
diff --git a/geode-core/src/main/java/org/apache/geode/internal/ObjectInputStreamFilterWrapper.java b/geode-core/src/main/java/org/apache/geode/internal/ObjectInputStreamFilterWrapper.java
new file mode 100644
index 0000000..841d052
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/internal/ObjectInputStreamFilterWrapper.java
@@ -0,0 +1,92 @@
+/*
+ * 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.geode.internal;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.net.URL;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.logging.log4j.Logger;
+
+import org.apache.geode.InternalGemFireException;
+import org.apache.geode.distributed.internal.DistributedSystemService;
+import org.apache.geode.internal.logging.LogService;
+
+import sun.misc.ObjectInputFilter;
+
+
+public class ObjectInputStreamFilterWrapper implements InputStreamFilter {
+ private static final Logger logger = LogService.getLogger();
+ private final ObjectInputFilter serializationFilter;
+
+ public ObjectInputStreamFilterWrapper(String serializationFilterSpec,
+ Collection<DistributedSystemService> services) {
+
+ Set<String> sanctionedClasses = new HashSet<>(500);
+ for (DistributedSystemService service : services) {
+ try {
+ sanctionedClasses.addAll(service.getSerializationWhitelist());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ try {
+ URL sanctionedSerializables = ClassPathLoader.getLatest()
+ .getResource(InternalDataSerializer.class, "sanctionedSerializables.txt");
+ Collection<String> coreClassNames =
+ InternalDataSerializer.loadClassNames(sanctionedSerializables);
+ sanctionedClasses.addAll(coreClassNames);
+ } catch (IOException e) {
+ throw new InternalGemFireException(
+ "unable to read sanctionedSerializables.txt to form a serialization white-list", e);
+ }
+
+ logger.debug("setting a serialization filter containing {}", serializationFilterSpec);
+
+ final ObjectInputFilter userFilter =
+ ObjectInputFilter.Config.createFilter(serializationFilterSpec);
+ serializationFilter = filterInfo -> {
+ if (filterInfo.serialClass() == null) {
+ return userFilter.checkInput(filterInfo);
+ }
+
+ String className = filterInfo.serialClass().getName();
+ if (filterInfo.serialClass().isArray()) {
+ className = filterInfo.serialClass().getComponentType().getName();
+ }
+ if (sanctionedClasses.contains(className)) {
+ return ObjectInputFilter.Status.ALLOWED;
+ // return ObjectInputFilter.Status.UNDECIDED;
+ } else {
+ ObjectInputFilter.Status status = userFilter.checkInput(filterInfo);
+ if (status == ObjectInputFilter.Status.REJECTED) {
+ logger.warn("Serialization filter is rejecting class {}", className);
+ }
+ return status;
+ }
+ };
+
+ // global filter - if we enable this it will affect all ObjectInputStreams
+ // ObjectInputFilter.Config.setSerialFilter(serializationFilter);
+ }
+
+ @Override
+ public void setFilterOn(ObjectInputStream objectInputStream) {
+ ObjectInputFilter.Config.setObjectInputFilter(objectInputStream, serializationFilter);
+ }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/internal/InternalDataSerializerSerializationWhitelistTest.java b/geode-core/src/test/java/org/apache/geode/internal/InternalDataSerializerSerializationWhitelistTest.java
index 1064e2f..73690d9 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/InternalDataSerializerSerializationWhitelistTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/InternalDataSerializerSerializationWhitelistTest.java
@@ -12,6 +12,7 @@ import java.util.ArrayList;
import java.util.Properties;
import org.junit.AfterClass;
+import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@@ -43,11 +44,22 @@ public class InternalDataSerializerSerializationWhitelistTest {
@Before
public void setUp() {
+ Assume.assumeTrue("ObjectInputFilter is present in this JVM (post- 8.111)",
+ hasObjectInputFilter());
outputStream = new HeapDataOutputStream(Version.CURRENT);
testSerializable = new TestSerializable();
properties = new Properties();
}
+ private boolean hasObjectInputFilter() {
+ try {
+ Class.forName("sun.misc.ObjectInputFilter");
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
@AfterClass
public static void clearDataSerializerFilter() {
InternalDataSerializer.initialize(new DistributionConfigImpl(new Properties()),
--
To stop receiving notification emails like this one, please contact
"commits@geode.apache.org" <co...@geode.apache.org>.