Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19f87a7f authored by Chiachang Wang's avatar Chiachang Wang
Browse files

Catch possible buffer access exception

Returned message from kernel in cf device may not work
as intended and crash NetworkStack. Since NetworkStack stays
in the system process, the crash will break device and impact
users. Catch the exception to prevent break whole device.

Bug: 145275899
Bug: 142035706
Test: atest NetworkStackTests NetworkStackNextTests
Change-Id: I7b7ecacfc76c54748a4428f04c5422506d85b8d2
parent f6d6cd29
Loading
Loading
Loading
Loading
+42 −32
Original line number Diff line number Diff line
@@ -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,7 +174,7 @@ public class TcpSocketTracker {
                // | struct nlmsghdr  | struct rtmsg  | struct rtattr|  data  |
                // +------------------+---------------+--------------+--------+
                final ByteBuffer bytes = mDependencies.recvMesssage(fd);

                try {
                    while (enoughBytesRemainForValidNlMsg(bytes)) {
                        final StructNlMsgHdr nlmsghdr = StructNlMsgHdr.parse(bytes);
                        if (nlmsghdr == null) {
@@ -180,13 +182,14 @@ public class TcpSocketTracker {
                            break;
                        }
                        final int nlmsgLen = nlmsghdr.nlmsg_len;
                    log("pollSocketsInfo: nlmsghdr=" + nlmsghdr);
                        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);
                                    + " SOCK_DIAG_BY_FAMILY message but get "
                                    + nlmsghdr.nlmsg_type);
                            break;
                        }

@@ -199,13 +202,20 @@ public class TcpSocketTracker {
                            final long cookie = bytes.getLong();
                            // Skip the rest part of StructInetDiagMsg.
                            bytes.position(bytes.position()
                                + StructInetDiagMsg.STRUCT_SIZE - IDIAG_COOKIE_OFFSET - Long.BYTES);
                                    + 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)));
                            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.
            mSentSinceLastRecv = (stat.receivedCount == 0)