|
1 https://bugzilla.redhat.com/show_bug.cgi?id=1577277 |
|
2 https://hg.mozilla.org/mozilla-central/rev/6bb3adfa15c6 |
|
3 https://bugzilla.mozilla.org/show_bug.cgi?id=1436242 |
|
4 diff --git a/ipc/chromium/src/chrome/common/ipc_channel_posix.cc b/ipc/chromium/src/chrome/common/ipc_channel_posix.cc |
|
5 --- a/ipc/chromium/src/chrome/common/ipc_channel_posix.cc |
|
6 +++ b/ipc/chromium/src/chrome/common/ipc_channel_posix.cc |
|
7 @@ -418,20 +418,37 @@ bool Channel::ChannelImpl::ProcessIncomi |
|
8 const int* fds; |
|
9 unsigned num_fds; |
|
10 unsigned fds_i = 0; // the index of the first unused descriptor |
|
11 |
|
12 if (input_overflow_fds_.empty()) { |
|
13 fds = wire_fds; |
|
14 num_fds = num_wire_fds; |
|
15 } else { |
|
16 - const size_t prev_size = input_overflow_fds_.size(); |
|
17 - input_overflow_fds_.resize(prev_size + num_wire_fds); |
|
18 - memcpy(&input_overflow_fds_[prev_size], wire_fds, |
|
19 - num_wire_fds * sizeof(int)); |
|
20 + // This code may look like a no-op in the case where |
|
21 + // num_wire_fds == 0, but in fact: |
|
22 + // |
|
23 + // 1. wire_fds will be nullptr, so passing it to memcpy is |
|
24 + // undefined behavior according to the C standard, even though |
|
25 + // the memcpy length is 0. |
|
26 + // |
|
27 + // 2. prev_size will be an out-of-bounds index for |
|
28 + // input_overflow_fds_; this is undefined behavior according to |
|
29 + // the C++ standard, even though the element only has its |
|
30 + // pointer taken and isn't accessed (and the corresponding |
|
31 + // operation on a C array would be defined). |
|
32 + // |
|
33 + // UBSan makes #1 a fatal error, and assertions in libstdc++ do |
|
34 + // the same for #2 if enabled. |
|
35 + if (num_wire_fds > 0) { |
|
36 + const size_t prev_size = input_overflow_fds_.size(); |
|
37 + input_overflow_fds_.resize(prev_size + num_wire_fds); |
|
38 + memcpy(&input_overflow_fds_[prev_size], wire_fds, |
|
39 + num_wire_fds * sizeof(int)); |
|
40 + } |
|
41 fds = &input_overflow_fds_[0]; |
|
42 num_fds = input_overflow_fds_.size(); |
|
43 } |
|
44 |
|
45 // The data for the message we're currently reading consists of any data |
|
46 // stored in incoming_message_ followed by data in input_buf_ (followed by |
|
47 // other messages). |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |