diff --git a/init/uevent_listener.cpp b/init/uevent_listener.cpp index d8d9b36ff..7cd396a8b 100644 --- a/init/uevent_listener.cpp +++ b/init/uevent_listener.cpp @@ -95,20 +95,18 @@ UeventListener::UeventListener(size_t uevent_socket_rcvbuf_size) { fcntl(device_fd_, F_SETFL, O_NONBLOCK); } -bool UeventListener::ReadUevent(Uevent* uevent) const { +ReadUeventResult UeventListener::ReadUevent(Uevent* uevent) const { char msg[UEVENT_MSG_LEN + 2]; int n = uevent_kernel_multicast_recv(device_fd_, msg, UEVENT_MSG_LEN); if (n <= 0) { if (errno != EAGAIN && errno != EWOULDBLOCK) { PLOG(ERROR) << "Error reading from Uevent Fd"; } - return false; + return ReadUeventResult::kFailed; } if (n >= UEVENT_MSG_LEN) { LOG(ERROR) << "Uevent overflowed buffer, discarding"; - // Return true here even if we discard as we may have more uevents pending and we - // want to keep processing them. - return true; + return ReadUeventResult::kInvalid; } msg[n] = '\0'; @@ -116,7 +114,7 @@ bool UeventListener::ReadUevent(Uevent* uevent) const { ParseEvent(msg, uevent); - return true; + return ReadUeventResult::kSuccess; } // RegenerateUevents*() walks parts of the /sys tree and pokes the uevent files to cause the kernel @@ -137,7 +135,10 @@ ListenerAction UeventListener::RegenerateUeventsForDir(DIR* d, close(fd); Uevent uevent; - while (ReadUevent(&uevent)) { + ReadUeventResult result; + while ((result = ReadUevent(&uevent)) != ReadUeventResult::kFailed) { + // Skip processing the uevent if it is invalid. + if (result == ReadUeventResult::kInvalid) continue; if (callback(uevent) == ListenerAction::kStop) return ListenerAction::kStop; } } @@ -212,7 +213,10 @@ void UeventListener::Poll(const ListenerCallback& callback, // We're non-blocking, so if we receive a poll event keep processing until // we have exhausted all uevent messages. Uevent uevent; - while (ReadUevent(&uevent)) { + ReadUeventResult result; + while ((result = ReadUevent(&uevent)) != ReadUeventResult::kFailed) { + // Skip processing the uevent if it is invalid. + if (result == ReadUeventResult::kInvalid) continue; if (callback(uevent) == ListenerAction::kStop) return; } } diff --git a/init/uevent_listener.h b/init/uevent_listener.h index f9f954aa0..277286064 100644 --- a/init/uevent_listener.h +++ b/init/uevent_listener.h @@ -37,6 +37,12 @@ enum class ListenerAction { kContinue, // Continue regenerating uevents as we haven't seen the one(s) we're interested in. }; +enum class ReadUeventResult { + kSuccess = 0, // Uevent was successfully read. + kFailed, // Uevent reading has failed. + kInvalid, // An Invalid Uevent was read (like say, the msg received is >= UEVENT_MSG_LEN). +}; + using ListenerCallback = std::function; class UeventListener { @@ -50,7 +56,7 @@ class UeventListener { const std::optional relative_timeout = {}) const; private: - bool ReadUevent(Uevent* uevent) const; + ReadUeventResult ReadUevent(Uevent* uevent) const; ListenerAction RegenerateUeventsForDir(DIR* d, const ListenerCallback& callback) const; android::base::unique_fd device_fd_;