From 3f4f07415c7e3962e89c0bfcf1037bba051fb6b4 Mon Sep 17 00:00:00 2001 From: Joey Grover Date: Thu, 27 Oct 2016 16:26:25 -0400 Subject: [PATCH] Add protection against incorrect implementations of SdlRouterService Adding checks to ensure the SdlRouterService is exported and prevent crashes when attempting to connect to nonexported services. --- .../transport/SdlBroadcastReceiver.java | 4 ++- .../transport/SdlRouterService.java | 13 ++++++++-- .../transport/SdlRouterStatusProvider.java | 10 +++++++- .../smartdevicelink/util/AndroidTools.java | 25 +++++++++++++++++++ 4 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 sdl_android_lib/src/com/smartdevicelink/util/AndroidTools.java diff --git a/sdl_android_lib/src/com/smartdevicelink/transport/SdlBroadcastReceiver.java b/sdl_android_lib/src/com/smartdevicelink/transport/SdlBroadcastReceiver.java index a304191ff1..0ef76d3abe 100644 --- a/sdl_android_lib/src/com/smartdevicelink/transport/SdlBroadcastReceiver.java +++ b/sdl_android_lib/src/com/smartdevicelink/transport/SdlBroadcastReceiver.java @@ -4,6 +4,8 @@ import java.util.Vector; import java.util.concurrent.ConcurrentLinkedQueue; +import com.smartdevicelink.util.AndroidTools; + import android.app.ActivityManager; import android.app.ActivityManager.RunningServiceInfo; import android.bluetooth.BluetoothAdapter; @@ -182,7 +184,7 @@ private static boolean isRouterServiceRunning(Context context, boolean pingServi for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { //We will check to see if it contains this name, should be pretty specific //Log.d(TAG, "Found Service: "+ service.service.getClassName()); - if ((service.service.getClassName()).toLowerCase(Locale.US).contains(SDL_ROUTER_SERVICE_CLASS_NAME)) { + if ((service.service.getClassName()).toLowerCase(Locale.US).contains(SDL_ROUTER_SERVICE_CLASS_NAME) && AndroidTools.isServiceExported(context, service.service)) { runningBluetoothServicePackage.add(service.service); //Store which instance is running if(pingService){ diff --git a/sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterService.java b/sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterService.java index c17690b120..e571d5379b 100644 --- a/sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterService.java +++ b/sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterService.java @@ -36,7 +36,10 @@ import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Build; @@ -67,6 +70,7 @@ import com.smartdevicelink.transport.enums.TransportType; import com.smartdevicelink.transport.utl.ByteAraryMessageAssembler; import com.smartdevicelink.transport.utl.ByteArrayMessageSpliter; +import com.smartdevicelink.util.AndroidTools; import com.smartdevicelink.util.BitConverter; /** @@ -223,7 +227,7 @@ public void onReceive(Context context, Intent intent) if(tempService.name!=null){ sdlMultiList.remove(tempService.name.getPackageName()); } - if((localCompareTo == null || localCompareTo.isNewer(tempService))){ + if((localCompareTo == null || localCompareTo.isNewer(tempService)) && AndroidTools.isServiceExported(context, tempService.name)){ LocalRouterService self = getLocalRouterService(); if(!self.isEqual(tempService)){ //We want to ignore self Log.i(TAG, "Newer service received than previously stored service - " + tempService.launchIntent.getAction()); @@ -759,7 +763,7 @@ private boolean processCheck(){ return false; } - + @Override public void onCreate() { super.onCreate(); @@ -770,6 +774,11 @@ public void onCreate() { stopSelf(); return; } + if(!AndroidTools.isServiceExported(this, new ComponentName(this, this.getClass()))){ //We want to check to see if our service is actually exported + Log.e(TAG, "Service isn't exported. Shutting down"); + stopSelf(); + return; + } else{Log.d(TAG, "We are in the correct process");} synchronized(REGISTERED_APPS_LOCK){ registeredApps = new HashMap(); diff --git a/sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterStatusProvider.java b/sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterStatusProvider.java index 7daad47609..4b98475dba 100644 --- a/sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterStatusProvider.java +++ b/sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterStatusProvider.java @@ -2,11 +2,16 @@ import java.lang.ref.WeakReference; +import com.smartdevicelink.util.AndroidTools; + import android.annotation.SuppressLint; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.content.pm.PackageManager; +import android.content.pm.ServiceInfo; +import android.content.pm.PackageManager.NameNotFoundException; import android.os.Handler; import android.os.IBinder; import android.os.Message; @@ -70,7 +75,7 @@ public void setFlags(int flags){ this.flags = flags; } public void checkIsConnected(){ - if(!bindToService()){ + if(!AndroidTools.isServiceExported(context,routerService) || !bindToService()){ //We are unable to bind to service cb.onConnectionStatusUpdate(false, routerService, context); unBindFromService(); @@ -87,6 +92,9 @@ private boolean bindToService(){ if(isBound){ return true; } + if(clientMessenger == null){ + return false; + } Intent bindingIntent = new Intent(); bindingIntent.setClassName(this.routerService.getPackageName(), this.routerService.getClassName());//This sets an explicit intent //Quickly make sure it's just up and running diff --git a/sdl_android_lib/src/com/smartdevicelink/util/AndroidTools.java b/sdl_android_lib/src/com/smartdevicelink/util/AndroidTools.java new file mode 100644 index 0000000000..ff8819ec3a --- /dev/null +++ b/sdl_android_lib/src/com/smartdevicelink/util/AndroidTools.java @@ -0,0 +1,25 @@ +package com.smartdevicelink.util; + +import android.content.ComponentName; +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.pm.ServiceInfo; +import android.content.pm.PackageManager.NameNotFoundException; + +public class AndroidTools { + /** + * Check to see if a component is exported + * @param Context object used to retrieve the package manager + * @param componentName of the component in question + * @return true if this component is tagged as exported + */ + public static boolean isServiceExported(Context context, ComponentName name) { + try { + ServiceInfo serviceInfo = context.getPackageManager().getServiceInfo(name, PackageManager.GET_META_DATA); + return serviceInfo.exported; + } catch (NameNotFoundException e) { + e.printStackTrace(); + } + return false; + } +}