From f1e8bd3f46fc53dc8eea88a729fd784e66b05972 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Mon, 29 Oct 2018 23:32:25 -0700 Subject: [PATCH] [M69 Dev][Tizen] Fix compiler errors Change-Id: I7c2785cc527f0ae84f5afe491aa5d100adf408b7 Signed-off-by: Youngsoo Choi Signed-off-by: Chandan Padhi --- base/BUILD.gn | 6 +- build/config/compiler/BUILD.gn | 3 +- .../core/browser/browser_policy_connector.cc | 5 +- components/policy/tools/generate_policy_source.py | 2 - components/url_formatter/top_domains/BUILD.gn | 3 + content/BUILD.gn | 1 - content/browser/BUILD.gn | 10 - content/browser/child_process_launcher.cc | 1 + .../zygote_host/zygote_communication_linux.cc | 347 ---------- .../zygote_host/zygote_communication_linux.h | 108 --- content/common/BUILD.gn | 6 +- content/common/zygote_commands_linux.h | 62 -- content/zygote/zygote_linux.cc | 725 --------------------- content/zygote/zygote_linux.h | 174 ----- content/zygote/zygote_main_linux.cc | 249 ------- .../transport_security_state_generator/BUILD.gn | 3 + services/network/network_service.cc | 4 +- services/network/network_service.h | 2 +- services/network/public/mojom/BUILD.gn | 2 +- .../zygote/common/zygote_commands_linux.h | 10 +- .../zygote/host/zygote_communication_linux.cc | 24 + .../zygote/host/zygote_communication_linux.h | 5 + services/service_manager/zygote/zygote_linux.cc | 18 +- services/service_manager/zygote/zygote_linux.h | 22 + .../service_manager/zygote/zygote_main_linux.cc | 5 + .../skia/third_party/skcms/src/Transform_inl.h | 2 + tizen_src/build/config/compiler/BUILD.gn | 1 + tizen_src/ewk/efl_integration/eweb_context.cc | 13 +- tools/variations/fieldtrial_to_struct.py | 1 + ui/gfx/gpu_fence.cc | 4 +- 30 files changed, 113 insertions(+), 1705 deletions(-) delete mode 100644 content/browser/zygote_host/zygote_communication_linux.cc delete mode 100644 content/browser/zygote_host/zygote_communication_linux.h delete mode 100644 content/common/zygote_commands_linux.h delete mode 100644 content/zygote/zygote_linux.cc delete mode 100644 content/zygote/zygote_linux.h delete mode 100644 content/zygote/zygote_main_linux.cc diff --git a/base/BUILD.gn b/base/BUILD.gn index c035d21..8513860 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn @@ -61,7 +61,7 @@ declare_args() { } # Determines whether libevent should be dep. -dep_libevent = !is_fuchsia && !is_win && !(is_nacl && !is_nacl_nonsfi) && !is_tizen +dep_libevent = !is_fuchsia && !is_win && !(is_nacl && !is_nacl_nonsfi) # Determines whether message_pump_libevent should be used. use_libevent = dep_libevent && !is_ios @@ -1267,6 +1267,10 @@ jumbo_component("base") { libs += [ "atomic" ] } + if (is_tizen) { + libs += [ "pthread" ] + } + if (use_allocator_shim) { sources += [ "allocator/allocator_shim.cc", diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 62952f8..734fdd9 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn @@ -541,7 +541,8 @@ config("compiler") { # C11/C++11 compiler flags setup. # --------------------------- - if (is_linux || is_android || (is_nacl && is_clang) || current_os == "aix") { + if (is_linux || is_tizen || is_android || (is_nacl && is_clang) || + current_os == "aix") { if (target_os == "android") { cxx11_override = use_cxx11_on_android } else { diff --git a/components/policy/core/browser/browser_policy_connector.cc b/components/policy/core/browser/browser_policy_connector.cc index a029d24..a7a045e 100644 --- a/components/policy/core/browser/browser_policy_connector.cc +++ b/components/policy/core/browser/browser_policy_connector.cc @@ -112,10 +112,7 @@ void BrowserPolicyConnector::InitInternal( std::unique_ptr device_management_service) { device_management_service_ = std::move(device_management_service); -#if defined(OS_TIZEN) - // FIXME: For EWK_BRINGUP. - NOTIMPLEMENTED(); -#else +#if !defined(EWK_BRINGUP) // FIXME: m69 bringup policy_statistics_collector_.reset(new policy::PolicyStatisticsCollector( base::Bind(&GetChromePolicyDetails), GetChromeSchema(), GetPolicyService(), local_state, base::ThreadTaskRunnerHandle::Get())); diff --git a/components/policy/tools/generate_policy_source.py b/components/policy/tools/generate_policy_source.py index 519aea4..ac73fbc 100755 --- a/components/policy/tools/generate_policy_source.py +++ b/components/policy/tools/generate_policy_source.py @@ -355,12 +355,10 @@ def _WritePolicyConstantHeader(policies, os, f, risk_tags): 'void SetEnterpriseUsersDefaults(PolicyMap* policy_map);\n' '#endif\n' '\n' - '#if !defined (OS_TIZEN)\n' '// Returns the PolicyDetails for |policy| if |policy| is a known\n' '// Chrome policy, otherwise returns NULL.\n' 'const PolicyDetails* GetChromePolicyDetails(' 'const std::string& policy);\n' - '#endif\n' '\n' '// Returns the schema data of the Chrome policy schema.\n' 'const internal::SchemaData* GetChromeSchemaData();\n' diff --git a/components/url_formatter/top_domains/BUILD.gn b/components/url_formatter/top_domains/BUILD.gn index aa76af7..4c13047 100644 --- a/components/url_formatter/top_domains/BUILD.gn +++ b/components/url_formatter/top_domains/BUILD.gn @@ -30,6 +30,9 @@ executable("top_domain_generator") { "//base", "//net/tools/huffman_trie:huffman_trie_generator_sources", ] + if (is_tizen) { + libs = [ "dlog" ] + } if (is_ios) { libs = [ "UIKit.framework" ] } diff --git a/content/BUILD.gn b/content/BUILD.gn index b6dd0bc..14c8cac 100644 --- a/content/BUILD.gn +++ b/content/BUILD.gn @@ -108,7 +108,6 @@ if (is_component_build) { set_sources_assignment_filter([]) sources = [ "common/sandbox_linux/sandbox_seccomp_bpf_linux.cc", - "common/send_zygote_child_ping_linux.cc", "public/common/content_switches.cc", ] set_sources_assignment_filter(sources_assignment_filter) diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index af508c7..15793f7 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn @@ -2464,26 +2464,16 @@ jumbo_source_set("browser") { if (is_tizen) { set_sources_assignment_filter([]) sources += [ - "//content/zygote/zygote_linux.cc", - "//content/zygote/zygote_linux.h", - "//content/zygote/zygote_main_linux.cc", "child_process_launcher_helper_linux.cc", "memory/memory_monitor_linux.cc", "memory/memory_monitor_linux.h", "memory/swap_metrics_driver_impl_linux.cc", "memory/swap_metrics_driver_impl_linux.h", - "renderer_host/font_utils_linux.cc", - "renderer_host/font_utils_linux.h", "renderer_host/pepper/pepper_truetype_font_linux.cc", "sandbox_host_linux.cc", "sandbox_host_linux.h", "sandbox_ipc_linux.cc", "sandbox_ipc_linux.h", - "zygote_host/zygote_communication_linux.cc", - "zygote_host/zygote_communication_linux.h", - "zygote_host/zygote_handle_linux.cc", - "zygote_host/zygote_host_impl_linux.cc", - "zygote_host/zygote_host_impl_linux.h", ] set_sources_assignment_filter(sources_assignment_filter) } diff --git a/content/browser/child_process_launcher.cc b/content/browser/child_process_launcher.cc index 41606170..cfb7fb8 100644 --- a/content/browser/child_process_launcher.cc +++ b/content/browser/child_process_launcher.cc @@ -14,6 +14,7 @@ #include "base/process/launch.h" #include "build/build_config.h" #include "content/public/browser/child_process_launcher_utils.h" +#include "content/public/common/content_switches.h" #include "content/public/common/sandboxed_process_launcher_delegate.h" #include "services/service_manager/embedder/result_codes.h" diff --git a/content/browser/zygote_host/zygote_communication_linux.cc b/content/browser/zygote_host/zygote_communication_linux.cc deleted file mode 100644 index 206a062..0000000 --- a/content/browser/zygote_host/zygote_communication_linux.cc +++ /dev/null @@ -1,347 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/zygote_host/zygote_communication_linux.h" - -#include -#include - -#include "base/base_switches.h" -#include "base/command_line.h" -#include "base/i18n/unicodestring.h" -#include "base/logging.h" -#include "base/metrics/histogram_functions.h" -#include "base/path_service.h" -#include "base/pickle.h" -#include "base/posix/eintr_wrapper.h" -#include "base/posix/unix_domain_socket.h" -#include "content/common/zygote_commands_linux.h" -#include "content/public/common/content_switches.h" -#include "content/public/common/result_codes.h" -#include "services/service_manager/embedder/switches.h" -#include "services/service_manager/sandbox/switches.h" -#include "third_party/icu/source/i18n/unicode/timezone.h" - -namespace content { - -ZygoteCommunication::ZygoteCommunication() - : control_fd_(), - control_lock_(), - pid_(), - list_of_running_zygote_children_(), - child_tracking_lock_(), - sandbox_status_(0), - have_read_sandbox_status_word_(false), - init_(false) {} - -ZygoteCommunication::~ZygoteCommunication() {} - -bool ZygoteCommunication::SendMessage(const base::Pickle& data, - const std::vector* fds) { - DCHECK(control_fd_.is_valid()); - CHECK(data.size() <= kZygoteMaxMessageLength) - << "Trying to send too-large message to zygote (sending " << data.size() - << " bytes, max is " << kZygoteMaxMessageLength << ")"; - CHECK(!fds || fds->size() <= base::UnixDomainSocket::kMaxFileDescriptors) - << "Trying to send message with too many file descriptors to zygote " - << "(sending " << fds->size() << ", max is " - << base::UnixDomainSocket::kMaxFileDescriptors << ")"; - - return base::UnixDomainSocket::SendMsg(control_fd_.get(), data.data(), - data.size(), - fds ? *fds : std::vector()); -} - -ssize_t ZygoteCommunication::ReadSandboxStatus() { - DCHECK(control_fd_.is_valid()); - // At startup we send a kZygoteCommandGetSandboxStatus request to the zygote, - // but don't wait for the reply. Thus, the first time that we read from the - // zygote, we get the reply to that request. - ssize_t bytes_read = HANDLE_EINTR( - read(control_fd_.get(), &sandbox_status_, sizeof(sandbox_status_))); - if (bytes_read != sizeof(sandbox_status_)) { - return -1; - } - return bytes_read; -} - -ssize_t ZygoteCommunication::ReadReply(void* buf, size_t buf_len) { - DCHECK(control_fd_.is_valid()); - if (!have_read_sandbox_status_word_) { - if (ReadSandboxStatus() == -1) { - return -1; - } - have_read_sandbox_status_word_ = true; - base::UmaHistogramSparse("Linux.SandboxStatus", sandbox_status_); - } - - return HANDLE_EINTR(read(control_fd_.get(), buf, buf_len)); -} - -pid_t ZygoteCommunication::ForkRequest( - const std::vector& argv, - const base::FileHandleMappingVector& mapping, - const std::string& process_type) { - DCHECK(init_); - - base::Pickle pickle; - int raw_socks[2]; - PCHECK(0 == socketpair(AF_UNIX, SOCK_SEQPACKET, 0, raw_socks)); - base::ScopedFD my_sock(raw_socks[0]); - base::ScopedFD peer_sock(raw_socks[1]); - CHECK(base::UnixDomainSocket::EnableReceiveProcessId(my_sock.get())); - - pickle.WriteInt(kZygoteCommandFork); - pickle.WriteString(process_type); - pickle.WriteInt(argv.size()); - for (std::vector::const_iterator i = argv.begin(); - i != argv.end(); ++i) - pickle.WriteString(*i); - if (process_type == switches::kRendererProcess) { - std::unique_ptr timezone(icu::TimeZone::createDefault()); - icu::UnicodeString timezone_id; - pickle.WriteString16( - base::i18n::UnicodeStringToString16(timezone->getID(timezone_id))); - } - - // Fork requests contain one file descriptor for the PID oracle, and one - // more for each file descriptor mapping for the child process. - const size_t num_fds_to_send = 1 + mapping.size(); - pickle.WriteInt(num_fds_to_send); - - std::vector fds; - - // First FD to send is peer_sock. - // TODO(morrita): Ideally, this should be part of the mapping so that - // PosixFileDescriptorInfo can manages its lifetime. - fds.push_back(peer_sock.get()); - - // The rest come from mapping. - for (const auto& item : mapping) { - fds.push_back(item.first); - pickle.WriteUInt32(item.second); - } - - // Sanity check that we've populated |fds| correctly. - DCHECK_EQ(num_fds_to_send, fds.size()); - - pid_t pid; - { - base::AutoLock lock(control_lock_); - if (!SendMessage(pickle, &fds)) - return base::kNullProcessHandle; - peer_sock.reset(); - - { - char buf[sizeof(kZygoteChildPingMessage) + 1]; - std::vector recv_fds; - base::ProcessId real_pid; - - ssize_t n = base::UnixDomainSocket::RecvMsgWithPid( - my_sock.get(), buf, sizeof(buf), &recv_fds, &real_pid); - if (n != sizeof(kZygoteChildPingMessage) || - 0 != memcmp(buf, kZygoteChildPingMessage, - sizeof(kZygoteChildPingMessage))) { - // Zygote children should still be trustworthy when they're supposed to - // ping us, so something's broken if we don't receive a valid ping. - LOG(ERROR) << "Did not receive ping from zygote child"; - NOTREACHED(); - real_pid = -1; - } - my_sock.reset(); - - // Always send PID back to zygote. - base::Pickle pid_pickle; - pid_pickle.WriteInt(kZygoteCommandForkRealPID); - pid_pickle.WriteInt(real_pid); - if (!SendMessage(pid_pickle, nullptr)) - return base::kNullProcessHandle; - } - - // Read the reply, which pickles the PID and an optional UMA enumeration. - static const unsigned kMaxReplyLength = 2048; - char buf[kMaxReplyLength]; - const ssize_t len = ReadReply(buf, sizeof(buf)); - - base::Pickle reply_pickle(buf, len); - base::PickleIterator iter(reply_pickle); - if (len <= 0 || !iter.ReadInt(&pid)) - return base::kNullProcessHandle; - - // If there is a nonempty UMA name string, then there is a UMA - // enumeration to record. - std::string uma_name; - int uma_sample; - int uma_boundary_value; - if (iter.ReadString(&uma_name) && !uma_name.empty() && - iter.ReadInt(&uma_sample) && iter.ReadInt(&uma_boundary_value)) { - // We cannot use the UMA_HISTOGRAM_ENUMERATION macro here, - // because that's only for when the name is the same every time. - // Here we're using whatever name we got from the other side. - // But since it's likely that the same one will be used repeatedly - // (even though it's not guaranteed), we cache it here. - static base::HistogramBase* uma_histogram; - if (!uma_histogram || uma_histogram->histogram_name() != uma_name) { - uma_histogram = base::LinearHistogram::FactoryGet( - uma_name, 1, uma_boundary_value, uma_boundary_value + 1, - base::HistogramBase::kUmaTargetedHistogramFlag); - } - uma_histogram->Add(uma_sample); - } - - if (pid <= 0) - return base::kNullProcessHandle; - } - - ZygoteChildBorn(pid); - return pid; -} - -void ZygoteCommunication::EnsureProcessTerminated(pid_t process) { - DCHECK(init_); - base::Pickle pickle; - - pickle.WriteInt(kZygoteCommandReap); - pickle.WriteInt(process); - if (!SendMessage(pickle, nullptr)) - LOG(ERROR) << "Failed to send Reap message to zygote"; - ZygoteChildDied(process); -} - -void ZygoteCommunication::ZygoteChildBorn(pid_t process) { - base::AutoLock lock(child_tracking_lock_); - bool new_element_inserted = - list_of_running_zygote_children_.insert(process).second; - DCHECK(new_element_inserted); -} - -void ZygoteCommunication::ZygoteChildDied(pid_t process) { - base::AutoLock lock(child_tracking_lock_); - size_t num_erased = list_of_running_zygote_children_.erase(process); - DCHECK_EQ(1U, num_erased); -} - -void ZygoteCommunication::Init( - base::OnceCallback launcher) { - CHECK(!init_); - - base::FilePath chrome_path; - CHECK(PathService::Get(base::FILE_EXE, &chrome_path)); - - base::CommandLine cmd_line(chrome_path); - cmd_line.AppendSwitchASCII(switches::kProcessType, switches::kZygoteProcess); - - const base::CommandLine& browser_command_line = - *base::CommandLine::ForCurrentProcess(); - if (browser_command_line.HasSwitch(switches::kZygoteCmdPrefix)) { - cmd_line.PrependWrapper( - browser_command_line.GetSwitchValueNative(switches::kZygoteCmdPrefix)); - } - // Append any switches from the service manager that need to be forwarded on - // to the zygote/renderers. - static const char* const kForwardSwitches[] = { - service_manager::switches::kAllowSandboxDebugging, - service_manager::switches::kDisableInProcessStackTraces, - service_manager::switches::kDisableSeccompFilterSandbox, - service_manager::switches::kNoSandbox, - }; - cmd_line.CopySwitchesFrom(browser_command_line, kForwardSwitches, - arraysize(kForwardSwitches)); - - pid_ = std::move(launcher).Run(&cmd_line, &control_fd_); - - base::Pickle pickle; - pickle.WriteInt(kZygoteCommandGetSandboxStatus); - if (!SendMessage(pickle, nullptr)) - LOG(FATAL) << "Cannot communicate with zygote"; - - init_ = true; -} - -base::TerminationStatus ZygoteCommunication::GetTerminationStatus( - base::ProcessHandle handle, - bool known_dead, - int* exit_code) { - DCHECK(init_); - base::Pickle pickle; - pickle.WriteInt(kZygoteCommandGetTerminationStatus); - pickle.WriteBool(known_dead); - pickle.WriteInt(handle); - - static const unsigned kMaxMessageLength = 128; - char buf[kMaxMessageLength]; - ssize_t len; - { - base::AutoLock lock(control_lock_); - if (!SendMessage(pickle, nullptr)) - LOG(ERROR) << "Failed to send GetTerminationStatus message to zygote"; - len = ReadReply(buf, sizeof(buf)); - } - - // Set this now to handle the error cases. - if (exit_code) - *exit_code = RESULT_CODE_NORMAL_EXIT; - int status = base::TERMINATION_STATUS_NORMAL_TERMINATION; - - if (len == -1) { - LOG(WARNING) << "Error reading message from zygote: " << errno; - } else if (len == 0) { - LOG(WARNING) << "Socket closed prematurely."; - } else { - base::Pickle read_pickle(buf, len); - int tmp_status, tmp_exit_code; - base::PickleIterator iter(read_pickle); - if (!iter.ReadInt(&tmp_status) || !iter.ReadInt(&tmp_exit_code)) { - LOG(WARNING) - << "Error parsing GetTerminationStatus response from zygote."; - } else { - if (exit_code) - *exit_code = tmp_exit_code; - status = tmp_status; - } - } - - if (status != base::TERMINATION_STATUS_STILL_RUNNING) { - ZygoteChildDied(handle); - } - return static_cast(status); -} - -int ZygoteCommunication::GetSandboxStatus() { - if (have_read_sandbox_status_word_) { - return sandbox_status_; - } - if (ReadSandboxStatus() == -1) { - return 0; - } - have_read_sandbox_status_word_ = true; - base::UmaHistogramSparse("Linux.SandboxStatus", sandbox_status_); - 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 diff --git a/content/browser/zygote_host/zygote_communication_linux.h b/content/browser/zygote_host/zygote_communication_linux.h deleted file mode 100644 index 3a7051d..0000000 --- a/content/browser/zygote_host/zygote_communication_linux.h +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_ZYGOTE_HOST_ZYGOTE_COMMUNICATION_LINUX_H_ -#define CONTENT_BROWSER_ZYGOTE_HOST_ZYGOTE_COMMUNICATION_LINUX_H_ - -#include -#include -#include -#include - -#include - -#include "base/callback.h" -#include "base/files/scoped_file.h" -#include "base/process/kill.h" -#include "base/process/launch.h" -#include "base/process/process_handle.h" -#include "base/synchronization/lock.h" -#include "content/common/content_export.h" - -namespace base { -class Pickle; -} // namespace base - -namespace content { - -// Handles interprocess communication with the Linux zygote process. The zygote -// does not use standard Chrome IPC or mojo, see: -// https://chromium.googlesource.com/chromium/src/+/master/docs/linux_sandbox_ipc.md -class CONTENT_EXPORT ZygoteCommunication { - public: - ZygoteCommunication(); - ~ZygoteCommunication(); - - void Init( - base::OnceCallback launcher); - - // Tries to start a process of type indicated by process_type. - // Returns its pid on success, otherwise base::kNullProcessHandle; - pid_t ForkRequest(const std::vector& command_line, - const base::FileHandleMappingVector& mapping, - const std::string& process_type); - - void EnsureProcessTerminated(pid_t process); - - // Should be called every time a Zygote child died. - void ZygoteChildDied(pid_t process); - - // Get the termination status (and, optionally, the exit code) of - // the process. |exit_code| is set to the exit code of the child - // process. (|exit_code| may be NULL.) - // Unfortunately the Zygote can not accurately figure out if a process - // is already dead without waiting synchronously for it. - // |known_dead| should be set to true when we already know that the process - // is dead. When |known_dead| is false, processes could be seen as - // still running, even when they're not. When |known_dead| is true, the - // process will be SIGKILL-ed first (which should have no effect if it was - // really dead). This is to prevent a waiting waitpid() from blocking in - // a single-threaded Zygote. See crbug.com/157458. - base::TerminationStatus GetTerminationStatus(base::ProcessHandle handle, - bool known_dead, - int* exit_code); - - // 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); - - // Read the reply from the zygote. - ssize_t ReadReply(void* buf, size_t buf_len); - - // Sends |data| to the zygote via |control_fd_|. If |fds| is non-NULL, the - // included file descriptors will also be passed. The caller is responsible - // for acquiring |control_lock_|. - bool SendMessage(const base::Pickle& data, const std::vector* fds); - - // Get the sandbox status from the zygote. - ssize_t ReadSandboxStatus(); - - base::ScopedFD control_fd_; // the socket to the zygote. - // A lock protecting all communication with the zygote. This lock must be - // acquired before sending a command and released after the result has been - // received. - base::Lock control_lock_; - // The pid of the zygote. - pid_t pid_; - // The list of running zygote children. - std::set list_of_running_zygote_children_; - // The lock to guard the list of running zygote children. - base::Lock child_tracking_lock_; - int sandbox_status_; - bool have_read_sandbox_status_word_; - // Set to true when the zygote is initialized successfully. - bool init_; -}; - -} // namespace content - -#endif // CONTENT_BROWSER_ZYGOTE_HOST_ZYGOTE_COMMUNICATION_LINUX_H_ diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 25c9b73b..4094ed2 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn @@ -420,11 +420,7 @@ source_set("common") { if (is_tizen) { set_sources_assignment_filter([]) - sources += [ - "common_sandbox_support_linux.cc", - "font_config_ipc_linux.cc", - "send_zygote_child_ping_linux.cc", - ] + sources += [ "common_sandbox_support_linux.cc" ] set_sources_assignment_filter(sources_assignment_filter) } diff --git a/content/common/zygote_commands_linux.h b/content/common/zygote_commands_linux.h deleted file mode 100644 index 225e6f3..0000000 --- a/content/common/zygote_commands_linux.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_COMMON_ZYGOTE_COMMANDS_LINUX_H_ -#define CONTENT_COMMON_ZYGOTE_COMMANDS_LINUX_H_ - -#include - -#include "base/posix/global_descriptors.h" - -namespace content { - -// Contents of the initial message sent from the zygote to the browser right -// after it starts. -static const char kZygoteBootMessage[] = "ZYGOTE_BOOT"; - -// Contents of the initial message sent from the zygote to the browser when it -// is ready to go. -static const char kZygoteHelloMessage[] = "ZYGOTE_OK"; - -// Message sent by zygote children to the browser so the browser can discover -// the sending child's process ID. -static const char kZygoteChildPingMessage[] = "CHILD_PING"; - -// Maximum allowable length for messages sent to the zygote. -const size_t kZygoteMaxMessageLength = 8192; - -// File descriptors initialized by the Zygote Host -const int kZygoteSocketPairFd = base::GlobalDescriptors::kBaseDescriptor; - -// These are the command codes used on the wire between the browser and the -// zygote. -enum { - // Fork off a new renderer. - kZygoteCommandFork = 0, - - // Reap a renderer child. - kZygoteCommandReap = 1, - - // Check what happened to a child process. - kZygoteCommandGetTerminationStatus = 2, - - // Read a bitmask of kSandboxLinux* - kZygoteCommandGetSandboxStatus = 3, - - // 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, - -#if defined(OS_TIZEN) - // Load injected bundle library. - kZygoteCommandLoadInjectedBundle = 5, - - // Drop privilege of zygote process. - kZygoteCommandDropProcessPrivileges = 6 -#endif -}; - -} // namespace content - -#endif // CONTENT_COMMON_ZYGOTE_COMMANDS_LINUX_H_ diff --git a/content/zygote/zygote_linux.cc b/content/zygote/zygote_linux.cc deleted file mode 100644 index b1fea01..0000000 --- a/content/zygote/zygote_linux.cc +++ /dev/null @@ -1,725 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/zygote/zygote_linux.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "base/command_line.h" -#include "base/files/file_util.h" -#include "base/linux_util.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/pickle.h" -#include "base/posix/eintr_wrapper.h" -#include "base/posix/global_descriptors.h" -#include "base/posix/unix_domain_socket.h" -#include "base/process/kill.h" -#include "base/process/launch.h" -#include "base/process/process.h" -#include "base/process/process_handle.h" -#include "base/time/time.h" -#include "base/trace_event/trace_event.h" -#include "build/build_config.h" -#include "content/common/zygote_commands_linux.h" -#include "content/public/common/content_descriptors.h" -#include "content/public/common/content_switches.h" -#include "content/public/common/mojo_channel_switches.h" -#include "content/public/common/result_codes.h" -#include "content/public/common/send_zygote_child_ping_linux.h" -#include "content/public/common/zygote_fork_delegate_linux.h" -#include "ipc/ipc_channel.h" -#include "sandbox/linux/services/credentials.h" -#include "sandbox/linux/services/namespace_sandbox.h" -#include "services/service_manager/embedder/set_process_title.h" -#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 -#include -#endif - -// See https://chromium.googlesource.com/chromium/src/+/master/docs/linux_zygote.md - -namespace content { - -namespace { - -// NOP function. See below where this handler is installed. -void SIGCHLDHandler(int signal) { -} - -int LookUpFd(const base::GlobalDescriptors::Mapping& fd_mapping, uint32_t key) { - for (size_t index = 0; index < fd_mapping.size(); ++index) { - if (fd_mapping[index].key == key) - return fd_mapping[index].fd; - } - return -1; -} - -void CreatePipe(base::ScopedFD* read_pipe, base::ScopedFD* write_pipe) { - int raw_pipe[2]; - PCHECK(0 == pipe(raw_pipe)); - read_pipe->reset(raw_pipe[0]); - write_pipe->reset(raw_pipe[1]); -} - -void KillAndReap(pid_t pid, ZygoteForkDelegate* helper) { - if (helper) { - // Helper children may be forked in another PID namespace, so |pid| might - // be meaningless to us; or we just might not be able to directly send it - // signals. So we can't kill it. - // Additionally, we're not its parent, so we can't reap it anyway. - // TODO(mdempsky): Extend the ZygoteForkDelegate API to handle this. - LOG(WARNING) << "Unable to kill or reap helper children"; - return; - } - - // Kill the child process in case it's not already dead, so we can safely - // perform a blocking wait. - PCHECK(0 == kill(pid, SIGKILL)); - PCHECK(pid == HANDLE_EINTR(waitpid(pid, nullptr, 0))); -} - -} // namespace - -Zygote::Zygote(int sandbox_flags, - std::vector> helpers, - const base::GlobalDescriptors::Descriptor& ipc_backchannel) - : 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() { -#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 - // browser on it. - // A SOCK_DGRAM is installed in fd 5. This is the sandbox IPC channel. - // See https://chromium.googlesource.com/chromium/src/+/master/docs/linux_sandbox_ipc.md - - // We need to accept SIGCHLD, even though our handler is a no-op because - // otherwise we cannot wait on children. (According to POSIX 2001.) - struct sigaction action; - memset(&action, 0, sizeof(action)); - action.sa_handler = &SIGCHLDHandler; - PCHECK(sigaction(SIGCHLD, &action, nullptr) == 0); - - // Block SIGCHLD until a child might be ready to reap. - sigset_t sigset; - sigset_t orig_sigmask; - PCHECK(sigemptyset(&sigset) == 0); - PCHECK(sigaddset(&sigset, SIGCHLD) == 0); - PCHECK(sigprocmask(SIG_BLOCK, &sigset, &orig_sigmask) == 0); - - if (UsingSUIDSandbox() || UsingNSSandbox()) { - // Let the ZygoteHost know we are ready to go. - // The receiving code is in - // content/browser/zygote_host/zygote_host_impl_linux.cc. - bool r = base::UnixDomainSocket::SendMsg(kZygoteSocketPairFd, - kZygoteHelloMessage, - sizeof(kZygoteHelloMessage), - std::vector()); -#if defined(OS_CHROMEOS) - LOG_IF(WARNING, !r) << "Sending zygote magic failed"; - // Exit normally on chromeos because session manager may send SIGTERM - // right after the process starts and it may fail to send zygote magic - // number to browser process. - if (!r) - _exit(RESULT_CODE_NORMAL_EXIT); -#else - CHECK(r) << "Sending zygote magic failed"; -#endif - } - - sigset_t ppoll_sigmask = orig_sigmask; - PCHECK(sigdelset(&ppoll_sigmask, SIGCHLD) == 0); - struct pollfd pfd; - pfd.fd = kZygoteSocketPairFd; - pfd.events = POLLIN; - - struct timespec timeout; - timeout.tv_sec = 2; - timeout.tv_nsec = 0; - - for (;;) { - struct timespec* timeout_ptr = nullptr; - if (!to_reap_.empty()) - timeout_ptr = &timeout; - int rc = ppoll(&pfd, 1, timeout_ptr, &ppoll_sigmask); - PCHECK(rc >= 0 || errno == EINTR); - ReapChildren(); - - if (pfd.revents & POLLIN) { - // This function call can return multiple times, once per fork(). - if (HandleRequestFromBrowser(kZygoteSocketPairFd)) { - PCHECK(sigprocmask(SIG_SETMASK, &orig_sigmask, nullptr) == 0); - return true; - } - } - } - // The loop should not be exited unless a request was successfully processed. - NOTREACHED(); - return false; -} - -bool Zygote::ReapChild(const base::TimeTicks& now, ZygoteProcessInfo* child) { - pid_t pid = child->internal_pid; - pid_t r = HANDLE_EINTR(waitpid(pid, nullptr, WNOHANG)); - if (r > 0) { - if (r != pid) { - DLOG(ERROR) << "While waiting for " << pid << " to terminate, " - "waitpid returned " - << r; - } - return r == pid; - } - if ((now - child->time_of_reap_request).InSeconds() < 2) { - return false; - } - // If the process has been requested reaped >= 2 seconds ago, kill it. - if (!child->sent_sigkill) { - if (kill(pid, SIGKILL) != 0) - DPLOG(ERROR) << "Sending SIGKILL to process " << pid << " failed"; - - child->sent_sigkill = true; - } - return false; -} - -void Zygote::ReapChildren() { - base::TimeTicks now = base::TimeTicks::Now(); - std::vector::iterator it = to_reap_.begin(); - while (it != to_reap_.end()) { - if (ReapChild(now, &(*it))) { - it = to_reap_.erase(it); - } else { - it++; - } - } -} - -bool Zygote::GetProcessInfo(base::ProcessHandle pid, - ZygoteProcessInfo* process_info) { - DCHECK(process_info); - const ZygoteProcessMap::const_iterator it = process_info_map_.find(pid); - if (it == process_info_map_.end()) { - return false; - } - *process_info = it->second; - return true; -} - -bool Zygote::UsingSUIDSandbox() const { - return sandbox_flags_ & service_manager::SandboxLinux::kSUID; -} - -bool Zygote::UsingNSSandbox() const { - return sandbox_flags_ & service_manager::SandboxLinux::kUserNS; -} - -bool Zygote::HandleRequestFromBrowser(int fd) { - std::vector fds; - char buf[kZygoteMaxMessageLength]; - const ssize_t len = base::UnixDomainSocket::RecvMsg( - fd, buf, sizeof(buf), &fds); - - if (len == 0 || (len == -1 && errno == ECONNRESET)) { - // EOF from the browser. We should die. - // TODO(eugenis): call __sanititizer_cov_dump() here to obtain code - // coverage for the Zygote. Currently it's not possible because of - // confusion over who is responsible for closing the file descriptor. - _exit(0); - return false; - } - - if (len == -1) { - PLOG(ERROR) << "Error reading message from browser"; - return false; - } - - base::Pickle pickle(buf, len); - base::PickleIterator iter(pickle); - - int kind; - if (iter.ReadInt(&kind)) { - switch (kind) { - case kZygoteCommandFork: - // This function call can return multiple times, once per fork(). - return HandleForkRequest(fd, iter, std::move(fds)); - - case kZygoteCommandReap: - if (!fds.empty()) - break; - HandleReapRequest(fd, iter); - return false; - case kZygoteCommandGetTerminationStatus: - if (!fds.empty()) - break; - HandleGetTerminationStatus(fd, iter); - return false; - case kZygoteCommandGetSandboxStatus: - HandleGetSandboxStatus(fd, iter); - return false; - case kZygoteCommandForkRealPID: - // This shouldn't happen in practice, but some failure paths in - // HandleForkRequest (e.g., if ReadArgsAndFork fails during depickling) - // could leave this command pending on the socket. - 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; - } - } - - LOG(WARNING) << "Error parsing message from browser"; - return false; -} - -void Zygote::HandleReapRequest(int fd, base::PickleIterator iter) { - base::ProcessId child; - - if (!iter.ReadInt(&child)) { - LOG(WARNING) << "Error parsing reap request from browser"; - return; - } - - ZygoteProcessInfo child_info; - if (!GetProcessInfo(child, &child_info)) { - LOG(ERROR) << "Child not found!"; - NOTREACHED(); - return; - } - child_info.time_of_reap_request = base::TimeTicks::Now(); - - if (!child_info.started_from_helper) { - to_reap_.push_back(child_info); - } else { - // For processes from the helper, send a GetTerminationStatus request - // with known_dead set to true. - // This is not perfect, as the process may be killed instantly, but is - // better than ignoring the request. - base::TerminationStatus status; - int exit_code; - bool got_termination_status = - GetTerminationStatus(child, true /* known_dead */, &status, &exit_code); - DCHECK(got_termination_status); - } - process_info_map_.erase(child); -} - -bool Zygote::GetTerminationStatus(base::ProcessHandle real_pid, - bool known_dead, - base::TerminationStatus* status, - int* exit_code) { - - ZygoteProcessInfo child_info; - if (!GetProcessInfo(real_pid, &child_info)) { - LOG(ERROR) << "Zygote::GetTerminationStatus for unknown PID " - << real_pid; - NOTREACHED(); - return false; - } - // We know about |real_pid|. - const base::ProcessHandle child = child_info.internal_pid; - if (child_info.started_from_helper) { - if (!child_info.started_from_helper->GetTerminationStatus( - child, known_dead, status, exit_code)) { - return false; - } - } else { - // Handle the request directly. - if (known_dead) { - *status = base::GetKnownDeadTerminationStatus(child, exit_code); - } else { - // We don't know if the process is dying, so get its status but don't - // wait. - *status = base::GetTerminationStatus(child, exit_code); - } - } - // Successfully got a status for |real_pid|. - if (*status != base::TERMINATION_STATUS_STILL_RUNNING) { - // Time to forget about this process. - process_info_map_.erase(real_pid); - } - - if (WIFEXITED(*exit_code)) { - const int exit_status = WEXITSTATUS(*exit_code); - if (exit_status == sandbox::NamespaceSandbox::SignalExitCode(SIGINT) || - exit_status == sandbox::NamespaceSandbox::SignalExitCode(SIGTERM)) { - *status = base::TERMINATION_STATUS_PROCESS_WAS_KILLED; - } - } - - return true; -} - -void Zygote::HandleGetTerminationStatus(int fd, base::PickleIterator iter) { - bool known_dead; - base::ProcessHandle child_requested; - - if (!iter.ReadBool(&known_dead) || !iter.ReadInt(&child_requested)) { - LOG(WARNING) << "Error parsing GetTerminationStatus request " - << "from browser"; - return; - } - - base::TerminationStatus status; - int exit_code; - - bool got_termination_status = - GetTerminationStatus(child_requested, known_dead, &status, &exit_code); - if (!got_termination_status) { - // Assume that if we can't find the child in the sandbox, then - // it terminated normally. - NOTREACHED(); - status = base::TERMINATION_STATUS_NORMAL_TERMINATION; - exit_code = RESULT_CODE_NORMAL_EXIT; - } - - base::Pickle write_pickle; - write_pickle.WriteInt(static_cast(status)); - write_pickle.WriteInt(exit_code); - ssize_t written = - HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size())); - if (written != static_cast(write_pickle.size())) - PLOG(ERROR) << "write"; -} - -int Zygote::ForkWithRealPid(const std::string& process_type, - const base::GlobalDescriptors::Mapping& fd_mapping, - const std::string& channel_id, - base::ScopedFD pid_oracle, - std::string* uma_name, - int* uma_sample, - int* uma_boundary_value) { - ZygoteForkDelegate* helper = nullptr; - for (auto i = helpers_.begin(); i != helpers_.end(); ++i) { - if ((*i)->CanHelp(process_type, uma_name, uma_sample, uma_boundary_value)) { - helper = i->get(); - break; - } - } - - base::ScopedFD read_pipe, write_pipe; - base::ProcessId pid = 0; - if (helper) { - int mojo_channel_fd = LookUpFd(fd_mapping, kMojoIPCChannel); - if (mojo_channel_fd < 0) { - DLOG(ERROR) << "Failed to find kMojoIPCChannel in FD mapping"; - return -1; - } - std::vector fds; - fds.push_back(mojo_channel_fd); // kBrowserFDIndex - fds.push_back(pid_oracle.get()); // kPIDOracleFDIndex - pid = helper->Fork(process_type, fds, channel_id); - - // Helpers should never return in the child process. - CHECK_NE(pid, 0); - } else { - CreatePipe(&read_pipe, &write_pipe); - if (sandbox_flags_ & service_manager::SandboxLinux::kPIDNS && - sandbox_flags_ & service_manager::SandboxLinux::kUserNS) { - pid = sandbox::NamespaceSandbox::ForkInNewPidNamespace( - /*drop_capabilities_in_child=*/true); - } else { - pid = sandbox::Credentials::ForkAndDropCapabilitiesInChild(); - } - } - - if (pid == 0) { - // If the process is the init process inside a PID namespace, it must have - // explicit signal handlers. - if (getpid() == 1) { - static const int kTerminationSignals[] = { - SIGINT, SIGTERM, SIGHUP, SIGQUIT, SIGABRT, SIGPIPE, SIGUSR1, SIGUSR2}; - for (const int sig : kTerminationSignals) { - sandbox::NamespaceSandbox::InstallTerminationSignalHandler( - sig, sandbox::NamespaceSandbox::SignalExitCode(sig)); - } - } - - // In the child process. - write_pipe.reset(); - - // Ping the PID oracle socket so the browser can find our PID. - CHECK(SendZygoteChildPing(pid_oracle.get())); - - // Now read back our real PID from the zygote. - base::ProcessId real_pid; - if (!base::ReadFromFD(read_pipe.get(), - reinterpret_cast(&real_pid), - sizeof(real_pid))) { - LOG(FATAL) << "Failed to synchronise with parent zygote process"; - } - if (real_pid <= 0) { - LOG(FATAL) << "Invalid pid from parent zygote"; - } - // Sandboxed processes need to send the global, non-namespaced PID when - // setting up an IPC channel to their parent. - IPC::Channel::SetGlobalPid(real_pid); - // Force the real PID so chrome event data have a PID that corresponds - // to system trace event data. - base::trace_event::TraceLog::GetInstance()->SetProcessID( - static_cast(real_pid)); - base::InitUniqueIdForProcessInPidNamespace(real_pid); - return 0; - } - - // In the parent process. - read_pipe.reset(); - pid_oracle.reset(); - - // Always receive a real PID from the zygote host, though it might - // be invalid (see below). - base::ProcessId real_pid; - { - std::vector recv_fds; - char buf[kZygoteMaxMessageLength]; - const ssize_t len = base::UnixDomainSocket::RecvMsg( - kZygoteSocketPairFd, buf, sizeof(buf), &recv_fds); - CHECK_GT(len, 0); - CHECK(recv_fds.empty()); - - base::Pickle pickle(buf, len); - base::PickleIterator iter(pickle); - - int kind; - CHECK(iter.ReadInt(&kind)); - CHECK(kind == kZygoteCommandForkRealPID); - CHECK(iter.ReadInt(&real_pid)); - } - - // Fork failed. - if (pid < 0) { - return -1; - } - - // If we successfully forked a child, but it crashed without sending - // a message to the browser, the browser won't have found its PID. - if (real_pid < 0) { - KillAndReap(pid, helper); - return -1; - } - - // If we're not using a helper, send the PID back to the child process. - if (!helper) { - ssize_t written = - HANDLE_EINTR(write(write_pipe.get(), &real_pid, sizeof(real_pid))); - if (written != sizeof(real_pid)) { - KillAndReap(pid, helper); - return -1; - } - } - - // Now set-up this process to be tracked by the Zygote. - if (process_info_map_.find(real_pid) != process_info_map_.end()) { - LOG(ERROR) << "Already tracking PID " << real_pid; - NOTREACHED(); - } - process_info_map_[real_pid].internal_pid = pid; - process_info_map_[real_pid].started_from_helper = helper; - - return real_pid; -} - -base::ProcessId Zygote::ReadArgsAndFork(base::PickleIterator iter, - std::vector fds, - std::string* uma_name, - int* uma_sample, - int* uma_boundary_value) { - std::vector args; - int argc = 0; - int numfds = 0; - base::GlobalDescriptors::Mapping mapping; - std::string process_type; - std::string channel_id; - const std::string channel_id_prefix = std::string("--") + - switches::kServiceRequestChannelToken + - std::string("="); - - if (!iter.ReadString(&process_type)) - return -1; - if (!iter.ReadInt(&argc)) - return -1; - - for (int i = 0; i < argc; ++i) { - std::string arg; - if (!iter.ReadString(&arg)) - return -1; - args.push_back(arg); - if (arg.compare(0, channel_id_prefix.length(), channel_id_prefix) == 0) - channel_id = arg.substr(channel_id_prefix.length()); - } - - if (process_type == switches::kRendererProcess) { - // timezone_id is obtained from ICU in zygote host so that it can't be - // invalid. For an unknown reason, if an invalid ID is passed down here, - // the worst result would be that timezone would be set to Etc/Unknown. - base::string16 timezone_id; - if (!iter.ReadString16(&timezone_id)) - return -1; - icu::TimeZone::adoptDefault(icu::TimeZone::createTimeZone( - icu::UnicodeString(FALSE, timezone_id.data(), timezone_id.length()))); - } - - if (!iter.ReadInt(&numfds)) - return -1; - if (numfds != static_cast(fds.size())) - return -1; - - // First FD is the PID oracle socket. - if (fds.size() < 1) - return -1; - base::ScopedFD pid_oracle(std::move(fds[0])); - - // Remaining FDs are for the global descriptor mapping. - for (int i = 1; i < numfds; ++i) { - base::GlobalDescriptors::Key key; - if (!iter.ReadUInt32(&key)) - return -1; - mapping.push_back(base::GlobalDescriptors::Descriptor(key, fds[i].get())); - } - - mapping.push_back(ipc_backchannel_); - - // Returns twice, once per process. - base::ProcessId child_pid = - ForkWithRealPid(process_type, mapping, channel_id, std::move(pid_oracle), - uma_name, uma_sample, uma_boundary_value); - if (!child_pid) { - // This is the child process. - - // Our socket from the browser. - PCHECK(0 == IGNORE_EINTR(close(kZygoteSocketPairFd))); - - // Pass ownership of file descriptors from fds to GlobalDescriptors. - for (base::ScopedFD& fd : fds) - ignore_result(fd.release()); - base::GlobalDescriptors::GetInstance()->Reset(mapping); - - // Reset the process-wide command line to our new command line. - base::CommandLine::Reset(); - base::CommandLine::Init(0, nullptr); - base::CommandLine::ForCurrentProcess()->InitFromArgv(args); - - // Update the process title. The argv was already cached by the call to - // SetProcessTitleFromCommandLine in ChromeMain, so we can pass NULL here - // (we don't have the original argv at this point). - service_manager::SetProcessTitleFromCommandLine(nullptr); - } else if (child_pid < 0) { - LOG(ERROR) << "Zygote could not fork: process_type " << process_type - << " numfds " << numfds << " child_pid " << child_pid; - } - return child_pid; -} - -bool Zygote::HandleForkRequest(int fd, - base::PickleIterator iter, - std::vector fds) { - std::string uma_name; - int uma_sample; - int uma_boundary_value; - base::ProcessId child_pid = ReadArgsAndFork(iter, std::move(fds), &uma_name, - &uma_sample, &uma_boundary_value); - if (child_pid == 0) - return true; - // If there's no UMA report for this particular fork, then check if any - // helpers have an initial UMA report for us to send instead. - while (uma_name.empty() && initial_uma_index_ < helpers_.size()) { - helpers_[initial_uma_index_++]->InitialUMA( - &uma_name, &uma_sample, &uma_boundary_value); - } - // Must always send reply, as ZygoteHost blocks while waiting for it. - base::Pickle reply_pickle; - reply_pickle.WriteInt(child_pid); - reply_pickle.WriteString(uma_name); - if (!uma_name.empty()) { - reply_pickle.WriteInt(uma_sample); - reply_pickle.WriteInt(uma_boundary_value); - } - if (HANDLE_EINTR(write(fd, reply_pickle.data(), reply_pickle.size())) != - static_cast (reply_pickle.size())) - PLOG(ERROR) << "write"; - return false; -} - -bool Zygote::HandleGetSandboxStatus(int fd, base::PickleIterator iter) { - if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_))) != - sizeof(sandbox_flags_)) { - PLOG(ERROR) << "write"; - } - - 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( - 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 diff --git a/content/zygote/zygote_linux.h b/content/zygote/zygote_linux.h deleted file mode 100644 index c752586..0000000 --- a/content/zygote/zygote_linux.h +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_ZYGOTE_ZYGOTE_LINUX_H_ -#define CONTENT_ZYGOTE_ZYGOTE_LINUX_H_ - -#include - -#include -#include -#include - -#include "base/containers/small_map.h" -#include "base/files/scoped_file.h" -#include "base/posix/global_descriptors.h" -#include "base/process/kill.h" -#include "base/process/process.h" -#include "base/process/process_handle.h" -#include "base/time/time.h" - -namespace base { -class PickleIterator; -} - -namespace content { - -class ZygoteForkDelegate; - -// This is the object which implements the zygote. The ZygoteMain function, -// which is called from ChromeMain, simply constructs one of these objects and -// runs it. -class Zygote { - public: - Zygote(int sandbox_flags, - std::vector> helpers, - const base::GlobalDescriptors::Descriptor& ipc_backchannel); - ~Zygote(); - - bool ProcessRequests(); - - private: - struct ZygoteProcessInfo { - // Pid from inside the Zygote's PID namespace. - base::ProcessHandle internal_pid; - // Keeps track of which fork delegate helper the process was started from. - ZygoteForkDelegate* started_from_helper; - // Records when the browser requested the zygote to reap this process. - base::TimeTicks time_of_reap_request; - // Notes whether the zygote has sent SIGKILL to this process. - bool sent_sigkill; - }; - using ZygoteProcessMap = - base::small_map>; - - // Retrieve a ZygoteProcessInfo from the process_info_map_. - // Returns true and write to process_info if |pid| can be found, return - // false otherwise. - bool GetProcessInfo(base::ProcessHandle pid, ZygoteProcessInfo* process_info); - - // Returns true if the SUID sandbox is active. - bool UsingSUIDSandbox() const; - // Returns true if the NS sandbox is active. - bool UsingNSSandbox() const; - - // --------------------------------------------------------------------------- - // Requests from the browser... - - // Read and process a request from the browser. Returns true if we are in a - // new process and thus need to unwind back into ChromeMain. - bool HandleRequestFromBrowser(int fd); - - void HandleReapRequest(int fd, base::PickleIterator iter); - - // Get the termination status of |real_pid|. |real_pid| is the PID as it - // appears outside of the sandbox. - // Return true if it managed to get the termination status and return the - // status in |status| and the exit code in |exit_code|. - bool GetTerminationStatus(base::ProcessHandle real_pid, bool known_dead, - base::TerminationStatus* status, - int* exit_code); - - void HandleGetTerminationStatus(int fd, - base::PickleIterator iter); - - // This is equivalent to fork(), except that, when using the SUID sandbox, it - // returns the real PID of the child process as it appears outside the - // sandbox, rather than returning the PID inside the sandbox. The child's - // real PID is determined by having it call content::SendZygoteChildPing(int) - // using the |pid_oracle| descriptor. - // Finally, when using a ZygoteForkDelegate helper, |uma_name|, |uma_sample|, - // and |uma_boundary_value| may be set if the helper wants to make a UMA - // report via UMA_HISTOGRAM_ENUMERATION. - int ForkWithRealPid(const std::string& process_type, - const base::GlobalDescriptors::Mapping& fd_mapping, - const std::string& channel_id, - base::ScopedFD pid_oracle, - std::string* uma_name, - int* uma_sample, - int* uma_boundary_value); - - // Unpacks process type and arguments from |iter| and forks a new process. - // Returns -1 on error, otherwise returns twice, returning 0 to the child - // process and the child process ID to the parent process, like fork(). - base::ProcessId ReadArgsAndFork(base::PickleIterator iter, - std::vector fds, - std::string* uma_name, - int* uma_sample, - int* uma_boundary_value); - - // Handle a 'fork' request from the browser: this means that the browser - // wishes to start a new renderer. Returns true if we are in a new process, - // otherwise writes the child_pid back to the browser via |fd|. Writes a - // child_pid of -1 on error. - bool HandleForkRequest(int fd, - base::PickleIterator iter, - std::vector fds); - - bool HandleGetSandboxStatus(int fd, - base::PickleIterator iter); - - // Attempt to reap the child process by calling waitpid, and return - // whether successful. If the process has not terminated within - // 2 seconds of its reap request, send it SIGKILL. - bool ReapChild(const base::TimeTicks& now, ZygoteProcessInfo* child); - - // 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 - // ZygoteForkDelegate helper. - ZygoteProcessMap process_info_map_; - - const int sandbox_flags_; - std::vector> helpers_; - - // 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 to_reap_; - - // Sandbox IPC channel for renderers to invoke services from the browser. See - // https://chromium.googlesource.com/chromium/src/+/master/docs/linux_sandbox_ipc.md - base::GlobalDescriptors::Descriptor ipc_backchannel_; -}; - -} // namespace content - -#endif // CONTENT_ZYGOTE_ZYGOTE_LINUX_H_ diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc deleted file mode 100644 index 8bf29f2..0000000 --- a/content/zygote/zygote_main_linux.cc +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/zygote/zygote_main.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/compiler_specific.h" -#include "base/memory/protected_memory.h" -#include "base/memory/protected_memory_cfi.h" -#include "base/posix/eintr_wrapper.h" -#include "base/posix/unix_domain_socket.h" -#include "base/rand_util.h" -#include "base/strings/safe_sprintf.h" -#include "base/strings/string_number_conversions.h" -#include "base/sys_info.h" -#include "build/build_config.h" -#include "content/common/zygote_commands_linux.h" -#include "content/public/common/common_sandbox_support_linux.h" -#include "content/public/common/content_descriptors.h" -#include "content/public/common/content_switches.h" -#include "content/public/common/zygote_fork_delegate_linux.h" -#include "content/zygote/zygote_linux.h" -#include "sandbox/linux/services/credentials.h" -#include "sandbox/linux/services/init_process_reaper.h" -#include "sandbox/linux/services/libc_interceptor.h" -#include "sandbox/linux/services/namespace_sandbox.h" -#include "sandbox/linux/services/thread_helpers.h" -#include "sandbox/linux/suid/client/setuid_sandbox_client.h" -#include "services/service_manager/sandbox/linux/sandbox_debug_handling_linux.h" -#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" - -namespace content { - -namespace { - -void CloseFds(const std::vector& fds) { - for (const auto& it : fds) { - PCHECK(0 == IGNORE_EINTR(close(it))); - } -} - -base::OnceClosure ClosureFromTwoClosures(base::OnceClosure one, - base::OnceClosure two) { - return base::BindOnce( - [](base::OnceClosure one, base::OnceClosure two) { - if (!one.is_null()) - std::move(one).Run(); - if (!two.is_null()) - std::move(two).Run(); - }, - std::move(one), std::move(two)); -} - -} // namespace - -// This function triggers the static and lazy construction of objects that need -// to be created before imposing the sandbox. -static void ZygotePreSandboxInit() { - base::RandUint64(); - - base::SysInfo::AmountOfPhysicalMemory(); - base::SysInfo::NumberOfProcessors(); - - // ICU DateFormat class (used in base/time_format.cc) needs to get the - // Olson timezone ID by accessing the zoneinfo files on disk. After - // TimeZone::createDefault is called once here, the timezone ID is - // cached and there's no more need to access the file system. - std::unique_ptr zone(icu::TimeZone::createDefault()); -} - -static bool CreateInitProcessReaper( - base::OnceClosure post_fork_parent_callback) { - // The current process becomes init(1), this function returns from a - // newly created process. - if (!sandbox::CreateInitProcessReaper(std::move(post_fork_parent_callback))) { - LOG(ERROR) << "Error creating an init process to reap zombies"; - return false; - } - return true; -} - -// Enter the setuid sandbox. This requires the current process to have been -// created through the setuid sandbox. -static bool EnterSuidSandbox(sandbox::SetuidSandboxClient* setuid_sandbox, - base::OnceClosure post_fork_parent_callback) { - DCHECK(setuid_sandbox); - DCHECK(setuid_sandbox->IsSuidSandboxChild()); - - // Use the SUID sandbox. This still allows the seccomp sandbox to - // be enabled by the process later. - - if (!setuid_sandbox->IsSuidSandboxUpToDate()) { - LOG(WARNING) << - "You are using a wrong version of the setuid binary!\n" - "Please read " - "https://chromium.googlesource.com/chromium/src/+/master/docs/linux_suid_sandbox_development.md." - "\n\n"; - } - - if (!setuid_sandbox->ChrootMe()) - return false; - - if (setuid_sandbox->IsInNewPIDNamespace()) { - CHECK_EQ(1, getpid()) - << "The SUID sandbox created a new PID namespace but Zygote " - "is not the init process. Please, make sure the SUID " - "binary is up to date."; - } - - if (getpid() == 1) { - // The setuid sandbox has created a new PID namespace and we need - // to assume the role of init. - CHECK(CreateInitProcessReaper(std::move(post_fork_parent_callback))); - } - - CHECK(service_manager::SandboxDebugHandling::SetDumpableStatusAndHandlers()); - return true; -} - -static void DropAllCapabilities(int proc_fd) { - CHECK(sandbox::Credentials::DropAllCapabilities(proc_fd)); -} - -static void EnterNamespaceSandbox(service_manager::SandboxLinux* linux_sandbox, - base::OnceClosure post_fork_parent_callback) { - linux_sandbox->EngageNamespaceSandbox(true /* from_zygote */); - if (getpid() == 1) { - CHECK(CreateInitProcessReaper(ClosureFromTwoClosures( - base::BindOnce(DropAllCapabilities, linux_sandbox->proc_fd()), - std::move(post_fork_parent_callback)))); - } -} - -static void EnterLayerOneSandbox(service_manager::SandboxLinux* linux_sandbox, - const bool using_layer1_sandbox, - base::OnceClosure post_fork_parent_callback) { - DCHECK(linux_sandbox); - - ZygotePreSandboxInit(); - -// Check that the pre-sandbox initialization didn't spawn threads. -// It's not just our code which may do so - some system-installed libraries -// are known to be culprits, e.g. lttng. -#if !defined(THREAD_SANITIZER) -#if defined(OS_TIZEN) - // TODO: Check why IsSingleThreaded() returns false for tizen port. - DCHECK(sandbox::ThreadHelpers::IsSingleThreaded()); -#else - CHECK(sandbox::ThreadHelpers::IsSingleThreaded()); -#endif -#endif - - sandbox::SetuidSandboxClient* setuid_sandbox = - linux_sandbox->setuid_sandbox_client(); - if (setuid_sandbox->IsSuidSandboxChild()) { - CHECK( - EnterSuidSandbox(setuid_sandbox, std::move(post_fork_parent_callback))) - << "Failed to enter setuid sandbox"; - } else if (sandbox::NamespaceSandbox::InNewUserNamespace()) { - EnterNamespaceSandbox(linux_sandbox, std::move(post_fork_parent_callback)); - } else { - CHECK(!using_layer1_sandbox); - } -} - -bool ZygoteMain( - std::vector> fork_delegates) { - sandbox::SetAmZygoteOrRenderer(true, GetSandboxFD()); - - auto* linux_sandbox = service_manager::SandboxLinux::GetInstance(); - - // Skip pre-initializing sandbox under --no-sandbox for crbug.com/444900. - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kNoSandbox)) { - // This will pre-initialize the various sandboxes that need it. - linux_sandbox->PreinitializeSandbox(); - } - - const bool using_setuid_sandbox = - linux_sandbox->setuid_sandbox_client()->IsSuidSandboxChild(); - const bool using_namespace_sandbox = - sandbox::NamespaceSandbox::InNewUserNamespace(); - const bool using_layer1_sandbox = - using_setuid_sandbox || using_namespace_sandbox; - - if (using_setuid_sandbox) { - linux_sandbox->setuid_sandbox_client()->CloseDummyFile(); - } - - if (using_layer1_sandbox) { - // Let the ZygoteHost know we're booting up. - if (!base::UnixDomainSocket::SendMsg( - kZygoteSocketPairFd, kZygoteBootMessage, sizeof(kZygoteBootMessage), - std::vector())) { - // This is not a CHECK failure because the browser process could either - // crash or quickly exit while the zygote is starting. In either case a - // zygote crash is not useful. http://crbug.com/692227 - PLOG(ERROR) << "Failed sending zygote boot message"; - _exit(1); - } - } - - VLOG(1) << "ZygoteMain: initializing " << fork_delegates.size() - << " fork delegates"; - for (const auto& fork_delegate : fork_delegates) { - fork_delegate->Init(GetSandboxFD(), using_layer1_sandbox); - } - - // Turn on the first layer of the sandbox if the configuration warrants it. - EnterLayerOneSandbox( - linux_sandbox, using_layer1_sandbox, - base::BindOnce(CloseFds, linux_sandbox->GetFileDescriptorsToClose())); - - const int sandbox_flags = linux_sandbox->GetStatus(); - const bool setuid_sandbox_engaged = - !!(sandbox_flags & service_manager::SandboxLinux::kSUID); - CHECK_EQ(using_setuid_sandbox, setuid_sandbox_engaged); - - const bool namespace_sandbox_engaged = - !!(sandbox_flags & service_manager::SandboxLinux::kUserNS); - CHECK_EQ(using_namespace_sandbox, namespace_sandbox_engaged); - - Zygote zygote(sandbox_flags, std::move(fork_delegates), - base::GlobalDescriptors::Descriptor( - static_cast(kSandboxIPCChannel), GetSandboxFD())); - - // This function call can return multiple times, once per fork(). - return zygote.ProcessRequests(); -} - -} // namespace content diff --git a/net/tools/transport_security_state_generator/BUILD.gn b/net/tools/transport_security_state_generator/BUILD.gn index 9c80262..5b5ce475 100644 --- a/net/tools/transport_security_state_generator/BUILD.gn +++ b/net/tools/transport_security_state_generator/BUILD.gn @@ -55,4 +55,7 @@ executable("transport_security_state_generator") { "//crypto", "//third_party/boringssl", ] + if (is_tizen) { + libs = [ "dlog" ] + } } diff --git a/services/network/network_service.cc b/services/network/network_service.cc index b1ce382..2e670e9 100644 --- a/services/network/network_service.cc +++ b/services/network/network_service.cc @@ -367,9 +367,9 @@ void NetworkService::UpdateSignedTreeHead(const net::ct::SignedTreeHead& sth) { sth_distributor_->NewSTHObserved(sth); } -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(USE_EFL) void NetworkService::SetCryptConfig(mojom::CryptConfigPtr crypt_config) { -#if !defined(IS_CHROMECAST) && !defined(USE_EFL) +#if !defined(IS_CHROMECAST) auto config = std::make_unique(); config->store = crypt_config->store; config->product_name = crypt_config->product_name; diff --git a/services/network/network_service.h b/services/network/network_service.h index 839a5da..fc6e3a0 100644 --- a/services/network/network_service.h +++ b/services/network/network_service.h @@ -133,7 +133,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkService void GetTotalNetworkUsages( mojom::NetworkService::GetTotalNetworkUsagesCallback callback) override; void UpdateSignedTreeHead(const net::ct::SignedTreeHead& sth) override; -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(USE_EFL) void SetCryptConfig(mojom::CryptConfigPtr crypt_config) override; #endif diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn index e9d7bfe..ec66b89 100644 --- a/services/network/public/mojom/BUILD.gn +++ b/services/network/public/mojom/BUILD.gn @@ -124,7 +124,7 @@ mojom("mojom") { # This is only needed on desktop linux, but the defines make this difficult # because IS_CHROMECAST is not available in build/build_config.h. - if (is_linux && !is_chromeos) { + if (is_linux && !is_chromeos && !use_efl) { enabled_features = [ "needs_crypt_config" ] } } diff --git a/services/service_manager/zygote/common/zygote_commands_linux.h b/services/service_manager/zygote/common/zygote_commands_linux.h index 12b7212..8374818 100644 --- a/services/service_manager/zygote/common/zygote_commands_linux.h +++ b/services/service_manager/zygote/common/zygote_commands_linux.h @@ -46,7 +46,15 @@ enum { // 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 service_manager diff --git a/services/service_manager/zygote/host/zygote_communication_linux.cc b/services/service_manager/zygote/host/zygote_communication_linux.cc index 204fa4b..2bb55a4 100644 --- a/services/service_manager/zygote/host/zygote_communication_linux.cc +++ b/services/service_manager/zygote/host/zygote_communication_linux.cc @@ -317,4 +317,28 @@ int ZygoteCommunication::GetSandboxStatus() { 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 service_manager diff --git a/services/service_manager/zygote/host/zygote_communication_linux.h b/services/service_manager/zygote/host/zygote_communication_linux.h index a1b0ab0..19ce9f6 100644 --- a/services/service_manager/zygote/host/zygote_communication_linux.h +++ b/services/service_manager/zygote/host/zygote_communication_linux.h @@ -66,6 +66,11 @@ class COMPONENT_EXPORT(SERVICE_MANAGER_ZYGOTE) ZygoteCommunication { // 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); diff --git a/services/service_manager/zygote/zygote_linux.cc b/services/service_manager/zygote/zygote_linux.cc index 3252818..a9c11e5 100644 --- a/services/service_manager/zygote/zygote_linux.cc +++ b/services/service_manager/zygote/zygote_linux.cc @@ -46,6 +46,11 @@ #include "services/service_manager/zygote/common/zygote_fork_delegate_linux.h" #include "third_party/icu/source/i18n/unicode/timezone.h" +#if defined(OS_TIZEN) +#include +#include +#endif + // See // https://chromium.googlesource.com/chromium/src/+/master/docs/linux_zygote.md @@ -96,10 +101,19 @@ Zygote::Zygote(int sandbox_flags, : 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) {} + 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 diff --git a/services/service_manager/zygote/zygote_linux.h b/services/service_manager/zygote/zygote_linux.h index 9f85db7..153840b 100644 --- a/services/service_manager/zygote/zygote_linux.h +++ b/services/service_manager/zygote/zygote_linux.h @@ -127,6 +127,22 @@ class Zygote { // 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 @@ -139,6 +155,12 @@ class Zygote { // 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 to_reap_; diff --git a/services/service_manager/zygote/zygote_main_linux.cc b/services/service_manager/zygote/zygote_main_linux.cc index a007170..a836623 100644 --- a/services/service_manager/zygote/zygote_main_linux.cc +++ b/services/service_manager/zygote/zygote_main_linux.cc @@ -160,8 +160,13 @@ static void EnterLayerOneSandbox(service_manager::SandboxLinux* linux_sandbox, // It's not just our code which may do so - some system-installed libraries // are known to be culprits, e.g. lttng. #if !defined(THREAD_SANITIZER) +#if defined(OS_TIZEN) + // TODO: Check why IsSingleThreaded() returns false for tizen port. + DCHECK(sandbox::ThreadHelpers::IsSingleThreaded()); +#else CHECK(sandbox::ThreadHelpers::IsSingleThreaded()); #endif +#endif sandbox::SetuidSandboxClient* setuid_sandbox = linux_sandbox->setuid_sandbox_client(); diff --git a/third_party/skia/third_party/skcms/src/Transform_inl.h b/third_party/skia/third_party/skcms/src/Transform_inl.h index 09183bf..3f91155 100644 --- a/third_party/skia/third_party/skcms/src/Transform_inl.h +++ b/third_party/skia/third_party/skcms/src/Transform_inl.h @@ -442,10 +442,12 @@ SI ATTR F NS(F_from_U8_)(U8 v) { #define F_from_U8 NS(F_from_U8_) SI ATTR F NS(F_from_U16_BE_)(U16 v) { +#if !defined(EWK_BRINGUP) // All 16-bit ICC values are big-endian, so we byte swap before converting to float. // MSVC catches the "loss" of data here in the portable path, so we also make sure to mask. v = (U16)( ((v<<8)|(v>>8)) & 0xffff ); return CAST(F, v) * (1/65535.0f); +#endif } #define F_from_U16_BE NS(F_from_U16_BE_) diff --git a/tizen_src/build/config/compiler/BUILD.gn b/tizen_src/build/config/compiler/BUILD.gn index b1e649d..2892de6 100644 --- a/tizen_src/build/config/compiler/BUILD.gn +++ b/tizen_src/build/config/compiler/BUILD.gn @@ -125,6 +125,7 @@ config("tizen_default_include_dirs") { "$deps_lib_path/dbus-1.0/include", "$deps_lib_path/gstreamer-1.0/include", "$deps_lib_path/gstreamer-1.0/include/gst", + "//third_party/perfetto/include", ] } } diff --git a/tizen_src/ewk/efl_integration/eweb_context.cc b/tizen_src/ewk/efl_integration/eweb_context.cc index 79ccb0e..f660031d 100644 --- a/tizen_src/ewk/efl_integration/eweb_context.cc +++ b/tizen_src/ewk/efl_integration/eweb_context.cc @@ -13,7 +13,6 @@ #include "base/synchronization/waitable_event.h" #include "components/autofill/content/browser/content_autofill_driver.h" -//#include "content/browser/memory/memory_pressure_controller_impl.h" #include "browser/favicon/favicon_database.h" #include "browser/webdata/web_data_service_factory.h" #include "content/public/browser/appcache_service.h" @@ -49,11 +48,11 @@ #if defined(OS_TIZEN) #include "base/command_line.h" #include "common/content_switches_efl.h" -#include "content/browser/zygote_host/zygote_communication_linux.h" #include "content/common/content_client_export.h" #include "content/public/common/content_switches.h" -#include "content/public/common/zygote_handle.h" #include "content_browser_client_efl.h" +#include "services/service_manager/zygote/common/zygote_handle.h" +#include "services/service_manager/zygote/host/zygote_communication_linux.h" #endif using content::BrowserThread; @@ -252,13 +251,13 @@ void EWebContext::SetWidgetInfo(const std::string& tizen_app_id, // Drop process privillages while web app is launching // from WRT process pool. It should be handled in webengine side // in product tv profile because this profile uses the zygote process. - content::GetGenericZygote()->DropProcessPrivileges(tizen_app_id_); + service_manager::GetGenericZygote()->DropProcessPrivileges(tizen_app_id_); #endif // OS_TIZEN_TV_PRODUCT } else { // Drop process privillages while web app is launching // from WRT process pool. It is not necessary in single process mode, // because it is handled in crosswalk side in single process mode. - content::GetGenericZygote()->DropProcessPrivileges(tizen_app_id_); + service_manager::GetGenericZygote()->DropProcessPrivileges(tizen_app_id_); } #endif // OS_TIZEN } @@ -360,8 +359,8 @@ EWebContext::EWebContext(bool incognito, const std::string& injectedBundlePath) } } else { // Preload injected bundle on zygote process for process pool. - content::GetGenericZygote() - ->LoadInjectedBundlePath(injected_bundle_path_); + service_manager::GetGenericZygote()->LoadInjectedBundlePath( + injected_bundle_path_); } } #endif diff --git a/tools/variations/fieldtrial_to_struct.py b/tools/variations/fieldtrial_to_struct.py index 91a6ffa..3719d7c 100755 --- a/tools/variations/fieldtrial_to_struct.py +++ b/tools/variations/fieldtrial_to_struct.py @@ -30,6 +30,7 @@ _platforms = [ 'linux', 'mac', 'windows', + 'tizen', ] # Convert a platform argument to the matching Platform enum value in diff --git a/ui/gfx/gpu_fence.cc b/ui/gfx/gpu_fence.cc index 7d38c0e..aa44623 100644 --- a/ui/gfx/gpu_fence.cc +++ b/ui/gfx/gpu_fence.cc @@ -6,7 +6,7 @@ #include "base/logging.h" -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if (defined(OS_LINUX) || defined(OS_ANDROID)) && !defined(OS_TIZEN) #include #endif @@ -60,7 +60,7 @@ void GpuFence::Wait() { case GpuFenceHandleType::kEmpty: break; case GpuFenceHandleType::kAndroidNativeFenceSync: -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if (defined(OS_LINUX) || defined(OS_ANDROID)) && !defined(OS_TIZEN) static const int kInfiniteSyncWaitTimeout = -1; DCHECK_GE(owned_fd_.get(), 0); if (sync_wait(owned_fd_.get(), kInfiniteSyncWaitTimeout) < 0) { -- 2.7.4