}
# 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
libs += [ "atomic" ]
}
+ if (is_tizen) {
+ libs += [ "pthread" ]
+ }
+
if (use_allocator_shim) {
sources += [
"allocator/allocator_shim.cc",
# 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 {
std::unique_ptr<DeviceManagementService> 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()));
'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'
"//base",
"//net/tools/huffman_trie:huffman_trie_generator_sources",
]
+ if (is_tizen) {
+ libs = [ "dlog" ]
+ }
if (is_ios) {
libs = [ "UIKit.framework" ]
}
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)
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)
}
#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"
+++ /dev/null
-// 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 <string.h>
-#include <sys/socket.h>
-
-#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<int>* 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<int>());
-}
-
-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<std::string>& 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<std::string>::const_iterator i = argv.begin();
- i != argv.end(); ++i)
- pickle.WriteString(*i);
- if (process_type == switches::kRendererProcess) {
- std::unique_ptr<icu::TimeZone> 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<int> 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<base::ScopedFD> 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<pid_t(base::CommandLine*, base::ScopedFD*)> 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<base::TerminationStatus>(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
+++ /dev/null
-// 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 <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-#include <sys/types.h>
-
-#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<pid_t(base::CommandLine*, base::ScopedFD*)> 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<std::string>& 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<int>* 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<pid_t> 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_
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)
}
+++ /dev/null
-// 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 <stddef.h>
-
-#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_
+++ /dev/null
-// 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 <errno.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#include <utility>
-
-#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 <dlfcn.h>
-#include <security-manager/security-manager.h>
-#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<std::unique_ptr<ZygoteForkDelegate>> 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<int>());
-#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<ZygoteProcessInfo>::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<base::ScopedFD> 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<int>(status));
- write_pickle.WriteInt(exit_code);
- ssize_t written =
- HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size()));
- if (written != static_cast<ssize_t>(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<int> 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<char*>(&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<int>(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<base::ScopedFD> 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<base::ScopedFD> fds,
- std::string* uma_name,
- int* uma_sample,
- int* uma_boundary_value) {
- std::vector<std::string> 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<int>(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<base::ScopedFD> 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<ssize_t> (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<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
+++ /dev/null
-// 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 <stddef.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#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<std::unique_ptr<ZygoteForkDelegate>> 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<std::map<base::ProcessHandle, ZygoteProcessInfo>>;
-
- // 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<base::ScopedFD> 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<base::ScopedFD> 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<std::unique_ptr<ZygoteForkDelegate>> 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<ZygoteProcessInfo> 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_
+++ /dev/null
-// 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 <dlfcn.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <signal.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/prctl.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <utility>
-
-#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<int>& 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<icu::TimeZone> 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<std::unique_ptr<ZygoteForkDelegate>> 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<int>())) {
- // 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<uint32_t>(kSandboxIPCChannel), GetSandboxFD()));
-
- // This function call can return multiple times, once per fork().
- return zygote.ProcessRequests();
-}
-
-} // namespace content
"//crypto",
"//third_party/boringssl",
]
+ if (is_tizen) {
+ libs = [ "dlog" ]
+ }
}
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<os_crypt::Config>();
config->store = crypt_config->store;
config->product_name = crypt_config->product_name;
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
# 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" ]
}
}
// 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
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
// 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);
#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 <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) {}
+ 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
// 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_;
// 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 =
#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_)
"$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",
]
}
}
#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"
#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;
// 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
}
}
} else {
// Preload injected bundle on zygote process for process pool.
- content::GetGenericZygote()
- ->LoadInjectedBundlePath(injected_bundle_path_);
+ service_manager::GetGenericZygote()->LoadInjectedBundlePath(
+ injected_bundle_path_);
}
}
#endif
'linux',
'mac',
'windows',
+ 'tizen',
]
# Convert a platform argument to the matching Platform enum value in
#include "base/logging.h"
-#if defined(OS_LINUX) || defined(OS_ANDROID)
+#if (defined(OS_LINUX) || defined(OS_ANDROID)) && !defined(OS_TIZEN)
#include <sync/sync.h>
#endif
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) {