diff options
| author | Jeff Sharkey <jsharkey@android.com> | 2016-12-13 11:55:19 -0700 |
|---|---|---|
| committer | Jeff Sharkey <jsharkey@android.com> | 2016-12-13 13:28:08 -0700 |
| commit | dff44709cf462a3af7eb5770c90e3ada492295b7 (patch) | |
| tree | 260698ec335906df76fe1db439baa5f71089a953 | |
| parent | 2361ab0d3172adf472c7a8bbb7030f514543104d (diff) | |
| download | system_core-dff44709cf462a3af7eb5770c90e3ada492295b7.tar.gz system_core-dff44709cf462a3af7eb5770c90e3ada492295b7.tar.bz2 system_core-dff44709cf462a3af7eb5770c90e3ada492295b7.zip | |
Define range of GIDs for cached app data.
To support upcoming disk usage calculation optimizations, this change
creates a new GID for each app that will be used to mark its cached
data. We're allocating these unique GIDs so that we can use
quotactl() to track cached data on a per-app basis.
This change also tightens up the implementation of both the cache
and shared GID calculation to ensure that they stay inside the valid
ranges, and includes tests to verify.
Test: builds, boots, tests pass
Bug: 27948817
Change-Id: Ie4377e5aae267f2da39a165888139228995987cb
| -rw-r--r-- | include/cutils/multiuser.h | 16 | ||||
| -rw-r--r-- | include/private/android_filesystem_config.h | 18 | ||||
| -rw-r--r-- | libcutils/multiuser.c | 29 | ||||
| -rw-r--r-- | libcutils/tests/Android.bp | 3 | ||||
| -rw-r--r-- | libcutils/tests/multiuser_test.cpp | 67 | ||||
| -rw-r--r-- | logd/LogStatistics.cpp | 2 | ||||
| -rw-r--r-- | run-as/run-as.cpp | 4 |
7 files changed, 114 insertions, 25 deletions
diff --git a/include/cutils/multiuser.h b/include/cutils/multiuser.h index 7e7f8154a..4f23776df 100644 --- a/include/cutils/multiuser.h +++ b/include/cutils/multiuser.h @@ -23,19 +23,19 @@ extern "C" { #endif -// NOTE: keep in sync with android.os.UserId - -#define MULTIUSER_APP_PER_USER_RANGE 100000 -#define MULTIUSER_FIRST_SHARED_APPLICATION_GID 50000 -#define MULTIUSER_FIRST_APPLICATION_UID 10000 - typedef uid_t userid_t; typedef uid_t appid_t; extern userid_t multiuser_get_user_id(uid_t uid); extern appid_t multiuser_get_app_id(uid_t uid); -extern uid_t multiuser_get_uid(userid_t userId, appid_t appId); -extern appid_t multiuser_get_shared_app_gid(uid_t uid); + +extern uid_t multiuser_get_uid(userid_t user_id, appid_t app_id); + +extern gid_t multiuser_get_cache_gid(userid_t user_id, appid_t app_id); +extern gid_t multiuser_get_shared_gid(userid_t user_id, appid_t app_id); + +/* TODO: switch callers over to multiuser_get_shared_gid() */ +extern gid_t multiuser_get_shared_app_gid(uid_t uid); #ifdef __cplusplus } diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h index 303156266..f7cf9b808 100644 --- a/include/private/android_filesystem_config.h +++ b/include/private/android_filesystem_config.h @@ -157,15 +157,21 @@ #define AID_MISC 9998 /* access to misc storage */ #define AID_NOBODY 9999 -#define AID_APP 10000 /* first app user */ +#define AID_APP 10000 /* TODO: switch users over to AID_APP_START */ +#define AID_APP_START 10000 /* first app user */ +#define AID_APP_END 19999 /* last app user */ -#define AID_ISOLATED_START 99000 /* start of uids for fully isolated sandboxed processes */ -#define AID_ISOLATED_END 99999 /* end of uids for fully isolated sandboxed processes */ - -#define AID_USER 100000 /* offset for uid ranges for each user */ +#define AID_CACHE_GID_START 20000 /* start of gids for apps to mark cached data */ +#define AID_CACHE_GID_END 29999 /* end of gids for apps to mark cached data */ #define AID_SHARED_GID_START 50000 /* start of gids for apps in each user to share */ -#define AID_SHARED_GID_END 59999 /* start of gids for apps in each user to share */ +#define AID_SHARED_GID_END 59999 /* end of gids for apps in each user to share */ + +#define AID_ISOLATED_START 99000 /* start of uids for fully isolated sandboxed processes */ +#define AID_ISOLATED_END 99999 /* end of uids for fully isolated sandboxed processes */ + +#define AID_USER 100000 /* TODO: switch users over to AID_USER_OFFSET */ +#define AID_USER_OFFSET 100000 /* offset for uid ranges for each user */ #if !defined(EXCLUDE_FS_CONFIG_STRUCTURES) /* diff --git a/libcutils/multiuser.c b/libcutils/multiuser.c index 0f4427b35..0ef337d61 100644 --- a/libcutils/multiuser.c +++ b/libcutils/multiuser.c @@ -15,21 +15,36 @@ */ #include <cutils/multiuser.h> +#include <private/android_filesystem_config.h> userid_t multiuser_get_user_id(uid_t uid) { - return uid / MULTIUSER_APP_PER_USER_RANGE; + return uid / AID_USER_OFFSET; } appid_t multiuser_get_app_id(uid_t uid) { - return uid % MULTIUSER_APP_PER_USER_RANGE; + return uid % AID_USER_OFFSET; } -uid_t multiuser_get_uid(userid_t userId, appid_t appId) { - return userId * MULTIUSER_APP_PER_USER_RANGE + (appId % MULTIUSER_APP_PER_USER_RANGE); +uid_t multiuser_get_uid(userid_t user_id, appid_t app_id) { + return (user_id * AID_USER_OFFSET) + (app_id % AID_USER_OFFSET); } -appid_t multiuser_get_shared_app_gid(uid_t id) { - return MULTIUSER_FIRST_SHARED_APPLICATION_GID + (id % MULTIUSER_APP_PER_USER_RANGE) - - MULTIUSER_FIRST_APPLICATION_UID; +gid_t multiuser_get_cache_gid(userid_t user_id, appid_t app_id) { + if (app_id >= AID_APP_START && app_id <= AID_APP_END) { + return multiuser_get_uid(user_id, (app_id - AID_APP_START) + AID_CACHE_GID_START); + } else { + return -1; + } +} + +gid_t multiuser_get_shared_gid(userid_t user_id, appid_t app_id) { + if (app_id >= AID_APP_START && app_id <= AID_APP_END) { + return multiuser_get_uid(user_id, (app_id - AID_APP_START) + AID_SHARED_GID_START); + } else { + return -1; + } +} +gid_t multiuser_get_shared_app_gid(uid_t uid) { + return multiuser_get_shared_gid(multiuser_get_user_id(uid), multiuser_get_app_id(uid)); } diff --git a/libcutils/tests/Android.bp b/libcutils/tests/Android.bp index abe3c2145..0b0dc0910 100644 --- a/libcutils/tests/Android.bp +++ b/libcutils/tests/Android.bp @@ -26,7 +26,8 @@ cc_defaults { "trace-dev_test.cpp", "test_str_parms.cpp", "android_get_control_socket_test.cpp", - "android_get_control_file_test.cpp" + "android_get_control_file_test.cpp", + "multiuser_test.cpp" ], }, diff --git a/libcutils/tests/multiuser_test.cpp b/libcutils/tests/multiuser_test.cpp new file mode 100644 index 000000000..2307ea8f8 --- /dev/null +++ b/libcutils/tests/multiuser_test.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2016 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. + */ + +#include <cutils/multiuser.h> +#include <gtest/gtest.h> + +TEST(MultiuserTest, TestMerge) { + EXPECT_EQ(0, multiuser_get_uid(0, 0)); + EXPECT_EQ(1000, multiuser_get_uid(0, 1000)); + EXPECT_EQ(10000, multiuser_get_uid(0, 10000)); + EXPECT_EQ(50000, multiuser_get_uid(0, 50000)); + EXPECT_EQ(1000000, multiuser_get_uid(10, 0)); + EXPECT_EQ(1001000, multiuser_get_uid(10, 1000)); + EXPECT_EQ(1010000, multiuser_get_uid(10, 10000)); + EXPECT_EQ(1050000, multiuser_get_uid(10, 50000)); +} + +TEST(MultiuserTest, TestSplitUser) { + EXPECT_EQ(0, multiuser_get_user_id(0)); + EXPECT_EQ(0, multiuser_get_user_id(1000)); + EXPECT_EQ(0, multiuser_get_user_id(10000)); + EXPECT_EQ(0, multiuser_get_user_id(50000)); + EXPECT_EQ(10, multiuser_get_user_id(1000000)); + EXPECT_EQ(10, multiuser_get_user_id(1001000)); + EXPECT_EQ(10, multiuser_get_user_id(1010000)); + EXPECT_EQ(10, multiuser_get_user_id(1050000)); +} + +TEST(MultiuserTest, TestSplitApp) { + EXPECT_EQ(0, multiuser_get_app_id(0)); + EXPECT_EQ(1000, multiuser_get_app_id(1000)); + EXPECT_EQ(10000, multiuser_get_app_id(10000)); + EXPECT_EQ(50000, multiuser_get_app_id(50000)); + EXPECT_EQ(0, multiuser_get_app_id(1000000)); + EXPECT_EQ(1000, multiuser_get_app_id(1001000)); + EXPECT_EQ(10000, multiuser_get_app_id(1010000)); + EXPECT_EQ(50000, multiuser_get_app_id(1050000)); +} + +TEST(MultiuserTest, TestCache) { + EXPECT_EQ(-1, multiuser_get_cache_gid(0, 0)); + EXPECT_EQ(-1, multiuser_get_cache_gid(0, 1000)); + EXPECT_EQ(20000, multiuser_get_cache_gid(0, 10000)); + EXPECT_EQ(-1, multiuser_get_cache_gid(0, 50000)); + EXPECT_EQ(1020000, multiuser_get_cache_gid(10, 10000)); +} + +TEST(MultiuserTest, TestShared) { + EXPECT_EQ(-1, multiuser_get_shared_gid(0, 0)); + EXPECT_EQ(-1, multiuser_get_shared_gid(0, 1000)); + EXPECT_EQ(50000, multiuser_get_shared_gid(0, 10000)); + EXPECT_EQ(-1, multiuser_get_shared_gid(0, 50000)); + EXPECT_EQ(1050000, multiuser_get_shared_gid(10, 10000)); +} diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp index bab87bad9..3c8bd7517 100644 --- a/logd/LogStatistics.cpp +++ b/logd/LogStatistics.cpp @@ -182,7 +182,7 @@ const char *LogStatistics::uidToName(uid_t uid) const { } // Parse /data/system/packages.list - uid_t userId = uid % AID_USER; + uid_t userId = uid % AID_USER_OFFSET; const char *name = android::uidToName(userId); if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) { name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP)); diff --git a/run-as/run-as.cpp b/run-as/run-as.cpp index aec51f45b..e7b8cc2c8 100644 --- a/run-as/run-as.cpp +++ b/run-as/run-as.cpp @@ -165,12 +165,12 @@ int main(int argc, char* argv[]) { if (setegid(old_egid) == -1) error(1, errno, "couldn't restore egid"); // Verify that user id is not too big. - if ((UID_MAX - info.uid) / AID_USER < (uid_t)userId) { + if ((UID_MAX - info.uid) / AID_USER_OFFSET < (uid_t)userId) { error(1, 0, "user id too big: %d", userId); } // Calculate user app ID. - uid_t userAppId = (AID_USER * userId) + info.uid; + uid_t userAppId = (AID_USER_OFFSET * userId) + info.uid; // Reject system packages. if (userAppId < AID_APP) { |
