Skip to content

Commit e2d10a1

Browse files
committed
[security][CVE-2018-6337] Flush folly::secureRandom buffer on fork
D8109884 D8110240 CVE-2018-6337
1 parent 1ef6d97 commit e2d10a1

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

patches/folly-CVE-2018-6337.patch

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
diff --git a/third-party/folly/src/folly/Random.cpp b/third-party/folly/src/folly/Random.cpp
2+
index afb62f5d..40a6b17f 100644
3+
--- a/third-party/folly/src/folly/Random.cpp
4+
+++ b/third-party/folly/src/folly/Random.cpp
5+
@@ -72,6 +72,7 @@ void readRandomDevice(void* data, size_t size) {
6+
7+
class BufferedRandomDevice {
8+
public:
9+
+ static once_flag flag;
10+
static constexpr size_t kDefaultBufferSize = 128;
11+
12+
explicit BufferedRandomDevice(size_t bufferSize = kDefaultBufferSize);
13+
@@ -97,10 +98,28 @@ class BufferedRandomDevice {
14+
unsigned char* ptr_;
15+
};
16+
17+
+once_flag BufferedRandomDevice::flag;
18+
+struct RandomTag {};
19+
+
20+
BufferedRandomDevice::BufferedRandomDevice(size_t bufferSize)
21+
: bufferSize_(bufferSize),
22+
buffer_(new unsigned char[bufferSize]),
23+
ptr_(buffer_.get() + bufferSize) { // refill on first use
24+
+ call_once(flag, [this]() {
25+
+ detail::AtFork::registerHandler(
26+
+ this,
27+
+ /*prepare*/ []() { return true; },
28+
+ /*parent*/ []() {},
29+
+ /*child*/
30+
+ []() {
31+
+ using Single = SingletonThreadLocal<BufferedRandomDevice, RandomTag>;
32+
+ auto& t = Single::get();
33+
+ // Clear out buffered data on fork.
34+
+ //
35+
+ // Ensure child and parent do not share same entropy pool.
36+
+ t.ptr_ = t.buffer_.get() + t.bufferSize_;
37+
+ });
38+
+ });
39+
}
40+
41+
void BufferedRandomDevice::getSlow(unsigned char* data, size_t size) {
42+
@@ -124,8 +143,6 @@ void BufferedRandomDevice::getSlow(unsigned char* data, size_t size) {
43+
ptr_ += size;
44+
}
45+
46+
-struct RandomTag {};
47+
-
48+
} // namespace
49+
50+
void Random::secureRandom(void* data, size_t size) {
51+
diff --git a/third-party/folly/src/folly/detail/AtFork.cpp b/third-party/folly/src/folly/detail/AtFork.cpp
52+
index 48c42fd3..12a6f934 100644
53+
--- a/third-party/folly/src/folly/detail/AtFork.cpp
54+
+++ b/third-party/folly/src/folly/detail/AtFork.cpp
55+
@@ -13,12 +13,14 @@
56+
* See the License for the specific language governing permissions and
57+
* limitations under the License.
58+
*/
59+
+
60+
#include <folly/detail/AtFork.h>
61+
62+
#include <list>
63+
#include <mutex>
64+
65+
-#include <folly/Exception.h>
66+
+#include <folly/lang/Exception.h>
67+
+#include <folly/portability/PThread.h>
68+
69+
namespace folly {
70+
71+
@@ -72,7 +74,10 @@ class AtForkList {
72+
#if FOLLY_HAVE_PTHREAD_ATFORK
73+
int ret = pthread_atfork(
74+
&AtForkList::prepare, &AtForkList::parent, &AtForkList::child);
75+
- checkPosixError(ret, "pthread_atfork failed");
76+
+ if (ret != 0) {
77+
+ throw_exception<std::system_error>(
78+
+ ret, std::generic_category(), "pthread_atfork failed");
79+
+ }
80+
#elif !__ANDROID__ && !defined(_MSC_VER)
81+
// pthread_atfork is not part of the Android NDK at least as of n9d. If
82+
// something is trying to call native fork() directly at all with Android's
83+
diff --git a/third-party/folly/src/folly/test/RandomTest.cpp b/third-party/folly/src/folly/test/RandomTest.cpp
84+
index 9c33159b..2ee74c6d 100644
85+
--- a/third-party/folly/src/folly/test/RandomTest.cpp
86+
+++ b/third-party/folly/src/folly/test/RandomTest.cpp
87+
@@ -138,3 +138,24 @@ TEST(Random, sanity) {
88+
std::unordered_set<uint64_t>(vals.begin(), vals.end()).size());
89+
}
90+
}
91+
+
92+
+TEST(Random, SecureFork) {
93+
+ unsigned char buffer = 0;
94+
+ // Init random buffer
95+
+ folly::Random::secureRandom(&buffer, 1);
96+
+
97+
+ auto pid = fork();
98+
+ EXPECT_NE(pid, -1);
99+
+ if (pid) {
100+
+ // parent
101+
+ int status = 0;
102+
+ folly::Random::secureRandom(&buffer, 1);
103+
+ auto pid2 = wait(&status);
104+
+ EXPECT_NE(WEXITSTATUS(status), buffer);
105+
+ EXPECT_EQ(pid, pid2);
106+
+ } else {
107+
+ // child
108+
+ folly::Random::secureRandom(&buffer, 1);
109+
+ exit(buffer); // Do not print gtest results
110+
+ }
111+
+}

0 commit comments

Comments
 (0)