From d475c7042408a82b848a551ac453f59f96c20bf4 Mon Sep 17 00:00:00 2001 From: Chad Brubaker Date: Thu, 11 Jul 2013 13:29:30 -0700 Subject: [PATCH] Support routing sockets as another user Add support for routing sockets as if they were another user's. This is for services that handle delegated network tasks like MediaServer and DownloadManager. Change-Id: Id20efc1f5c2cce6f8838d777762f6c0a703a9437 --- .../android/net/IConnectivityManager.aidl | 2 ++ .../android/server/ConnectivityService.java | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 3dbe078313ac8..7ee10c3f12bf0 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -119,6 +119,8 @@ interface IConnectivityManager 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 a6344cafabf0e..476a6fdffb1a6 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -1749,6 +1749,16 @@ public class ConnectivityService extends IConnectivityManager.Stub { "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 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } + @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