mozilla-bmo1436242.patch
branchfirefox60
changeset 1080 e8d4a33582b8
equal deleted inserted replaced
1064:af29b3ac33ae 1080:e8d4a33582b8
       
     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