macOS: Add support for and enable the V2 sandbox (issue #2459)

The CEF_USE_SANDBOX define is now used on all platforms.
This commit is contained in:
Marshall Greenblatt 2018-07-27 17:28:12 -04:00
parent fcad76b405
commit dec98a5534
25 changed files with 461 additions and 108 deletions

View File

@ -1028,6 +1028,15 @@ if (is_win) {
} }
} }
if (is_mac) {
static_library("cef_sandbox") {
sources = [ "libcef_dll/sandbox/sandbox_mac.mm" ]
# CEF sources use include paths relative to the CEF root directory.
include_dirs = [ "." ]
deps = [ "//sandbox/mac:seatbelt" ]
}
}
# #
# Service manifests. # Service manifests.
@ -1568,6 +1577,7 @@ if (is_mac) {
sources = invoker.helper_sources sources = invoker.helper_sources
deps = [ deps = [
":cef_sandbox",
":libcef_dll_wrapper", ":libcef_dll_wrapper",
] ]
if (defined(invoker.helper_deps)) { if (defined(invoker.helper_deps)) {
@ -1582,6 +1592,10 @@ if (is_mac) {
] ]
info_plist_target = ":${app_name}_helper_plist" info_plist_target = ":${app_name}_helper_plist"
if (defined(invoker.helper_defines)) {
defines = invoker.helper_defines
}
} }
bundle_data("${app_name}_framework_bundle_data") { bundle_data("${app_name}_framework_bundle_data") {
@ -1628,6 +1642,10 @@ if (is_mac) {
libs = invoker.libs libs = invoker.libs
} }
if (defined(invoker.defines)) {
defines = invoker.defines
}
info_plist_target = ":${app_name}_plist" info_plist_target = ":${app_name}_plist"
} }
} }
@ -1687,6 +1705,9 @@ if (is_mac) {
helper_deps = [ helper_deps = [
":libcef_dll_wrapper", ":libcef_dll_wrapper",
] ]
helper_defines = [
"CEF_USE_SANDBOX",
]
info_plist = "tests/cefclient/resources/mac/Info.plist" info_plist = "tests/cefclient/resources/mac/Info.plist"
sources = gypi_paths2.includes_mac + sources = gypi_paths2.includes_mac +
@ -1710,6 +1731,9 @@ if (is_mac) {
"AppKit.framework", "AppKit.framework",
"OpenGL.framework", "OpenGL.framework",
] ]
defines = [
"CEF_USE_SANDBOX",
]
} }
@ -1755,6 +1779,9 @@ if (is_mac) {
helper_deps = [ helper_deps = [
":libcef_dll_wrapper", ":libcef_dll_wrapper",
] ]
helper_defines = [
"CEF_USE_SANDBOX",
]
info_plist = "tests/cefsimple/mac/Info.plist" info_plist = "tests/cefsimple/mac/Info.plist"
sources = gypi_paths2.includes_mac + sources = gypi_paths2.includes_mac +
@ -1769,6 +1796,9 @@ if (is_mac) {
":cefsimple_xibs", ":cefsimple_xibs",
":libcef_dll_wrapper", ":libcef_dll_wrapper",
] ]
defines = [
"CEF_USE_SANDBOX",
]
} }
@ -1816,6 +1846,9 @@ if (is_mac) {
":libcef_dll_wrapper", ":libcef_dll_wrapper",
"//testing/gtest", "//testing/gtest",
] ]
helper_defines = [
"CEF_USE_SANDBOX",
]
info_plist = "tests/ceftests/resources/mac/Info.plist" info_plist = "tests/ceftests/resources/mac/Info.plist"
sources = gypi_paths2.includes_mac + sources = gypi_paths2.includes_mac +
@ -1837,6 +1870,9 @@ if (is_mac) {
libs = [ libs = [
"AppKit.framework", "AppKit.framework",
] ]
defines = [
"CEF_USE_SANDBOX",
]
} }
} else { } else {
# #
@ -1893,6 +1929,10 @@ if (is_mac) {
":libcef_dll_wrapper", ":libcef_dll_wrapper",
] ]
defines = [
"CEF_USE_SANDBOX",
]
if (is_win) { if (is_win) {
sources += gypi_paths2.includes_win + sources += gypi_paths2.includes_win +
gypi_paths2.shared_sources_win + gypi_paths2.shared_sources_win +
@ -1902,9 +1942,8 @@ if (is_mac) {
configs -= [ "//build/config/win:console" ] configs -= [ "//build/config/win:console" ]
configs += [ "//build/config/win:windowed" ] configs += [ "//build/config/win:windowed" ]
defines = [ defines += [
"CEF_USE_ATL", "CEF_USE_ATL",
"CEF_USE_SANDBOX",
] ]
deps += [ deps += [
@ -1966,6 +2005,10 @@ if (is_mac) {
":libcef_dll_wrapper", ":libcef_dll_wrapper",
] ]
defines = [
"CEF_USE_SANDBOX",
]
if (is_win) { if (is_win) {
sources += gypi_paths2.includes_win + sources += gypi_paths2.includes_win +
gypi_paths2.cefsimple_sources_win gypi_paths2.cefsimple_sources_win
@ -1974,10 +2017,6 @@ if (is_mac) {
configs -= [ "//build/config/win:console" ] configs -= [ "//build/config/win:console" ]
configs += [ "//build/config/win:windowed" ] configs += [ "//build/config/win:windowed" ]
defines = [
"CEF_USE_SANDBOX",
]
deps += [ deps += [
":cef_sandbox", ":cef_sandbox",
"//build/win:default_exe_manifest", "//build/win:default_exe_manifest",
@ -2035,14 +2074,14 @@ if (is_mac) {
"//testing/gtest", "//testing/gtest",
] ]
defines = [
"CEF_USE_SANDBOX",
]
if (is_win) { if (is_win) {
sources += gypi_paths2.shared_sources_win + sources += gypi_paths2.shared_sources_win +
gypi_paths2.ceftests_sources_win gypi_paths2.ceftests_sources_win
defines = [
"CEF_USE_SANDBOX",
]
deps += [ deps += [
":cef_sandbox", ":cef_sandbox",
"//build/win:default_exe_manifest", "//build/win:default_exe_manifest",

View File

@ -79,6 +79,7 @@
'include/base/internal/cef_atomicops_atomicword_compat.h', 'include/base/internal/cef_atomicops_atomicword_compat.h',
'include/base/internal/cef_atomicops_mac.h', 'include/base/internal/cef_atomicops_mac.h',
'include/cef_application_mac.h', 'include/cef_application_mac.h',
'include/cef_sandbox_mac.h',
'include/internal/cef_mac.h', 'include/internal/cef_mac.h',
'include/internal/cef_types_mac.h', 'include/internal/cef_types_mac.h',
], ],

View File

@ -31,10 +31,11 @@ macro(PRINT_CEF_CONFIG)
endif() endif()
if(OS_WINDOWS) if(OS_WINDOWS)
message(STATUS "CEF Windows sandbox: ${USE_SANDBOX}")
message(STATUS "Visual Studio ATL support: ${USE_ATL}") message(STATUS "Visual Studio ATL support: ${USE_ATL}")
endif() endif()
message(STATUS "CEF sandbox: ${USE_SANDBOX}")
set(_libraries ${CEF_STANDARD_LIBS}) set(_libraries ${CEF_STANDARD_LIBS})
if(OS_WINDOWS AND USE_SANDBOX) if(OS_WINDOWS AND USE_SANDBOX)
list(APPEND _libraries ${CEF_SANDBOX_STANDARD_LIBS}) list(APPEND _libraries ${CEF_SANDBOX_STANDARD_LIBS})

View File

@ -66,6 +66,10 @@ list(APPEND CEF_COMPILER_DEFINES
) )
# Configure use of the sandbox.
option(USE_SANDBOX "Enable or disable use of the sandbox." ON)
# #
# Linux configuration. # Linux configuration.
# #
@ -217,6 +221,12 @@ if(OS_LINUX)
icudtl.dat icudtl.dat
locales locales
) )
if(USE_SANDBOX)
list(APPEND CEF_COMPILER_DEFINES
CEF_USE_SANDBOX # Used by apps to test if the sandbox is enabled
)
endif()
endif() endif()
@ -313,6 +323,16 @@ if(OS_MACOSX)
set(CEF_BINARY_DIR "${_CEF_ROOT}/$<CONFIGURATION>") set(CEF_BINARY_DIR "${_CEF_ROOT}/$<CONFIGURATION>")
set(CEF_BINARY_DIR_DEBUG "${_CEF_ROOT}/Debug") set(CEF_BINARY_DIR_DEBUG "${_CEF_ROOT}/Debug")
set(CEF_BINARY_DIR_RELEASE "${_CEF_ROOT}/Release") set(CEF_BINARY_DIR_RELEASE "${_CEF_ROOT}/Release")
if(USE_SANDBOX)
list(APPEND CEF_COMPILER_DEFINES
CEF_USE_SANDBOX # Used by apps to test if the sandbox is enabled
)
# CEF sandbox library paths.
set(CEF_SANDBOX_LIB_DEBUG "${CEF_BINARY_DIR_DEBUG}/cef_sandbox.a")
set(CEF_SANDBOX_LIB_RELEASE "${CEF_BINARY_DIR_RELEASE}/cef_sandbox.a")
endif()
endif() endif()
@ -329,8 +349,6 @@ if(OS_WINDOWS)
set(CMAKE_CXX_FLAGS_RELEASE "") set(CMAKE_CXX_FLAGS_RELEASE "")
endif() endif()
# Configure use of the sandbox.
option(USE_SANDBOX "Enable or disable use of the sandbox." ON)
if(USE_SANDBOX) if(USE_SANDBOX)
# Check if the current MSVC version is compatible with the cef_sandbox.lib # Check if the current MSVC version is compatible with the cef_sandbox.lib
# static library. For a list of all version numbers see # static library. For a list of all version numbers see

87
include/cef_sandbox_mac.h Normal file
View File

@ -0,0 +1,87 @@
// Copyright (c) 2018 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CEF_INCLUDE_CEF_SANDBOX_MAC_H_
#define CEF_INCLUDE_CEF_SANDBOX_MAC_H_
#pragma once
#include "include/base/cef_build.h"
#if defined(OS_MACOSX)
#ifdef __cplusplus
extern "C" {
#endif
// The sandbox is used to restrict sub-processes (renderer, plugin, GPU, etc)
// from directly accessing system resources. This helps to protect the user
// from untrusted and potentially malicious Web content.
// See http://www.chromium.org/developers/design-documents/sandbox for
// complete details.
//
// To enable the sandbox on macOS the following requirements must be met:
// 1. Link the helper process executable with the cef_sandbox static library.
// 2. Call the cef_sandbox_initialize() function at the beginning of the
// helper executable main() function and before loading the CEF framework
// library. See include/wrapper/cef_library_loader.h for example usage.
///
// Initialize the sandbox for this process. Returns the sandbox context
// handle on success or NULL on failure. The returned handle should be
// passed to cef_sandbox_destroy() immediately before process termination.
///
void* cef_sandbox_initialize(int argc, char** argv);
///
// Destroy the specified sandbox context handle.
///
void cef_sandbox_destroy(void* sandbox_context);
#ifdef __cplusplus
}
///
// Scoped helper for managing the life span of a sandbox context handle.
///
class CefScopedSandboxContext {
public:
CefScopedSandboxContext();
~CefScopedSandboxContext();
// Load the sandbox for this process. Returns true on success.
bool Initialize(int argc, char** argv);
private:
void* sandbox_context_;
};
#endif // __cplusplus
#endif // defined(OS_MACOSX)
#endif // CEF_INCLUDE_CEF_SANDBOX_MAC_H_

View File

@ -66,22 +66,34 @@ int cef_unload_library();
// //
// Example usage in the main process: // Example usage in the main process:
// //
// #include "include/wrapper/cef_library_loader.h"
//
// int main(int argc, char* argv[]) { // int main(int argc, char* argv[]) {
// // Dynamically load the CEF framework library.
// CefScopedLibraryLoader library_loader; // CefScopedLibraryLoader library_loader;
// if (!library_loader.LoadInMain()) // if (!library_loader.LoadInMain())
// return 1; // return 1;
// //
// // Rest of the function here... // // Continue with CEF initialization...
// } // }
// //
// Example usage in the helper process: // Example usage in the helper process:
// //
// #include "include/cef_sandbox_mac.h"
// #include "include/wrapper/cef_library_loader.h"
//
// int main(int argc, char* argv[]) { // int main(int argc, char* argv[]) {
// // Initialize the macOS sandbox for this helper process.
// CefScopedSandboxContext sandbox_context;
// if (!sandbox_context.Initialize(argc, argv))
// return 1;
//
// // Dynamically load the CEF framework library.
// CefScopedLibraryLoader library_loader; // CefScopedLibraryLoader library_loader;
// if (!library_loader.LoadInHelper()) // if (!library_loader.LoadInHelper())
// return 1; // return 1;
// //
// // Rest of the function here... // // Continue with CEF initialization...
// } // }
/// ///
class CefScopedLibraryLoader { class CefScopedLibraryLoader {

View File

@ -98,6 +98,20 @@ void OverrideFrameworkBundlePath() {
base::mac::SetOverrideFrameworkBundlePath(framework_path); base::mac::SetOverrideFrameworkBundlePath(framework_path);
} }
void OverrideOuterBundlePath() {
base::FilePath bundle_path = util_mac::GetMainBundlePath();
DCHECK(!bundle_path.empty());
base::mac::SetOverrideOuterBundlePath(bundle_path);
}
void OverrideBaseBundleID() {
std::string bundle_id = util_mac::GetMainBundleID();
DCHECK(!bundle_id.empty());
base::mac::SetBaseBundleID(bundle_id.c_str());
}
void OverrideChildProcessPath() { void OverrideChildProcessPath() {
base::FilePath child_process_path = base::FilePath child_process_path =
base::CommandLine::ForCurrentProcess()->GetSwitchValuePath( base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
@ -436,29 +450,6 @@ bool CefMainDelegate::BasicStartupComplete(int* exit_code) {
switches::kUncaughtExceptionStackSize, switches::kUncaughtExceptionStackSize,
base::IntToString(settings.uncaught_exception_stack_size)); base::IntToString(settings.uncaught_exception_stack_size));
} }
#if defined(OS_MACOSX)
std::vector<std::string> disable_features;
// TODO: Remove once MacV2Sandbox is supported. See issue #2459.
if (features::kMacV2Sandbox.default_state ==
base::FEATURE_ENABLED_BY_DEFAULT) {
disable_features.push_back(features::kMacV2Sandbox.name);
}
if (!disable_features.empty()) {
DCHECK(!base::FeatureList::GetInstance());
std::string disable_features_str =
command_line->GetSwitchValueASCII(switches::kDisableFeatures);
for (auto feature_str : disable_features) {
if (!disable_features_str.empty())
disable_features_str += ",";
disable_features_str += feature_str;
}
command_line->AppendSwitchASCII(switches::kDisableFeatures,
disable_features_str);
}
#endif // defined(OS_MACOSX)
} }
if (content_client_.application().get()) { if (content_client_.application().get()) {
@ -517,6 +508,8 @@ bool CefMainDelegate::BasicStartupComplete(int* exit_code) {
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
OverrideFrameworkBundlePath(); OverrideFrameworkBundlePath();
OverrideOuterBundlePath();
OverrideBaseBundleID();
#endif #endif
return false; return false;

View File

@ -6,6 +6,8 @@
#define CEF_LIBCEF_COMMON_UTIL_MAC_H_ #define CEF_LIBCEF_COMMON_UTIL_MAC_H_
#pragma once #pragma once
#include <string>
namespace base { namespace base {
class FilePath; class FilePath;
} }
@ -31,6 +33,13 @@ base::FilePath GetFrameworkResourcesDirectory();
// "myapp.app/Contents/MacOS/myapp"). // "myapp.app/Contents/MacOS/myapp").
base::FilePath GetMainProcessPath(); base::FilePath GetMainProcessPath();
// Returns the path to the top-level app bundle that contains the main process
// executable (e.g. "myapp.app").
base::FilePath GetMainBundlePath();
// Returns the identifier for the top-level app bundle.
std::string GetMainBundleID();
// Returns the path to the Resources directory inside the top-level app bundle // Returns the path to the Resources directory inside the top-level app bundle
// (e.g. "myapp.app/Contents/Resources"). May return an empty value if not // (e.g. "myapp.app/Contents/Resources"). May return an empty value if not
// running in an app bundle. // running in an app bundle.

View File

@ -9,19 +9,15 @@
#include "base/base_paths.h" #include "base/base_paths.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h" #include "base/mac/foundation_util.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/strings/sys_string_conversions.h"
namespace util_mac { namespace util_mac {
namespace { namespace {
// Returns the path to the top-level app bundle that contains the main process
// executable.
base::FilePath GetMainBundlePath() {
return base::mac::GetAppBundlePath(GetMainProcessPath());
}
// Returns the path to the Frameworks directory inside the top-level app bundle. // Returns the path to the Frameworks directory inside the top-level app bundle.
base::FilePath GetFrameworksPath() { base::FilePath GetFrameworksPath() {
base::FilePath bundle_path = GetMainBundlePath(); base::FilePath bundle_path = GetMainBundlePath();
@ -68,6 +64,15 @@ base::FilePath GetMainProcessPath() {
return path; return path;
} }
base::FilePath GetMainBundlePath() {
return base::mac::GetAppBundlePath(GetMainProcessPath());
}
std::string GetMainBundleID() {
NSBundle* bundle = base::mac::OuterBundle();
return base::SysNSStringToUTF8([bundle bundleIdentifier]);
}
base::FilePath GetMainResourcesDirectory() { base::FilePath GetMainResourcesDirectory() {
base::FilePath bundle_path = GetMainBundlePath(); base::FilePath bundle_path = GetMainBundlePath();
if (bundle_path.empty()) if (bundle_path.empty())

View File

@ -0,0 +1,65 @@
// Copyright 2018 The Chromium Embedded Framework Authors. Portions Copyright
// 2018 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 <mach-o/dyld.h>
#include <stdio.h>
#include <memory>
#include "sandbox/mac/seatbelt_exec.h"
#include "include/cef_sandbox_mac.h"
void* cef_sandbox_initialize(int argc, char** argv) {
uint32_t exec_path_size = 0;
int rv = _NSGetExecutablePath(NULL, &exec_path_size);
if (rv != -1) {
return NULL;
}
std::unique_ptr<char[]> exec_path(new char[exec_path_size]);
rv = _NSGetExecutablePath(exec_path.get(), &exec_path_size);
if (rv != 0) {
return NULL;
}
sandbox::SeatbeltExecServer::CreateFromArgumentsResult seatbelt =
sandbox::SeatbeltExecServer::CreateFromArguments(exec_path.get(), argc,
argv);
if (seatbelt.sandbox_required) {
if (!seatbelt.server) {
fprintf(stderr, "Failed to create the seatbelt sandbox server.\n");
return NULL;
}
if (!seatbelt.server->InitializeSandbox()) {
fprintf(stderr, "Failed to initialize the sandbox.\n");
return NULL;
}
}
auto* copy = new sandbox::SeatbeltExecServer::CreateFromArgumentsResult();
copy->sandbox_required = seatbelt.sandbox_required;
copy->server.swap(seatbelt.server);
return copy;
}
void cef_sandbox_destroy(void* sandbox_context) {
delete static_cast<sandbox::SeatbeltExecServer::CreateFromArgumentsResult*>(
sandbox_context);
}
CefScopedSandboxContext::CefScopedSandboxContext() : sandbox_context_(NULL) {}
CefScopedSandboxContext::~CefScopedSandboxContext() {
if (sandbox_context_) {
cef_sandbox_destroy(sandbox_context_);
}
}
bool CefScopedSandboxContext::Initialize(int argc, char** argv) {
if (sandbox_context_)
return false;
sandbox_context_ = cef_sandbox_initialize(argc, argv);
return !!sandbox_context_;
}

View File

@ -186,6 +186,12 @@ if(OS_MACOSX)
OUTPUT_NAME ${CEF_HELPER_OUTPUT_NAME} OUTPUT_NAME ${CEF_HELPER_OUTPUT_NAME}
) )
if(USE_SANDBOX)
# Logical target used to link the cef_sandbox library.
ADD_LOGICAL_TARGET("cef_sandbox_lib" "${CEF_SANDBOX_LIB_DEBUG}" "${CEF_SANDBOX_LIB_RELEASE}")
target_link_libraries(${CEF_HELPER_TARGET} cef_sandbox_lib)
endif()
# Main executable target. # Main executable target.
add_executable(${CEF_TARGET} MACOSX_BUNDLE ${CEFCLIENT_RESOURCES_SRCS} ${CEFCLIENT_SRCS}) add_executable(${CEF_TARGET} MACOSX_BUNDLE ${CEFCLIENT_RESOURCES_SRCS} ${CEFCLIENT_SRCS})
SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_TARGET}) SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_TARGET})

View File

@ -87,6 +87,13 @@ int RunMain(int argc, char* argv[]) {
CefSettings settings; CefSettings settings;
// When generating projects with CMake the CEF_USE_SANDBOX value will be defined
// automatically. Pass -DUSE_SANDBOX=OFF to the CMake command-line to disable
// use of the sandbox.
#if !defined(CEF_USE_SANDBOX)
settings.no_sandbox = true;
#endif
// Populate the settings based on command line arguments. // Populate the settings based on command line arguments.
context->PopulateSettings(&settings); context->PopulateSettings(&settings);

View File

@ -368,6 +368,13 @@ int RunMain(int argc, char* argv[]) {
CefSettings settings; CefSettings settings;
// When generating projects with CMake the CEF_USE_SANDBOX value will be defined
// automatically. Pass -DUSE_SANDBOX=OFF to the CMake command-line to disable
// use of the sandbox.
#if !defined(CEF_USE_SANDBOX)
settings.no_sandbox = true;
#endif
// Populate the settings based on command line arguments. // Populate the settings based on command line arguments.
context->PopulateSettings(&settings); context->PopulateSettings(&settings);

View File

@ -25,8 +25,8 @@
// #define CEF_USE_SANDBOX 1 // #define CEF_USE_SANDBOX 1
#if defined(CEF_USE_SANDBOX) #if defined(CEF_USE_SANDBOX)
// The cef_sandbox.lib static library is currently built with VS2015. It may not // The cef_sandbox.lib static library may not link successfully with all VS
// link successfully with other VS versions. // versions.
#pragma comment(lib, "cef_sandbox.lib") #pragma comment(lib, "cef_sandbox.lib")
#endif #endif

View File

@ -101,6 +101,12 @@ if(OS_MACOSX)
OUTPUT_NAME ${CEF_HELPER_OUTPUT_NAME} OUTPUT_NAME ${CEF_HELPER_OUTPUT_NAME}
) )
if(USE_SANDBOX)
# Logical target used to link the cef_sandbox library.
ADD_LOGICAL_TARGET("cef_sandbox_lib" "${CEF_SANDBOX_LIB_DEBUG}" "${CEF_SANDBOX_LIB_RELEASE}")
target_link_libraries(${CEF_HELPER_TARGET} cef_sandbox_lib)
endif()
# Main executable target. # Main executable target.
add_executable(${CEF_TARGET} MACOSX_BUNDLE ${CEFSIMPLE_RESOURCES_SRCS} ${CEFSIMPLE_SRCS}) add_executable(${CEF_TARGET} MACOSX_BUNDLE ${CEFSIMPLE_RESOURCES_SRCS} ${CEFSIMPLE_SRCS})
SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_TARGET}) SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_TARGET})

View File

@ -49,6 +49,13 @@ int main(int argc, char* argv[]) {
// Specify CEF global settings here. // Specify CEF global settings here.
CefSettings settings; CefSettings settings;
// When generating projects with CMake the CEF_USE_SANDBOX value will be defined
// automatically. Pass -DUSE_SANDBOX=OFF to the CMake command-line to disable
// use of the sandbox.
#if !defined(CEF_USE_SANDBOX)
settings.no_sandbox = true;
#endif
// SimpleApp implements application-level callbacks for the browser process. // SimpleApp implements application-level callbacks for the browser process.
// It will create the first browser instance in OnContextInitialized() after // It will create the first browser instance in OnContextInitialized() after
// CEF has initialized. // CEF has initialized.

View File

@ -128,6 +128,13 @@ int main(int argc, char* argv[]) {
// Specify CEF global settings here. // Specify CEF global settings here.
CefSettings settings; CefSettings settings;
// When generating projects with CMake the CEF_USE_SANDBOX value will be defined
// automatically. Pass -DUSE_SANDBOX=OFF to the CMake command-line to disable
// use of the sandbox.
#if !defined(CEF_USE_SANDBOX)
settings.no_sandbox = true;
#endif
// SimpleApp implements application-level callbacks for the browser process. // SimpleApp implements application-level callbacks for the browser process.
// It will create the first browser instance in OnContextInitialized() after // It will create the first browser instance in OnContextInitialized() after
// CEF has initialized. // CEF has initialized.

View File

@ -14,8 +14,8 @@
// #define CEF_USE_SANDBOX 1 // #define CEF_USE_SANDBOX 1
#if defined(CEF_USE_SANDBOX) #if defined(CEF_USE_SANDBOX)
// The cef_sandbox.lib static library is currently built with VS2013. It may not // The cef_sandbox.lib static library may not link successfully with all VS
// link successfully with other VS versions. // versions.
#pragma comment(lib, "cef_sandbox.lib") #pragma comment(lib, "cef_sandbox.lib")
#endif #endif

View File

@ -5,8 +5,22 @@
#include "include/cef_app.h" #include "include/cef_app.h"
#include "include/wrapper/cef_library_loader.h" #include "include/wrapper/cef_library_loader.h"
// When generating projects with CMake the CEF_USE_SANDBOX value will be defined
// automatically. Pass -DUSE_SANDBOX=OFF to the CMake command-line to disable
// use of the sandbox.
#if defined(CEF_USE_SANDBOX)
#include "include/cef_sandbox_mac.h"
#endif
// Entry point function for sub-processes. // Entry point function for sub-processes.
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
#if defined(CEF_USE_SANDBOX)
// Initialize the macOS sandbox for this helper process.
CefScopedSandboxContext sandbox_context;
if (!sandbox_context.Initialize(argc, argv))
return 1;
#endif
// Load the CEF framework library at runtime instead of linking directly // Load the CEF framework library at runtime instead of linking directly
// as required by the macOS sandbox implementation. // as required by the macOS sandbox implementation.
CefScopedLibraryLoader library_loader; CefScopedLibraryLoader library_loader;

View File

@ -121,6 +121,12 @@ if(OS_MACOSX)
OUTPUT_NAME ${CEF_HELPER_OUTPUT_NAME} OUTPUT_NAME ${CEF_HELPER_OUTPUT_NAME}
) )
if(USE_SANDBOX)
# Logical target used to link the cef_sandbox library.
ADD_LOGICAL_TARGET("cef_sandbox_lib" "${CEF_SANDBOX_LIB_DEBUG}" "${CEF_SANDBOX_LIB_RELEASE}")
target_link_libraries(${CEF_HELPER_TARGET} cef_sandbox_lib)
endif()
# Main executable target. # Main executable target.
add_executable(${CEF_TARGET} MACOSX_BUNDLE ${UNITTESTS_RESOURCES_SRCS} ${UNITTESTS_SRCS}) add_executable(${CEF_TARGET} MACOSX_BUNDLE ${UNITTESTS_RESOURCES_SRCS} ${UNITTESTS_SRCS})
SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_TARGET}) SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_TARGET})

View File

@ -33,8 +33,15 @@
#include "include/wrapper/cef_library_loader.h" #include "include/wrapper/cef_library_loader.h"
#endif #endif
#if defined(OS_WIN) // When generating projects with CMake the CEF_USE_SANDBOX value will be defined
// automatically if using the required compiler version. Pass -DUSE_SANDBOX=OFF
// to the CMake command-line to disable use of the sandbox.
#if defined(OS_WIN) && defined(CEF_USE_SANDBOX)
#include "include/cef_sandbox_win.h" #include "include/cef_sandbox_win.h"
// The cef_sandbox.lib static library may not link successfully with all VS
// versions.
#pragma comment(lib, "cef_sandbox.lib")
#endif #endif
namespace { namespace {
@ -121,7 +128,7 @@ int main(int argc, char* argv[]) {
void* windows_sandbox_info = NULL; void* windows_sandbox_info = NULL;
#if defined(OS_WIN) #if defined(OS_WIN) && defined(CEF_USE_SANDBOX)
// Manages the life span of the sandbox information object. // Manages the life span of the sandbox information object.
CefScopedSandboxInfo scoped_sandbox; CefScopedSandboxInfo scoped_sandbox;
windows_sandbox_info = scoped_sandbox.sandbox_info(); windows_sandbox_info = scoped_sandbox.sandbox_info();
@ -153,6 +160,11 @@ int main(int argc, char* argv[]) {
#endif #endif
CefSettings settings; CefSettings settings;
#if !defined(CEF_USE_SANDBOX)
settings.no_sandbox = true;
#endif
test_suite.GetSettings(settings); test_suite.GetSettings(settings);
#if defined(OS_MACOSX) #if defined(OS_MACOSX)

View File

@ -3,14 +3,28 @@
// be found in the LICENSE file. // be found in the LICENSE file.
#include "include/cef_app.h" #include "include/cef_app.h"
#import "include/wrapper/cef_library_loader.h" #include "include/wrapper/cef_library_loader.h"
#include "tests/shared/common/client_app_other.h" #include "tests/shared/common/client_app_other.h"
#include "tests/shared/renderer/client_app_renderer.h" #include "tests/shared/renderer/client_app_renderer.h"
// When generating projects with CMake the CEF_USE_SANDBOX value will be defined
// automatically. Pass -DUSE_SANDBOX=OFF to the CMake command-line to disable
// use of the sandbox.
#if defined(CEF_USE_SANDBOX)
#include "include/cef_sandbox_mac.h"
#endif
namespace client { namespace client {
int RunMain(int argc, char* argv[]) { int RunMain(int argc, char* argv[]) {
#if defined(CEF_USE_SANDBOX)
// Initialize the macOS sandbox for this helper process.
CefScopedSandboxContext sandbox_context;
if (!sandbox_context.Initialize(argc, argv))
return 1;
#endif
// Load the CEF framework library at runtime instead of linking directly // Load the CEF framework library at runtime instead of linking directly
// as required by the macOS sandbox implementation. // as required by the macOS sandbox implementation.
CefScopedLibraryLoader library_loader; CefScopedLibraryLoader library_loader;

View File

@ -1002,11 +1002,6 @@ if options.clientdistrib or options.clientdistribonly:
parser.print_help(sys.stderr) parser.print_help(sys.stderr)
sys.exit() sys.exit()
if platform != 'windows' and (options.sandboxdistrib or
options.sandboxdistribonly):
print 'The sandbox distribution is only supported on Windows.'
sys.exit()
# CEF branch. # CEF branch.
if options.branch != 'trunk' and not options.branch.isdigit(): if options.branch != 'trunk' and not options.branch.isdigit():
print 'Invalid branch value: %s' % (options.branch) print 'Invalid branch value: %s' % (options.branch)
@ -1033,6 +1028,9 @@ branch_is_newer_than_2785 = (cef_branch == 'trunk' or int(cef_branch) > 2785)
# True if the requested branch is 3029 or older. # True if the requested branch is 3029 or older.
branch_is_3029_or_older = (cef_branch != 'trunk' and int(cef_branch) <= 3029) branch_is_3029_or_older = (cef_branch != 'trunk' and int(cef_branch) <= 3029)
# True if the requested branch is newer than 3497.
branch_is_newer_than_3497 = (cef_branch == 'trunk' or int(cef_branch) > 3497)
# Enable GN by default for branches newer than 2785. # Enable GN by default for branches newer than 2785.
if branch_is_newer_than_2785 and not 'CEF_USE_GN' in os.environ.keys(): if branch_is_newer_than_2785 and not 'CEF_USE_GN' in os.environ.keys():
os.environ['CEF_USE_GN'] = '1' os.environ['CEF_USE_GN'] = '1'
@ -1082,6 +1080,16 @@ if platform == 'macosx' and not options.x64build and branch_is_2272_or_newer:
'newer. Add --x64-build flag to generate a 64-bit build.' 'newer. Add --x64-build flag to generate a 64-bit build.'
sys.exit() sys.exit()
# Platforms that build a cef_sandbox library.
sandbox_lib_platforms = ['windows']
if branch_is_newer_than_3497:
sandbox_lib_platforms.append('macosx')
if not platform in sandbox_lib_platforms and (options.sandboxdistrib or
options.sandboxdistribonly):
print 'The sandbox distribution is not supported on this platform.'
sys.exit()
# Options that force the sources to change. # Options that force the sources to change.
force_change = options.forceclean or options.forceupdate force_change = options.forceclean or options.forceupdate
@ -1519,8 +1527,8 @@ if not options.nobuild and (chromium_checkout_changed or \
os.path.join(download_dir, 'build-%s-debug.log' % (cef_branch)) \ os.path.join(download_dir, 'build-%s-debug.log' % (cef_branch)) \
if options.buildlogfile else None) if options.buildlogfile else None)
if use_gn and platform == 'windows': if use_gn and platform in sandbox_lib_platforms:
# Make the separate cef_sandbox.lib build when GN is_official_build=true. # Make the separate cef_sandbox build when GN is_official_build=true.
build_path += '_sandbox' build_path += '_sandbox'
if os.path.exists(os.path.join(chromium_src_dir, build_path)): if os.path.exists(os.path.join(chromium_src_dir, build_path)):
args_path = os.path.join(chromium_src_dir, build_path, 'args.gn') args_path = os.path.join(chromium_src_dir, build_path, 'args.gn')
@ -1541,8 +1549,8 @@ if not options.nobuild and (chromium_checkout_changed or \
os.path.join(download_dir, 'build-%s-release.log' % (cef_branch)) \ os.path.join(download_dir, 'build-%s-release.log' % (cef_branch)) \
if options.buildlogfile else None) if options.buildlogfile else None)
if use_gn and platform == 'windows': if use_gn and platform in sandbox_lib_platforms:
# Make the separate cef_sandbox.lib build when GN is_official_build=true. # Make the separate cef_sandbox build when GN is_official_build=true.
build_path += '_sandbox' build_path += '_sandbox'
if os.path.exists(os.path.join(chromium_src_dir, build_path)): if os.path.exists(os.path.join(chromium_src_dir, build_path)):
args_path = os.path.join(chromium_src_dir, build_path, 'args.gn') args_path = os.path.join(chromium_src_dir, build_path, 'args.gn')

View File

@ -436,10 +436,9 @@ def GetConfigArgs(args, is_debug, cpu):
return result return result
def WinGetConfigArgsSandbox(args, is_debug, cpu): def GetConfigArgsSandbox(platform, args, is_debug, cpu):
""" """
Return merged GN args for the Windows cef_sandbox.lib configuration and Return merged GN args for the cef_sandbox configuration and validate.
validate.
""" """
add_args = { add_args = {
# Avoid libucrt.lib linker errors. # Avoid libucrt.lib linker errors.
@ -520,13 +519,14 @@ def GetAllPlatformConfigs(build_args):
result['Debug_GN_' + cpu] = GetConfigArgs(args, True, cpu) result['Debug_GN_' + cpu] = GetConfigArgs(args, True, cpu)
result['Release_GN_' + cpu] = GetConfigArgs(args, False, cpu) result['Release_GN_' + cpu] = GetConfigArgs(args, False, cpu)
if platform == 'windows' and GetArgValue(args, 'is_official_build'): if platform in ('windows', 'macosx') and GetArgValue(
args, 'is_official_build'):
# Build cef_sandbox.lib with a different configuration. # Build cef_sandbox.lib with a different configuration.
if create_debug: if create_debug:
result['Debug_GN_' + cpu + '_sandbox'] = WinGetConfigArgsSandbox( result['Debug_GN_' + cpu + '_sandbox'] = GetConfigArgsSandbox(
args, True, cpu) platform, args, True, cpu)
result['Release_GN_' + cpu + '_sandbox'] = WinGetConfigArgsSandbox( result['Release_GN_' + cpu + '_sandbox'] = GetConfigArgsSandbox(
args, False, cpu) platform, args, False, cpu)
return result return result

View File

@ -301,16 +301,19 @@ def copy_files_list(build_dir, dst_dir, paths):
raise Exception('Missing required path: %s' % source_path) raise Exception('Missing required path: %s' % source_path)
def combine_libs(build_dir, libs, dest_lib): def combine_libs(platform, build_dir, libs, dest_lib):
""" Combine multiple static libraries into a single static library. """ """ Combine multiple static libraries into a single static library. """
cmdline = 'msvs_env.bat win%s python combine_libs.py -o "%s"' % ( if platform == 'windows':
platform_arch, dest_lib) cmdline = 'msvs_env.bat win%s python combine_libs.py -o "%s"' % (
platform_arch, dest_lib)
else:
cmdline = 'libtool -static -o "%s"' % dest_lib
for lib in libs: for lib in libs:
lib_path = os.path.join(build_dir, lib) lib_path = os.path.join(build_dir, lib)
for path in get_files(lib_path): # Expand wildcards in |lib_path|. for path in get_files(lib_path): # Expand wildcards in |lib_path|.
if not path_exists(path): if not path_exists(path):
raise Exception('File not found: ' + path) raise Exception('File not found: ' + path)
cmdline = cmdline + ' "%s"' % path cmdline += ' "%s"' % path
run(cmdline, os.path.join(cef_dir, 'tools')) run(cmdline, os.path.join(cef_dir, 'tools'))
@ -745,7 +748,7 @@ if platform == 'windows':
if path_exists(os.path.join(src_dir, cef_sandbox_lib)): if path_exists(os.path.join(src_dir, cef_sandbox_lib)):
dst_dir = os.path.join(output_dir, dir_name) dst_dir = os.path.join(output_dir, dir_name)
make_dir(dst_dir, options.quiet) make_dir(dst_dir, options.quiet)
combine_libs(src_dir, sandbox_libs, combine_libs(platform, src_dir, sandbox_libs,
os.path.join(dst_dir, 'cef_sandbox.lib')) os.path.join(dst_dir, 'cef_sandbox.lib'))
break break
@ -849,6 +852,30 @@ elif platform == 'macosx':
framework_dsym = '%s.dSYM' % framework_name framework_dsym = '%s.dSYM' % framework_name
cefclient_app = 'cefclient.app' cefclient_app = 'cefclient.app'
cef_sandbox_lib = 'obj/cef/libcef_sandbox.a'
sandbox_libs = [
cef_sandbox_lib,
'obj/sandbox/mac/libseatbelt.a',
'obj/sandbox/mac/libseatbelt_proto.a',
'obj/third_party/protobuf/libprotobuf_lite.a',
]
# Generate the cef_sandbox.a merged library. A separate *_sandbox build
# should exist when GN is_official_build=true.
if mode in ('standard', 'minimal', 'sandbox'):
dirs = {
'Debug': (build_dir_debug + '_sandbox', build_dir_debug),
'Release': (build_dir_release + '_sandbox', build_dir_release)
}
for dir_name in dirs.keys():
for src_dir in dirs[dir_name]:
if path_exists(os.path.join(src_dir, cef_sandbox_lib)):
dst_dir = os.path.join(output_dir, dir_name)
make_dir(dst_dir, options.quiet)
combine_libs(platform, src_dir, sandbox_libs,
os.path.join(dst_dir, 'cef_sandbox.a'))
break
valid_build_dir = None valid_build_dir = None
if mode == 'standard': if mode == 'standard':
@ -879,42 +906,44 @@ elif platform == 'macosx':
else: else:
sys.stdout.write("No Debug build files.\n") sys.stdout.write("No Debug build files.\n")
# transfer Release files if mode != 'sandbox':
build_dir = build_dir_release # transfer Release files
if not options.allowpartial or path_exists( build_dir = build_dir_release
os.path.join(build_dir, cefclient_app)): if not options.allowpartial or path_exists(
valid_build_dir = build_dir os.path.join(build_dir, cefclient_app)):
dst_dir = os.path.join(output_dir, 'Release') valid_build_dir = build_dir
make_dir(dst_dir, options.quiet) dst_dir = os.path.join(output_dir, 'Release')
framework_src_dir = os.path.join( make_dir(dst_dir, options.quiet)
build_dir, '%s/Contents/Frameworks/%s.framework/Versions/A' % framework_src_dir = os.path.join(
(cefclient_app, framework_name)) build_dir, '%s/Contents/Frameworks/%s.framework/Versions/A' %
if mode != 'client': (cefclient_app, framework_name))
framework_dst_dir = os.path.join(dst_dir, '%s.framework' % framework_name) if mode != 'client':
framework_dst_dir = os.path.join(dst_dir,
'%s.framework' % framework_name)
else:
copy_dir(
os.path.join(build_dir, cefclient_app),
os.path.join(dst_dir, cefclient_app), options.quiet)
# Replace the versioned framework with an unversioned framework in the sample app.
framework_dst_dir = os.path.join(
dst_dir, '%s/Contents/Frameworks/%s.framework' % (cefclient_app,
framework_name))
remove_dir(framework_dst_dir, options.quiet)
copy_dir(framework_src_dir, framework_dst_dir, options.quiet)
if not options.nosymbols:
# create the symbol output directory
symbol_output_dir = create_output_dir(
output_dir_name + '_release_symbols', options.outputdir)
# The real dSYM already exists, just copy it to the output directory.
# dSYMs are only generated when is_official_build=true or enable_dsyms=true.
# See //build/config/mac/symbols.gni.
copy_dir(
os.path.join(build_dir, framework_dsym),
os.path.join(symbol_output_dir, framework_dsym), options.quiet)
else: else:
copy_dir( sys.stdout.write("No Release build files.\n")
os.path.join(build_dir, cefclient_app),
os.path.join(dst_dir, cefclient_app), options.quiet)
# Replace the versioned framework with an unversioned framework in the sample app.
framework_dst_dir = os.path.join(
dst_dir, '%s/Contents/Frameworks/%s.framework' % (cefclient_app,
framework_name))
remove_dir(framework_dst_dir, options.quiet)
copy_dir(framework_src_dir, framework_dst_dir, options.quiet)
if not options.nosymbols:
# create the symbol output directory
symbol_output_dir = create_output_dir(
output_dir_name + '_release_symbols', options.outputdir)
# The real dSYM already exists, just copy it to the output directory.
# dSYMs are only generated when is_official_build=true or enable_dsyms=true.
# See //build/config/mac/symbols.gni.
copy_dir(
os.path.join(build_dir, framework_dsym),
os.path.join(symbol_output_dir, framework_dsym), options.quiet)
else:
sys.stdout.write("No Release build files.\n")
if mode == 'standard' or mode == 'minimal': if mode == 'standard' or mode == 'minimal':
# transfer include files # transfer include files