From f12af5e90727869d225f169e7f475695da64bf48 Mon Sep 17 00:00:00 2001 From: Martin Wallgren Date: Tue, 11 Aug 2015 15:10:31 +0200 Subject: RRO: Synchronize access to overlays.list idmap --scan is executed as a part of the pre-loading in ZygoteInit. The pre loading is executed in parallel for each supported architecture (32/64 bit). This will cause a race condition in the creation of the overlays.list file and the idmap files for the system overlays. Apply flock on overlays.list to prevent the file from being thrown away and recreated when it is in use by another Zygote. Bug: 28032298 Change-Id: I51d39f121d207b11181340b68b164b60020f0c61 --- cmds/idmap/scan.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'cmds/idmap/scan.cpp') diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp index 6d30f0d0ce34..ab6adfb9475f 100644 --- a/cmds/idmap/scan.cpp +++ b/cmds/idmap/scan.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include "idmap.h" @@ -35,16 +36,31 @@ namespace { bool writePackagesList(const char *filename, const SortedVector& overlayVector) { - FILE* fout = fopen(filename, "w"); + // the file is opened for appending so that it doesn't get truncated + // before we can guarantee mutual exclusion via the flock + FILE* fout = fopen(filename, "a"); if (fout == NULL) { return false; } + if (TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_EX)) != 0) { + fclose(fout); + return false; + } + + if (TEMP_FAILURE_RETRY(ftruncate(fileno(fout), 0)) != 0) { + TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN)); + fclose(fout); + return false; + } + for (size_t i = 0; i < overlayVector.size(); ++i) { const Overlay& overlay = overlayVector[i]; fprintf(fout, "%s %s\n", overlay.apk_path.string(), overlay.idmap_path.string()); } + TEMP_FAILURE_RETRY(fflush(fout)); + TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN)); fclose(fout); // Make file world readable since Zygote (running as root) will read @@ -171,9 +187,6 @@ int idmap_scan(const char *target_package_name, const char *target_apk_path, { String8 filename = String8(idmap_dir); filename.appendPath("overlays.list"); - if (unlink(filename.string()) != 0 && errno != ENOENT) { - return EXIT_FAILURE; - } SortedVector overlayVector; const size_t N = overlay_dirs->size(); -- cgit v1.2.3-59-g8ed1b