Merge "Support routing sockets as another user"
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 3dbe078..7ee10c3 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -119,6 +119,8 @@
boolean prepareVpn(String oldPackage, String newPackage);
+ void markSocketAsUser(in ParcelFileDescriptor socket, int uid);
+
ParcelFileDescriptor establishVpn(in VpnConfig config);
void startLegacyVpn(in VpnProfile profile);
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index a6344ca..476a6fd 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -1749,6 +1749,16 @@
"ConnectivityService");
}
+ private void enforceMarkNetworkSocketPermission() {
+ //Media server special case
+ if (Binder.getCallingUid() == Process.MEDIA_UID) {
+ return;
+ }
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.MARK_NETWORK_SOCKET,
+ "ConnectivityService");
+ }
+
/**
* Handle a {@code DISCONNECTED} event. If this pertains to the non-active
* network, we ignore it. If it is for the active network, we send out a
@@ -3350,6 +3360,23 @@
}
}
+ @Override
+ public void markSocketAsUser(ParcelFileDescriptor socket, int uid) {
+ enforceMarkNetworkSocketPermission();
+ final long token = Binder.clearCallingIdentity();
+ try {
+ int mark = mNetd.getMarkForUid(uid);
+ // Clear the mark on the socket if no mark is needed to prevent socket reuse issues
+ if (mark == -1) {
+ mark = 0;
+ }
+ NetworkUtils.markSocket(socket.getFd(), mark);
+ } catch (RemoteException e) {
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
/**
* Configure a TUN interface and return its file descriptor. Parameters
* are encoded and opaque to this class. This method is used by VpnBuilder