1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker ** Copyright 2008, The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker **
4*38e8c45fSAndroid Build Coastguard Worker ** Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker ** you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker ** You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker **
8*38e8c45fSAndroid Build Coastguard Worker ** http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker **
10*38e8c45fSAndroid Build Coastguard Worker ** Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker ** distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker ** See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker ** limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker */
16*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "installd"
17*38e8c45fSAndroid Build Coastguard Worker
18*38e8c45fSAndroid Build Coastguard Worker #include <fcntl.h>
19*38e8c45fSAndroid Build Coastguard Worker #include <selinux/android.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <selinux/avc.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <sys/capability.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <sys/fsuid.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <sys/prctl.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <sys/stat.h>
25*38e8c45fSAndroid Build Coastguard Worker
26*38e8c45fSAndroid Build Coastguard Worker #include <android-base/logging.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <cutils/fs.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <cutils/properties.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h> // TODO: Move everything to base::logging.
30*38e8c45fSAndroid Build Coastguard Worker #include <private/android_filesystem_config.h>
31*38e8c45fSAndroid Build Coastguard Worker
32*38e8c45fSAndroid Build Coastguard Worker #include "InstalldNativeService.h"
33*38e8c45fSAndroid Build Coastguard Worker #include "dexopt.h"
34*38e8c45fSAndroid Build Coastguard Worker #include "globals.h"
35*38e8c45fSAndroid Build Coastguard Worker #include "installd_constants.h"
36*38e8c45fSAndroid Build Coastguard Worker #include "installd_deps.h" // Need to fill in requirements of commands.
37*38e8c45fSAndroid Build Coastguard Worker #include "utils.h"
38*38e8c45fSAndroid Build Coastguard Worker
39*38e8c45fSAndroid Build Coastguard Worker namespace android {
40*38e8c45fSAndroid Build Coastguard Worker namespace installd {
41*38e8c45fSAndroid Build Coastguard Worker
42*38e8c45fSAndroid Build Coastguard Worker // Check that installd-deps sizes match cutils sizes.
43*38e8c45fSAndroid Build Coastguard Worker static_assert(kPropertyKeyMax == PROPERTY_KEY_MAX, "Size mismatch.");
44*38e8c45fSAndroid Build Coastguard Worker static_assert(kPropertyValueMax == PROPERTY_VALUE_MAX, "Size mismatch.");
45*38e8c45fSAndroid Build Coastguard Worker
46*38e8c45fSAndroid Build Coastguard Worker ////////////////////////
47*38e8c45fSAndroid Build Coastguard Worker // Plug-in functions. //
48*38e8c45fSAndroid Build Coastguard Worker ////////////////////////
49*38e8c45fSAndroid Build Coastguard Worker
get_property(const char * key,char * value,const char * default_value)50*38e8c45fSAndroid Build Coastguard Worker int get_property(const char *key, char *value, const char *default_value) {
51*38e8c45fSAndroid Build Coastguard Worker return property_get(key, value, default_value);
52*38e8c45fSAndroid Build Coastguard Worker }
53*38e8c45fSAndroid Build Coastguard Worker
calculate_oat_file_path(char path[PKG_PATH_MAX],const char * oat_dir,const char * apk_path,const char * instruction_set)54*38e8c45fSAndroid Build Coastguard Worker bool calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path,
55*38e8c45fSAndroid Build Coastguard Worker const char *instruction_set) {
56*38e8c45fSAndroid Build Coastguard Worker return calculate_oat_file_path_default(path, oat_dir, apk_path, instruction_set);
57*38e8c45fSAndroid Build Coastguard Worker }
58*38e8c45fSAndroid Build Coastguard Worker
calculate_odex_file_path(char path[PKG_PATH_MAX],const char * apk_path,const char * instruction_set)59*38e8c45fSAndroid Build Coastguard Worker bool calculate_odex_file_path(char path[PKG_PATH_MAX], const char *apk_path,
60*38e8c45fSAndroid Build Coastguard Worker const char *instruction_set) {
61*38e8c45fSAndroid Build Coastguard Worker return calculate_odex_file_path_default(path, apk_path, instruction_set);
62*38e8c45fSAndroid Build Coastguard Worker }
63*38e8c45fSAndroid Build Coastguard Worker
create_cache_path(char path[PKG_PATH_MAX],const char * src,const char * instruction_set)64*38e8c45fSAndroid Build Coastguard Worker bool create_cache_path(char path[PKG_PATH_MAX], const char *src, const char *instruction_set) {
65*38e8c45fSAndroid Build Coastguard Worker return create_cache_path_default(path, src, instruction_set);
66*38e8c45fSAndroid Build Coastguard Worker }
67*38e8c45fSAndroid Build Coastguard Worker
force_compile_without_image()68*38e8c45fSAndroid Build Coastguard Worker bool force_compile_without_image() {
69*38e8c45fSAndroid Build Coastguard Worker return false;
70*38e8c45fSAndroid Build Coastguard Worker }
71*38e8c45fSAndroid Build Coastguard Worker
initialize_globals()72*38e8c45fSAndroid Build Coastguard Worker static bool initialize_globals() {
73*38e8c45fSAndroid Build Coastguard Worker return init_globals_from_data_and_root();
74*38e8c45fSAndroid Build Coastguard Worker }
75*38e8c45fSAndroid Build Coastguard Worker
initialize_directories()76*38e8c45fSAndroid Build Coastguard Worker static int initialize_directories() {
77*38e8c45fSAndroid Build Coastguard Worker int res = -1;
78*38e8c45fSAndroid Build Coastguard Worker
79*38e8c45fSAndroid Build Coastguard Worker // Read current filesystem layout version to handle upgrade paths
80*38e8c45fSAndroid Build Coastguard Worker char version_path[PATH_MAX];
81*38e8c45fSAndroid Build Coastguard Worker snprintf(version_path, PATH_MAX, "%smisc/installd/layout_version", android_data_dir.c_str());
82*38e8c45fSAndroid Build Coastguard Worker
83*38e8c45fSAndroid Build Coastguard Worker int oldVersion;
84*38e8c45fSAndroid Build Coastguard Worker if (fs_read_atomic_int(version_path, &oldVersion) == -1) {
85*38e8c45fSAndroid Build Coastguard Worker oldVersion = 0;
86*38e8c45fSAndroid Build Coastguard Worker }
87*38e8c45fSAndroid Build Coastguard Worker int version = oldVersion;
88*38e8c45fSAndroid Build Coastguard Worker
89*38e8c45fSAndroid Build Coastguard Worker if (version < 2) {
90*38e8c45fSAndroid Build Coastguard Worker SLOGD("Assuming that device has multi-user storage layout; upgrade no longer supported");
91*38e8c45fSAndroid Build Coastguard Worker version = 2;
92*38e8c45fSAndroid Build Coastguard Worker }
93*38e8c45fSAndroid Build Coastguard Worker
94*38e8c45fSAndroid Build Coastguard Worker if (ensure_config_user_dirs(0) == -1) {
95*38e8c45fSAndroid Build Coastguard Worker SLOGE("Failed to setup misc for user 0");
96*38e8c45fSAndroid Build Coastguard Worker goto fail;
97*38e8c45fSAndroid Build Coastguard Worker }
98*38e8c45fSAndroid Build Coastguard Worker
99*38e8c45fSAndroid Build Coastguard Worker if (version == 2) {
100*38e8c45fSAndroid Build Coastguard Worker SLOGD("Upgrading to /data/misc/user directories");
101*38e8c45fSAndroid Build Coastguard Worker
102*38e8c45fSAndroid Build Coastguard Worker char misc_dir[PATH_MAX];
103*38e8c45fSAndroid Build Coastguard Worker snprintf(misc_dir, PATH_MAX, "%smisc", android_data_dir.c_str());
104*38e8c45fSAndroid Build Coastguard Worker
105*38e8c45fSAndroid Build Coastguard Worker char keychain_added_dir[PATH_MAX];
106*38e8c45fSAndroid Build Coastguard Worker snprintf(keychain_added_dir, PATH_MAX, "%s/keychain/cacerts-added", misc_dir);
107*38e8c45fSAndroid Build Coastguard Worker
108*38e8c45fSAndroid Build Coastguard Worker char keychain_removed_dir[PATH_MAX];
109*38e8c45fSAndroid Build Coastguard Worker snprintf(keychain_removed_dir, PATH_MAX, "%s/keychain/cacerts-removed", misc_dir);
110*38e8c45fSAndroid Build Coastguard Worker
111*38e8c45fSAndroid Build Coastguard Worker DIR *dir;
112*38e8c45fSAndroid Build Coastguard Worker struct dirent *dirent;
113*38e8c45fSAndroid Build Coastguard Worker dir = opendir("/data/user");
114*38e8c45fSAndroid Build Coastguard Worker if (dir != nullptr) {
115*38e8c45fSAndroid Build Coastguard Worker while ((dirent = readdir(dir))) {
116*38e8c45fSAndroid Build Coastguard Worker const char *name = dirent->d_name;
117*38e8c45fSAndroid Build Coastguard Worker
118*38e8c45fSAndroid Build Coastguard Worker // skip "." and ".."
119*38e8c45fSAndroid Build Coastguard Worker if (name[0] == '.') {
120*38e8c45fSAndroid Build Coastguard Worker if (name[1] == 0) continue;
121*38e8c45fSAndroid Build Coastguard Worker if ((name[1] == '.') && (name[2] == 0)) continue;
122*38e8c45fSAndroid Build Coastguard Worker }
123*38e8c45fSAndroid Build Coastguard Worker
124*38e8c45fSAndroid Build Coastguard Worker uint32_t user_id = std::stoi(name);
125*38e8c45fSAndroid Build Coastguard Worker
126*38e8c45fSAndroid Build Coastguard Worker // /data/misc/user/<user_id>
127*38e8c45fSAndroid Build Coastguard Worker if (ensure_config_user_dirs(user_id) == -1) {
128*38e8c45fSAndroid Build Coastguard Worker goto fail;
129*38e8c45fSAndroid Build Coastguard Worker }
130*38e8c45fSAndroid Build Coastguard Worker
131*38e8c45fSAndroid Build Coastguard Worker char misc_added_dir[PATH_MAX];
132*38e8c45fSAndroid Build Coastguard Worker snprintf(misc_added_dir, PATH_MAX, "%s/user/%s/cacerts-added", misc_dir, name);
133*38e8c45fSAndroid Build Coastguard Worker
134*38e8c45fSAndroid Build Coastguard Worker char misc_removed_dir[PATH_MAX];
135*38e8c45fSAndroid Build Coastguard Worker snprintf(misc_removed_dir, PATH_MAX, "%s/user/%s/cacerts-removed", misc_dir, name);
136*38e8c45fSAndroid Build Coastguard Worker
137*38e8c45fSAndroid Build Coastguard Worker uid_t uid = multiuser_get_uid(user_id, AID_SYSTEM);
138*38e8c45fSAndroid Build Coastguard Worker gid_t gid = uid;
139*38e8c45fSAndroid Build Coastguard Worker if (access(keychain_added_dir, F_OK) == 0) {
140*38e8c45fSAndroid Build Coastguard Worker if (copy_dir_files(keychain_added_dir, misc_added_dir, uid, gid) != 0) {
141*38e8c45fSAndroid Build Coastguard Worker SLOGE("Some files failed to copy");
142*38e8c45fSAndroid Build Coastguard Worker }
143*38e8c45fSAndroid Build Coastguard Worker }
144*38e8c45fSAndroid Build Coastguard Worker if (access(keychain_removed_dir, F_OK) == 0) {
145*38e8c45fSAndroid Build Coastguard Worker if (copy_dir_files(keychain_removed_dir, misc_removed_dir, uid, gid) != 0) {
146*38e8c45fSAndroid Build Coastguard Worker SLOGE("Some files failed to copy");
147*38e8c45fSAndroid Build Coastguard Worker }
148*38e8c45fSAndroid Build Coastguard Worker }
149*38e8c45fSAndroid Build Coastguard Worker }
150*38e8c45fSAndroid Build Coastguard Worker closedir(dir);
151*38e8c45fSAndroid Build Coastguard Worker
152*38e8c45fSAndroid Build Coastguard Worker if (access(keychain_added_dir, F_OK) == 0) {
153*38e8c45fSAndroid Build Coastguard Worker delete_dir_contents(keychain_added_dir, 1, nullptr);
154*38e8c45fSAndroid Build Coastguard Worker }
155*38e8c45fSAndroid Build Coastguard Worker if (access(keychain_removed_dir, F_OK) == 0) {
156*38e8c45fSAndroid Build Coastguard Worker delete_dir_contents(keychain_removed_dir, 1, nullptr);
157*38e8c45fSAndroid Build Coastguard Worker }
158*38e8c45fSAndroid Build Coastguard Worker }
159*38e8c45fSAndroid Build Coastguard Worker
160*38e8c45fSAndroid Build Coastguard Worker version = 3;
161*38e8c45fSAndroid Build Coastguard Worker }
162*38e8c45fSAndroid Build Coastguard Worker
163*38e8c45fSAndroid Build Coastguard Worker // Persist layout version if changed
164*38e8c45fSAndroid Build Coastguard Worker if (version != oldVersion) {
165*38e8c45fSAndroid Build Coastguard Worker if (fs_write_atomic_int(version_path, version) == -1) {
166*38e8c45fSAndroid Build Coastguard Worker SLOGE("Failed to save version to %s: %s", version_path, strerror(errno));
167*38e8c45fSAndroid Build Coastguard Worker goto fail;
168*38e8c45fSAndroid Build Coastguard Worker }
169*38e8c45fSAndroid Build Coastguard Worker }
170*38e8c45fSAndroid Build Coastguard Worker
171*38e8c45fSAndroid Build Coastguard Worker // Success!
172*38e8c45fSAndroid Build Coastguard Worker res = 0;
173*38e8c45fSAndroid Build Coastguard Worker
174*38e8c45fSAndroid Build Coastguard Worker fail:
175*38e8c45fSAndroid Build Coastguard Worker return res;
176*38e8c45fSAndroid Build Coastguard Worker }
177*38e8c45fSAndroid Build Coastguard Worker
log_callback(int type,const char * fmt,...)178*38e8c45fSAndroid Build Coastguard Worker static int log_callback(int type, const char *fmt, ...) { // NOLINT
179*38e8c45fSAndroid Build Coastguard Worker va_list ap;
180*38e8c45fSAndroid Build Coastguard Worker int priority;
181*38e8c45fSAndroid Build Coastguard Worker
182*38e8c45fSAndroid Build Coastguard Worker switch (type) {
183*38e8c45fSAndroid Build Coastguard Worker case SELINUX_WARNING:
184*38e8c45fSAndroid Build Coastguard Worker priority = ANDROID_LOG_WARN;
185*38e8c45fSAndroid Build Coastguard Worker break;
186*38e8c45fSAndroid Build Coastguard Worker case SELINUX_INFO:
187*38e8c45fSAndroid Build Coastguard Worker priority = ANDROID_LOG_INFO;
188*38e8c45fSAndroid Build Coastguard Worker break;
189*38e8c45fSAndroid Build Coastguard Worker default:
190*38e8c45fSAndroid Build Coastguard Worker priority = ANDROID_LOG_ERROR;
191*38e8c45fSAndroid Build Coastguard Worker break;
192*38e8c45fSAndroid Build Coastguard Worker }
193*38e8c45fSAndroid Build Coastguard Worker va_start(ap, fmt);
194*38e8c45fSAndroid Build Coastguard Worker LOG_PRI_VA(priority, "SELinux", fmt, ap);
195*38e8c45fSAndroid Build Coastguard Worker va_end(ap);
196*38e8c45fSAndroid Build Coastguard Worker return 0;
197*38e8c45fSAndroid Build Coastguard Worker }
198*38e8c45fSAndroid Build Coastguard Worker
installd_main(const int argc ATTRIBUTE_UNUSED,char * argv[])199*38e8c45fSAndroid Build Coastguard Worker static int installd_main(const int argc ATTRIBUTE_UNUSED, char *argv[]) {
200*38e8c45fSAndroid Build Coastguard Worker int ret;
201*38e8c45fSAndroid Build Coastguard Worker int selinux_enabled = (is_selinux_enabled() > 0);
202*38e8c45fSAndroid Build Coastguard Worker
203*38e8c45fSAndroid Build Coastguard Worker setenv("ANDROID_LOG_TAGS", "*:v", 1);
204*38e8c45fSAndroid Build Coastguard Worker android::base::InitLogging(argv);
205*38e8c45fSAndroid Build Coastguard Worker
206*38e8c45fSAndroid Build Coastguard Worker SLOGI("installd firing up");
207*38e8c45fSAndroid Build Coastguard Worker
208*38e8c45fSAndroid Build Coastguard Worker union selinux_callback cb;
209*38e8c45fSAndroid Build Coastguard Worker cb.func_log = log_callback;
210*38e8c45fSAndroid Build Coastguard Worker selinux_set_callback(SELINUX_CB_LOG, cb);
211*38e8c45fSAndroid Build Coastguard Worker
212*38e8c45fSAndroid Build Coastguard Worker if (!initialize_globals()) {
213*38e8c45fSAndroid Build Coastguard Worker SLOGE("Could not initialize globals; exiting.\n");
214*38e8c45fSAndroid Build Coastguard Worker exit(1);
215*38e8c45fSAndroid Build Coastguard Worker }
216*38e8c45fSAndroid Build Coastguard Worker
217*38e8c45fSAndroid Build Coastguard Worker if (initialize_directories() < 0) {
218*38e8c45fSAndroid Build Coastguard Worker SLOGE("Could not create directories; exiting.\n");
219*38e8c45fSAndroid Build Coastguard Worker exit(1);
220*38e8c45fSAndroid Build Coastguard Worker }
221*38e8c45fSAndroid Build Coastguard Worker
222*38e8c45fSAndroid Build Coastguard Worker if (selinux_enabled && selinux_status_open(true) < 0) {
223*38e8c45fSAndroid Build Coastguard Worker SLOGE("Could not open selinux status; exiting.\n");
224*38e8c45fSAndroid Build Coastguard Worker exit(1);
225*38e8c45fSAndroid Build Coastguard Worker }
226*38e8c45fSAndroid Build Coastguard Worker
227*38e8c45fSAndroid Build Coastguard Worker if ((ret = InstalldNativeService::start()) != android::OK) {
228*38e8c45fSAndroid Build Coastguard Worker SLOGE("Unable to start InstalldNativeService: %d", ret);
229*38e8c45fSAndroid Build Coastguard Worker exit(1);
230*38e8c45fSAndroid Build Coastguard Worker }
231*38e8c45fSAndroid Build Coastguard Worker
232*38e8c45fSAndroid Build Coastguard Worker IPCThreadState::self()->joinThreadPool();
233*38e8c45fSAndroid Build Coastguard Worker
234*38e8c45fSAndroid Build Coastguard Worker LOG(INFO) << "installd shutting down";
235*38e8c45fSAndroid Build Coastguard Worker
236*38e8c45fSAndroid Build Coastguard Worker return 0;
237*38e8c45fSAndroid Build Coastguard Worker }
238*38e8c45fSAndroid Build Coastguard Worker
239*38e8c45fSAndroid Build Coastguard Worker } // namespace installd
240*38e8c45fSAndroid Build Coastguard Worker } // namespace android
241*38e8c45fSAndroid Build Coastguard Worker
main(const int argc,char * argv[])242*38e8c45fSAndroid Build Coastguard Worker int main(const int argc, char *argv[]) {
243*38e8c45fSAndroid Build Coastguard Worker return android::installd::installd_main(argc, argv);
244*38e8c45fSAndroid Build Coastguard Worker }
245