Loading src/java/com/android/internal/telephony/TelephonyComponentFactory.java +36 −18 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.internal.telephony; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.res.XmlResourceParser; import android.database.Cursor; Loading Loading @@ -50,10 +51,13 @@ import dalvik.system.PathClassLoader; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.function.Consumer; import java.util.stream.Collectors; Loading @@ -77,6 +81,7 @@ public class TelephonyComponentFactory { private static final String TAG_COMPONENTS = "components"; private static final String TAG_COMPONENT = "component"; private static final String SYSTEM = "/system/"; private static final String PRODUCT = "/product/"; private final Set<String> mComponentNames = new HashSet<>(); private TelephonyComponentFactory mInjectedInstance; Loading @@ -84,29 +89,41 @@ public class TelephonyComponentFactory { private String mJarPath; /** * @return if jar path is correctly configured to inject. * @return paths correctly configured to inject. * 1) PackageName and JarPath mustn't be empty. * 2) JarPath is restricted under /system only * 2) JarPath is restricted under /system or /product only. * 3) JarPath is on a READ-ONLY partition. */ private boolean isConfigValid() { return !TextUtils.isEmpty(mPackageName) && !TextUtils.isEmpty(mJarPath) && mJarPath.startsWith(SYSTEM); private @Nullable String getValidatedPaths() { if (TextUtils.isEmpty(mPackageName) || TextUtils.isEmpty(mJarPath)) { return null; } // filter out invalid paths return Arrays.stream(mJarPath.split(File.pathSeparator)) .filter(s -> (s.startsWith(SYSTEM) || s.startsWith(PRODUCT))) .filter(s -> { try { // This will also throw an error if the target doesn't exist. StructStatVfs vfs = Os.statvfs(s); return (vfs.f_flag & OsConstants.ST_RDONLY) != 0; } catch (ErrnoException e) { Rlog.w(TAG, "Injection jar is not protected , path: " + s + e.getMessage()); return false; } }).distinct() .collect(Collectors.joining(File.pathSeparator)); } private void makeInjectedInstance() { if (isConfigValid()) { String validatedPaths = getValidatedPaths(); Rlog.d(TAG, "validated paths: " + validatedPaths); if (!TextUtils.isEmpty(validatedPaths)) { try { StructStatVfs vfs = Os.statvfs(mJarPath); if ((vfs.f_flag & OsConstants.ST_RDONLY) != 0) { PathClassLoader classLoader = new PathClassLoader(mJarPath, PathClassLoader classLoader = new PathClassLoader(validatedPaths, ClassLoader.getSystemClassLoader()); Class<?> cls = classLoader.loadClass(mPackageName); mInjectedInstance = (TelephonyComponentFactory) cls.newInstance(); } else { Rlog.w(TAG, "Injection jar is not protected"); } } catch (ErrnoException e) { Rlog.e(TAG, "failed file mount, " + e.getMessage()); } catch (ClassNotFoundException e) { Rlog.e(TAG, "failed: " + e.getMessage()); } catch (IllegalAccessException | InstantiationException e) { Loading Loading @@ -233,7 +250,8 @@ public class TelephonyComponentFactory { mInjectedComponents = new InjectedComponents(); mInjectedComponents.parseXml(parser); mInjectedComponents.makeInjectedInstance(); Rlog.d(TAG, "Total components injected: " + (mInjectedComponents.isConfigValid() boolean injectSuccessful = !TextUtils.isEmpty(mInjectedComponents.getValidatedPaths()); Rlog.d(TAG, "Total components injected: " + (injectSuccessful ? mInjectedComponents.mComponentNames.size() : 0)); } } Loading Loading
src/java/com/android/internal/telephony/TelephonyComponentFactory.java +36 −18 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.internal.telephony; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.res.XmlResourceParser; import android.database.Cursor; Loading Loading @@ -50,10 +51,13 @@ import dalvik.system.PathClassLoader; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.function.Consumer; import java.util.stream.Collectors; Loading @@ -77,6 +81,7 @@ public class TelephonyComponentFactory { private static final String TAG_COMPONENTS = "components"; private static final String TAG_COMPONENT = "component"; private static final String SYSTEM = "/system/"; private static final String PRODUCT = "/product/"; private final Set<String> mComponentNames = new HashSet<>(); private TelephonyComponentFactory mInjectedInstance; Loading @@ -84,29 +89,41 @@ public class TelephonyComponentFactory { private String mJarPath; /** * @return if jar path is correctly configured to inject. * @return paths correctly configured to inject. * 1) PackageName and JarPath mustn't be empty. * 2) JarPath is restricted under /system only * 2) JarPath is restricted under /system or /product only. * 3) JarPath is on a READ-ONLY partition. */ private boolean isConfigValid() { return !TextUtils.isEmpty(mPackageName) && !TextUtils.isEmpty(mJarPath) && mJarPath.startsWith(SYSTEM); private @Nullable String getValidatedPaths() { if (TextUtils.isEmpty(mPackageName) || TextUtils.isEmpty(mJarPath)) { return null; } // filter out invalid paths return Arrays.stream(mJarPath.split(File.pathSeparator)) .filter(s -> (s.startsWith(SYSTEM) || s.startsWith(PRODUCT))) .filter(s -> { try { // This will also throw an error if the target doesn't exist. StructStatVfs vfs = Os.statvfs(s); return (vfs.f_flag & OsConstants.ST_RDONLY) != 0; } catch (ErrnoException e) { Rlog.w(TAG, "Injection jar is not protected , path: " + s + e.getMessage()); return false; } }).distinct() .collect(Collectors.joining(File.pathSeparator)); } private void makeInjectedInstance() { if (isConfigValid()) { String validatedPaths = getValidatedPaths(); Rlog.d(TAG, "validated paths: " + validatedPaths); if (!TextUtils.isEmpty(validatedPaths)) { try { StructStatVfs vfs = Os.statvfs(mJarPath); if ((vfs.f_flag & OsConstants.ST_RDONLY) != 0) { PathClassLoader classLoader = new PathClassLoader(mJarPath, PathClassLoader classLoader = new PathClassLoader(validatedPaths, ClassLoader.getSystemClassLoader()); Class<?> cls = classLoader.loadClass(mPackageName); mInjectedInstance = (TelephonyComponentFactory) cls.newInstance(); } else { Rlog.w(TAG, "Injection jar is not protected"); } } catch (ErrnoException e) { Rlog.e(TAG, "failed file mount, " + e.getMessage()); } catch (ClassNotFoundException e) { Rlog.e(TAG, "failed: " + e.getMessage()); } catch (IllegalAccessException | InstantiationException e) { Loading Loading @@ -233,7 +250,8 @@ public class TelephonyComponentFactory { mInjectedComponents = new InjectedComponents(); mInjectedComponents.parseXml(parser); mInjectedComponents.makeInjectedInstance(); Rlog.d(TAG, "Total components injected: " + (mInjectedComponents.isConfigValid() boolean injectSuccessful = !TextUtils.isEmpty(mInjectedComponents.getValidatedPaths()); Rlog.d(TAG, "Total components injected: " + (injectSuccessful ? mInjectedComponents.mComponentNames.size() : 0)); } } Loading