Example #1
0
int su_main(int argc, char *argv[]) {
    int ppid = getppid();
	if ((geteuid() != AID_ROOT && getuid() != AID_ROOT) ||
			(get_api_version() >= 18 && getuid() == AID_SHELL) ||
			get_api_version() >= 19) {
		// attempt to connect to daemon...
		LOGD("starting daemon client %d %d", getuid(), geteuid());
		return connect_daemon(argc, argv, ppid);
	} else {
		return su_main_nodaemon(argc, argv);
	}

}
static int l_get_compile_options(lua_State *L)
{
    lua_settop(L, 0);
    lua_newtable(L);

#ifdef CORSIX_TH_64BIT
    lua_pushboolean(L, 1);
#else
    lua_pushboolean(L, 0);
#endif
    lua_setfield(L, -2, "arch_64");

#if defined(CORSIX_TH_USE_OGL_RENDERER)
    lua_pushliteral(L, "OpenGL");
#elif defined(CORSIX_TH_USE_DX9_RENDERER)
    lua_pushliteral(L, "DirectX 9");
#elif defined(CORSIX_TH_USE_SDL_RENDERER)
    lua_pushliteral(L, "SDL");
#else
    lua_pushliteral(L, "Unknown");
#endif
    lua_setfield(L, -2, "renderer");

#ifdef CORSIX_TH_USE_SDL_MIXER
    lua_pushboolean(L, 1);
#else
    lua_pushboolean(L, 0);
#endif
    lua_setfield(L, -2, "audio");

    lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
    lua_getfield(L, -1, "jit");
    if(lua_type(L, -1) == LUA_TNIL)
    {
        lua_replace(L, -2);
    }
    else
    {
        lua_getfield(L, -1, "version");
        lua_replace(L, -3);
        lua_pop(L, 1);
    }
    lua_setfield(L, -2, "jit");

    lua_pushinteger(L, get_api_version());
    lua_setfield(L, -2, "api_version");

    return 1;
}
Example #3
0
bool mount_fstab(const std::string &fstab_path)
{
    bool ret = true;

    std::vector<util::fstab_rec> fstab;
    std::vector<util::fstab_rec *> recs_system;
    std::vector<util::fstab_rec *> recs_cache;
    std::vector<util::fstab_rec *> recs_data;
    std::vector<util::fstab_rec *> flags_system;
    std::vector<util::fstab_rec *> flags_cache;
    std::vector<util::fstab_rec *> flags_data;
    std::string target_system;
    std::string target_cache;
    std::string target_data;
    std::string path_fstab_gen;
    std::string path_completed;
    std::string path_failed;
    std::string base_name;
    std::string dir_name;
    struct stat st;
    std::shared_ptr<Rom> rom;
    std::string rom_id;

    Roms roms;
    roms.add_builtin();

    base_name = util::base_name(fstab_path);
    dir_name = util::dir_name(fstab_path);

    path_fstab_gen += dir_name;
    path_fstab_gen += "/.";
    path_fstab_gen += base_name;
    path_fstab_gen += ".gen";
    path_completed += dir_name;
    path_completed += "/.";
    path_completed += base_name;
    path_completed += ".completed";
    path_failed += dir_name;
    path_failed += "/.";
    path_failed += base_name;
    path_failed += ".failed";

    auto on_finish = util::finally([&] {
        if (ret) {
            util::create_empty_file(path_completed);
            LOGI("Successfully mounted partitions");
        } else {
            util::create_empty_file(path_failed);
        }
    });

    // This is a oneshot operation
    if (stat(path_completed.c_str(), &st) == 0) {
        LOGV("Filesystems already successfully mounted");
        return true;
    }

    if (stat(path_failed.c_str(), &st) == 0) {
        LOGE("Failed to mount partitions ealier. No further attempts will be made");
        return false;
    }

    // Remount rootfs as read-write so a new fstab file can be written
    if (mount("", "/", "", MS_REMOUNT, "") < 0) {
        LOGE("Failed to remount rootfs as rw: {}", strerror(errno));
    }

    // Read original fstab
    fstab = util::read_fstab(fstab_path);
    if (fstab.empty()) {
        LOGE("Failed to read {}", fstab_path);
        return false;
    }

    // Generate new fstab without /system, /cache, or /data entries
    file_ptr out(std::fopen(path_fstab_gen.c_str(), "wb"), std::fclose);
    if (!out) {
        LOGE("Failed to open {} for writing: {}",
             path_fstab_gen, strerror(errno));
        return false;
    }

    for (util::fstab_rec &rec : fstab) {
        if (rec.mount_point == "/system") {
            recs_system.push_back(&rec);
        } else if (rec.mount_point == "/cache") {
            recs_cache.push_back(&rec);
        } else if (rec.mount_point == "/data") {
            recs_data.push_back(&rec);
        } else {
            std::fprintf(out.get(), "%s\n", rec.orig_line.c_str());
        }
    }

    out.reset();

    // /system and /data are always in the fstab. The patcher should create
    // an entry for /cache for the ROMs that mount it manually in one of the
    // init scripts
    if (recs_system.empty() || recs_cache.empty() || recs_data.empty()) {
        LOGE("fstab does not contain all of /system, /cache, and /data!");
        return false;
    }

    // Mount raw partitions to /raw/*
    if (!util::kernel_cmdline_get_option("romid", &rom_id)
            && !util::file_first_line("/romid", &rom_id)) {
        LOGE("Failed to determine ROM ID");
        return false;
    }

    if (Roms::is_named_rom(rom_id)) {
        rom = Roms::create_named_rom(rom_id);
    } else {
        rom = roms.find_by_id(rom_id);
        if (!rom) {
            LOGE("Unknown ROM ID: {}", rom_id);
            return false;
        }
    }

    LOGD("ROM ID is: {}", rom_id);

    // Set property for the Android app to use
    if (!util::set_property("ro.multiboot.romid", rom_id)) {
        LOGE("Failed to set 'ro.multiboot.romid' to '{}'", rom_id);
    }

    // Because of how Android deals with partitions, if, say, the source path
    // for the /system bind mount resides on /cache, then the cache partition
    // must be mounted with the system partition's flags. In this future, this
    // may be avoided by mounting every partition with some more liberal flags,
    // since the current setup does not allow two bind mounted locations to
    // reside on the same partition.

    if (util::starts_with(rom->system_path, "/cache")) {
        flags_system = recs_cache;
    } else {
        flags_system = recs_system;
    }

    if (util::starts_with(rom->cache_path, "/system")) {
        flags_cache = recs_system;
    } else {
        flags_cache = recs_cache;
    }

    flags_data = recs_data;

    if (mkdir("/raw", 0755) < 0) {
        LOGE("Failed to create /raw");
        return false;
    }

    if (!create_dir_and_mount(recs_system, flags_system, "/raw/system")) {
        LOGE("Failed to mount /raw/system");
        return false;
    }
    if (!create_dir_and_mount(recs_cache, flags_cache, "/raw/cache")) {
        LOGE("Failed to mount /raw/cache");
        return false;
    }
    if (!create_dir_and_mount(recs_data, flags_data, "/raw/data")) {
        LOGE("Failed to mount /raw/data");
        return false;
    }

    // Make paths use /raw/...
    if (rom->system_path.empty()
            || rom->cache_path.empty()
            || rom->data_path.empty()) {
        LOGE("Invalid or empty paths");
        return false;
    }

    target_system += "/raw";
    target_system += rom->system_path;
    target_cache += "/raw";
    target_cache += rom->cache_path;
    target_data += "/raw";
    target_data += rom->data_path;

    if (!util::bind_mount(target_system, 0771, "/system", 0771)) {
        return false;
    }

    if (!util::bind_mount(target_cache, 0771, "/cache", 0771)) {
        return false;
    }

    if (!util::bind_mount(target_data, 0771, "/data", 0771)) {
        return false;
    }

    // Bind mount internal SD directory
    if (!util::bind_mount("/raw/data/media", 0771, "/data/media", 0771)) {
        return false;
    }

    // Prevent installd from dying because it can't unmount /data/media for
    // multi-user migration. Since <= 4.2 devices aren't supported anyway,
    // we'll bypass this.
    file_ptr fp(std::fopen("/data/.layout_version", "wb"), std::fclose);
    if (fp) {
        const char *layout_version;
        if (get_api_version() >= 21) {
            layout_version = "3";
        } else {
            layout_version = "2";
        }

        fwrite(layout_version, 1, strlen(layout_version), fp.get());
        fp.reset();
    } else {
        LOGE("Failed to open /data/.layout_version to disable migration");
    }

    static std::string context("u:object_r:install_data_file:s0");
    if (lsetxattr("/data/.layout_version", "security.selinux",
                  context.c_str(), context.size() + 1, 0) < 0) {
        LOGE("{}: Failed to set SELinux context: {}",
             "/data/.layout_version", strerror(errno));
    }


    // Global app sharing
    std::string config_path("/data/media/0/MultiBoot/");
    config_path += rom->id;
    config_path += "/config.json";

    RomConfig config;
    if (config.load_file(config_path)) {
        if (config.indiv_app_sharing && (config.global_app_sharing
                || config.global_paid_app_sharing)) {
            LOGW("Both individual and global sharing are enabled");
            LOGW("Global sharing settings will be ignored");
        } else {
            if (config.global_app_sharing || config.global_paid_app_sharing) {
                if (!util::bind_mount("/raw/data/app-lib", 0771,
                                      "/data/app-lib", 0771)) {
                    return false;
                }
            }
            if (config.global_app_sharing) {
                if (!util::bind_mount("/raw/data/app", 0771,
                                      "/data/app", 0771)) {
                    return false;
                }
            }
            if (config.global_paid_app_sharing) {
                if (!util::bind_mount("/raw/data/app-asec", 0771,
                                      "/data/app-asec", 0771)) {
                    return false;
                }
            }
        }
    }

    return true;
}