Commit 49bb6911 authored by Frank Li's avatar Frank Li Committed by Commit Bot

Sandbox of Media Foundation (MF) based Content Decryption Module (Cdm)

- Added SandboxType::kMediaFoundationCdm and its corresponding sandbox
  switch of "mf_cdm" for the creation of MF Cdm LPAC Utility process.
- SandboxWin::IsAppContainerEnabledForSandbox() is updated to opt-in
  SandboxType::kMediaFoundationCdm to be created as AppContainer
  process.
- In SandboxWin::StartSandboxedProcess(), the MF Cdm is added with
  policies and LPAC capabilities to allow existing Windows platform
  compoenents to work properly.

More details can be found in this doc:
https://docs.google.com/document/d/19Y4Js5v3BlzA5uSuiVTvcvPNIOwmxcMSFJWtuc1A-w8/edit#heading=h.iqvhsrml3gl9

Bug: 999747
Change-Id: I8e0a0febb20b697c5631cf2561429305bf47b2e9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2401506
Commit-Queue: Frank Li <frankli@microsoft.com>
Reviewed-by: default avatarWill Harris <wfh@chromium.org>
Reviewed-by: default avatarAlex Gough <ajgo@chromium.org>
Reviewed-by: default avatarJames Forshaw <forshaw@chromium.org>
Reviewed-by: default avatarXiaohan Wang <xhwang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812187}
parent d6fd3a17
...@@ -3783,6 +3783,7 @@ base::string16 ChromeContentBrowserClient::GetAppContainerSidForSandboxType( ...@@ -3783,6 +3783,7 @@ base::string16 ChromeContentBrowserClient::GetAppContainerSidForSandboxType(
case sandbox::policy::SandboxType::kSharingService: case sandbox::policy::SandboxType::kSharingService:
case sandbox::policy::SandboxType::kVideoCapture: case sandbox::policy::SandboxType::kVideoCapture:
case sandbox::policy::SandboxType::kIconReader: case sandbox::policy::SandboxType::kIconReader:
case sandbox::policy::SandboxType::kMediaFoundationCdm:
// Should never reach here. // Should never reach here.
CHECK(0); CHECK(0);
return base::string16(); return base::string16();
......
...@@ -37,6 +37,7 @@ UtilitySandboxedProcessLauncherDelegate:: ...@@ -37,6 +37,7 @@ UtilitySandboxedProcessLauncherDelegate::
sandbox_type_ == sandbox::policy::SandboxType::kProxyResolver || sandbox_type_ == sandbox::policy::SandboxType::kProxyResolver ||
sandbox_type_ == sandbox::policy::SandboxType::kPdfConversion || sandbox_type_ == sandbox::policy::SandboxType::kPdfConversion ||
sandbox_type_ == sandbox::policy::SandboxType::kIconReader || sandbox_type_ == sandbox::policy::SandboxType::kIconReader ||
sandbox_type_ == sandbox::policy::SandboxType::kMediaFoundationCdm ||
#endif #endif
sandbox_type_ == sandbox::policy::SandboxType::kUtility || sandbox_type_ == sandbox::policy::SandboxType::kUtility ||
sandbox_type_ == sandbox::policy::SandboxType::kNetwork || sandbox_type_ == sandbox::policy::SandboxType::kNetwork ||
......
...@@ -74,8 +74,9 @@ bool NetworkPreSpawnTarget(sandbox::TargetPolicy* policy, ...@@ -74,8 +74,9 @@ bool NetworkPreSpawnTarget(sandbox::TargetPolicy* policy,
bool UtilitySandboxedProcessLauncherDelegate::GetAppContainerId( bool UtilitySandboxedProcessLauncherDelegate::GetAppContainerId(
std::string* appcontainer_id) { std::string* appcontainer_id) {
if (sandbox_type_ == sandbox::policy::SandboxType::kXrCompositing && if ((sandbox_type_ == sandbox::policy::SandboxType::kXrCompositing &&
base::FeatureList::IsEnabled(sandbox::policy::features::kXRSandbox)) { base::FeatureList::IsEnabled(sandbox::policy::features::kXRSandbox)) ||
sandbox_type_ == sandbox::policy::SandboxType::kMediaFoundationCdm) {
*appcontainer_id = base::WideToUTF8(cmd_line_.GetProgram().value()); *appcontainer_id = base::WideToUTF8(cmd_line_.GetProgram().value());
return true; return true;
} }
...@@ -95,6 +96,10 @@ bool UtilitySandboxedProcessLauncherDelegate::DisableDefaultPolicy() { ...@@ -95,6 +96,10 @@ bool UtilitySandboxedProcessLauncherDelegate::DisableDefaultPolicy() {
case sandbox::policy::SandboxType::kXrCompositing: case sandbox::policy::SandboxType::kXrCompositing:
return base::FeatureList::IsEnabled( return base::FeatureList::IsEnabled(
sandbox::policy::features::kXRSandbox); sandbox::policy::features::kXRSandbox);
case sandbox::policy::SandboxType::kMediaFoundationCdm:
// Default policy is disabled for MF Cdm process to allow the application
// of specific LPAC sandbox policies.
return true;
default: default:
return false; return false;
} }
...@@ -179,6 +184,10 @@ bool UtilitySandboxedProcessLauncherDelegate::PreSpawnTarget( ...@@ -179,6 +184,10 @@ bool UtilitySandboxedProcessLauncherDelegate::PreSpawnTarget(
cmd_line_, sandbox::JOB_UNPROTECTED, 0, policy); cmd_line_, sandbox::JOB_UNPROTECTED, 0, policy);
} }
if (sandbox_type_ == sandbox::policy::SandboxType::kMediaFoundationCdm) {
policy->SetTokenLevel(sandbox::USER_UNPROTECTED, sandbox::USER_UNPROTECTED);
}
if (sandbox_type_ == sandbox::policy::SandboxType::kSharingService) { if (sandbox_type_ == sandbox::policy::SandboxType::kSharingService) {
auto result = auto result =
sandbox::policy::SandboxWin::AddWin32kLockdownPolicy(policy, false); sandbox::policy::SandboxWin::AddWin32kLockdownPolicy(policy, false);
......
...@@ -159,7 +159,10 @@ source_set("tests") { ...@@ -159,7 +159,10 @@ source_set("tests") {
] ]
if (is_win) { if (is_win) {
sources += [ "win/sandbox_win_unittest.cc" ] sources += [
"win/mf_cdm_sandbox_type_unittest.cc",
"win/sandbox_win_unittest.cc",
]
deps += [ "//sandbox/win:sandbox" ] deps += [ "//sandbox/win:sandbox" ]
data = [ data = [
"//base/test/data/pe_image/pe_image_test_32.dll", "//base/test/data/pe_image/pe_image_test_32.dll",
......
...@@ -28,6 +28,7 @@ bool IsUnsandboxedSandboxType(SandboxType sandbox_type) { ...@@ -28,6 +28,7 @@ bool IsUnsandboxedSandboxType(SandboxType sandbox_type) {
case SandboxType::kProxyResolver: case SandboxType::kProxyResolver:
case SandboxType::kPdfConversion: case SandboxType::kPdfConversion:
case SandboxType::kIconReader: case SandboxType::kIconReader:
case SandboxType::kMediaFoundationCdm:
return false; return false;
#endif #endif
case SandboxType::kAudio: case SandboxType::kAudio:
...@@ -124,6 +125,7 @@ void SetCommandLineFlagsForSandboxType(base::CommandLine* command_line, ...@@ -124,6 +125,7 @@ void SetCommandLineFlagsForSandboxType(base::CommandLine* command_line,
case SandboxType::kProxyResolver: case SandboxType::kProxyResolver:
case SandboxType::kPdfConversion: case SandboxType::kPdfConversion:
case SandboxType::kIconReader: case SandboxType::kIconReader:
case SandboxType::kMediaFoundationCdm:
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
case SandboxType::kIme: case SandboxType::kIme:
...@@ -249,6 +251,8 @@ std::string StringFromUtilitySandboxType(SandboxType sandbox_type) { ...@@ -249,6 +251,8 @@ std::string StringFromUtilitySandboxType(SandboxType sandbox_type) {
return switches::kPdfConversionSandbox; return switches::kPdfConversionSandbox;
case SandboxType::kIconReader: case SandboxType::kIconReader:
return switches::kIconReaderSandbox; return switches::kIconReaderSandbox;
case SandboxType::kMediaFoundationCdm:
return switches::kMediaFoundationCdmSandbox;
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
case SandboxType::kIme: case SandboxType::kIme:
...@@ -303,6 +307,8 @@ SandboxType UtilitySandboxTypeFromString(const std::string& sandbox_string) { ...@@ -303,6 +307,8 @@ SandboxType UtilitySandboxTypeFromString(const std::string& sandbox_string) {
return SandboxType::kPdfConversion; return SandboxType::kPdfConversion;
if (sandbox_string == switches::kIconReaderSandbox) if (sandbox_string == switches::kIconReaderSandbox)
return SandboxType::kIconReader; return SandboxType::kIconReader;
if (sandbox_string == switches::kMediaFoundationCdmSandbox)
return SandboxType::kMediaFoundationCdm;
#endif #endif
if (sandbox_string == switches::kAudioSandbox) if (sandbox_string == switches::kAudioSandbox)
return SandboxType::kAudio; return SandboxType::kAudio;
......
...@@ -34,6 +34,9 @@ enum class SandboxType { ...@@ -34,6 +34,9 @@ enum class SandboxType {
// The icon reader service. // The icon reader service.
kIconReader, kIconReader,
// The MediaFoundation CDM service process.
kMediaFoundationCdm,
#endif #endif
#if defined(OS_FUCHSIA) #if defined(OS_FUCHSIA)
......
...@@ -38,6 +38,7 @@ const char kPdfConversionSandbox[] = "pdf_conversion"; ...@@ -38,6 +38,7 @@ const char kPdfConversionSandbox[] = "pdf_conversion";
const char kProxyResolverSandbox[] = "proxy_resolver"; const char kProxyResolverSandbox[] = "proxy_resolver";
const char kXrCompositingSandbox[] = "xr_compositing"; const char kXrCompositingSandbox[] = "xr_compositing";
const char kIconReaderSandbox[] = "icon_reader"; const char kIconReaderSandbox[] = "icon_reader";
const char kMediaFoundationCdmSandbox[] = "mf_cdm";
#endif // OS_WIN #endif // OS_WIN
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
......
...@@ -36,6 +36,7 @@ SANDBOX_POLICY_EXPORT extern const char kPdfConversionSandbox[]; ...@@ -36,6 +36,7 @@ SANDBOX_POLICY_EXPORT extern const char kPdfConversionSandbox[];
SANDBOX_POLICY_EXPORT extern const char kProxyResolverSandbox[]; SANDBOX_POLICY_EXPORT extern const char kProxyResolverSandbox[];
SANDBOX_POLICY_EXPORT extern const char kXrCompositingSandbox[]; SANDBOX_POLICY_EXPORT extern const char kXrCompositingSandbox[];
SANDBOX_POLICY_EXPORT extern const char kIconReaderSandbox[]; SANDBOX_POLICY_EXPORT extern const char kIconReaderSandbox[];
SANDBOX_POLICY_EXPORT extern const char kMediaFoundationCdmSandbox[];
#endif // OS_WIN #endif // OS_WIN
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
......
// Copyright 2020 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 "sandbox/policy/sandbox_type.h"
#include "base/command_line.h"
#include "sandbox/policy/switches.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {
TEST(SandboxTypeTest, Utility) {
// Setup to have '--type=utility' first.
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
command_line.AppendSwitchASCII(service_manager::switches::kProcessType,
sandbox::policy::switches::kUtilityProcess);
EXPECT_EQ(sandbox::policy::SandboxType::kUtility,
sandbox::policy::SandboxTypeFromCommandLine(command_line));
base::CommandLine command_line2(command_line);
SetCommandLineFlagsForSandboxType(
&command_line2, sandbox::policy::SandboxType::kMediaFoundationCdm);
EXPECT_EQ(sandbox::policy::SandboxType::kMediaFoundationCdm,
sandbox::policy::SandboxTypeFromCommandLine(command_line2));
}
} // namespace media
...@@ -621,12 +621,22 @@ ResultCode SetJobMemoryLimit(const base::CommandLine& cmd_line, ...@@ -621,12 +621,22 @@ ResultCode SetJobMemoryLimit(const base::CommandLine& cmd_line,
// isn't a security concern. // isn't a security concern.
base::string16 GetAppContainerProfileName(const std::string& appcontainer_id, base::string16 GetAppContainerProfileName(const std::string& appcontainer_id,
SandboxType sandbox_type) { SandboxType sandbox_type) {
DCHECK(sandbox_type == SandboxType::kGpu || std::string sandbox_base_name;
sandbox_type == SandboxType::kXrCompositing); switch (sandbox_type) {
case SandboxType::kXrCompositing:
sandbox_base_name = std::string("cr.sb.xr");
break;
case SandboxType::kGpu:
sandbox_base_name = std::string("cr.sb.gpu");
break;
case SandboxType::kMediaFoundationCdm:
sandbox_base_name = std::string("cr.sb.cdm");
break;
default:
DCHECK(0);
}
auto sha1 = base::SHA1HashString(appcontainer_id); auto sha1 = base::SHA1HashString(appcontainer_id);
std::string sandbox_base_name = (sandbox_type == SandboxType::kXrCompositing)
? std::string("cr.sb.xr")
: std::string("cr.sb.gpu");
std::string profile_name = base::StrCat( std::string profile_name = base::StrCat(
{sandbox_base_name, base::HexEncode(sha1.data(), sha1.size())}); {sandbox_base_name, base::HexEncode(sha1.data(), sha1.size())});
// CreateAppContainerProfile requires that the profile name is at most 64 // CreateAppContainerProfile requires that the profile name is at most 64
...@@ -640,7 +650,8 @@ base::string16 GetAppContainerProfileName(const std::string& appcontainer_id, ...@@ -640,7 +650,8 @@ base::string16 GetAppContainerProfileName(const std::string& appcontainer_id,
ResultCode SetupAppContainerProfile(AppContainerProfile* profile, ResultCode SetupAppContainerProfile(AppContainerProfile* profile,
const base::CommandLine& command_line, const base::CommandLine& command_line,
SandboxType sandbox_type) { SandboxType sandbox_type) {
if (sandbox_type != SandboxType::kGpu && if (sandbox_type != SandboxType::kMediaFoundationCdm &&
sandbox_type != SandboxType::kGpu &&
sandbox_type != SandboxType::kXrCompositing) sandbox_type != SandboxType::kXrCompositing)
return SBOX_ERROR_UNSUPPORTED; return SBOX_ERROR_UNSUPPORTED;
...@@ -666,6 +677,36 @@ ResultCode SetupAppContainerProfile(AppContainerProfile* profile, ...@@ -666,6 +677,36 @@ ResultCode SetupAppContainerProfile(AppContainerProfile* profile,
return SBOX_ERROR_CREATE_APPCONTAINER_PROFILE_CAPABILITY; return SBOX_ERROR_CREATE_APPCONTAINER_PROFILE_CAPABILITY;
} }
if (sandbox_type == SandboxType::kMediaFoundationCdm) {
// Please refer to the following design doc on why we add the capabilities:
// https://docs.google.com/document/d/19Y4Js5v3BlzA5uSuiVTvcvPNIOwmxcMSFJWtuc1A-w8/edit#heading=h.iqvhsrml3gl9
if (!profile->AddCapability(
sandbox::WellKnownCapabilities::kPrivateNetworkClientServer) ||
!profile->AddCapability(
sandbox::WellKnownCapabilities::kInternetClient)) {
DLOG(ERROR)
<< "AppContainerProfile::AddCapability() - "
<< "SandboxType::kMediaFoundationCdm internet capabilities failed";
return sandbox::SBOX_ERROR_CREATE_APPCONTAINER_PROFILE_CAPABILITY;
}
if (!profile->AddCapability(L"lpacCom") ||
!profile->AddCapability(L"lpacIdentityServices") ||
!profile->AddCapability(L"lpacMedia") ||
!profile->AddCapability(L"lpacPnPNotifications") ||
!profile->AddCapability(L"lpacServicesManagement") ||
!profile->AddCapability(L"lpacSessionManagement") ||
!profile->AddCapability(L"lpacAppExperience") ||
!profile->AddCapability(L"lpacAppServices") ||
!profile->AddCapability(L"lpacCryptoServices") ||
!profile->AddCapability(L"lpacEnterprisePolicyChangeNotifications")) {
DLOG(ERROR)
<< "AppContainerProfile::AddCapability() - "
<< "SandboxType::kMediaFoundationCdm lpac capabilities failed";
return sandbox::SBOX_ERROR_CREATE_APPCONTAINER_PROFILE_CAPABILITY;
}
}
std::vector<base::string16> base_caps = { std::vector<base::string16> base_caps = {
L"lpacChromeInstallFiles", L"lpacChromeInstallFiles",
L"registryRead", L"registryRead",
...@@ -698,6 +739,9 @@ ResultCode SetupAppContainerProfile(AppContainerProfile* profile, ...@@ -698,6 +739,9 @@ ResultCode SetupAppContainerProfile(AppContainerProfile* profile,
profile->SetEnableLowPrivilegeAppContainer(true); profile->SetEnableLowPrivilegeAppContainer(true);
} }
if (sandbox_type == SandboxType::kMediaFoundationCdm)
profile->SetEnableLowPrivilegeAppContainer(true);
return SBOX_ALL_OK; return SBOX_ALL_OK;
} }
...@@ -813,10 +857,14 @@ ResultCode SandboxWin::AddAppContainerProfileToPolicy( ...@@ -813,10 +857,14 @@ ResultCode SandboxWin::AddAppContainerProfileToPolicy(
bool SandboxWin::IsAppContainerEnabledForSandbox( bool SandboxWin::IsAppContainerEnabledForSandbox(
const base::CommandLine& command_line, const base::CommandLine& command_line,
SandboxType sandbox_type) { SandboxType sandbox_type) {
if (sandbox_type != SandboxType::kGpu)
return false;
if (base::win::GetVersion() < base::win::Version::WIN10_RS1) if (base::win::GetVersion() < base::win::Version::WIN10_RS1)
return false; return false;
if (sandbox_type == SandboxType::kMediaFoundationCdm)
return true;
if (sandbox_type != SandboxType::kGpu)
return false;
return base::FeatureList::IsEnabled(features::kGpuAppContainer); return base::FeatureList::IsEnabled(features::kGpuAppContainer);
} }
...@@ -1016,6 +1064,15 @@ ResultCode SandboxWin::StartSandboxedProcess( ...@@ -1016,6 +1064,15 @@ ResultCode SandboxWin::StartSandboxedProcess(
} }
} }
if (sandbox_type == SandboxType::kMediaFoundationCdm) {
// Set a policy that would normally allow for process creation. This allows
// the mf cdm process to launch the protected media pipeline process
// (mfpmp.exe) without process interception.
result = policy->SetJobLevel(JOB_INTERACTIVE, 0);
if (result != SBOX_ALL_OK)
return result;
}
#if !defined(OFFICIAL_BUILD) #if !defined(OFFICIAL_BUILD)
// If stdout/stderr point to a Windows console, these calls will // If stdout/stderr point to a Windows console, these calls will
// have no effect. These calls can fail with SBOX_ERROR_BAD_PARAMS. // have no effect. These calls can fail with SBOX_ERROR_BAD_PARAMS.
...@@ -1120,6 +1177,8 @@ std::string SandboxWin::GetSandboxTypeInEnglish(SandboxType sandbox_type) { ...@@ -1120,6 +1177,8 @@ std::string SandboxWin::GetSandboxTypeInEnglish(SandboxType sandbox_type) {
return "Proxy Resolver"; return "Proxy Resolver";
case SandboxType::kPdfConversion: case SandboxType::kPdfConversion:
return "PDF Conversion"; return "PDF Conversion";
case SandboxType::kMediaFoundationCdm:
return "Media Foundation CDM";
case SandboxType::kSharingService: case SandboxType::kSharingService:
return "Sharing"; return "Sharing";
case SandboxType::kVideoCapture: case SandboxType::kVideoCapture:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment