cannam@133
|
1 Problem
|
cannam@133
|
2 =======
|
cannam@133
|
3
|
cannam@133
|
4 Integer underflow in pointer validation.
|
cannam@133
|
5
|
cannam@133
|
6 Discovered by
|
cannam@133
|
7 =============
|
cannam@133
|
8
|
cannam@133
|
9 Kenton Varda <kenton@sandstorm.io>
|
cannam@133
|
10
|
cannam@133
|
11 Announced
|
cannam@133
|
12 =========
|
cannam@133
|
13
|
cannam@133
|
14 2015-03-02
|
cannam@133
|
15
|
cannam@133
|
16 CVE
|
cannam@133
|
17 ===
|
cannam@133
|
18
|
cannam@133
|
19 CVE-2015-2311
|
cannam@133
|
20
|
cannam@133
|
21 Impact
|
cannam@133
|
22 ======
|
cannam@133
|
23
|
cannam@133
|
24 - Remotely segfault a peer by sending it a malicious message.
|
cannam@133
|
25 - Possible exfiltration of memory, depending on application behavior.
|
cannam@133
|
26 - If the application performs a sequence of operations that "probably" no
|
cannam@133
|
27 application does (see below), possible memory corruption / code execution.
|
cannam@133
|
28
|
cannam@133
|
29 Fixed in
|
cannam@133
|
30 ========
|
cannam@133
|
31
|
cannam@133
|
32 - git commit [26bcceda72372211063d62aab7e45665faa83633][0]
|
cannam@133
|
33 - release 0.5.1.1:
|
cannam@133
|
34 - Unix: https://capnproto.org/capnproto-c++-0.5.1.1.tar.gz
|
cannam@133
|
35 - Windows: https://capnproto.org/capnproto-c++-win32-0.5.1.1.zip
|
cannam@133
|
36 - release 0.4.1.1:
|
cannam@133
|
37 - Unix: https://capnproto.org/capnproto-c++-0.4.1.1.tar.gz
|
cannam@133
|
38 - release 0.6 (future)
|
cannam@133
|
39
|
cannam@133
|
40 [0]: https://github.com/sandstorm-io/capnproto/commit/26bcceda72372211063d62aab7e45665faa83633
|
cannam@133
|
41
|
cannam@133
|
42 Details
|
cannam@133
|
43 =======
|
cannam@133
|
44
|
cannam@133
|
45 *The following text contains speculation about the exploitability of this
|
cannam@133
|
46 bug. This is provided for informational purposes, but as such speculation is
|
cannam@133
|
47 often shown to be wrong, you should not rely on the accuracy of this
|
cannam@133
|
48 section for the safety of your service. Please update your library.*
|
cannam@133
|
49
|
cannam@133
|
50 A `Text` pointer, when non-null, must point to a NUL-terminated string, meaning
|
cannam@133
|
51 it must have a size of at least 1. Under most circumstances, Cap'n Proto will
|
cannam@133
|
52 reject zero-size text objects. However, if an application performs the
|
cannam@133
|
53 following sequence, they may hit a code path that was missing a check:
|
cannam@133
|
54
|
cannam@133
|
55 1. Receive a message containing a `Text` value, but do not actually look at
|
cannam@133
|
56 that value.
|
cannam@133
|
57 2. Copy the message into a `MessageBuilder`.
|
cannam@133
|
58 3. Call the `get()` method for the `Text` value within the `MessageBuilder`,
|
cannam@133
|
59 obtaining a `Text::Builder` for the *copy*.
|
cannam@133
|
60
|
cannam@133
|
61 In this case, the `Text::Builder` will appear to point at a string with size
|
cannam@133
|
62 2^32-1, starting at a location within the Cap'n Proto message.
|
cannam@133
|
63
|
cannam@133
|
64 The `Text::Builder` is writable. If the application decided to overwrite the
|
cannam@133
|
65 text in-place, it could overwrite arbitrary memory in the next 4GB of virtual
|
cannam@133
|
66 address space. However, there are several reasons to believe this is unusual:
|
cannam@133
|
67
|
cannam@133
|
68 - Usually, when an application `get()`s a text field, it only intends to
|
cannam@133
|
69 read it. Overwriting the text in-place is unusual.
|
cannam@133
|
70 - Calling `set()` on the field -- the usual way to overwrite text -- will
|
cannam@133
|
71 create an all-new text object and harmlessly discard the old, invalid
|
cannam@133
|
72 pointer.
|
cannam@133
|
73
|
cannam@133
|
74 Note that even if an application does overwrite the text, it would still be
|
cannam@133
|
75 hard for the attacker to exploit this for code execution unless the attacker
|
cannam@133
|
76 also controls the data that the application writes into the field.
|
cannam@133
|
77
|
cannam@133
|
78 This vulnerability is somewhat more likely to allow exfiltration of memory.
|
cannam@133
|
79 However, this requires the app to additionally echo the text back to the
|
cannam@133
|
80 attacker. To do this without segfaulting, the app would either need to attempt
|
cannam@133
|
81 to read only a subset of the text, or would need to have 2^32 contiguous bytes
|
cannam@133
|
82 of virtual memory mapped into its address space.
|
cannam@133
|
83
|
cannam@133
|
84 A related problem, also fixed in this change, occurs when a `Text` value
|
cannam@133
|
85 has non-zero size but lacks a NUL terminator. Again, if an application
|
cannam@133
|
86 performs the series of operations described above, the NUL terminator check
|
cannam@133
|
87 may be bypassed. If the app then passes the string to an API that assumes
|
cannam@133
|
88 NUL-terminated strings, the contents of memory after the text blob may be
|
cannam@133
|
89 interpreted as being part of the string, up to the next zero-valued byte.
|
cannam@133
|
90 This again could lead to exfiltration of data, this time without the high
|
cannam@133
|
91 chance of segfault, although only up to the next zero-valued byte, which
|
cannam@133
|
92 are typically quite common.
|
cannam@133
|
93
|
cannam@133
|
94 Preventative measures
|
cannam@133
|
95 =====================
|
cannam@133
|
96
|
cannam@133
|
97 This problem was discovered through preventative measures implemented after
|
cannam@133
|
98 the security problem discussed in the [previous advisory][1]. Specifically, this
|
cannam@133
|
99 problem was found by using template metaprogramming to implement integer
|
cannam@133
|
100 bounds analysis in order to effectively "prove" that there are no integer
|
cannam@133
|
101 overflows in the core pointer validation code (capnp/layout.c++).
|
cannam@133
|
102 Tentatively, I believe that this analysis exhaustively covers this file.
|
cannam@133
|
103 The instrumentation has not been merged into master yet as it requires some
|
cannam@133
|
104 cleanup, but [check the Cap'n Proto blog for an in-depth discussion][2].
|
cannam@133
|
105
|
cannam@133
|
106 This problem is also caught by capnp/fuzz-test.c++, which *has* been
|
cannam@133
|
107 merged into master but likely doesn't have as broad coverage.
|
cannam@133
|
108
|
cannam@133
|
109 [1]: https://github.com/sandstorm-io/capnproto/tree/master/security-advisories/2015-03-02-0-c++-integer-overflow.md
|
cannam@133
|
110 [2]: https://capnproto.org/news/2015-03-02-security-advisory-and-integer-overflow-protection.html
|