Open Bug 845736 Opened 7 years ago Updated 4 years ago

Create "Supervisor" protocol to request privileged operations

Categories

(Core :: General, defect)

x86_64
Linux
defect
Not set

Tracking

()

People

(Reporter: cjones, Unassigned)

References

(Blocks 1 open bug)

Details

The v1.0 b2g "system" process needs elevated privileges to
 - configure lmk on startup
 - adjust oom_adj values
 - adjust nice values
 - reboot/shutdown
 - initiate applying gecko update
 - initiate applying system update
 - (!!!!) drop privileges of spawned subprocesses

This is a much more reasonable set of interfaces to secure.

In gonk, we can implement everything but the last by having init launch a b2g process that spawns a special system app as system.system.  But not that last one (AFAIK), which is pretty sensible from the kernel perspective.

So the work here covers everything but the last item: we want to create something like PSupervisor with those interfaces, then have the spawned child sete(u|g)id() to system.  Until the followup work lands, it can seteuid() back to privileged to implement the last item.  That is, we don't really add better security here, but we prepare for it.
This will add one more gecko process to the system, BUT
 - it MUST NOT initialize xpcom.  Nothing in there we need or want.
 - it MUST NOT create instances of the JS runtime.  Do not want.

Since this code will use IPC and common helpers, we do want it to use libxul.  It should hopefully touch a small number of code pages.

So I expect this process to have a small memory footprint (RSS).
Assignee: nobody → jhector
Hi Julian,

Reading your comment  at [1] I thought I should give you some guidance on how to properly do I/O in b2g's system code.

There are usually two threads involved in I/O the main thread and the I/O thread. The main thread runs JS and all DOM requests. When you execute JS code and call a DOM interface, the call will be processed on the main thread.

The I/O thread implements a poll loop and handles all file-descriptor I/O.

Both thread communicate using message passing via classes of |nsRunnable| of |Task|. When you need to write to a file descriptor, you should send the data task to the I/O thread, poll the file descriptor to become writable and then write the data on the I/O thread. When you need to read from a file descriptor, you should send a task to the I/O thread, poll for readable data, read the data on the I/O thread and  send a |nsRunnable| with the result back to the main thread.

Both threads are shared by a lot of code, so it's important that you never block during I/O. Never use blocking shared variables (e.g., locks) for thread-communication; use message passing instead. Always add your file descriptor to the poll loop and perform I/O in the callback method.

You should to go through |UnixSocketConsumer| [2] to see how this works in practice. Methods of UnixSocketConsumer are executed on the main thread, it's I/O component, |UnixSocketImpl|, executes on the I/O thread. Both communicate using instances of |nsRunnable| and |Task|.

[1] https://github.com/tdz/platform_system_libfdio/commit/b89b1e12cdb6b70c47a849c3f6ee5a84a290f0a8
[2] http://dxr.mozilla.org/mozilla-central/source/ipc/unixsocket/UnixSocket.cpp#743
(In reply to Thomas Zimmermann [:tzimmermann] [:tdz] from comment #2)

Hey Thomas, sorry for the late response, I didn't have time to look at this last week.
Thank you for the tip with the SocketConsumer, I will look at it and work with it in b2g 

Thanks
Assignee: julian.r.hector → nobody
You need to log in before you can comment on or make changes to this bug.