summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/nacl_host/nacl_process_host.cc10
-rw-r--r--chrome/nacl/nacl_listener.cc70
2 files changed, 48 insertions, 32 deletions
diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc
index d254d44..a119ec3 100644
--- a/chrome/browser/nacl_host/nacl_process_host.cc
+++ b/chrome/browser/nacl_host/nacl_process_host.cc
@@ -498,11 +498,11 @@ void NaClProcessHost::SendStart(base::PlatformFile irt_file) {
return;
}
-#if defined(OS_MACOSX)
- // For dynamic loading support, NaCl requires a file descriptor that
- // was created in /tmp, since those created with shm_open() are not
- // mappable with PROT_EXEC. Rather than requiring an extra IPC
- // round trip out of the sandbox, we create an FD here.
+#if defined(OS_POSIX)
+ // For dynamic loading support, NaCl requires a file descriptor on an
+ // anonymous file that can have PROT_EXEC applied to its mappings.
+ // Rather than requiring an extra IPC round trip out of the sandbox,
+ // we create an FD here.
base::SharedMemory memory_buffer;
if (!memory_buffer.CreateAnonymous(/* size= */ 1)) {
LOG(ERROR) << "Failed to allocate memory buffer";
diff --git a/chrome/nacl/nacl_listener.cc b/chrome/nacl/nacl_listener.cc
index 55f7e43..9141025 100644
--- a/chrome/nacl/nacl_listener.cc
+++ b/chrome/nacl/nacl_listener.cc
@@ -33,41 +33,59 @@ typedef HANDLE NaClHandle;
typedef int NaClHandle;
#endif // NaClHandle
-#if defined(OS_MACOSX)
+#if defined(OS_POSIX)
namespace {
-// On Mac OS X, shm_open() works in the sandbox but does not give us
-// an FD that we can map as PROT_EXEC. Rather than doing an IPC to
-// get an executable SHM region when CreateMemoryObject() is called,
-// we preallocate one on startup, since NaCl's sel_ldr only needs one
-// of them. This saves a round trip.
+// On Mac OS X, shm_open() works in the sandbox but does not give us an FD
+// that we can map as PROT_EXEC. On Linux, shm_open() can only be used
+// outside the sandbox anyway. Rather than doing an IPC to get an
+// executable SHM region when CreateMemoryObject() is called, we
+// preallocate one on startup, since NaCl's sel_ldr only needs one of them.
+// This saves a round trip.
+
+bool SetShmFdSize(int fd, size_t size) {
+#if defined(OS_MACOSX)
+ // ftruncate() is disallowed by the Mac OS X sandbox and returns EPERM.
+ // Luckily, we can get the same effect with lseek() + write().
+ if (lseek(fd, size - 1, SEEK_SET) == -1) {
+ LOG(ERROR) << "lseek() failed: " << errno;
+ close(fd);
+ return false;
+ }
+ if (write(fd, "", 1) != 1) {
+ LOG(ERROR) << "write() failed: " << errno;
+ close(fd);
+ return -1;
+ }
+#else
+ if (ftruncate(fd, size) < 0) {
+ LOG(ERROR) << "ftruncate() failed: " << errno;
+ close(fd);
+ return false;
+ }
+#endif // defined(OS_MACOSX)
+ return true;
+}
base::subtle::Atomic32 g_shm_fd = -1;
int CreateMemoryObject(size_t size, bool executable) {
if (executable && size > 0) {
int result_fd = base::subtle::NoBarrier_AtomicExchange(&g_shm_fd, -1);
- if (result_fd != -1) {
- // ftruncate() is disallowed by the Mac OS X sandbox and
- // returns EPERM. Luckily, we can get the same effect with
- // lseek() + write().
- if (lseek(result_fd, size - 1, SEEK_SET) == -1) {
- LOG(ERROR) << "lseek() failed: " << errno;
- return -1;
- }
- if (write(result_fd, "", 1) != 1) {
- LOG(ERROR) << "write() failed: " << errno;
- return -1;
- }
+ if (result_fd != -1 && SetShmFdSize(result_fd, size))
return result_fd;
- }
}
+#if defined(OS_LINUX)
+ // Use the proxied implementation. It doesn't really support executability.
+ CHECK(!executable);
+ return content::MakeSharedMemorySegmentViaIPC(size, executable);
+#endif
// Fall back to NaCl's default implementation.
return -1;
}
} // namespace
-#endif // defined(OS_MACOSX)
+#endif // defined(OS_POSIX)
extern "C" void NaClMainForChromium(int handle_count,
const NaClHandle* handles,
@@ -97,17 +115,15 @@ bool NaClListener::OnMessageReceived(const IPC::Message& msg) {
}
void NaClListener::OnStartSelLdr(std::vector<nacl::FileDescriptor> handles) {
-#if defined(OS_LINUX)
- nacl::SetCreateMemoryObjectFunc(content::MakeSharedMemorySegmentViaIPC);
-#elif defined(OS_MACOSX)
+#if defined(OS_POSIX)
nacl::SetCreateMemoryObjectFunc(CreateMemoryObject);
- CHECK(handles.size() >= 1);
- g_shm_fd = nacl::ToNativeHandle(handles[handles.size() - 1]);
+ CHECK(!handles.empty());
+ g_shm_fd = nacl::ToNativeHandle(handles.back());
handles.pop_back();
#endif
- CHECK(handles.size() >= 1);
- NaClHandle irt_handle = nacl::ToNativeHandle(handles[handles.size() - 1]);
+ CHECK(!handles.empty());
+ NaClHandle irt_handle = nacl::ToNativeHandle(handles.back());
handles.pop_back();
#if defined(OS_WIN)