xref: /aosp_15_r20/frameworks/native/cmds/installd/installd.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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