This adds process pool feature for web runtime.
Also, sometimes kZygoteCommandDropProcessPrivileges will be sent
between the operation to sent kZygoteCommandForkRealPID.
Now kZygoteCommandForkRealPID has been locked by |control_lock_|,
add the lock to prevent it from being interrupted.
Reference:
https://review.tizen.org/gerrit/#/c/173439
https://review.tizen.org/gerrit/#/c/189532
Change-Id: Ic0b23425a3c336d6fd65711532c9cc3f46f021e6
Signed-off-by: yh106.jung <yh106.jung@samsung.com>
Signed-off-by: Youngsoo Choi <kenshin.choi@samsung.com>
return sandbox_status_;
}
+#if defined(OS_TIZEN)
+void ZygoteCommunication::LoadInjectedBundlePath(
+ const std::string& injected_bundle_path) {
+ DCHECK(init_);
+ base::Pickle pickle;
+
+ pickle.WriteInt(kZygoteCommandLoadInjectedBundle);
+ pickle.WriteString(injected_bundle_path);
+ if (!SendMessage(pickle, NULL))
+ LOG(ERROR) << "Failed to send LoadInjectedBundlePath message to zygote";
+}
+
+void ZygoteCommunication::DropProcessPrivileges(const std::string& app_id) {
+ DCHECK(init_);
+ base::Pickle pickle;
+
+ pickle.WriteInt(kZygoteCommandDropProcessPrivileges);
+ pickle.WriteString(app_id);
+ base::AutoLock lock(control_lock_);
+ if (!SendMessage(pickle, NULL))
+ LOG(ERROR) << "Failed to send DropProcessPrivileges message to zygote";
+}
+#endif
+
} // namespace content
// Returns the sandbox status of this zygote.
int GetSandboxStatus();
+#if defined(OS_TIZEN)
+ void LoadInjectedBundlePath(const std::string& injected_bundle_path);
+ void DropProcessPrivileges(const std::string& app_id);
+#endif
+
private:
// Should be called every time a Zygote child is born.
void ZygoteChildBorn(pid_t process);
// Not a real zygote command, but a subcommand used during the zygote fork
// protocol. Sends the child's PID as seen from the browser process.
- kZygoteCommandForkRealPID = 4
+ kZygoteCommandForkRealPID = 4,
+
+#if defined(OS_TIZEN)
+ // Load injected bundle library.
+ kZygoteCommandLoadInjectedBundle = 5,
+
+ // Drop privilege of zygote process.
+ kZygoteCommandDropProcessPrivileges = 6
+#endif
};
} // namespace content
#include "services/service_manager/sandbox/linux/sandbox_linux.h"
#include "services/service_manager/sandbox/sandbox.h"
#include "third_party/icu/source/i18n/unicode/timezone.h"
+#if defined(OS_TIZEN)
+#include <dlfcn.h>
+#include <security-manager/security-manager.h>
+#endif
// See https://chromium.googlesource.com/chromium/src/+/master/docs/linux_zygote.md
: sandbox_flags_(sandbox_flags),
helpers_(std::move(helpers)),
initial_uma_index_(0),
+#if defined(OS_TIZEN)
+ injected_bundle_handle_(nullptr),
+#endif
to_reap_(),
ipc_backchannel_(ipc_backchannel) {}
-Zygote::~Zygote() {}
+Zygote::~Zygote() {
+#if defined(OS_TIZEN)
+ if (injected_bundle_handle_)
+ dlclose(injected_bundle_handle_);
+#endif
+}
bool Zygote::ProcessRequests() {
// A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the
LOG(ERROR) << "Unexpected real PID message from browser";
NOTREACHED();
return false;
+#if defined(OS_TIZEN)
+ case kZygoteCommandLoadInjectedBundle:
+ HandleLoadInjectedBundle(fd, iter);
+ return false;
+ case kZygoteCommandDropProcessPrivileges:
+ HandleDropProcessPrivileges(fd, iter);
+ return false;
+#endif
default:
NOTREACHED();
break;
return false;
}
+#if defined(OS_TIZEN)
+typedef void (*DynamicPreloading)(void);
+void Zygote::HandleLoadInjectedBundle(int fd, base::PickleIterator iter) {
+ std::string injected_bundle_path;
+ if (!iter.ReadString(&injected_bundle_path))
+ return;
+
+ injected_bundle_handle_ = dlopen(injected_bundle_path.c_str(), RTLD_LAZY);
+ if (!injected_bundle_handle_) {
+ LOG(ERROR) << "No handle to " << injected_bundle_path.c_str() << " error "
+ << dlerror();
+ return;
+ }
+
+ DynamicPreloading dp = reinterpret_cast<DynamicPreloading>(
+ dlsym(injected_bundle_handle_, "DynamicPreloading"));
+ if (dp) {
+ dp();
+ } else {
+ LOG(ERROR) << "Fail to load symbol 'DynamicPreloading'"
+ << ", error " << dlerror();
+ }
+}
+
+void Zygote::HandleDropProcessPrivileges(int fd, base::PickleIterator iter) {
+ std::string app_id;
+ if (!iter.ReadString(&app_id))
+ return;
+
+ int error = security_manager_prepare_app(app_id.c_str());
+ if (error) {
+ LOG(ERROR) << "Fail on security_manager_prepare_app"
+ << ", error code " << error;
+ }
+}
+#endif
+
} // namespace content
// Attempt to reap all outstanding children in |to_reap_|.
void ReapChildren();
+#if defined(OS_TIZEN)
+ // Get a library path from |iter|, and load it via dlopen().
+ // This step will reduce the launching time of
+ // actual web application launching.
+ // The loaded handle must be closed on termination.
+ void HandleLoadInjectedBundle(int fd, base::PickleIterator iter);
+
+ // Handle a 'drop privileges' request from the browser: this means
+ // that a new application will be launched and the browser
+ // will request a new renderer process. Thus before forking new process,
+ // zygote process should has restrict privileges.
+
+ // Get an actual application ID, and manipulate privileges of current process.
+ void HandleDropProcessPrivileges(int fd, base::PickleIterator iter);
+#endif
+
// The Zygote needs to keep some information about each process. Most
// notably what the PID of the process is inside the PID namespace of
// the Zygote and whether or not a process was started by the
// Count of how many fork delegates for which we've invoked InitialUMA().
size_t initial_uma_index_;
+#if defined(OS_TIZEN)
+ // This contains the FD that must be closed when current process is
+ // terminated.
+ void* injected_bundle_handle_;
+#endif
+
// The vector contains the child processes that need to be reaped.
std::vector<ZygoteProcessInfo> to_reap_;
BuildRequires: pkgconfig(nss)
BuildRequires: pkgconfig(openssl)
BuildRequires: pkgconfig(scim)
+BuildRequires: pkgconfig(security-manager)
BuildRequires: pkgconfig(sqlite3)
BuildRequires: pkgconfig(tts)
BuildRequires: pkgconfig(ui-gadget-1)
}
}
+config("security-manager") {
+ if (is_tizen) {
+ ldflags = [ "-lsecurity-manager-client" ]
+ }
+}
+
+tizen_pkg_config("libsecurity-manager") {
+ packages = []
+ if (is_tizen) {
+ packages = [ "security-manager" ]
+ }
+}
+
+config("security-manager-public") {
+ if (is_tizen) {
+ cflags = [ "-security-manager" ]
+ }
+}
+
config("tts") {
if (is_tizen) {
ldflags = [ "-ltts" ]
"//tizen_src/build:libelementary",
"//tizen_src/build:efl-extension",
"//tizen_src/build:libefl-extension",
+ "//tizen_src/build:security-manager",
+ "//tizen_src/build:libsecurity-manager",
"//tizen_src/build:tts",
"//tizen_src/build:libtts",
]
"//tizen_src/build:libelementary",
"//tizen_src/build:efl-extension",
"//tizen_src/build:libefl-extension",
+ "//tizen_src/build:security-manager",
+ "//tizen_src/build:libsecurity-manager",
]
external_content_browser_extra_configs = [
#include "private/ewk_security_origin_private.h"
#include "wrt/wrt_widget_host.h"
+#if defined(OS_TIZEN)
+#include "content/browser/zygote_host/zygote_communication_linux.h"
+#include "content/public/common/zygote_handle.h"
+#endif
+
using content::BrowserThread;
using content::BrowserContext;
using content::BrowserContextEfl;
widget_scale_ = scale;
widget_theme_ = theme;
widget_encoded_bundle_ = encoded_bundle;
+
+#if defined(OS_TIZEN)
+ // Drop process privillages while web app is launching from WRT process pool.
+ content::GetGenericZygote()->DropProcessPrivileges(tizen_app_id_);
+#endif
}
void EWebContext::SendWrtMessage(const Ewk_Wrt_Message_Data& data) {
widget_scale_(0),
m_pixmap(0),
inspector_server_(NULL) {
+#if defined(OS_TIZEN)
+ // In order to support process pool for WRT, injected bundle should be
+ // preloaded on zygote process after first intialization of EwkGlobalData.
+ bool should_preload_injected_bundle =
+ (!injected_bundle_path_.empty() && !EwkGlobalData::IsInitialized());
+#endif
CHECK(EwkGlobalData::GetInstance());
// WRT does not really care about incognito, so set it to false
notification_cb_.reset(
new EWebContextNotificationCallback(nullptr, nullptr, nullptr, nullptr));
tizen_extensible_.reset(TizenExtensible::create());
+
+#if defined(OS_TIZEN)
+ // Preload injected bundle on zygote process for process pool.
+ if (should_preload_injected_bundle) {
+ content::GetGenericZygote()->LoadInjectedBundlePath(injected_bundle_path_);
+ }
+#endif
}
EWebContext::~EWebContext() {}