libsurfaceflinger: fix screenshot permission check am: fc0b911090
am: fd630967bb
Change-Id: Ie3e87725d8c07bb72307229c65cf71ad54da28e8
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index de86cdc..28b2240 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -1838,6 +1838,11 @@
result = unlink_if_exists(current_profile) && result;
result = unlink_if_exists(reference_profile) && result;
+ // We upgraded once the location of current profile for secondary dex files.
+ // Check for any previous left-overs and remove them as well.
+ std::string old_current_profile = dex_path + ".prof";
+ result = unlink_if_exists(old_current_profile);
+
// Try removing the directories as well, they might be empty.
result = rmdir_if_empty(oat_isa_dir) && result;
result = rmdir_if_empty(oat_dir) && result;
diff --git a/cmds/installd/tests/installd_utils_test.cpp b/cmds/installd/tests/installd_utils_test.cpp
index dab3236..46ed85f 100644
--- a/cmds/installd/tests/installd_utils_test.cpp
+++ b/cmds/installd/tests/installd_utils_test.cpp
@@ -38,16 +38,6 @@
#define TEST_PROFILE_DIR "/data/misc/profiles"
-#define REALLY_LONG_APP_NAME "com.example." \
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." \
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." \
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-
-#define REALLY_LONG_LEAF_NAME "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_" \
- "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_" \
- "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_" \
- "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_"
-
namespace android {
namespace installd {
@@ -88,6 +78,14 @@
virtual void TearDown() {
free(android_system_dirs.dirs);
}
+
+ std::string create_too_long_path(const std::string& seed) {
+ std::string result = seed;
+ for (size_t i = seed.size(); i < PKG_PATH_MAX; i++) {
+ result += "a";
+ }
+ return result;
+ }
};
TEST_F(UtilsTest, IsValidApkPath_BadPrefix) {
@@ -388,17 +386,18 @@
<< "Primary user package directory should be created correctly";
}
+
TEST_F(UtilsTest, CreateMovePath_Fail_AppTooLong) {
char path[PKG_PATH_MAX];
-
- EXPECT_EQ(-1, create_move_path(path, REALLY_LONG_APP_NAME, "shared_prefs", 0))
+ std::string really_long_app_name = create_too_long_path("com.example");
+ EXPECT_EQ(-1, create_move_path(path, really_long_app_name.c_str(), "shared_prefs", 0))
<< "Should fail to create move path for primary user";
}
TEST_F(UtilsTest, CreateMovePath_Fail_LeafTooLong) {
char path[PKG_PATH_MAX];
-
- EXPECT_EQ(-1, create_move_path(path, "com.android.test", REALLY_LONG_LEAF_NAME, 0))
+ std::string really_long_leaf_name = create_too_long_path("leaf_");
+ EXPECT_EQ(-1, create_move_path(path, "com.android.test", really_long_leaf_name.c_str(), 0))
<< "Should fail to create move path for primary user";
}
@@ -560,7 +559,7 @@
}
TEST_F(UtilsTest, CreateSecondaryCurrentProfile) {
- EXPECT_EQ("/data/user/0/com.example/secondary.dex.prof",
+ EXPECT_EQ("/data/user/0/com.example/oat/secondary.dex.cur.prof",
create_current_profile_path(/*user*/0,
"/data/user/0/com.example/secondary.dex", /*is_secondary*/true));
}
@@ -571,5 +570,88 @@
"/data/user/0/com.example/secondary.dex", /*is_secondary*/true));
}
+static void pass_secondary_dex_validation(const std::string& package_name,
+ const std::string& dex_path, int uid, int storage_flag) {
+ EXPECT_TRUE(validate_secondary_dex_path(package_name, dex_path, /*volume_uuid*/ nullptr, uid,
+ storage_flag))
+ << dex_path << " should be allowed as a valid secondary dex path";
+}
+
+static void fail_secondary_dex_validation(const std::string& package_name,
+ const std::string& dex_path, int uid, int storage_flag) {
+ EXPECT_FALSE(validate_secondary_dex_path(package_name, dex_path, /*volume_uuid*/ nullptr, uid,
+ storage_flag))
+ << dex_path << " should not be allowed as a valid secondary dex path";
+}
+
+TEST_F(UtilsTest, ValidateSecondaryDexFilesPath) {
+ std::string package_name = "com.test.app";
+ std::string app_dir_ce_user_0 = "/data/data/" + package_name;
+ std::string app_dir_ce_user_10 = "/data/user/10/" + package_name;
+
+ std::string app_dir_de_user_0 = "/data/user_de/0/" + package_name;
+ std::string app_dir_de_user_10 = "/data/user_de/10/" + package_name;
+
+ EXPECT_EQ(app_dir_ce_user_0,
+ create_data_user_ce_package_path(nullptr, 0, package_name.c_str()));
+ EXPECT_EQ(app_dir_ce_user_10,
+ create_data_user_ce_package_path(nullptr, 10, package_name.c_str()));
+
+ EXPECT_EQ(app_dir_de_user_0,
+ create_data_user_de_package_path(nullptr, 0, package_name.c_str()));
+ EXPECT_EQ(app_dir_de_user_10,
+ create_data_user_de_package_path(nullptr, 10, package_name.c_str()));
+
+ uid_t app_uid_for_user_0 = multiuser_get_uid(/*user_id*/0, /*app_id*/ 1234);
+ uid_t app_uid_for_user_10 = multiuser_get_uid(/*user_id*/10, /*app_id*/ 1234);
+
+ // Standard path for user 0 on CE storage.
+ pass_secondary_dex_validation(
+ package_name, app_dir_ce_user_0 + "/ce0.dex", app_uid_for_user_0, FLAG_STORAGE_CE);
+ // Standard path for user 10 on CE storage.
+ pass_secondary_dex_validation(
+ package_name, app_dir_ce_user_10 + "/ce10.dex", app_uid_for_user_10, FLAG_STORAGE_CE);
+
+ // Standard path for user 0 on DE storage.
+ pass_secondary_dex_validation(
+ package_name, app_dir_de_user_0 + "/de0.dex", app_uid_for_user_0, FLAG_STORAGE_DE);
+ // Standard path for user 10 on DE storage.
+ pass_secondary_dex_validation(
+ package_name, app_dir_de_user_10 + "/de0.dex", app_uid_for_user_10, FLAG_STORAGE_DE);
+
+ // Dex path for user 0 accessed from user 10.
+ fail_secondary_dex_validation(
+ package_name, app_dir_ce_user_0 + "/path0_from10.dex",
+ app_uid_for_user_10, FLAG_STORAGE_CE);
+
+ // Dex path for CE storage accessed with DE.
+ fail_secondary_dex_validation(
+ package_name, app_dir_ce_user_0 + "/ce_from_de.dex", app_uid_for_user_0, FLAG_STORAGE_DE);
+
+ // Dex path for DE storage accessed with CE.
+ fail_secondary_dex_validation(
+ package_name, app_dir_de_user_0 + "/de_from_ce.dex", app_uid_for_user_0, FLAG_STORAGE_CE);
+
+ // Location which does not start with '/'.
+ fail_secondary_dex_validation(
+ package_name, "without_slash.dex", app_uid_for_user_10, FLAG_STORAGE_DE);
+
+ // The dex file is not in the specified package directory.
+ fail_secondary_dex_validation(
+ "another.package", app_dir_ce_user_0 + "/for_another_package.dex",
+ app_uid_for_user_0, FLAG_STORAGE_DE);
+
+ // The dex path contains indirect directories.
+ fail_secondary_dex_validation(
+ package_name, app_dir_ce_user_0 + "/1/../foo.dex", app_uid_for_user_0, FLAG_STORAGE_CE);
+ fail_secondary_dex_validation(
+ package_name, app_dir_ce_user_0 + "/1/./foo.dex", app_uid_for_user_0, FLAG_STORAGE_CE);
+
+ // Super long path.
+ std::string too_long = create_too_long_path("too_long_");
+ fail_secondary_dex_validation(
+ package_name, app_dir_ce_user_10 + "/" + too_long, app_uid_for_user_10, FLAG_STORAGE_CE);
+}
+
} // namespace installd
} // namespace android
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index 7c05417..0faddf0 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -238,13 +238,38 @@
// Keep profile paths in sync with ActivityThread and LoadedApk.
const std::string PROFILE_EXT = ".prof";
+const std::string CURRENT_PROFILE_EXT = ".cur";
const std::string PRIMARY_PROFILE_NAME = "primary" + PROFILE_EXT;
+// Gets the parent directory and the file name for the given secondary dex path.
+// Returns true on success, false on failure (if the dex_path does not have the expected
+// structure).
+static bool get_secondary_dex_location(const std::string& dex_path,
+ std::string* out_dir_name, std::string* out_file_name) {
+ size_t dirIndex = dex_path.rfind('/');
+ if (dirIndex == std::string::npos) {
+ return false;
+ }
+ if (dirIndex == dex_path.size() - 1) {
+ return false;
+ }
+ *out_dir_name = dex_path.substr(0, dirIndex);
+ *out_file_name = dex_path.substr(dirIndex + 1);
+
+ return true;
+}
+
std::string create_current_profile_path(userid_t user, const std::string& location,
bool is_secondary_dex) {
if (is_secondary_dex) {
- // Secondary dex profiles are stored next to the dex files using .prof extension.
- return StringPrintf("%s%s", location.c_str(), PROFILE_EXT.c_str());
+ // Secondary dex current profiles are stored next to the dex files under the oat folder.
+ std::string dex_dir;
+ std::string dex_name;
+ CHECK(get_secondary_dex_location(location, &dex_dir, &dex_name))
+ << "Unexpected dir structure for secondary dex " << location;
+ return StringPrintf("%s/oat/%s%s%s",
+ dex_dir.c_str(), dex_name.c_str(), CURRENT_PROFILE_EXT.c_str(),
+ PROFILE_EXT.c_str());
} else {
// Profiles for primary apks are under /data/misc/profiles/cur.
std::string profile_dir = create_primary_current_profile_package_dir_path(user, location);
@@ -255,12 +280,10 @@
std::string create_reference_profile_path(const std::string& location, bool is_secondary_dex) {
if (is_secondary_dex) {
// Secondary dex reference profiles are stored next to the dex files under the oat folder.
- size_t dirIndex = location.rfind('/');
- CHECK(dirIndex != std::string::npos)
+ std::string dex_dir;
+ std::string dex_name;
+ CHECK(get_secondary_dex_location(location, &dex_dir, &dex_name))
<< "Unexpected dir structure for secondary dex " << location;
-
- std::string dex_dir = location.substr(0, dirIndex);
- std::string dex_name = location.substr(dirIndex +1);
return StringPrintf("%s/oat/%s%s",
dex_dir.c_str(), dex_name.c_str(), PROFILE_EXT.c_str());
} else {
@@ -781,21 +804,30 @@
const char* volume_uuid, int uid, int storage_flag) {
CHECK(storage_flag == FLAG_STORAGE_CE || storage_flag == FLAG_STORAGE_DE);
+ // Empty paths are not allowed.
+ if (dex_path.empty()) { return false; }
+ // First character should always be '/'. No relative paths.
+ if (dex_path[0] != '/') { return false; }
+ // The last character should not be '/'.
+ if (dex_path[dex_path.size() - 1] == '/') { return false; }
+ // There should be no '.' after the directory marker.
+ if (dex_path.find("/.") != std::string::npos) { return false; }
+ // The path should be at most PKG_PATH_MAX long.
+ if (dex_path.size() > PKG_PATH_MAX) { return false; }
+
+ // The dex_path should be under the app data directory.
std::string app_private_dir = storage_flag == FLAG_STORAGE_CE
? create_data_user_ce_package_path(
volume_uuid, multiuser_get_user_id(uid), pkgname.c_str())
: create_data_user_de_package_path(
volume_uuid, multiuser_get_user_id(uid), pkgname.c_str());
- dir_rec_t dir;
- if (get_path_from_string(&dir, app_private_dir.c_str()) != 0) {
- LOG(WARNING) << "Could not get dir rec for " << app_private_dir;
+
+ if (strncmp(dex_path.c_str(), app_private_dir.c_str(), app_private_dir.size()) != 0) {
return false;
}
- // Usually secondary dex files have a nested directory structure.
- // Pick at most 10 subdirectories when validating (arbitrary value).
- // If the secondary dex file is >10 directory nested then validation will
- // fail and the file will not be compiled.
- return validate_path(&dir, dex_path.c_str(), /*max_subdirs*/ 10) == 0;
+
+ // If we got here we have a valid path.
+ return true;
}
/**
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 09fd0cb..83b8021 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -69,8 +69,13 @@
"TextOutput.cpp",
"IpPrefix.cpp",
"Value.cpp",
+ "aidl/android/content/pm/IPackageManagerNative.aidl",
],
+ aidl: {
+ export_aidl_headers: true,
+ },
+
cflags: [
"-Wall",
"-Wextra",
diff --git a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
new file mode 100644
index 0000000..6b7254c
--- /dev/null
+++ b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
@@ -0,0 +1,41 @@
+/*
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+/**
+ * Parallel implementation of certain {@link PackageManager} APIs that need to
+ * be exposed to native code.
+ * <p>These APIs are a parallel definition to the APIs in PackageManager, so,
+ * they can technically diverge. However, it's good practice to keep these
+ * APIs in sync with each other.
+ * <p>Because these APIs are exposed to native code, it's possible they will
+ * be exposed to privileged components [such as UID 0]. Care should be taken
+ * to avoid exposing potential security holes for methods where permission
+ * checks are bypassed based upon UID alone.
+ *
+ * @hide
+ */
+interface IPackageManagerNative {
+ /**
+ * Returns a set of names for the given UIDs.
+ * IMPORTANT: Unlike the Java version of this API, unknown UIDs are
+ * not represented by 'null's. Instead, they are represented by empty
+ * strings.
+ */
+ @utf8InCpp String[] getNamesForUids(in int[] uids);
+}
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index ed2f30a..21debc1 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -20,6 +20,9 @@
cc_library_shared {
name: "libgui",
vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
clang: true,
cppflags: [
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 6630d90..cabe94e 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -15,6 +15,9 @@
cc_library_shared {
name: "libui",
vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
clang: true,
cppflags: [
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index b4cc211..1cfc513 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -117,6 +117,9 @@
cc_library_shared {
name: "libEGL",
defaults: ["egl_libs_defaults"],
+ vndk: {
+ enabled: true,
+ },
srcs: [
"EGL/egl_tls.cpp",
"EGL/egl_cache.cpp",
@@ -180,6 +183,9 @@
cc_library_shared {
name: "libGLESv2",
defaults: ["gles_libs_defaults"],
+ vndk: {
+ enabled: true,
+ },
srcs: ["GLES2/gl2.cpp"],
cflags: ["-DLOG_TAG=\"libGLESv2\""],
}