Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d746057f authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Change new file installs to be cluster-based!

Now that all the other pieces are in place, we're ready to start
installing new file-based packages as a cluster (the new unified
directory-based layout).  This greatly simplifies the renaming
process.

Also add helper methods to ApplicationInfo to give a much clearer
mapping between it and internal field names, since we can't change
the public API.

Add recursive restorecon().

Bug: 14975160
Change-Id: I72a63c5ddbc594c2fec4a91dd59f73ef253fbfd7
parent 255edb55
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -410,10 +410,14 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
     */
    public int largestWidthLimitDp = 0;

    /** {@hide} */
    public String scanSourceDir;
    /** {@hide} */
    public String scanPublicSourceDir;

    /**
     * Full path to the base APK for this application.
     */
    // TODO: verify that nobody is doing codePath comparisons against this
    public String sourceDir;

    /**
@@ -786,4 +790,18 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
    @Override protected ApplicationInfo getApplicationInfo() {
        return this;
    }

    /** {@hide} */ public void setCodePath(String codePath) { scanSourceDir = codePath; }
    /** {@hide} */ public void setBaseCodePath(String baseCodePath) { sourceDir = baseCodePath; }
    /** {@hide} */ public void setSplitCodePaths(String[] splitCodePaths) { splitSourceDirs = splitCodePaths; }
    /** {@hide} */ public void setResourcePath(String resourcePath) { scanPublicSourceDir = resourcePath; }
    /** {@hide} */ public void setBaseResourcePath(String baseResourcePath) { publicSourceDir = baseResourcePath; }
    /** {@hide} */ public void setSplitResourcePaths(String[] splitResourcePaths) { splitPublicSourceDirs = splitResourcePaths; }

    /** {@hide} */ public String getCodePath() { return scanSourceDir; }
    /** {@hide} */ public String getBaseCodePath() { return sourceDir; }
    /** {@hide} */ public String[] getSplitCodePaths() { return splitSourceDirs; }
    /** {@hide} */ public String getResourcePath() { return scanPublicSourceDir; }
    /** {@hide} */ public String getBaseResourcePath() { return publicSourceDir; }
    /** {@hide} */ public String[] getSplitResourcePaths() { return splitSourceDirs; }
}
+5 −0
Original line number Diff line number Diff line
@@ -719,7 +719,12 @@ public class PackageParser {
     * <p>
     * Note that this <em>does not</em> perform signature verification; that
     * must be done separately in {@link #collectCertificates(Package, int)}.
     *
     * @deprecated external callers should move to
     *             {@link #parsePackage(File, int)}. Eventually this method will
     *             be marked private.
     */
    @Deprecated
    public Package parseMonolithicPackage(File apkFile, int flags) throws PackageParserException {
        final Package pkg = parseBaseApk(apkFile, flags);
        if (pkg == null) {
+13 −0
Original line number Diff line number Diff line
@@ -371,6 +371,8 @@ public class FileUtils {
     * attacks.
     */
    public static boolean contains(File dir, File file) {
        if (file == null) return false;

        String dirPath = dir.getAbsolutePath();
        String filePath = file.getAbsolutePath();

@@ -418,16 +420,27 @@ public class FileUtils {
    }

    public static String rewriteAfterRename(File beforeDir, File afterDir, String path) {
        if (path == null) return null;
        final File result = rewriteAfterRename(beforeDir, afterDir, new File(path));
        return (result != null) ? result.getAbsolutePath() : null;
    }

    public static String[] rewriteAfterRename(File beforeDir, File afterDir, String[] paths) {
        if (paths == null) return null;
        final String[] result = new String[paths.length];
        for (int i = 0; i < paths.length; i++) {
            result[i] = rewriteAfterRename(beforeDir, afterDir, paths[i]);
        }
        return result;
    }

    /**
     * Given a path under the "before" directory, rewrite it to live under the
     * "after" directory. For example, {@code /before/foo/bar.txt} would become
     * {@code /after/foo/bar.txt}.
     */
    public static File rewriteAfterRename(File beforeDir, File afterDir, File file) {
        if (file == null) return null;
        if (contains(beforeDir, file)) {
            final String splice = file.getAbsolutePath().substring(
                    beforeDir.getAbsolutePath().length());
+18 −13
Original line number Diff line number Diff line
@@ -28,9 +28,15 @@ import java.io.FileDescriptor;
 * {@hide}
 */
public class SELinux {

    private static final String TAG = "SELinux";

    /** Keep in sync with ./external/libselinux/include/selinux/android.h */
    private static final int SELINUX_ANDROID_RESTORECON_NOCHANGE = 1;
    private static final int SELINUX_ANDROID_RESTORECON_VERBOSE = 2;
    private static final int SELINUX_ANDROID_RESTORECON_RECURSE = 4;
    private static final int SELINUX_ANDROID_RESTORECON_FORCE = 8;
    private static final int SELINUX_ANDROID_RESTORECON_DATADATA = 16;

    /**
     * Determine whether SELinux is disabled or enabled.
     * @return a boolean indicating whether SELinux is enabled.
@@ -136,7 +142,7 @@ public class SELinux {
     */
    public static boolean restorecon(String pathname) throws NullPointerException {
        if (pathname == null) { throw new NullPointerException(); }
        return native_restorecon(pathname);
        return native_restorecon(pathname, 0);
    }

    /**
@@ -149,7 +155,7 @@ public class SELinux {
     * @param pathname The pathname of the file to be relabeled.
     * @return a boolean indicating whether the relabeling succeeded.
     */
    private static native boolean native_restorecon(String pathname);
    private static native boolean native_restorecon(String pathname, int flags);

    /**
     * Restores a file to its default SELinux security context.
@@ -164,7 +170,7 @@ public class SELinux {
     */
    public static boolean restorecon(File file) throws NullPointerException {
        try {
            return native_restorecon(file.getCanonicalPath());
            return native_restorecon(file.getCanonicalPath(), 0);
        } catch (IOException e) {
            Slog.e(TAG, "Error getting canonical path. Restorecon failed for " +
                    file.getPath(), e);
@@ -180,14 +186,13 @@ public class SELinux {
     *
     * @return a boolean indicating whether the relabeling succeeded.
     */
    public static boolean restoreconTree(File dir) {
        final File[] files = dir.listFiles();
        boolean success = true;
        if (files != null) {
            for (File file : files) {
                success &= restorecon(file);
            }
    public static boolean restoreconRecursive(File file) {
        try {
            return native_restorecon(file.getCanonicalPath(), SELINUX_ANDROID_RESTORECON_RECURSE);
        } catch (IOException e) {
            Slog.e(TAG, "Error getting canonical path. Restorecon failed for " +
                    file.getPath(), e);
            return false;
        }
        return success;
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -404,7 +404,7 @@ static jboolean checkSELinuxAccess(JNIEnv *env, jobject, jstring subjectContextS
 * Returns: boolean: (true) file label successfully restored, (false) otherwise
 * Exceptions: none
 */
static jboolean native_restorecon(JNIEnv *env, jobject, jstring pathnameStr) {
static jboolean native_restorecon(JNIEnv *env, jobject, jstring pathnameStr, jint flags) {
    if (isSELinuxDisabled) {
        return true;
    }
@@ -415,7 +415,7 @@ static jboolean native_restorecon(JNIEnv *env, jobject, jstring pathnameStr) {
        return false;
    }

    int ret = selinux_android_restorecon(pathname.c_str(), 0);
    int ret = selinux_android_restorecon(pathname.c_str(), flags);
    ALOGV("restorecon(%s) => %d", pathname.c_str(), ret);
    return (ret == 0);
}
@@ -434,7 +434,7 @@ static JNINativeMethod method_table[] = {
    { "getPidContext"            , "(I)Ljava/lang/String;"                        , (void*)getPidCon        },
    { "isSELinuxEnforced"        , "()Z"                                          , (void*)isSELinuxEnforced},
    { "isSELinuxEnabled"         , "()Z"                                          , (void*)isSELinuxEnabled },
    { "native_restorecon"        , "(Ljava/lang/String;)Z"                        , (void*)native_restorecon},
    { "native_restorecon"        , "(Ljava/lang/String;I)Z"                       , (void*)native_restorecon},
    { "setBooleanValue"          , "(Ljava/lang/String;Z)Z"                       , (void*)setBooleanValue  },
    { "setFileContext"           , "(Ljava/lang/String;Ljava/lang/String;)Z"      , (void*)setFileCon       },
    { "setFSCreateContext"       , "(Ljava/lang/String;)Z"                        , (void*)setFSCreateCon   },
Loading