File: CVE-2017-7957.patch

package info (click to toggle)
libxstream-java 1.4.9-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 5,816 kB
  • ctags: 9,108
  • sloc: java: 48,081; xml: 2,233; sh: 28; makefile: 4
file content (97 lines) | stat: -rw-r--r-- 4,029 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
Description: Fixes CVE-2017-7957: When a certain denyTypes workaround is not
 used, XStream mishandles attempts to create an instance of the primitive type
 'void' during unmarshalling, leading to a remote application crash, as
 demonstrated by an xstream.fromXML("<void/>") call.
Origin: backport, https://github.com/x-stream/xstream/commit/b3570be
Bug-Debian: https://bugs.debian.org/861521
--- a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProvider.java
+++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProvider.java
@@ -78,14 +78,18 @@
             throw ex;
         }
         ErrorWritingException ex = null;
-        try {
-            return unsafe.allocateInstance(type);
-        } catch (SecurityException e) {
-            ex = new ObjectAccessException("Cannot construct type", e);
-        } catch (InstantiationException e) {
-            ex =  new ConversionException("Cannot construct type", e);
-        } catch (IllegalArgumentException e) {
-            ex = new ObjectAccessException("Cannot construct type", e);
+        if (type == void.class || type == Void.class) {
+            ex = new ConversionException("Type void cannot have an instance");
+        } else {
+            try {
+                return unsafe.allocateInstance(type);
+            } catch (final SecurityException e) {
+                ex = new ObjectAccessException("Cannot construct type", e);
+            } catch (final InstantiationException e) {
+                ex = new ConversionException("Cannot construct type", e);
+            } catch (final IllegalArgumentException e) {
+                ex = new ObjectAccessException("Cannot construct type", e);
+            }
         }
         ex.add("construction-type", type.getName());
         throw ex;
--- a/xstream/src/java/com/thoughtworks/xstream/security/PrimitiveTypePermission.java
+++ b/xstream/src/java/com/thoughtworks/xstream/security/PrimitiveTypePermission.java
@@ -8,8 +8,9 @@
 
 import com.thoughtworks.xstream.core.util.Primitives;
 
+
 /**
- * Permission for any primitive type and its boxed counterpart (incl. void).
+ * Permission for any primitive type and its boxed counterpart (excl. void).
  * 
  * @author J&ouml;rg Schaible
  * @since 1.4.7
@@ -21,7 +22,8 @@
     public static final TypePermission PRIMITIVES = new PrimitiveTypePermission();
 
     public boolean allows(Class type) {
-        return type != null && type.isPrimitive() || Primitives.isBoxed(type);
+        return type != null && type != void.class && type != Void.class && type.isPrimitive()
+            || Primitives.isBoxed(type);
     }
 
     public int hashCode() {
--- a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java
+++ b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java
@@ -13,9 +13,12 @@
 import java.beans.EventHandler;
 
 import com.thoughtworks.xstream.XStreamException;
+import com.thoughtworks.xstream.converters.ConversionException;
 import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
+import com.thoughtworks.xstream.security.ForbiddenClassException;
 import com.thoughtworks.xstream.security.ProxyTypePermission;
 
+
 /**
  * @author J&ouml;rg Schaible
  */
@@ -80,4 +83,23 @@
             BUFFER.append("Executed!");
         }
     }
+
+    public void testDeniedInstanceOfVoid() {
+        try {
+            xstream.fromXML("<void/>");
+            fail("Thrown " + ForbiddenClassException.class.getName() + " expected");
+        } catch (final ForbiddenClassException e) {
+            // OK
+        }
+    }
+
+    public void testAllowedInstanceOfVoid() {
+        xstream.allowTypes(void.class, Void.class);
+        try {
+            xstream.fromXML("<void/>");
+            fail("Thrown " + ConversionException.class.getName() + " expected");
+        } catch (final ConversionException e) {
+            assertEquals("void", e.get("construction-type"));
+        }
+    }
 }