diff options
26 files changed, 511 insertions, 113 deletions
diff --git a/chrome/test/data/nacl/manifest_file/irt_manifest_file.nmf b/chrome/test/data/nacl/manifest_file/irt_manifest_file.nmf new file mode 100644 index 0000000..ffb06a87 --- /dev/null +++ b/chrome/test/data/nacl/manifest_file/irt_manifest_file.nmf @@ -0,0 +1,19 @@ +{ + "files": { + "nmf says hello world": { + "portable": { + "url": "test_file.txt" + } + }, + "test_file": { + "portable": { + "url": "test_file.txt" + } + } + }, + "program": { + "x86-32-nonsfi": { + "url": "irt_manifest_file_pnacl_newlib_x32_nonsfi.nexe" + } + } +} diff --git a/chrome/test/data/nacl/nacl_test_data.gyp b/chrome/test/data/nacl/nacl_test_data.gyp index 8a2fc93..589a12f 100644 --- a/chrome/test/data/nacl/nacl_test_data.gyp +++ b/chrome/test/data/nacl/nacl_test_data.gyp @@ -1170,6 +1170,46 @@ }, ], }, + { + 'target_name': 'nonsfi_irt_manifest_file', + 'type': 'none', + 'variables': { + 'nexe_target': 'irt_manifest_file', + 'enable_x86_32': 0, + 'enable_x86_64': 0, + 'enable_x86_32_nonsfi': 1, + 'build_pnacl_newlib': 1, + # create_nmf.py doesn't support nonsfi. + # TODO(crbug.com/368949): Clean this up after nonsfi support on + # create_nmf.py. + 'generate_nmf': 0, + 'nexe_destination_dir': 'nacl_test_data', + 'link_flags': [ + '-lnacl_ppapi_util', + '-lppapi_cpp', + '-lppapi', + '-lnacl', + ], + 'sources': [ + 'manifest_file/irt_manifest_file_test.cc', + ], + 'test_files': [ + # TODO(ncbray) move into chrome/test/data/nacl when all tests are + # converted. + '<(DEPTH)/ppapi/native_client/tools/browser_tester/browserdata/nacltest.js', + 'manifest_file/irt_manifest_file.nmf', + 'manifest_file/irt_manifest_file_test.html', + 'manifest_file/test_file.txt', + ], + }, + 'dependencies': [ + '<(DEPTH)/native_client/tools.gyp:prep_toolchain', + '<(DEPTH)/ppapi/ppapi_nacl.gyp:ppapi_cpp_lib', + '<(DEPTH)/ppapi/native_client/native_client.gyp:ppapi_lib', + '<(DEPTH)/native_client/src/untrusted/nacl/nacl.gyp:nacl_lib', + 'nacl_ppapi_util', + ], + }, ], }], ], diff --git a/chrome/test/nacl/nacl_browsertest.cc b/chrome/test/nacl/nacl_browsertest.cc index cd31331..1e48883 100644 --- a/chrome/test/nacl/nacl_browsertest.cc +++ b/chrome/test/nacl/nacl_browsertest.cc @@ -37,25 +37,11 @@ NACL_BROWSER_TEST_F(NaClBrowserTest, SimpleLoad, { RunLoadTest(FILE_PATH_LITERAL("nacl_load_test.html")); }) -// ASan does not work with libc-free context, so disable the test. -#if defined(OS_LINUX) && !defined(ADDRESS_SANITIZER) -# define MAYBE_NonSfiMessaging NonSfiMessaging -#else -# define MAYBE_NonSfiMessaging DISABLED_NonSfiMessaging -#endif - -IN_PROC_BROWSER_TEST_F(NaClBrowserTestNonSfiMode, MAYBE_NonSfiMessaging) { +IN_PROC_BROWSER_TEST_F(NaClBrowserTestNonSfiMode, MAYBE_NONSFI(Messaging)) { RunLoadTest(FILE_PATH_LITERAL("libc_free.html")); } -// ASan does not work with libc-free context, so disable the test. -#if defined(OS_LINUX) && !defined(ADDRESS_SANITIZER) -# define MAYBE_NonSfiIrt NonSfiIrt -#else -# define MAYBE_NonSfiIrt DISABLED_NonSfiIrt -#endif - -IN_PROC_BROWSER_TEST_F(NaClBrowserTestNonSfiMode, MAYBE_NonSfiIrt) { +IN_PROC_BROWSER_TEST_F(NaClBrowserTestNonSfiMode, MAYBE_NONSFI(Irt)) { RunNaClIntegrationTest(FILE_PATH_LITERAL("irt_test.html")); } @@ -143,20 +129,16 @@ IN_PROC_BROWSER_TEST_F(NaClBrowserTestGLibc, PreInitManifestFile) { IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlib, IrtManifestFile) { RunNaClIntegrationTest(FILE_PATH_LITERAL("irt_manifest_file_test.html")); } - -// The NonSFI test is currently available only on linux-x86-32 -// architecture. -#if defined(OS_LINUX) && defined(ARCH_CPU_X86) -#define MAYBE_NONSFI(test_name) test_name -#else -#define MAYBE_NONSFI(test_name) DISABLED_##test_name -#endif +IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnaclNonSfi, + MAYBE_PNACL_NONSFI(IrtManifestFile)) { + RunNaClIntegrationTest(FILE_PATH_LITERAL("irt_manifest_file_test.html")); +} IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlib, IrtException) { RunNaClIntegrationTest(FILE_PATH_LITERAL("irt_exception_test.html")); } IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnaclNonSfi, - MAYBE_NONSFI(IrtException)) { + MAYBE_PNACL_NONSFI(IrtException)) { RunNaClIntegrationTest(FILE_PATH_LITERAL("irt_exception_test.html")); } diff --git a/chrome/test/nacl/nacl_browsertest_util.h b/chrome/test/nacl/nacl_browsertest_util.h index 22fd852..976d227 100644 --- a/chrome/test/nacl/nacl_browsertest_util.h +++ b/chrome/test/nacl/nacl_browsertest_util.h @@ -125,8 +125,8 @@ class NaClBrowserTestPnacl : public NaClBrowserTestBase { class NaClBrowserTestPnaclNonSfi : public NaClBrowserTestBase { public: - virtual base::FilePath::StringType Variant() OVERRIDE; virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE; + virtual base::FilePath::StringType Variant() OVERRIDE; }; // Class used to test that when --disable-pnacl is specified the PNaCl mime @@ -164,6 +164,21 @@ class NaClBrowserTestStatic : public NaClBrowserTestBase { #define MAYBE_PNACL(test_name) test_name #endif +// ASan does not work with libc-free context, so disable the test. +#if defined(OS_LINUX) && !defined(ADDRESS_SANITIZER) +# define MAYBE_NONSFI(test_case) test_case +#else +# define MAYBE_NONSFI(test_case) DISABLED_##test_case +#endif + +// Currently, translation from pexe to non-sfi nexe is supported only for +// x86-32 binary. +#if defined(OS_LINUX) && defined(ARCH_CPU_X86) +# define MAYBE_PNACL_NONSFI(test_case) test_case +#else +# define MAYBE_PNACL_NONSFI(test_case) DISABLED_##test_case +#endif + #if defined(ARCH_CPU_ARM_FAMILY) || defined(ARCH_CPU_MIPS_FAMILY) // There is no support for Glibc on ARM and MIPS NaCl. diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc index 1f5f2f0..39b870d 100644 --- a/chrome/test/ppapi/ppapi_browsertest.cc +++ b/chrome/test/ppapi/ppapi_browsertest.cc @@ -13,6 +13,7 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/javascript_test_observer.h" #include "chrome/test/base/ui_test_utils.h" +#include "chrome/test/nacl/nacl_browsertest_util.h" #include "content/public/browser/web_contents.h" #include "content/public/common/url_constants.h" #include "content/public/test/test_renderer_host.h" @@ -65,13 +66,6 @@ using content::RenderViewHost; #define MAYBE_GLIBC(test_name) DISABLED_##test_name #endif -// The NonSFI test is currently available only on linux-x86-32 architecture. -#if defined(OS_LINUX) && defined(ARCH_CPU_X86) -#define MAYBE_NONSFI(test_name) test_name -#else -#define MAYBE_NONSFI(test_name) DISABLED_##test_name -#endif - #if defined(DISABLE_NACL) #define TEST_PPAPI_NACL(test_name) @@ -92,7 +86,7 @@ using content::RenderViewHost; RunTestViaHTTP(STRIP_PREFIXES(test_name)); \ } \ IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, \ - MAYBE_NONSFI(test_name)) { \ + MAYBE_PNACL_NONSFI(test_name)) { \ RunTestViaHTTP(STRIP_PREFIXES(test_name)); \ } @@ -114,7 +108,7 @@ using content::RenderViewHost; RunTestWithSSLServer(STRIP_PREFIXES(test_name)); \ } \ IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, \ - MAYBE_NONSFI(test_name)) { \ + MAYBE_PNACL_NONSFI(test_name)) { \ RunTestWithSSLServer(STRIP_PREFIXES(test_name)); \ } @@ -351,7 +345,8 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, MAYBE_GLIBC(TCPSocket)) { IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, TCPSocket) { RUN_TCPSOCKET_SUBTESTS; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(TCPSocket)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, + MAYBE_PNACL_NONSFI(TCPSocket)) { RUN_TCPSOCKET_SUBTESTS; } @@ -391,7 +386,8 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, MAYBE_GLIBC(UDPSocket)) { IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, UDPSocket) { RUN_UDPSOCKET_SUBTESTS; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(UDPSocket)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, + MAYBE_PNACL_NONSFI(UDPSocket)) { RUN_UDPSOCKET_SUBTESTS; } @@ -438,7 +434,8 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, MAYBE_GLIBC(HostResolver)) { IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, HostResolver) { RUN_HOST_RESOLVER_SUBTESTS; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(HostResolver)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, + MAYBE_PNACL_NONSFI(HostResolver)) { RUN_HOST_RESOLVER_SUBTESTS; } @@ -583,16 +580,20 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, URLLoader2) { IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, URLLoader3) { RUN_URLLOADER_SUBTESTS_3; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(URLLoader0)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, + MAYBE_PNACL_NONSFI(URLLoader0)) { RUN_URLLOADER_SUBTESTS_0; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(URLLoader1)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, + MAYBE_PNACL_NONSFI(URLLoader1)) { RUN_URLLOADER_SUBTESTS_1; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(URLLoader2)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, + MAYBE_PNACL_NONSFI(URLLoader2)) { RUN_URLLOADER_SUBTESTS_2; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(URLLoader3)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, + MAYBE_PNACL_NONSFI(URLLoader3)) { RUN_URLLOADER_SUBTESTS_3; } @@ -718,7 +719,8 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, MAYBE_GLIBC(PostMessage)) { IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, PostMessage) { RUN_POSTMESSAGE_SUBTESTS; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(PostMessage)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, + MAYBE_PNACL_NONSFI(PostMessage)) { RUN_POSTMESSAGE_SUBTESTS; } @@ -812,11 +814,11 @@ IN_PROC_BROWSER_TEST_F(PPAPIPrivateNaClPNaClTest, MAYBE_PNaCl_FileIO_Private) { RUN_FILEIO_PRIVATE_SUBTESTS; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(FileIO)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_PNACL_NONSFI(FileIO)) { RUN_FILEIO_SUBTESTS; } IN_PROC_BROWSER_TEST_F(PPAPIPrivateNaClPNaClTest, - MAYBE_NONSFI(FILEIO_Private)) { + MAYBE_PNACL_NONSFI(FILEIO_Private)) { RUN_FILEIO_PRIVATE_SUBTESTS; } @@ -894,10 +896,12 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, FileRef1) { IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, FileRef2) { RUN_FILEREF_SUBTESTS_2; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(FileRef1)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, + MAYBE_PNACL_NONSFI(FileRef1)) { RUN_FILEREF_SUBTESTS_1; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(FileRef2)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, + MAYBE_PNACL_NONSFI(FileRef2)) { RUN_FILEREF_SUBTESTS_2; } @@ -957,7 +961,8 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, MAYBE_GLIBC(NetAddress)) { IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, NetAddress) { RUN_NETADDRESS_SUBTESTS; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(NetAddress)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, + MAYBE_PNACL_NONSFI(NetAddress)) { RUN_NETADDRESS_SUBTESTS; } @@ -1005,7 +1010,7 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, NetAddressPrivate) { RUN_NETADDRESS_PRIVATE_UNTRUSTED_SUBTESTS; } IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, - MAYBE_NONSFI(NetAddressPrivate)) { + MAYBE_PNACL_NONSFI(NetAddressPrivate)) { RUN_NETADDRESS_PRIVATE_UNTRUSTED_SUBTESTS; } @@ -1030,7 +1035,7 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, NetworkMonitor) { RUN_NETWORK_MONITOR_SUBTESTS; } IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, - MAYBE_NONSFI(NetworkMonitor)) { + MAYBE_PNACL_NONSFI(NetworkMonitor)) { RUN_NETWORK_MONITOR_SUBTESTS; } @@ -1118,10 +1123,12 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, WebSocket1) { IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, WebSocket2) { RUN_WEBSOCKET_SUBTESTS_2; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(WebSocket1)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, + MAYBE_PNACL_NONSFI(WebSocket1)) { RUN_WEBSOCKET_SUBTESTS_1; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(WebSocket2)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, + MAYBE_PNACL_NONSFI(WebSocket2)) { RUN_WEBSOCKET_SUBTESTS_2; } @@ -1148,7 +1155,8 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, MAYBE_GLIBC(AudioConfig)) { IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, AudioConfig) { RUN_AUDIO_CONFIG_SUBTESTS; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(AudioConfig)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, + MAYBE_PNACL_NONSFI(AudioConfig)) { RUN_AUDIO_CONFIG_SUBTESTS; } @@ -1177,7 +1185,8 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, MAYBE_GLIBC(Audio)) { IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, Audio) { RUN_AUDIO_SUBTESTS; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(Audio)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, + MAYBE_PNACL_NONSFI(Audio)) { RUN_AUDIO_SUBTESTS; } @@ -1197,7 +1206,7 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, AudioThreadCreator) { RUN_AUDIO_THREAD_CREATOR_SUBTESTS; } IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, - MAYBE_NONSFI(AudioThreadCreator)) { + MAYBE_PNACL_NONSFI(AudioThreadCreator)) { RUN_AUDIO_THREAD_CREATOR_SUBTESTS; } @@ -1289,7 +1298,7 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, MAYBE_GLIBC(View)) { IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, View) { RUN_VIEW_SUBTESTS; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(View)) { +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_PNACL_NONSFI(View)) { RUN_VIEW_SUBTESTS; } diff --git a/components/nacl.gyp b/components/nacl.gyp index 74b0204..23d886e 100644 --- a/components/nacl.gyp +++ b/components/nacl.gyp @@ -267,6 +267,7 @@ 'nacl/loader/nonsfi/irt_memory.cc', 'nacl/loader/nonsfi/irt_ppapi.cc', 'nacl/loader/nonsfi/irt_random.cc', + 'nacl/loader/nonsfi/irt_resource_open.cc', 'nacl/loader/nonsfi/irt_thread.cc', 'nacl/loader/nonsfi/irt_util.h', 'nacl/loader/nonsfi/nonsfi_main.cc', @@ -275,6 +276,7 @@ 'nacl/loader/nonsfi/nonsfi_sandbox.h', 'nacl/loader/sandbox_linux/nacl_bpf_sandbox_linux.cc', 'nacl/loader/sandbox_linux/nacl_sandbox_linux.cc', + '../ppapi/nacl_irt/irt_manifest.h', '../ppapi/nacl_irt/manifest_service.cc', '../ppapi/nacl_irt/manifest_service.h', '../ppapi/nacl_irt/plugin_main.cc', diff --git a/components/nacl/loader/nonsfi/irt_interfaces.cc b/components/nacl/loader/nonsfi/irt_interfaces.cc index 79bb8f5..52826e0 100644 --- a/components/nacl/loader/nonsfi/irt_interfaces.cc +++ b/components/nacl/loader/nonsfi/irt_interfaces.cc @@ -30,6 +30,7 @@ const NaClInterfaceTable kIrtInterfaces[] = { NACL_INTERFACE_TABLE(NACL_IRT_TLS_v0_1, kIrtTls), NACL_INTERFACE_TABLE(NACL_IRT_CLOCK_v0_1, kIrtClock), NACL_INTERFACE_TABLE(NACL_IRT_PPAPIHOOK_v0_1, kIrtPpapiHook), + NACL_INTERFACE_TABLE(NACL_IRT_RESOURCE_OPEN_v0_1, kIrtResourceOpen), NACL_INTERFACE_TABLE(NACL_IRT_RANDOM_v0_1, kIrtRandom), NACL_INTERFACE_TABLE(NACL_IRT_EXCEPTION_HANDLING_v0_1, kIrtExceptionHandling), }; diff --git a/components/nacl/loader/nonsfi/irt_interfaces.h b/components/nacl/loader/nonsfi/irt_interfaces.h index 6d723e6..3dbdfb6 100644 --- a/components/nacl/loader/nonsfi/irt_interfaces.h +++ b/components/nacl/loader/nonsfi/irt_interfaces.h @@ -23,6 +23,7 @@ extern const struct nacl_irt_futex kIrtFutex; extern const struct nacl_irt_tls kIrtTls; extern const struct nacl_irt_clock kIrtClock; extern const struct nacl_irt_ppapihook kIrtPpapiHook; +extern const struct nacl_irt_resource_open kIrtResourceOpen; extern const struct nacl_irt_random kIrtRandom; extern const struct nacl_irt_exception_handling kIrtExceptionHandling; diff --git a/components/nacl/loader/nonsfi/irt_resource_open.cc b/components/nacl/loader/nonsfi/irt_resource_open.cc new file mode 100644 index 0000000..cf193c1 --- /dev/null +++ b/components/nacl/loader/nonsfi/irt_resource_open.cc @@ -0,0 +1,16 @@ +// Copyright 2014 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 "components/nacl/loader/nonsfi/irt_interfaces.h" +#include "ppapi/nacl_irt/irt_manifest.h" + +namespace nacl { +namespace nonsfi { + +const nacl_irt_resource_open kIrtResourceOpen = { + ppapi::IrtOpenResource, +}; + +} // namespace nonsfi +} // namespace nacl diff --git a/components/nacl/renderer/manifest_service_channel.cc b/components/nacl/renderer/manifest_service_channel.cc index f0f4adb..606be61 100644 --- a/components/nacl/renderer/manifest_service_channel.cc +++ b/components/nacl/renderer/manifest_service_channel.cc @@ -4,6 +4,7 @@ #include "components/nacl/renderer/manifest_service_channel.h" +#include "base/bind.h" #include "base/callback.h" #include "base/callback_helpers.h" #include "content/public/renderer/render_thread.h" @@ -24,7 +25,8 @@ ManifestServiceChannel::ManifestServiceChannel( channel_(new IPC::SyncChannel( handle, IPC::Channel::MODE_CLIENT, this, content::RenderThread::Get()->GetIOMessageLoopProxy(), - true, waitable_event)) { + true, waitable_event)), + weak_ptr_factory_(this) { } ManifestServiceChannel::~ManifestServiceChannel() { @@ -32,12 +34,17 @@ ManifestServiceChannel::~ManifestServiceChannel() { base::ResetAndReturn(&connected_callback_).Run(PP_ERROR_FAILED); } +void ManifestServiceChannel::Send(IPC::Message* message) { + channel_->Send(message); +} + bool ManifestServiceChannel::OnMessageReceived(const IPC::Message& message) { - // TODO(hidehiko): Implement OpenResource. bool handled = true; IPC_BEGIN_MESSAGE_MAP(ManifestServiceChannel, message) IPC_MESSAGE_HANDLER(PpapiHostMsg_StartupInitializationComplete, OnStartupInitializationComplete) + IPC_MESSAGE_HANDLER_DELAY_REPLY(PpapiHostMsg_OpenResource, + OnOpenResource) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -57,4 +64,33 @@ void ManifestServiceChannel::OnStartupInitializationComplete() { delegate_->StartupInitializationComplete(); } +void ManifestServiceChannel::OnOpenResource( + const std::string& key, IPC::Message* reply) { + // Currently this is used only for non-SFI mode, which is not supported on + // windows. +#if !defined(OS_WIN) + delegate_->OpenResource( + key, + base::Bind(&ManifestServiceChannel::DidOpenResource, + weak_ptr_factory_.GetWeakPtr(), reply)); +#else + PpapiHostMsg_OpenResource::WriteReplyParams( + reply, ppapi::proxy::SerializedHandle()); + Send(reply); +#endif +} + +#if !defined(OS_WIN) +void ManifestServiceChannel::DidOpenResource( + IPC::Message* reply, const base::PlatformFile& platform_file) { + // Here, PlatformFileForTransit is alias of base::FileDescriptor. + PpapiHostMsg_OpenResource::WriteReplyParams( + reply, + ppapi::proxy::SerializedHandle( + ppapi::proxy::SerializedHandle::FILE, + base::FileDescriptor(platform_file, true))); + Send(reply); +} +#endif + } // namespace nacl diff --git a/components/nacl/renderer/manifest_service_channel.h b/components/nacl/renderer/manifest_service_channel.h index 6dc394fe..c75b35a 100644 --- a/components/nacl/renderer/manifest_service_channel.h +++ b/components/nacl/renderer/manifest_service_channel.h @@ -8,6 +8,10 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/platform_file.h" +#include "base/process/process.h" +#include "base/synchronization/lock.h" #include "ipc/ipc_listener.h" namespace base { @@ -24,6 +28,8 @@ namespace nacl { class ManifestServiceChannel : public IPC::Listener { public: + typedef base::Callback<void(const base::PlatformFile&)> OpenResourceCallback; + class Delegate { public: virtual ~Delegate() {} @@ -31,7 +37,11 @@ class ManifestServiceChannel : public IPC::Listener { // Called when PPAPI initialization in the NaCl plugin is finished. virtual void StartupInitializationComplete() = 0; - // TODO(hidehiko): Add OpenResource() here. + // Called when irt_open_resource() is invoked in the NaCl plugin. + // Upon completion, callback is invoked with the platform file. + virtual void OpenResource( + const std::string& key, + const OpenResourceCallback& callback) = 0; }; ManifestServiceChannel( @@ -41,6 +51,8 @@ class ManifestServiceChannel : public IPC::Listener { base::WaitableEvent* waitable_event); virtual ~ManifestServiceChannel(); + void Send(IPC::Message* message); + // Listener implementation. virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; @@ -48,11 +60,20 @@ class ManifestServiceChannel : public IPC::Listener { private: void OnStartupInitializationComplete(); + void OnOpenResource(const std::string& key, IPC::Message* reply); +#if !defined(OS_WIN) + void DidOpenResource( + IPC::Message* reply, const base::PlatformFile& platform_file); +#endif base::Callback<void(int32_t)> connected_callback_; scoped_ptr<Delegate> delegate_; scoped_ptr<IPC::SyncChannel> channel_; + // Note: This should remain the last member so it'll be destroyed and + // invalidate the weak pointers before any other members are destroyed. + base::WeakPtrFactory<ManifestServiceChannel> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(ManifestServiceChannel); }; diff --git a/components/nacl/renderer/ppb_nacl_private_impl.cc b/components/nacl/renderer/ppb_nacl_private_impl.cc index 7986cf0..a4020d9 100644 --- a/components/nacl/renderer/ppb_nacl_private_impl.cc +++ b/components/nacl/renderer/ppb_nacl_private_impl.cc @@ -164,13 +164,13 @@ class ChannelConnectedCallback { DISALLOW_COPY_AND_ASSIGN(ChannelConnectedCallback); }; -// Thin adapter from PP_ManifestService to ManifestServiceChannel::Delegate. +// Thin adapter from PPP_ManifestService to ManifestServiceChannel::Delegate. // Note that user_data is managed by the caller of LaunchSelLdr. Please see // also PP_ManifestService's comment for more details about resource // management. class ManifestServiceProxy : public ManifestServiceChannel::Delegate { public: - ManifestServiceProxy(const PP_ManifestService* manifest_service, + ManifestServiceProxy(const PPP_ManifestService* manifest_service, void* user_data) : manifest_service_(*manifest_service), user_data_(user_data) { @@ -190,7 +190,30 @@ class ManifestServiceProxy : public ManifestServiceChannel::Delegate { } } + virtual void OpenResource( + const std::string& key, + const ManifestServiceChannel::OpenResourceCallback& callback) OVERRIDE { + if (!user_data_) + return; + + // The allocated callback will be freed in DidOpenResource, which is always + // called regardless whether OpenResource() succeeds or fails. + if (!PP_ToBool(manifest_service_.OpenResource( + user_data_, + key.c_str(), + DidOpenResource, + new ManifestServiceChannel::OpenResourceCallback(callback)))) { + user_data_ = NULL; + } + } + private: + static void DidOpenResource(void* user_data, PP_FileHandle file_handle) { + scoped_ptr<ManifestServiceChannel::OpenResourceCallback> callback( + static_cast<ManifestServiceChannel::OpenResourceCallback*>(user_data)); + callback->Run(file_handle); + } + void Quit() { if (!user_data_) return; @@ -200,7 +223,7 @@ class ManifestServiceProxy : public ManifestServiceChannel::Delegate { user_data_ = NULL; } - PP_ManifestService manifest_service_; + PPP_ManifestService manifest_service_; void* user_data_; DISALLOW_COPY_AND_ASSIGN(ManifestServiceProxy); }; @@ -215,7 +238,7 @@ void LaunchSelLdr(PP_Instance instance, PP_Bool enable_dyncode_syscalls, PP_Bool enable_exception_handling, PP_Bool enable_crash_throttling, - const PP_ManifestService* manifest_service_interface, + const PPP_ManifestService* manifest_service_interface, void* manifest_service_user_data, void* imc_handle, struct PP_Var* error_message, @@ -327,7 +350,14 @@ void LaunchSelLdr(PP_Instance instance, } // Stash the manifest service handle as well. + // For security hardening, disable the IPCs for open_resource() when they + // aren't needed. PNaCl doesn't expose open_resource(), and the new + // open_resource() IPCs are currently only used for Non-SFI NaCl so far, + // not SFI NaCl. Note that enable_dyncode_syscalls is true if and only if + // the plugin is a non-PNaCl plugin. if (load_manager && + enable_dyncode_syscalls && + uses_nonsfi_mode && IsValidChannelHandle( launch_result.manifest_service_ipc_channel_handle)) { scoped_ptr<ManifestServiceChannel> manifest_service_channel( diff --git a/ppapi/api/private/ppb_nacl_private.idl b/ppapi/api/private/ppb_nacl_private.idl index ac93742..04b6758 100644 --- a/ppapi/api/private/ppb_nacl_private.idl +++ b/ppapi/api/private/ppb_nacl_private.idl @@ -139,6 +139,10 @@ struct PP_PNaClOptions { int32_t opt_level; }; +/* Callback invoked upon completion of PPP_ManifestService::OpenResource(). */ +typedef void PP_OpenResourceCompletionCallback([inout] mem_t user_data, + [in] PP_FileHandle file_handle); + /* ManifestService to support irt_open_resource() function. * All functions of the service should have PP_Bool return value. It represents * whether the service is still alive or not. Trivially Quit() should always @@ -146,12 +150,20 @@ struct PP_PNaClOptions { * Once false is called, as the service has been destructed, all functions * should never be called afterwords. */ -interface PP_ManifestService { +interface PPP_ManifestService { /* Called when ManifestService should be destructed. */ PP_Bool Quit([inout] mem_t user_data); /* Called when PPAPI initialization in the NaCl plugin is finished. */ PP_Bool StartupInitializationComplete([inout] mem_t user_data); + + /* Called when irt_open_resource() is invoked in the NaCl plugin. + * Upon completion, callback will be invoked with given callback_user_data + * and the result file handle (or PP_kInvalidFileHandle on error). */ + PP_Bool OpenResource([inout] mem_t user_data, + [in] str_t entry_key, + [in] PP_OpenResourceCompletionCallback callback, + [inout] mem_t callback_user_data); }; /* PPB_NaCl_Private */ @@ -184,7 +196,7 @@ interface PPB_NaCl_Private { [in] PP_Bool enable_dyncode_syscalls, [in] PP_Bool enable_exception_handling, [in] PP_Bool enable_crash_throttling, - [in] PP_ManifestService manifest_service_interface, + [in] PPP_ManifestService manifest_service_interface, [inout] mem_t manifest_service_user_data, [out] mem_t imc_handle, [out] PP_Var error_message, diff --git a/ppapi/c/private/ppb_nacl_private.h b/ppapi/c/private/ppb_nacl_private.h index 573b8d0..9ac540a 100644 --- a/ppapi/c/private/ppb_nacl_private.h +++ b/ppapi/c/private/ppb_nacl_private.h @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -/* From private/ppb_nacl_private.idl modified Wed Apr 30 14:13:27 2014. */ +/* From private/ppb_nacl_private.idl modified Sat May 3 04:07:13 2014. */ #ifndef PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_ #define PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_ @@ -15,8 +15,8 @@ #include "ppapi/c/pp_stdint.h" #include "ppapi/c/pp_var.h" -#define PP_MANIFESTSERVICE_INTERFACE_1_0 "PP_ManifestService;1.0" -#define PP_MANIFESTSERVICE_INTERFACE PP_MANIFESTSERVICE_INTERFACE_1_0 +#define PPP_MANIFESTSERVICE_INTERFACE_1_0 "PPP_ManifestService;1.0" +#define PPP_MANIFESTSERVICE_INTERFACE PPP_MANIFESTSERVICE_INTERFACE_1_0 #define PPB_NACL_PRIVATE_INTERFACE_1_0 "PPB_NaCl_Private;1.0" #define PPB_NACL_PRIVATE_INTERFACE PPB_NACL_PRIVATE_INTERFACE_1_0 @@ -168,6 +168,17 @@ struct PP_PNaClOptions { */ /** + * @addtogroup Typedefs + * @{ + */ +/* Callback invoked upon completion of PPP_ManifestService::OpenResource(). */ +typedef void (*PP_OpenResourceCompletionCallback)(void* user_data, + PP_FileHandle file_handle); +/** + * @} + */ + +/** * @addtogroup Interfaces * @{ */ @@ -178,14 +189,21 @@ struct PP_PNaClOptions { * Once false is called, as the service has been destructed, all functions * should never be called afterwords. */ -struct PP_ManifestService_1_0 { +struct PPP_ManifestService_1_0 { /* Called when ManifestService should be destructed. */ PP_Bool (*Quit)(void* user_data); /* Called when PPAPI initialization in the NaCl plugin is finished. */ PP_Bool (*StartupInitializationComplete)(void* user_data); + /* Called when irt_open_resource() is invoked in the NaCl plugin. + * Upon completion, callback will be invoked with given callback_user_data + * and the result file handle (or PP_kInvalidFileHandle on error). */ + PP_Bool (*OpenResource)(void* user_data, + const char* entry_key, + PP_OpenResourceCompletionCallback callback, + void* callback_user_data); }; -typedef struct PP_ManifestService_1_0 PP_ManifestService; +typedef struct PPP_ManifestService_1_0 PPP_ManifestService; /* PPB_NaCl_Private */ struct PPB_NaCl_Private_1_0 { @@ -218,7 +236,7 @@ struct PPB_NaCl_Private_1_0 { PP_Bool enable_dyncode_syscalls, PP_Bool enable_exception_handling, PP_Bool enable_crash_throttling, - const struct PP_ManifestService_1_0* manifest_service_interface, + const struct PPP_ManifestService_1_0* manifest_service_interface, void* manifest_service_user_data, void* imc_handle, struct PP_Var* error_message, diff --git a/ppapi/nacl_irt/DEPS b/ppapi/nacl_irt/DEPS index b759edf..8e4bc77 100644 --- a/ppapi/nacl_irt/DEPS +++ b/ppapi/nacl_irt/DEPS @@ -10,6 +10,7 @@ include_rules = [ "+native_client/src/shared/srpc/nacl_srpc.h", "+native_client/src/untrusted/irt/irt.h", "+native_client/src/untrusted/irt/irt_private.h", - # The IRT also needs to know the sysconf enums. + # The IRT also needs to know the errno and sysconf enums. + "+native_client/src/trusted/service_runtime/include/sys/errno.h", "+native_client/src/trusted/service_runtime/include/sys/unistd.h", ] diff --git a/ppapi/nacl_irt/irt_manifest.h b/ppapi/nacl_irt/irt_manifest.h new file mode 100644 index 0000000..b1e0923 --- /dev/null +++ b/ppapi/nacl_irt/irt_manifest.h @@ -0,0 +1,21 @@ +// Copyright 2014 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 PPAPI_NACL_IRT_IRT_MANIFEST_H_ +#define PPAPI_NACL_IRT_IRT_MANIFEST_H_ + +#include "ppapi/proxy/ppapi_proxy_export.h" + +namespace ppapi { + +// The implementation of irt_open_resource() based on ManifestService. +// This communicates with the renderer process via Chrome IPC to obtain the +// read-only file descriptor of the resource specified in the manifest file +// with the key |file| in files section. Returns 0 on success, or error number +// on failure. See also irt_open_resource()'s comment. +PPAPI_PROXY_EXPORT int IrtOpenResource(const char* file, int* fd); + +} // namespace ppapi + +#endif // PPAPI_NACL_IRT_IRT_MANIFEST_H_ diff --git a/ppapi/nacl_irt/manifest_service.cc b/ppapi/nacl_irt/manifest_service.cc index ed7c4eb..0afa217 100644 --- a/ppapi/nacl_irt/manifest_service.cc +++ b/ppapi/nacl_irt/manifest_service.cc @@ -8,10 +8,15 @@ #include "ipc/ipc_channel_handle.h" #include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_sync_message_filter.h" +#include "native_client/src/trusted/service_runtime/include/sys/errno.h" +#include "ppapi/nacl_irt/irt_manifest.h" +#include "ppapi/nacl_irt/plugin_startup.h" #include "ppapi/proxy/ppapi_messages.h" namespace ppapi { +const char kFilePrefix[] = "files/"; + ManifestService::ManifestService( const IPC::ChannelHandle& handle, scoped_refptr<base::MessageLoopProxy> io_message_loop, @@ -19,7 +24,7 @@ ManifestService::ManifestService( filter_ = new IPC::SyncMessageFilter(shutdown_event); channel_.reset(new IPC::ChannelProxy(handle, IPC::Channel::MODE_SERVER, - NULL, // Listener + NULL, // Listener io_message_loop)); channel_->AddFilter(filter_.get()); } @@ -31,4 +36,34 @@ void ManifestService::StartupInitializationComplete() { filter_->Send(new PpapiHostMsg_StartupInitializationComplete); } +bool ManifestService::OpenResource(const char* file, int* fd) { + // OpenResource will return INVALID SerializedHandle, if it is not supported. + // Specifically, PNaCl doesn't support open resource. + ppapi::proxy::SerializedHandle ipc_fd; + if (!filter_->Send(new PpapiHostMsg_OpenResource( + std::string(kFilePrefix) + file, &ipc_fd)) || + !ipc_fd.is_file()) { + LOG(ERROR) << "ManifestService::OpenResource failed:" << file; + *fd = -1; + return false; + } + + *fd = ipc_fd.descriptor().fd; + return true; +} + +int IrtOpenResource(const char* file, int* fd) { + // Remove leading '/' character. + if (file[0] == '/') + ++file; + + ManifestService* manifest_service = GetManifestService(); + if (manifest_service == NULL || + !manifest_service->OpenResource(file, fd)) { + return NACL_ABI_EIO; + } + + return (*fd == -1) ? NACL_ABI_ENOENT : 0; +} + } // namespace ppapi diff --git a/ppapi/nacl_irt/manifest_service.h b/ppapi/nacl_irt/manifest_service.h index ec5e38c..ce414cc 100644 --- a/ppapi/nacl_irt/manifest_service.h +++ b/ppapi/nacl_irt/manifest_service.h @@ -30,6 +30,7 @@ class ManifestService { ~ManifestService(); void StartupInitializationComplete(); + bool OpenResource(const char* file, int* fd); private: scoped_ptr<IPC::ChannelProxy> channel_; diff --git a/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h b/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h index 4d4c923..5e8ca99 100644 --- a/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h +++ b/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h @@ -28,7 +28,7 @@ typedef PP_ExternalPluginResult (*LaunchNaClProcessFunc)( PP_Bool enable_dyncode_syscalls, PP_Bool enable_exception_handling, PP_Bool enable_crash_throttling, - const PP_ManifestService* manifest_service_interface, + const PPP_ManifestService* manifest_service_interface, void* manifest_service_user_data, NaClHandle* result_socket, struct PP_Var* error_message, diff --git a/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc b/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc index bd8ee9e..d27de7e 100644 --- a/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc +++ b/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc @@ -27,7 +27,7 @@ void SelLdrLauncherChrome::Start( bool enable_dyncode_syscalls, bool enable_exception_handling, bool enable_crash_throttling, - const PP_ManifestService* manifest_service_interface, + const PPP_ManifestService* manifest_service_interface, void* manifest_service_user_data, PP_Var* error_message, pp::CompletionCallback callback) { diff --git a/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h b/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h index 50e8848..7ab2339 100644 --- a/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h +++ b/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h @@ -25,7 +25,7 @@ class SelLdrLauncherChrome : public nacl::SelLdrLauncherBase { bool enable_dyncode_syscalls, bool enable_exception_handling, bool enable_crash_throttling, - const PP_ManifestService* manifest_service_interface, + const PPP_ManifestService* manifest_service_interface, void* manifest_service_user_data, PP_Var* error_message, pp::CompletionCallback callback); diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.cc b/ppapi/native_client/src/trusted/plugin/service_runtime.cc index 7406e79..d7c8683 100644 --- a/ppapi/native_client/src/trusted/plugin/service_runtime.cc +++ b/ppapi/native_client/src/trusted/plugin/service_runtime.cc @@ -56,6 +56,42 @@ #include "ppapi/native_client/src/trusted/weak_ref/call_on_main_thread.h" namespace plugin { + +class OpenManifestEntryAsyncCallback { + public: + OpenManifestEntryAsyncCallback(PP_OpenResourceCompletionCallback callback, + void* callback_user_data) + : callback_(callback), callback_user_data_(callback_user_data) { + } + + ~OpenManifestEntryAsyncCallback() { + if (callback_) + callback_(callback_user_data_, PP_kInvalidFileHandle); + } + + void Run(int32_t pp_error) { +#if defined(OS_WIN) + // Currently, this is used only for non-SFI mode, and now the mode is not + // supported on windows. + // TODO(hidehiko): Support it on Windows when we switch to use + // ManifestService also in SFI-mode. + NACL_NOTREACHED(); +#elif defined(OS_POSIX) + // On posix, PlatformFile is the file descriptor. + callback_(callback_user_data_, (pp_error == PP_OK) ? info_.desc : -1); + callback_ = NULL; +#endif + } + + NaClFileInfo* mutable_info() { return &info_; } + + private: + NaClFileInfo info_; + PP_OpenResourceCompletionCallback callback_; + void* callback_user_data_; + DISALLOW_COPY_AND_ASSIGN(OpenManifestEntryAsyncCallback); +}; + namespace { // For doing crude quota enforcement on writes to temp files. @@ -92,6 +128,25 @@ class ManifestService { return true; } + bool OpenResource(const char* entry_key, + PP_OpenResourceCompletionCallback callback, + void* callback_user_data) { + // Release this instance if the ServiceRuntime is already destructed. + if (anchor_->is_abandoned()) { + callback(callback_user_data, PP_kInvalidFileHandle); + delete this; + return false; + } + + OpenManifestEntryAsyncCallback* open_manifest_callback = + new OpenManifestEntryAsyncCallback(callback, callback_user_data); + plugin_reverse_->OpenManifestEntryAsync( + entry_key, + open_manifest_callback->mutable_info(), + open_manifest_callback); + return true; + } + static PP_Bool QuitTrampoline(void* user_data) { return PP_FromBool(static_cast<ManifestService*>(user_data)->Quit()); } @@ -101,6 +156,15 @@ class ManifestService { StartupInitializationComplete()); } + static PP_Bool OpenResourceTrampoline( + void* user_data, + const char* entry_key, + PP_OpenResourceCompletionCallback callback, + void* callback_user_data) { + return PP_FromBool(static_cast<ManifestService*>(user_data)->OpenResource( + entry_key, callback, callback_user_data)); + } + private: // Weak reference to check if plugin_reverse is legally accessible or not. nacl::WeakRefAnchor* anchor_; @@ -110,13 +174,27 @@ class ManifestService { }; // Vtable to pass functions to LaunchSelLdr. -const PP_ManifestService kManifestServiceVTable = { +const PPP_ManifestService kManifestServiceVTable = { &ManifestService::QuitTrampoline, &ManifestService::StartupInitializationCompleteTrampoline, + &ManifestService::OpenResourceTrampoline, }; } // namespace +OpenManifestEntryResource::~OpenManifestEntryResource() { + MaybeRunCallback(PP_ERROR_ABORTED); +} + +void OpenManifestEntryResource::MaybeRunCallback(int32_t pp_error) { + if (!callback) + return; + + callback->Run(pp_error); + delete callback; + callback = NULL; +} + PluginReverseInterface::PluginReverseInterface( nacl::WeakRefAnchor* anchor, Plugin* plugin, @@ -195,7 +273,7 @@ bool PluginReverseInterface::OpenManifestEntry(nacl::string url_key, // the main thread before this function can return. The pointers it contains // to stack variables will not leak. OpenManifestEntryResource* to_open = - new OpenManifestEntryResource(url_key, info, &op_complete); + new OpenManifestEntryResource(url_key, info, &op_complete, NULL); CHECK(to_open != NULL); NaClLog(4, "PluginReverseInterface::OpenManifestEntry: %s\n", url_key.c_str()); @@ -245,6 +323,16 @@ bool PluginReverseInterface::OpenManifestEntry(nacl::string url_key, return true; } +void PluginReverseInterface::OpenManifestEntryAsync( + const nacl::string& entry_key, + struct NaClFileInfo* info, + OpenManifestEntryAsyncCallback* callback) { + bool op_complete = false; + OpenManifestEntryResource to_open( + entry_key, info, &op_complete, callback); + OpenManifestEntry_MainThreadContinuation(&to_open, PP_OK); +} + // Transfer point from OpenManifestEntry() which runs on the main thread // (Some PPAPI actions -- like StreamAsFile -- can only run on the main thread). // OpenManifestEntry() is waiting on a condvar for this continuation to @@ -265,10 +353,13 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation( NaClLog(4, "OpenManifestEntry_MainThreadContinuation: ResolveKey failed\n"); // Failed, and error_info has the details on what happened. Wake // up requesting thread -- we are done. - nacl::MutexLocker take(&mu_); - *p->op_complete_ptr = true; // done... - p->file_info->desc = -1; // but failed. - NaClXCondVarBroadcast(&cv_); + { + nacl::MutexLocker take(&mu_); + *p->op_complete_ptr = true; // done... + p->file_info->desc = -1; // but failed. + NaClXCondVarBroadcast(&cv_); + } + p->MaybeRunCallback(PP_OK); return; } NaClLog(4, @@ -281,10 +372,13 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation( NaClLog(4, "OpenManifestEntry_MainThreadContinuation: " "Requires PNaCl translation -- not supported\n"); - nacl::MutexLocker take(&mu_); - *p->op_complete_ptr = true; // done... - p->file_info->desc = -1; // but failed. - NaClXCondVarBroadcast(&cv_); + { + nacl::MutexLocker take(&mu_); + *p->op_complete_ptr = true; // done... + p->file_info->desc = -1; // but failed. + NaClXCondVarBroadcast(&cv_); + } + p->MaybeRunCallback(PP_OK); return; } @@ -302,14 +396,17 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation( "OpenManifestEntry_MainThreadContinuation: " "GetReadonlyPnaclFd failed\n"); } - nacl::MutexLocker take(&mu_); - *p->op_complete_ptr = true; // done! - // TODO(ncbray): enable the fast loading and validation paths for this - // type of file. - p->file_info->desc = fd; - NaClXCondVarBroadcast(&cv_); + { + nacl::MutexLocker take(&mu_); + *p->op_complete_ptr = true; // done! + // TODO(ncbray): enable the fast loading and validation paths for this + // type of file. + p->file_info->desc = fd; + NaClXCondVarBroadcast(&cv_); + } NaClLog(4, "OpenManifestEntry_MainThreadContinuation: GetPnaclFd okay\n"); + p->MaybeRunCallback(PP_OK); return; } @@ -319,6 +416,9 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation( // to create another instance. OpenManifestEntryResource* open_cont = new OpenManifestEntryResource(*p); open_cont->url = mapped_url; + // Callback is now delegated from p to open_cont. So, here we manually clear + // complete callback. + p->callback = NULL; pp::CompletionCallback stream_cc = WeakRefNewCallback( anchor_, this, @@ -346,22 +446,26 @@ void PluginReverseInterface::StreamAsFile_MainThreadContinuation( NaClLog(4, "Entered StreamAsFile_MainThreadContinuation\n"); - nacl::MutexLocker take(&mu_); - if (result == PP_OK) { - NaClLog(4, "StreamAsFile_MainThreadContinuation: GetFileInfo(%s)\n", - p->url.c_str()); - *p->file_info = plugin_->GetFileInfo(p->url); + { + nacl::MutexLocker take(&mu_); + if (result == PP_OK) { + NaClLog(4, "StreamAsFile_MainThreadContinuation: GetFileInfo(%s)\n", + p->url.c_str()); + *p->file_info = plugin_->GetFileInfo(p->url); - NaClLog(4, - "StreamAsFile_MainThreadContinuation: PP_OK, desc %d\n", - p->file_info->desc); - } else { - NaClLog(4, - "StreamAsFile_MainThreadContinuation: !PP_OK, setting desc -1\n"); - p->file_info->desc = -1; + NaClLog(4, + "StreamAsFile_MainThreadContinuation: PP_OK, desc %d\n", + p->file_info->desc); + } else { + NaClLog( + 4, + "StreamAsFile_MainThreadContinuation: !PP_OK, setting desc -1\n"); + p->file_info->desc = -1; + } + *p->op_complete_ptr = true; + NaClXCondVarBroadcast(&cv_); } - *p->op_complete_ptr = true; - NaClXCondVarBroadcast(&cv_); + p->MaybeRunCallback(PP_OK); } bool PluginReverseInterface::CloseManifestEntry(int32_t desc) { diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.h b/ppapi/native_client/src/trusted/plugin/service_runtime.h index 07850d4..ca12764 100644 --- a/ppapi/native_client/src/trusted/plugin/service_runtime.h +++ b/ppapi/native_client/src/trusted/plugin/service_runtime.h @@ -41,6 +41,7 @@ namespace plugin { class ErrorInfo; class Manifest; +class OpenManifestEntryAsyncCallback; class Plugin; class SrpcClient; class ServiceRuntime; @@ -87,13 +88,19 @@ struct OpenManifestEntryResource { public: OpenManifestEntryResource(const std::string& target_url, struct NaClFileInfo* finfo, - bool* op_complete) + bool* op_complete, + OpenManifestEntryAsyncCallback* callback) : url(target_url), file_info(finfo), - op_complete_ptr(op_complete) {} + op_complete_ptr(op_complete), + callback(callback) {} + ~OpenManifestEntryResource(); + void MaybeRunCallback(int32_t pp_error); + std::string url; struct NaClFileInfo* file_info; bool* op_complete_ptr; + OpenManifestEntryAsyncCallback* callback; }; struct CloseManifestEntryResource { @@ -170,6 +177,15 @@ class PluginReverseInterface: public nacl::ReverseInterface { const pp::FileIO& file_io); void AddTempQuotaManagedFile(const nacl::string& file_id); + // This is a sibling of OpenManifestEntry. While OpenManifestEntry is + // a sync function and must be called on a non-main thread, + // OpenManifestEntryAsync must be called on the main thread. Upon completion + // (even on error), callback will be invoked. The caller has responsibility + // to keep the memory passed to info until callback is invoked. + void OpenManifestEntryAsync(const nacl::string& key, + struct NaClFileInfo* info, + OpenManifestEntryAsyncCallback* callback); + protected: virtual void PostMessage_MainThreadContinuation(PostMessageResource* p, int32_t err); diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c index b6efef0..4713148 100644 --- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c +++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c @@ -3082,11 +3082,11 @@ static int32_t Pnacl_M33_PPB_IsolatedFileSystem_Private_Open(PP_Instance instanc /* End wrapper methods for PPB_IsolatedFileSystem_Private_0_2 */ -/* Not generating wrapper methods for PP_ManifestService_1_0 */ +/* Not generating wrapper methods for PPP_ManifestService_1_0 */ /* Begin wrapper methods for PPB_NaCl_Private_1_0 */ -static void Pnacl_M25_PPB_NaCl_Private_LaunchSelLdr(PP_Instance instance, const char* alleged_url, PP_Bool uses_irt, PP_Bool uses_ppapi, PP_Bool uses_nonsfi_mode, PP_Bool enable_ppapi_dev, PP_Bool enable_dyncode_syscalls, PP_Bool enable_exception_handling, PP_Bool enable_crash_throttling, const struct PP_ManifestService_1_0* manifest_service_interface, void* manifest_service_user_data, void* imc_handle, struct PP_Var* error_message, struct PP_CompletionCallback* callback) { +static void Pnacl_M25_PPB_NaCl_Private_LaunchSelLdr(PP_Instance instance, const char* alleged_url, PP_Bool uses_irt, PP_Bool uses_ppapi, PP_Bool uses_nonsfi_mode, PP_Bool enable_ppapi_dev, PP_Bool enable_dyncode_syscalls, PP_Bool enable_exception_handling, PP_Bool enable_crash_throttling, const struct PPP_ManifestService_1_0* manifest_service_interface, void* manifest_service_user_data, void* imc_handle, struct PP_Var* error_message, struct PP_CompletionCallback* callback) { const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; iface->LaunchSelLdr(instance, alleged_url, uses_irt, uses_ppapi, uses_nonsfi_mode, enable_ppapi_dev, enable_dyncode_syscalls, enable_exception_handling, enable_crash_throttling, manifest_service_interface, manifest_service_user_data, imc_handle, error_message, *callback); } @@ -4971,10 +4971,10 @@ static const struct PPB_IsolatedFileSystem_Private_0_2 Pnacl_Wrappers_PPB_Isolat .Open = (int32_t (*)(PP_Instance instance, PP_IsolatedFileSystemType_Private type, PP_Resource* file_system, struct PP_CompletionCallback callback))&Pnacl_M33_PPB_IsolatedFileSystem_Private_Open }; -/* Not generating wrapper interface for PP_ManifestService_1_0 */ +/* Not generating wrapper interface for PPP_ManifestService_1_0 */ static const struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = { - .LaunchSelLdr = (void (*)(PP_Instance instance, const char* alleged_url, PP_Bool uses_irt, PP_Bool uses_ppapi, PP_Bool uses_nonsfi_mode, PP_Bool enable_ppapi_dev, PP_Bool enable_dyncode_syscalls, PP_Bool enable_exception_handling, PP_Bool enable_crash_throttling, const struct PP_ManifestService_1_0* manifest_service_interface, void* manifest_service_user_data, void* imc_handle, struct PP_Var* error_message, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_LaunchSelLdr, + .LaunchSelLdr = (void (*)(PP_Instance instance, const char* alleged_url, PP_Bool uses_irt, PP_Bool uses_ppapi, PP_Bool uses_nonsfi_mode, PP_Bool enable_ppapi_dev, PP_Bool enable_dyncode_syscalls, PP_Bool enable_exception_handling, PP_Bool enable_crash_throttling, const struct PPP_ManifestService_1_0* manifest_service_interface, void* manifest_service_user_data, void* imc_handle, struct PP_Var* error_message, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_LaunchSelLdr, .StartPpapiProxy = (PP_Bool (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_StartPpapiProxy, .UrandomFD = (int32_t (*)(void))&Pnacl_M25_PPB_NaCl_Private_UrandomFD, .Are3DInterfacesDisabled = (PP_Bool (*)(void))&Pnacl_M25_PPB_NaCl_Private_Are3DInterfacesDisabled, diff --git a/ppapi/ppapi_nacl_test_common.gypi b/ppapi/ppapi_nacl_test_common.gypi index b5c60555..0d9b676 100644 --- a/ppapi/ppapi_nacl_test_common.gypi +++ b/ppapi/ppapi_nacl_test_common.gypi @@ -19,6 +19,7 @@ 'nacl_newlib_out_dir': '<(PRODUCT_DIR)/>(nexe_destination_dir)/newlib', 'nacl_glibc_out_dir': '<(PRODUCT_DIR)/>(nexe_destination_dir)/glibc', 'nacl_pnacl_newlib_out_dir': '<(PRODUCT_DIR)/>(nexe_destination_dir)/pnacl', + 'nacl_pnacl_newlib_nonsfi_out_dir': '<(PRODUCT_DIR)/>(nexe_destination_dir)/nonsfi', 'target_conditions': [ ['nexe_target!=""', { # These variables are used for nexe building and for library building. @@ -33,6 +34,7 @@ 'nmf_glibc%': '>(nacl_glibc_out_dir)/>(nexe_target).nmf', 'out_pnacl_newlib%': '>(nacl_pnacl_newlib_out_dir)/>(nexe_target)_newlib_pnacl.pexe', 'nmf_pnacl_newlib%': '>(nacl_pnacl_newlib_out_dir)/>(nexe_target).nmf', + 'out_pnacl_newlib_x86_32_nonsfi_nexe': '>(nacl_pnacl_newlib_nonsfi_out_dir)/>(nexe_target)_pnacl_newlib_x32_nonsfi.nexe', }], ], }, @@ -62,7 +64,8 @@ }, ], }], - ['test_files!=[] and build_pnacl_newlib==1 and disable_pnacl==0', { + # Nonsfi pnacl copy is covered below. Currently, these are exclusive. + ['test_files!=[] and build_pnacl_newlib==1 and disable_pnacl==0 and enable_x86_32_nonsfi==0', { 'copies': [ { 'destination': '>(nacl_pnacl_newlib_out_dir)', @@ -72,6 +75,16 @@ }, ], }], + ['test_files!=[] and build_pnacl_newlib==1 and enable_x86_32_nonsfi==1', { + 'copies': [ + { + 'destination': '>(nacl_pnacl_newlib_nonsfi_out_dir)', + 'files': [ + '>@(test_files)', + ], + }, + ], + }], ['nexe_target!=""', { 'variables': { # Patch over the fact that untrusted.gypi doesn't define these in all diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 10cde4e..5fe5e968 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -756,6 +756,11 @@ IPC_MESSAGE_CONTROL1(PpapiHostMsg_ChannelCreated, // Notify the renderer that the PPAPI channel gets ready in the plugin. IPC_MESSAGE_CONTROL0(PpapiHostMsg_StartupInitializationComplete); +// Calls renderer to open a resource file for nacl_irt_open_resource(). +IPC_SYNC_MESSAGE_CONTROL1_1(PpapiHostMsg_OpenResource, + std::string /* key */, + ppapi::proxy::SerializedHandle /* fd */) + // Logs the given message to the console of all instances. IPC_MESSAGE_CONTROL4(PpapiHostMsg_LogWithSource, PP_Instance /* instance */, |