Copy arguments from NetworkAgent registration early
These objects have a non-trivial lifetime, as they will be
stored while the NetworkMonitor (which lives in another
process) starts. Agents that live in the system server will
still have a reference to the passed arguments and might
want to keep and mutate them for their own purposes. To
avoid bad surprises, ConnectivityService should copy these
objects before the function returns.
This patch should not cause any additional copies, because
the copies that used to happen after the monitor has started
are now not necessary and are removed.
Bug: 238139913
Test: FrameworksNetTests
Change-Id: I1cdd14e7a247dc01a3d73f528c3f3d77bd103be5
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 960059b..f5fcdcb 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -7295,18 +7295,23 @@
NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId,
int uid) {
+ // Make a copy of the passed NI, LP, NC as the caller may hold a reference to them
+ // and mutate them at any time.
+ final NetworkInfo niCopy = new NetworkInfo(networkInfo);
+ final NetworkCapabilities ncCopy = new NetworkCapabilities(networkCapabilities);
+ final LinkProperties lpCopy = new LinkProperties(linkProperties);
+
// At this point the capabilities/properties are untrusted and unverified, e.g. checks that
- // the capabilities' access UID comply with security limitations. They will be sanitized
+ // the capabilities' access UIDs comply with security limitations. They will be sanitized
// as the NAI registration finishes, in handleRegisterNetworkAgent(). This is
// because some of the checks must happen on the handler thread.
final NetworkAgentInfo nai = new NetworkAgentInfo(na,
- new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo),
- linkProperties, networkCapabilities,
+ new Network(mNetIdManager.reserveNetId()), niCopy, lpCopy, ncCopy,
currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
this, mNetd, mDnsResolver, providerId, uid, mLingerDelayMs,
mQosCallbackTracker, mDeps);
- final String extraInfo = networkInfo.getExtraInfo();
+ final String extraInfo = niCopy.getExtraInfo();
final String name = TextUtils.isEmpty(extraInfo)
? nai.networkCapabilities.getSsid() : extraInfo;
if (DBG) log("registerNetworkAgent " + nai);
@@ -7321,19 +7326,12 @@
private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) {
if (VDBG) log("Network Monitor created for " + nai);
- // nai.nc and nai.lp are the same object that was passed by the network agent if the agent
- // lives in the same process as this code (e.g. wifi), so make sure this code doesn't
- // mutate their object. TODO : make this copy much earlier to avoid them mutating it
- // while the network monitor is starting.
- final LinkProperties lp = new LinkProperties(nai.linkProperties);
// Store a copy of the declared capabilities.
nai.setDeclaredCapabilities(nai.networkCapabilities);
// Make sure the LinkProperties and NetworkCapabilities reflect what the agent info said.
- final NetworkCapabilities sanitized =
- nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator);
- nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, sanitized));
- processLinkPropertiesFromAgent(nai, lp);
- nai.linkProperties = lp;
+ nai.getAndSetNetworkCapabilities(mixInCapabilities(nai,
+ nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator)));
+ processLinkPropertiesFromAgent(nai, nai.linkProperties);
nai.onNetworkMonitorCreated(networkMonitor);