Fix comparison of uninitialized memory in signalfd wrapper.
In newer glibc versions, sigemptyset isn't guaranteed to fill the
entire size of sigset_t with 0's, so memcmp on the entire size
is undefined.
Signed-off-by: Tyler Chatow <tchatow@gmail.com>
Change-Id: Ib6afaeb68f944ba67a309a4bfea3a7680e70c9bf
diff --git a/aos/ipc_lib/signalfd.cc b/aos/ipc_lib/signalfd.cc
index 051a654..3689b7e 100644
--- a/aos/ipc_lib/signalfd.cc
+++ b/aos/ipc_lib/signalfd.cc
@@ -6,6 +6,7 @@
#include <sanitizer/msan_interface.h>
#endif
#include <unistd.h>
+
#include <initializer_list>
#include "glog/logging.h"
@@ -78,6 +79,16 @@
}
}
+namespace {
+// sizeof(sigset_t) is larger than the bytes actually used to represent all
+// signals. This size is only the bytes initialized. _NSIG is 1-indexed.
+static constexpr size_t kSigSetSize = (_NSIG - 1) / 8;
+
+// If the size of the mask changes, we should check that we still have
+// correct behavior.
+static_assert(kSigSetSize == 8 && kSigSetSize <= sizeof(sigset_t));
+} // namespace
+
SignalFd::~SignalFd() {
// Unwind the constructor. Unblock the signals and close the fd. Verify nobody
// else unblocked the signals we're supposed to unblock in the meantime.
@@ -85,7 +96,7 @@
CHECK_EQ(0, wrapped_pthread_sigmask(SIG_UNBLOCK, &blocked_mask_, &old_mask));
sigset_t unblocked_mask;
CHECK_EQ(0, wrapped_sigandset(&unblocked_mask, &blocked_mask_, &old_mask));
- if (memcmp(&unblocked_mask, &blocked_mask_, sizeof(unblocked_mask)) != 0) {
+ if (memcmp(&unblocked_mask, &blocked_mask_, kSigSetSize) != 0) {
LOG(FATAL) << "Some other code unblocked one or more of our signals";
}
PCHECK(close(fd_) == 0);