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

Commit 3bed4c9f authored by Kazuhiro Ondo's avatar Kazuhiro Ondo Committed by Wink Saville
Browse files

Fix FeatureUser leak in ConnectivityService

In case infinite restoral timer is used for a network feature,
FeatureUser could be keep added but never released if a user
is keep calling "startUsingNetworkFeature".

This patch will add duplication check when adding a FeatureUser
into the list in case infinite restoral timer is used.

Bug: 5043513
Change-Id: I47e7076e217f201454fae33ce596ecdc63cf7908
parent cd4636ec
Loading
Loading
Loading
Loading
+37 −15
Original line number Diff line number Diff line
@@ -220,7 +220,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {

    // list of DeathRecipients used to make sure features are turned off when
    // a process dies
    private List mFeatureUsers;
    private List<FeatureUser> mFeatureUsers;

    private boolean mSystemReady;
    private Intent mInitialBroadcast;
@@ -404,7 +404,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
            mNetRequestersPids[i] = new ArrayList();
        }

        mFeatureUsers = new ArrayList();
        mFeatureUsers = new ArrayList<FeatureUser>();

        mNumDnsEntries = 0;

@@ -677,6 +677,20 @@ public class ConnectivityService extends IConnectivityManager.Stub {
            stopUsingNetworkFeature(this, false);
        }

        public boolean isSameUser(FeatureUser u) {
            if (u == null) return false;

            return isSameUser(u.mPid, u.mUid, u.mNetworkType, u.mFeature);
        }

        public boolean isSameUser(int pid, int uid, int networkType, String feature) {
            if ((mPid == pid) && (mUid == uid) && (mNetworkType == networkType) &&
                TextUtils.equals(mFeature, feature)) {
                return true;
            }
            return false;
        }

        public String toString() {
            return "FeatureUser("+mNetworkType+","+mFeature+","+mPid+","+mUid+"), created " +
                    (System.currentTimeMillis() - mCreateTime) + " mSec ago";
@@ -727,16 +741,29 @@ public class ConnectivityService extends IConnectivityManager.Stub {
                    }
                }

                int restoreTimer = getRestoreDefaultNetworkDelay(usedNetworkType);

                synchronized(this) {
                    mFeatureUsers.add(f);
                    boolean addToList = true;
                    if (restoreTimer < 0) {
                        // In case there is no timer is specified for the feature,
                        // make sure we don't add duplicate entry with the same request.
                        for (FeatureUser u : mFeatureUsers) {
                            if (u.isSameUser(f)) {
                                // Duplicate user is found. Do not add.
                                addToList = false;
                                break;
                            }
                        }
                    }

                    if (addToList) mFeatureUsers.add(f);
                    if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) {
                        // this gets used for per-pid dns when connected
                        mNetRequestersPids[usedNetworkType].add(currentPid);
                    }
                }

                int restoreTimer = getRestoreDefaultNetworkDelay(usedNetworkType);

                if (restoreTimer >= 0) {
                    mHandler.sendMessageDelayed(
                            mHandler.obtainMessage(EVENT_RESTORE_DEFAULT_NETWORK, f), restoreTimer);
@@ -786,11 +813,9 @@ public class ConnectivityService extends IConnectivityManager.Stub {
        boolean found = false;

        synchronized(this) {
            for (int i = 0; i < mFeatureUsers.size() ; i++) {
                u = (FeatureUser)mFeatureUsers.get(i);
                if (uid == u.mUid && pid == u.mPid &&
                        networkType == u.mNetworkType &&
                        TextUtils.equals(feature, u.mFeature)) {
            for (FeatureUser x : mFeatureUsers) {
                if (x.isSameUser(pid, uid, networkType, feature)) {
                    u = x;
                    found = true;
                    break;
                }
@@ -842,11 +867,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
            // do not pay attention to duplicate requests - in effect the
            // API does not refcount and a single stop will counter multiple starts.
            if (ignoreDups == false) {
                for (int i = 0; i < mFeatureUsers.size() ; i++) {
                    FeatureUser x = (FeatureUser)mFeatureUsers.get(i);
                    if (x.mUid == u.mUid && x.mPid == u.mPid &&
                            x.mNetworkType == u.mNetworkType &&
                            TextUtils.equals(x.mFeature, u.mFeature)) {
                for (FeatureUser x : mFeatureUsers) {
                    if (x.isSameUser(u)) {
                        if (DBG) log("ignoring stopUsingNetworkFeature as dup is found");
                        return 1;
                    }