diff options
author | Chiachang Wang <chiachangwang@google.com> | 2019-11-27 22:59:49 -0800 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-11-27 22:59:49 -0800 |
commit | ccdf1c2670abe2c2fbc9ae3a839093846e4c6b3e (patch) | |
tree | 61282b851a7bebce4bee1654c8e194ba5fce5860 | |
parent | 242ab14055a25a65c176d9535fb844ed3d00240b (diff) | |
parent | d077658de4737f1e18934289dfc5f571f7d33687 (diff) |
Merge "Catch possible buffer access exception"
am: d077658de4
Change-Id: I0c0dc6437bf4927dc1ddb1e09c6b4ad9f30ddcc2
-rw-r--r-- | src/com/android/networkstack/netlink/TcpSocketTracker.java | 74 |
1 files changed, 42 insertions, 32 deletions
diff --git a/src/com/android/networkstack/netlink/TcpSocketTracker.java b/src/com/android/networkstack/netlink/TcpSocketTracker.java index 9de3118..58d934e 100644 --- a/src/com/android/networkstack/netlink/TcpSocketTracker.java +++ b/src/com/android/networkstack/netlink/TcpSocketTracker.java @@ -63,8 +63,10 @@ import com.android.internal.annotations.VisibleForTesting; import java.io.FileDescriptor; import java.io.InterruptedIOException; import java.net.SocketException; +import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Base64; import java.util.List; /** @@ -172,39 +174,47 @@ public class TcpSocketTracker { // | struct nlmsghdr | struct rtmsg | struct rtattr| data | // +------------------+---------------+--------------+--------+ final ByteBuffer bytes = mDependencies.recvMesssage(fd); - - while (enoughBytesRemainForValidNlMsg(bytes)) { - final StructNlMsgHdr nlmsghdr = StructNlMsgHdr.parse(bytes); - if (nlmsghdr == null) { - Log.e(TAG, "Badly formatted data."); - break; - } - final int nlmsgLen = nlmsghdr.nlmsg_len; - log("pollSocketsInfo: nlmsghdr=" + nlmsghdr); - // End of the message. Stop parsing. - if (nlmsghdr.nlmsg_type == NLMSG_DONE) break; - - if (nlmsghdr.nlmsg_type != SOCK_DIAG_BY_FAMILY) { - Log.e(TAG, "Expect to get family " + family - + " SOCK_DIAG_BY_FAMILY message but get " + nlmsghdr.nlmsg_type); - break; - } - - if (isValidInetDiagMsgSize(nlmsgLen)) { - // Get the socket cookie value. Composed by two Integers value. - // Corresponds to inet_diag_sockid in - // <linux_src>/include/uapi/linux/inet_diag.h - bytes.position(bytes.position() + IDIAG_COOKIE_OFFSET); - // It's stored in native with 2 int. Parse it as long for convenience. - final long cookie = bytes.getLong(); - // Skip the rest part of StructInetDiagMsg. - bytes.position(bytes.position() - + StructInetDiagMsg.STRUCT_SIZE - IDIAG_COOKIE_OFFSET - Long.BYTES); - final SocketInfo info = parseSockInfo(bytes, family, nlmsgLen, time); - // Update TcpStats based on previous and current socket info. - stat.accumulate(calculateLatestPacketsStat(info, mSocketInfos.get(cookie))); - mSocketInfos.put(cookie, info); + try { + while (enoughBytesRemainForValidNlMsg(bytes)) { + final StructNlMsgHdr nlmsghdr = StructNlMsgHdr.parse(bytes); + if (nlmsghdr == null) { + Log.e(TAG, "Badly formatted data."); + break; + } + final int nlmsgLen = nlmsghdr.nlmsg_len; + log("pollSocketsInfo: nlmsghdr=" + nlmsghdr + ", limit=" + bytes.limit()); + // End of the message. Stop parsing. + if (nlmsghdr.nlmsg_type == NLMSG_DONE) break; + + if (nlmsghdr.nlmsg_type != SOCK_DIAG_BY_FAMILY) { + Log.e(TAG, "Expect to get family " + family + + " SOCK_DIAG_BY_FAMILY message but get " + + nlmsghdr.nlmsg_type); + break; + } + + if (isValidInetDiagMsgSize(nlmsgLen)) { + // Get the socket cookie value. Composed by two Integers value. + // Corresponds to inet_diag_sockid in + // <linux_src>/include/uapi/linux/inet_diag.h + bytes.position(bytes.position() + IDIAG_COOKIE_OFFSET); + // It's stored in native with 2 int. Parse it as long for convenience. + final long cookie = bytes.getLong(); + // Skip the rest part of StructInetDiagMsg. + bytes.position(bytes.position() + + StructInetDiagMsg.STRUCT_SIZE - IDIAG_COOKIE_OFFSET + - Long.BYTES); + final SocketInfo info = parseSockInfo(bytes, family, nlmsgLen, time); + // Update TcpStats based on previous and current socket info. + stat.accumulate( + calculateLatestPacketsStat(info, mSocketInfos.get(cookie))); + mSocketInfos.put(cookie, info); + } } + } catch (IllegalArgumentException | BufferUnderflowException e) { + Log.wtf(TAG, "Unexpected socket info parsing, " + e + ", family " + family + + " buffer:" + bytes + " " + + Base64.getEncoder().encodeToString(bytes.array())); } } // Calculate mLatestReceiveCount, mSentSinceLastRecv and mLatestPacketFailPercentage. |