mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
Bug 1660826 - Work around apparent bug with sendmsg() in some 64-bit Android devices. r=nika
Some Android ARM64 devices appear to have a bug where sendmsg sometimes returns 0xFFFFFFFF, which we're assuming is a -1 that was incorrectly truncated to 32-bit and then zero-extended. This patch detects that value (which should never legitimately be returned, because it's 16x the maximum message size) and replaces it with -1, with some additional assertions. The workaround is also enabled on x86_64 Android on debug builds only, so that the code has CI coverage. Differential Revision: https://phabricator.services.mozilla.com/D89845
This commit is contained in:
parent
c4dd52a672
commit
c0cd7e11b5
@ -108,6 +108,42 @@ bool SetCloseOnExec(int fd) {
|
||||
|
||||
bool ErrorIsBrokenPipe(int err) { return err == EPIPE || err == ECONNRESET; }
|
||||
|
||||
// Some Android ARM64 devices appear to have a bug where sendmsg
|
||||
// sometimes returns 0xFFFFFFFF, which we're assuming is a -1 that was
|
||||
// incorrectly truncated to 32-bit and then zero-extended.
|
||||
// See bug 1660826 for details.
|
||||
//
|
||||
// This is a workaround to detect that value and replace it with -1
|
||||
// (and check that there really was an error), because the largest
|
||||
// amount we'll ever write is Channel::kMaximumMessageSize (256MiB).
|
||||
//
|
||||
// The workaround is also enabled on x86_64 Android on debug builds,
|
||||
// although the bug isn't known to manifest there, so that there will
|
||||
// be some CI coverage of this code.
|
||||
|
||||
static inline ssize_t corrected_sendmsg(int socket,
|
||||
const struct msghdr* message,
|
||||
int flags) {
|
||||
#if defined(ANDROID) && \
|
||||
(defined(__aarch64__) || (defined(DEBUG) && defined(__x86_64__)))
|
||||
static constexpr auto kBadValue = static_cast<ssize_t>(0xFFFFFFFF);
|
||||
static_assert(kBadValue > 0);
|
||||
|
||||
# ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
errno = 0;
|
||||
# endif
|
||||
ssize_t bytes_written = sendmsg(socket, message, flags);
|
||||
if (bytes_written == kBadValue) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(errno != 0);
|
||||
bytes_written = -1;
|
||||
}
|
||||
MOZ_DIAGNOSTIC_ASSERT(bytes_written < kBadValue);
|
||||
return bytes_written;
|
||||
#else
|
||||
return sendmsg(socket, message, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@ -616,7 +652,8 @@ bool Channel::ChannelImpl::ProcessOutgoingMessages() {
|
||||
msgh.msg_iov = iov;
|
||||
msgh.msg_iovlen = iov_count;
|
||||
|
||||
ssize_t bytes_written = HANDLE_EINTR(sendmsg(pipe_, &msgh, MSG_DONTWAIT));
|
||||
ssize_t bytes_written =
|
||||
HANDLE_EINTR(corrected_sendmsg(pipe_, &msgh, MSG_DONTWAIT));
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
// On OSX CommitAll gets called later, once we get the
|
||||
|
Loading…
Reference in New Issue
Block a user