Skip to content

Commit

Permalink
preload/host: Allow disabling spawning the latest version on re-exec
Browse files Browse the repository at this point in the history
This is now controlled by ZYPAK_SPAWN_LATEST_ON_REEXEC, which will be
set to 0 by default at some point in the future.

Closes #19
  • Loading branch information
refi64 committed Mar 7, 2022
1 parent 1a352e1 commit 8424c6b
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 29 deletions.
19 changes: 14 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,21 @@ This requires your Flatpak to be using:
Now, instead of running your Electron binary directly, call it via
`zypak-wrapper PATH/TO/MY/ELECTRON/BINARY`.

## Usage with a wrapper script
## Re-exec behavior

If this is wrapping an application that requries some sort of wrapper script,
make sure you set `CHROME_WRAPPER=` to the path of said script. Otherwise, if the
application attempts to re-exec itself (i.e. `chrome://restart`), it won't be using
the wrapper on re-exec, leading to potentially unexpected behavior.
By default, Zypak will detect when the app is re-exec'ing itself and attempt to
spawn the latest version, in order for `chrome://restart` to function. This can
be disabled by setting `ZYPAK_SPAWN_LATEST_ON_REEXEC=0`. **This will be the
default in the future once existing browsers are migrated,** because it matches
more closely with what Electron would expect.

### Usage with a wrapper script

If `ZYPAK_SPAWN_LATEST_ON_REEXEC=1` (the current default) is active, and Zypak
was invoked by some sort of wrapper script, make sure you set `CHROME_WRAPPER=`
to the path of said script. Otherwise, if the application attempts to re-exec
itself (i.e. `chrome://restart`), it won't be using the wrapper on re-exec,
leading to potentially unexpected behavior.

## Widevine support

Expand Down
4 changes: 2 additions & 2 deletions src/base/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ void Env::Set(cstring_view name, cstring_view value, bool overwrite /*= true*/)
void Env::Clear(cstring_view name) { ZYPAK_ASSERT(unsetenv(name.c_str()) == 0); }

// static
bool Env::Test(cstring_view name) {
bool Env::Test(cstring_view name, bool default_value /*= false*/) {
if (auto env = Get(name)) {
return !env->empty() && *env != "0" && *env != "false";
} else {
return false;
return default_value;
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/base/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Env {
// Clears the given environment variable.
static void Clear(cstring_view name);
// Tests if the variable is set to a truthy value (i.e. not empty, 0, or false).
static bool Test(cstring_view name);
static bool Test(cstring_view name, bool default_value = false);

static constexpr cstring_view kZypakBin = "ZYPAK_BIN";
static constexpr cstring_view kZypakLib = "ZYPAK_LIB";
Expand All @@ -38,6 +38,7 @@ class Env {
static constexpr cstring_view kZypakSettingSandboxFilename = "ZYPAK_SANDBOX_FILENAME";
static constexpr cstring_view kZypakSettingExposeWidevinePath = "ZYPAK_EXPOSE_WIDEVINE_PATH";
static constexpr cstring_view kZypakSettingLdPreload = "ZYPAK_LD_PRELOAD";
static constexpr cstring_view kZypakSettingSpawnLatestOnReexec = "ZYPAK_SPAWN_LATEST_ON_REEXEC";
};

} // namespace zypak
35 changes: 18 additions & 17 deletions src/preload/host/exec_zypak_sandbox.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,36 +49,37 @@ DECLARE_OVERRIDE(int, execvp, const char* file, char* const* argv) {
return -1;
}

Env::Clear("LD_PRELOAD");

if (file == SandboxPath::instance()->sandbox_path()) {
Env::Clear("LD_PRELOAD");
file = "zypak-sandbox";
} else if (!HasTypeArg(argv)) {
Env::Clear("LD_PRELOAD");

if (IsCurrentExe(file)) {
// exec on the host exe, so pass it through the sandbox.
// "Leaking" calls to 'new' doesn't matter here since we're about to exec anyway.
std::vector<const char*> c_argv;
c_argv.push_back("zypak-helper");
} else if (!HasTypeArg(argv) && IsCurrentExe(file)) {
// exec on the host exe, so pass it through the sandbox.
// "Leaking" calls to 'new' doesn't matter here since we're about to exec anyway.
std::vector<const char*> c_argv;
c_argv.push_back("zypak-helper");

// Swap out the main binary to the wrapper if one was used, and assume the wrapper will use
// zypak-wrapper.sh itself (i.e. we don't need to handle it here).
if (Env::Test(Env::kZypakSettingSpawnLatestOnReexec, /*default_value=*/true)) {
if (auto wrapper = Env::Get("CHROME_WRAPPER")) {
// Swap out the main binary to the wrapper if one was used, and assume the wrapper
// will use zypak-wrapper.sh itself (i.e. we don't need to handle it here).
c_argv.push_back("exec-latest");
c_argv.push_back(wrapper->data());
argv++;
} else {
c_argv.push_back("host-latest");
}
} else {
c_argv.push_back("host");
}

for (; *argv != nullptr; argv++) {
c_argv.push_back(*argv);
}
for (; *argv != nullptr; argv++) {
c_argv.push_back(*argv);
}

c_argv.push_back(nullptr);
c_argv.push_back(nullptr);

return original("zypak-helper", const_cast<char* const*>(c_argv.data()));
}
return original("zypak-helper", const_cast<char* const*>(c_argv.data()));
}

return original(file, argv);
Expand Down
4 changes: 0 additions & 4 deletions src/preload/host/spawn_strategy/initialize.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ int MAIN_OVERRIDE(int argc, char** argv, char** envp) {
DebugContext::instance()->LoadFromEnvironment();
DebugContext::instance()->set_name("preload-host-spawn-strategy");

// Unset LD_PRELOAD so exec'd processes don't call back into here again.
// This would particularly break anything that assumes only one thread is running.
unsetenv("LD_PRELOAD");

dbus::Bus* bus = dbus::Bus::Acquire();
ZYPAK_ASSERT(bus);

Expand Down

0 comments on commit 8424c6b

Please sign in to comment.