Skip to content

Commit 9f3e932

Browse files
UldiniadGenkzsz11
authored andcommitted
Implement backup/restore for network policy
Modify network policy XML parser helper functions for backup/restore scenarios Issue: calyxos#384 Change-Id: I77158b344a47138a17fbce72d3ecb3be6927b870 Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
1 parent 6245ece commit 9f3e932

4 files changed

Lines changed: 166 additions & 9 deletions

File tree

core/java/android/net/INetworkPolicyManager.aidl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,7 @@ interface INetworkPolicyManager {
7878
void factoryReset(String subscriber);
7979

8080
boolean isUidNetworkingBlocked(int uid, boolean meteredNetwork);
81+
82+
byte[] getBackupPayload();
83+
void applyRestore(in byte[] payload);
8184
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright (C) 2021 The Calyx Institute
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.android.server.backup;
18+
19+
import android.app.backup.BlobBackupHelper;
20+
import android.content.Context;
21+
import android.net.INetworkPolicyManager;
22+
import android.os.ServiceManager;
23+
import android.util.Log;
24+
import android.util.Slog;
25+
26+
public class NetworkPolicyBackupHelper extends BlobBackupHelper {
27+
private static final String TAG = "NetworkPolicyBackupHelper";
28+
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
29+
30+
// Current version of the blob schema
31+
static final int BLOB_VERSION = 1;
32+
33+
// Key under which the payload blob is stored
34+
static final String KEY_NETWORK_POLICY = "network_policy";
35+
36+
public NetworkPolicyBackupHelper() {
37+
super(BLOB_VERSION, KEY_NETWORK_POLICY);
38+
}
39+
40+
@Override
41+
protected byte[] getBackupPayload(String key) {
42+
byte[] newPayload = null;
43+
if (KEY_NETWORK_POLICY.equals(key)) {
44+
try {
45+
INetworkPolicyManager npm = INetworkPolicyManager.Stub.asInterface(
46+
ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
47+
newPayload = npm.getBackupPayload();
48+
} catch (Exception e) {
49+
// Treat as no data
50+
Slog.e(TAG, "Couldn't communicate with network policy manager");
51+
newPayload = null;
52+
}
53+
}
54+
return newPayload;
55+
}
56+
57+
@Override
58+
protected void applyRestoredPayload(String key, byte[] payload) {
59+
if (DEBUG) {
60+
Slog.v(TAG, "Got restore of " + key);
61+
}
62+
63+
if (KEY_NETWORK_POLICY.equals(key)) {
64+
try {
65+
INetworkPolicyManager.Stub.asInterface(
66+
ServiceManager.getService(Context.NETWORK_POLICY_SERVICE))
67+
.applyRestore(payload);
68+
} catch (Exception e) {
69+
Slog.e(TAG, "Couldn't communicate with network policy manager");
70+
}
71+
}
72+
}
73+
74+
}

services/core/java/com/android/server/backup/SystemBackupAgent.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import android.app.backup.FullBackupDataOutput;
2525
import android.app.backup.WallpaperBackupHelper;
2626
import android.content.Context;
27+
import android.net.INetworkPolicyManager;
2728
import android.os.Environment;
2829
import android.os.ParcelFileDescriptor;
2930
import android.os.RemoteException;
@@ -56,6 +57,7 @@ public class SystemBackupAgent extends BackupAgentHelper {
5657
private static final String ACCOUNT_MANAGER_HELPER = "account_manager";
5758
private static final String SLICES_HELPER = "slices";
5859
private static final String PEOPLE_HELPER = "people";
60+
private static final String NETWORK_POLICY_HELPER = "network_policy";
5961

6062
// These paths must match what the WallpaperManagerService uses. The leaf *_FILENAME
6163
// are also used in the full-backup file format, so must not change unless steps are
@@ -101,6 +103,7 @@ public void onCreate(UserHandle user) {
101103
addHelper(ACCOUNT_MANAGER_HELPER, new AccountManagerBackupHelper());
102104
addHelper(SLICES_HELPER, new SliceBackupHelper(this));
103105
addHelper(PEOPLE_HELPER, new PeopleBackupHelper(mUserId));
106+
addHelper(NETWORK_POLICY_HELPER, new NetworkPolicyBackupHelper());
104107
}
105108

106109
@Override

services/core/java/com/android/server/net/NetworkPolicyManagerService.java

Lines changed: 86 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@
252252
import org.xmlpull.v1.XmlPullParserException;
253253
import org.xmlpull.v1.XmlSerializer;
254254

255+
import java.io.ByteArrayInputStream;
256+
import java.io.ByteArrayOutputStream;
255257
import java.io.File;
256258
import java.io.FileDescriptor;
257259
import java.io.FileInputStream;
@@ -377,6 +379,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
377379
private static final String ATTR_OWNER_PACKAGE = "ownerPackage";
378380
private static final String ATTR_NETWORK_TYPES = "networkTypes";
379381
private static final String ATTR_XML_UTILS_NAME = "name";
382+
private static final String ATTR_USER_ID = "userId";
380383

381384
private static final String ACTION_ALLOW_BACKGROUND =
382385
"com.android.server.net.action.ALLOW_BACKGROUND";
@@ -2233,7 +2236,7 @@ private void readPolicyAL() {
22332236
FileInputStream fis = null;
22342237
try {
22352238
fis = mPolicyFile.openRead();
2236-
readPolicyXml(fis);
2239+
readPolicyXml(fis, false);
22372240
} catch (FileNotFoundException e) {
22382241
// missing policy is okay, probably first boot
22392242
upgradeDefaultBackgroundDataUL();
@@ -2244,7 +2247,7 @@ private void readPolicyAL() {
22442247
}
22452248
}
22462249

2247-
private void readPolicyXml(InputStream inputStream) {
2250+
private void readPolicyXml(InputStream inputStream, boolean forRestore) throws IOException, XmlPullParserException {
22482251
final XmlPullParser in = Xml.newPullParser();
22492252
in.setInput(inputStream, StandardCharsets.UTF_8.name());
22502253

@@ -2384,7 +2387,12 @@ private void readPolicyXml(InputStream inputStream) {
23842387
SubscriptionPlan.class, mSubscriptionPlans.get(subId), plan));
23852388
mSubscriptionPlansOwner.put(subId, ownerPackage);
23862389
} else if (TAG_UID_POLICY.equals(tag)) {
2387-
final int uid = readIntAttribute(in, ATTR_UID);
2390+
int uid;
2391+
if (!forRestore) {
2392+
uid = readIntAttribute(in, ATTR_UID);
2393+
} else {
2394+
uid = getUidForPackage(readStringAttribute(in, ATTR_XML_UTILS_NAME), readIntAttribute(in, ATTR_USER_ID));
2395+
}
23882396
final int policy = readIntAttribute(in, ATTR_POLICY);
23892397

23902398
if (UserHandle.isApp(uid)) {
@@ -2407,10 +2415,20 @@ private void readPolicyXml(InputStream inputStream) {
24072415
} else if (TAG_WHITELIST.equals(tag)) {
24082416
insideWhitelist = true;
24092417
} else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) {
2410-
final int uid = readIntAttribute(in, ATTR_UID);
2418+
int uid;
2419+
if (!forRestore) {
2420+
uid = readIntAttribute(in, ATTR_UID);
2421+
} else {
2422+
uid = getUidForPackage(readStringAttribute(in, ATTR_XML_UTILS_NAME), readIntAttribute(in, ATTR_USER_ID));
2423+
}
24112424
whitelistedRestrictBackground.append(uid, true);
24122425
} else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) {
2413-
final int uid = readIntAttribute(in, ATTR_UID);
2426+
int uid;
2427+
if (!forRestore) {
2428+
uid = readIntAttribute(in, ATTR_UID);
2429+
} else {
2430+
uid = getUidForPackage(readStringAttribute(in, ATTR_XML_UTILS_NAME), readIntAttribute(in, ATTR_USER_ID));
2431+
}
24142432
mRestrictBackgroundWhitelistRevokedUids.put(uid, true);
24152433
}
24162434
} else if (type == END_TAG) {
@@ -2506,7 +2524,7 @@ void writePolicyAL() {
25062524
try {
25072525
fos = mPolicyFile.startWrite();
25082526

2509-
writePolicyXml(fos);
2527+
writePolicyXml(fos, false);
25102528

25112529
mPolicyFile.finishWrite(fos);
25122530
} catch (IOException e) {
@@ -2516,7 +2534,7 @@ void writePolicyAL() {
25162534
}
25172535
}
25182536

2519-
private void writePolicyXml(OutputStream outputStream) {
2537+
private void writePolicyXml(OutputStream outputStream, boolean forBackup) throws IOException {
25202538
XmlSerializer out = new FastXmlSerializer();
25212539
out.setOutput(outputStream, StandardCharsets.UTF_8.name());
25222540
out.startDocument(null, true);
@@ -2596,7 +2614,13 @@ private void writePolicyXml(OutputStream outputStream) {
25962614
if (policy == POLICY_NONE) continue;
25972615

25982616
out.startTag(null, TAG_UID_POLICY);
2599-
writeIntAttribute(out, ATTR_UID, uid);
2617+
2618+
if (!forBackup) {
2619+
writeIntAttribute(out, ATTR_UID, uid);
2620+
} else {
2621+
writeStringAttribute(out, ATTR_XML_UTILS_NAME, getPackageForUid(uid));
2622+
writeIntAttribute(out, ATTR_USER_ID, UserHandle.getUserId(uid));
2623+
}
26002624
writeIntAttribute(out, ATTR_POLICY, policy);
26012625
out.endTag(null, TAG_UID_POLICY);
26022626
}
@@ -2611,7 +2635,12 @@ private void writePolicyXml(OutputStream outputStream) {
26112635
for (int i = 0; i < size; i++) {
26122636
final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i);
26132637
out.startTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
2614-
writeIntAttribute(out, ATTR_UID, uid);
2638+
if (!forBackup) {
2639+
writeIntAttribute(out, ATTR_UID, uid);
2640+
} else {
2641+
writeStringAttribute(out, ATTR_XML_UTILS_NAME, getPackageForUid(uid));
2642+
writeIntAttribute(out, ATTR_USER_ID, UserHandle.getUserId(uid));
2643+
}
26152644
out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
26162645
}
26172646

@@ -2620,6 +2649,44 @@ private void writePolicyXml(OutputStream outputStream) {
26202649
out.endDocument();
26212650
}
26222651

2652+
@Override
2653+
public byte[] getBackupPayload() {
2654+
enforceSystemCaller();
2655+
if (LOGD) Slog.d(TAG, "getBackupPayload");
2656+
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
2657+
try {
2658+
writePolicyXml(baos, true);
2659+
return baos.toByteArray();
2660+
} catch (IOException e) {
2661+
Slog.w(TAG, "getBackupPayload: error writing payload", e);
2662+
}
2663+
return null;
2664+
}
2665+
2666+
@Override
2667+
public void applyRestore(byte[] payload) {
2668+
enforceSystemCaller();
2669+
if (LOGD) Slog.d(TAG, "applyRestore payload="
2670+
+ (payload != null ? new String(payload, StandardCharsets.UTF_8) : null));
2671+
if (payload == null) {
2672+
Slog.w(TAG, "applyRestore: no payload to restore");
2673+
return;
2674+
}
2675+
2676+
// clear any existing policy and read from disk
2677+
mNetworkPolicy.clear();
2678+
mSubscriptionPlans.clear();
2679+
mSubscriptionPlansOwner.clear();
2680+
mUidPolicy.clear();
2681+
2682+
final ByteArrayInputStream bais = new ByteArrayInputStream(payload);
2683+
try {
2684+
readPolicyXml(bais, true);
2685+
} catch (IOException | XmlPullParserException e) {
2686+
Slog.w(TAG, "applyRestore: error reading payload", e);
2687+
}
2688+
}
2689+
26232690
@Override
26242691
public void setUidPolicy(int uid, int policy) {
26252692
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
@@ -2828,6 +2895,12 @@ private void enforceAnyPermissionOf(String... permissions) {
28282895
}
28292896
}
28302897

2898+
private void enforceSystemCaller() {
2899+
if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
2900+
throw new SecurityException("Caller must be system");
2901+
}
2902+
}
2903+
28312904
@Override
28322905
public void registerListener(INetworkPolicyListener listener) {
28332906
// TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps
@@ -5522,6 +5595,10 @@ private void setMeteredRestrictedPackagesInternal(Set<String> packageNames, int
55225595
}
55235596
}
55245597

5598+
private String getPackageForUid(int uid) {
5599+
return mContext.getPackageManager().getPackagesForUid(uid)[0];
5600+
}
5601+
55255602
private int getUidForPackage(String packageName, int userId) {
55265603
try {
55275604
return mContext.getPackageManager().getPackageUidAsUser(packageName,

0 commit comments

Comments
 (0)