Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to pass data from to a content process when it starts up?

73 views
Skip to first unread message

Nicholas Nethercote

unread,
Feb 14, 2018, 2:02:43 AM2/14/18
to dev-platform
Hi,

When a content process is started, a bunch of pref values are sent via
some -intPrefs/-boolPrefs/-stringPrefs arguments on the command line. This
is
ugly and limiting and causes multiple problems, so I'd like to find a
different
way to send this data.

The use case is pretty simple, because it's one way data transfer. The
important thing is that it must happen very early, i.e. before the normal
IPC
mechanism gets going.

I figured shared memory would be a reasonable way to do this, something like
the following.

- The parent sets up a shared memory segment, and writes some data to it.

- The parent spawns the child, and passes identifying information about the
shared memory segment to the child (e.g. via the command line).

- The child gets the shared memory segment identifer, uses it to open the
segment, and reads the data.

- The child disposes of the shared memory segment.

At first I tried using NSPR's shared memory functions, but they're not used
anywhere else in Firefox, and they have bugs, and shmget() is blocked by the
Linux sandbox.

So then I tried using base::SharedMemory instead, from
ipc/chromium/src/base/shared_memory.h, basically like this:

Parent:
SharedMemory shm;
shm.Create(name, size);
shm.Open();
shm.Map();
char* p = shm.memory();
... write data to p ...
... launch child process, passing `name` via cmdline ...
shm.Unmap(); // done automatically when shm is destroyed
shm.Close(); // done automatically when shm is destroyed

Child:
... get `name` from the command line...
SharedMemory shm;
shm.Open(name);
shm.Map();
char* p = shm.memory();
... read data from p ...
shm.Delete(); // this is a no-op on Windows
shm.Unmap(); // done automatically when shm is destroyed
shm.Close(); // done automatically when shm is destroyed

This works fine on Unix. If the shared memory file is closed by the parent
before it's opened by the child, that's ok, because it persists until it is
explicitly deleted.

But it doesn't work on Windows. On Windows Delete() does nothing. Instead, a
file mapping object is auto-deleted when its refcount falls to zero. So if
the
parent calls Close() before the child calls Open() -- which happens in
practice -- then the file mapping object is auto-deleted and the child
Open()
fails.

If I change the parent to heap-allocate `shm` so it's not auto-destroyed at
the
end of the function, things work out, but we'll end up with leaks: the
SharedMemory object, opened file view, the handle, and the file mapping will
all leak.

I then tried using SharedMemory::ShareToProcess(), but that requires that
the
child process already exist and the parent has its PID, which is a pain.

I then found this blog post from Raymond Chen:
https://blogs.msdn.microsoft.com/oldnewthing/20031211-00/?p=41543

It describes exactly what I want, but it requires using the bInheritHandle
parameter, which base::SharedMemory doesn't do. I could change it to do so,
but
then it looks like I'd need to deal with I then found
LaunchOptions::handles_to_inherit as well... and at this point I figure it's
worth asking for help!

Does anybody have suggestions about the best way to do this? Thanks.

Nick

bo...@mozilla.com

unread,
Feb 14, 2018, 4:23:05 AM2/14/18
to
Hi Nick,

SandboxBroker::AddHandleToShare was added to add the handles to the sandbox policy, before it was realised that we'd need to do this for the non-sandboxed process launch as well, hence LaunchOptions::handles_to_inherit.

I think we should change [1] to pass the LaunchOptions and then use them within SandboxBroker::LaunchApp to add the handles to the policy and get rid of SandboxBroker::AddHandleToShare.

Cheers,
Bob

[1] https://searchfox.org/mozilla-central/rev/d03ad8843e3bf2e856126bc53b0475c595e5183b/ipc/glue/GeckoChildProcessHost.cpp#1046

bo...@mozilla.com

unread,
Feb 14, 2018, 4:35:51 AM2/14/18
to
Perhaps we should also change the various GeckoChildProcessHost Launch methods to accept LaunchOptions or a similar structure instead of aExtraOpts.

Nicholas Nethercote

unread,
Feb 15, 2018, 7:26:57 PM2/15/18
to bo...@mozilla.com, dev-platform
Thank you! That was exactly the info I needed, and I have it working
locally.

However, I didn't do exactly as you suggested -- passing
LaunchOptions to Sandbroker::LaunchApp dragged me into #include hell:

- base::LaunchOptions must be visible in
security/sandbox/win/src/sandboxbroker/sandboxBroker.{h,cpp}, which
requires
including ipc/chromium/src/base/process_util.h.

- We end up including headers from two significantly different versions of
the
Chromium code: ipc/chromium/base/process_util.h and
security/sandbox/chromium/sandbox/win/src/src/sandbox.h and we hit trouble
with repeated declarations, e.g.:
- DISALLOW_COPY_AND_ASSIGN, from ipc/chromium/src/base/basictypes.h and
security/sandbox/chromium/base/macros.h
- DISALLOW_IMPLICIT_CONSTRUCTORS, likewise
- LinkerInitialized
- etc.

To avoid this, I chose to pass in a std::vector<HANDLE> instead of a
LaunchOptions to SandboxBroker::LaunchApp.

Nick
> _______________________________________________
> dev-platform mailing list
> dev-pl...@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-platform
>
0 new messages