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

Commit 068ef222 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Calin Juravle
Browse files

Update is_valid_package_name() to match framework.

The framework has a new format for /data/app directory names in OC
to protect user privacy.  This change updates the validation logic
in installd to support the new format.

For consistency the logic now mirrors the package name validation
logic used by PackageParser.

Test: /data/nativetest64/installd_utils_test/installd_utils_test
Bug: 33705143

(cherry picked from commit 367ace2f)

Merged-In: I41d270942479c52e063c29a2cb9552d7b238b86e
Change-Id: I15363803fb45310697e29be810e800dc1b1902d0
parent 028ad63e
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -317,6 +317,7 @@ TEST_F(UtilsTest, CreatePkgPath_LongPkgNameSuccess) {
    size_t pkgnameSize = PKG_NAME_MAX;
    char pkgname[pkgnameSize + 1];
    memset(pkgname, 'a', pkgnameSize);
    pkgname[1] = '.';
    pkgname[pkgnameSize] = '\0';

    EXPECT_EQ(0, create_pkg_path(path, pkgname, "", 0))
@@ -508,5 +509,22 @@ TEST_F(UtilsTest, CreateDataUserPackagePath) {
            create_data_user_ce_package_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 10, "com.example"));
}

TEST_F(UtilsTest, IsValidPackageName) {
    EXPECT_EQ(true, is_valid_package_name("com.example"));
    EXPECT_EQ(true, is_valid_package_name("com.example-1"));
    EXPECT_EQ(true, is_valid_package_name("com.example-1024"));
    EXPECT_EQ(true, is_valid_package_name("com.example.foo---KiJFj4a_tePVw95pSrjg=="));
    EXPECT_EQ(true, is_valid_package_name("really_LONG.a1234.package_name"));

    EXPECT_EQ(false, is_valid_package_name("1234.package"));
    EXPECT_EQ(false, is_valid_package_name("com.1234.package"));
    EXPECT_EQ(false, is_valid_package_name("package"));
    EXPECT_EQ(false, is_valid_package_name(""));
    EXPECT_EQ(false, is_valid_package_name("."));
    EXPECT_EQ(false, is_valid_package_name("com.example/../com.evil/"));
    EXPECT_EQ(false, is_valid_package_name("com.example-1/../com.evil/"));
    EXPECT_EQ(false, is_valid_package_name("/com.evil"));
}

}  // namespace installd
}  // namespace android
+31 −35
Original line number Diff line number Diff line
@@ -346,47 +346,43 @@ int create_move_path(char path[PKG_PATH_MAX],
 * 0 on success.
 */
bool is_valid_package_name(const std::string& packageName) {
    const char* pkgname = packageName.c_str();
    const char *x = pkgname;
    int alpha = -1;

    if (strlen(pkgname) > PKG_NAME_MAX) {
        return false;
    // This logic is borrowed from PackageParser.java
    bool hasSep = false;
    bool front = true;

    auto it = packageName.begin();
    for (; it != packageName.end() && *it != '-'; it++) {
        char c = *it;
        if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
            front = false;
            continue;
        }

    while (*x) {
        if (isalnum(*x) || (*x == '_')) {
                /* alphanumeric or underscore are fine */
        } else if (*x == '.') {
            if ((x == pkgname) || (x[1] == '.') || (x[1] == 0)) {
                    /* periods must not be first, last, or doubled */
                ALOGE("invalid package name '%s'\n", pkgname);
                return false;
        if (!front) {
            if ((c >= '0' && c <= '9') || c == '_') {
                continue;
            }
        } else if (*x == '-') {
            /* Suffix -X is fine to let versioning of packages.
               But whatever follows should be alphanumeric.*/
            alpha = 1;
        } else {
                /* anything not A-Z, a-z, 0-9, _, or . is invalid */
            ALOGE("invalid package name '%s'\n", pkgname);
        }
        if (c == '.') {
            hasSep = true;
            front = true;
            continue;
        }
        LOG(WARNING) << "Bad package character " << c << " in " << packageName;
        return false;
    }

        x++;
    if (!hasSep || front) {
        LOG(WARNING) << "Missing separator in " << packageName;
        return false;
    }

    if (alpha == 1) {
        // Skip current character
        x++;
        while (*x) {
            if (!isalnum(*x)) {
                ALOGE("invalid package name '%s' should include only numbers after -\n", pkgname);
    for (; it != packageName.end(); it++) {
        char c = *it;
        if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) continue;
        if ((c >= '0' && c <= '9') || c == '_' || c == '-' || c == '=') continue;
        LOG(WARNING) << "Bad suffix character " << c << " in " << packageName;
        return false;
    }
            x++;
        }
    }

    return true;
}