macOS: Enable the MacV2Sandbox

Issue #2459 resolved
Marshall Greenblatt
created an issue

Chromium has implemented a new version of the sandbox on macOS. We need to move CEF over to the new implementation (V2) before the old implementation (V1) is deleted.

Design doc: https://chromium.googlesource.com/chromium/src/+/master/sandbox/mac/seatbelt_sandbox_design.md

Chromium tracking bug: https://crbug.com/689306

Related changes for content_shell: https://crbug.com/850735

Official response

  • Marshall Greenblatt reporter

    Client usage on macOS will change as follows in order to support the V2 sandbox:

    • Executables should no longer directly link the CEF framework library. Instead, the libcef_dll_wrapper library now supports dynamic loading of CEF framework library at runtime via CefScopedLibraryLoader (using dlopen/dlsym internally). The CMake macros for fixing rpath have been removed because this is no longer necessary with dynamic loading.
    • Helper processes should link the new cef_sandbox library and initialize the V2 sandbox in the helper process using CefScopedSandboxContext.
    • Due to dynamic loading the UnderlayOpenGLHostingWindow class which is exported by the CEF framework library must now be used as follows:
      // The CEF framework library is loaded at runtime so we need to use this
      // mechanism for retrieving the class.
      Class window_class = NSClassFromString(@"UnderlayOpenGLHostingWindow");
      CHECK(window_class);
    
      NSWindow* window = [[window_class alloc] init...];
    

    Example usage from the new include/wrapper/cef_library_loader.h header:

    // Example usage in the main process:
    //
    //   #include "include/wrapper/cef_library_loader.h"
    //
    //   int main(int argc, char* argv[]) {
    //     // Dynamically load the CEF framework library.
    //     CefScopedLibraryLoader library_loader;
    //     if (!library_loader.LoadInMain())
    //       return 1;
    //
    //     // Continue with CEF initialization...
    //   }
    //
    // 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[]) {
    //     // 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;
    //     if (!library_loader.LoadInHelper())
    //       return 1;
    //
    //     // Continue with CEF initialization...
    //   }
    

    To verify that the MacV2Sandbox is enabled you can look for the --seatbelt-client=[id] flag passed to the renderer process (using ps -ax | grep cefclient, for example).

    For a limited time the V2 sandbox can be disabled by passing the --disable-features=MacV2Sandbox command line to the main process.

Comments (8)

  1. Marshall Greenblatt reporter

    The new sandbox implementation requires use of dlopen() to load the framework dylib. This means that we'll need to provide an additional wrapper layer to dlopen/dlsym all of the global functions exported by CEF. This same wrapper can optionally be used on Linux if you want to delay load libcef.so, and on Windows you can already use /DELAYLOAD:libcef.dll.

  2. Marshall Greenblatt reporter

    Client usage on macOS will change as follows in order to support the V2 sandbox:

    • Executables should no longer directly link the CEF framework library. Instead, the libcef_dll_wrapper library now supports dynamic loading of CEF framework library at runtime via CefScopedLibraryLoader (using dlopen/dlsym internally). The CMake macros for fixing rpath have been removed because this is no longer necessary with dynamic loading.
    • Helper processes should link the new cef_sandbox library and initialize the V2 sandbox in the helper process using CefScopedSandboxContext.
    • Due to dynamic loading the UnderlayOpenGLHostingWindow class which is exported by the CEF framework library must now be used as follows:
      // The CEF framework library is loaded at runtime so we need to use this
      // mechanism for retrieving the class.
      Class window_class = NSClassFromString(@"UnderlayOpenGLHostingWindow");
      CHECK(window_class);
    
      NSWindow* window = [[window_class alloc] init...];
    

    Example usage from the new include/wrapper/cef_library_loader.h header:

    // Example usage in the main process:
    //
    //   #include "include/wrapper/cef_library_loader.h"
    //
    //   int main(int argc, char* argv[]) {
    //     // Dynamically load the CEF framework library.
    //     CefScopedLibraryLoader library_loader;
    //     if (!library_loader.LoadInMain())
    //       return 1;
    //
    //     // Continue with CEF initialization...
    //   }
    //
    // 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[]) {
    //     // 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;
    //     if (!library_loader.LoadInHelper())
    //       return 1;
    //
    //     // Continue with CEF initialization...
    //   }
    

    To verify that the MacV2Sandbox is enabled you can look for the --seatbelt-client=[id] flag passed to the renderer process (using ps -ax | grep cefclient, for example).

    For a limited time the V2 sandbox can be disabled by passing the --disable-features=MacV2Sandbox command line to the main process.

  3. Log in to comment