Closed Bug 1550900 Opened 5 years ago Closed 4 years ago

IPC support for shared memory with both read-only and read/write capabilities

Categories

(Core :: IPC, enhancement, P2)

enhancement

Tracking

()

RESOLVED FIXED
mozilla76
Fission Milestone M6
Tracking Status
firefox76 --- fixed

People

(Reporter: jld, Assigned: jld)

References

Details

Attachments

(1 file)

This is discussed in bug 1479960 comment #7 through 17: there are shared memory use cases where it would help to have one process retain write access to a shared memory object while giving other processes read-only access (that they can't escalate to write access even if compromised).

This can be implemented on Windows, and using POSIX shm_open, and with Linux's memfd_create (assuming the creating process can access /proc). However, older versions of Android have none of these: we have to use ashmem, where there's no way to implement this, or else temporary files which will be written back to secondary storage (even though the OS knows they won't persist) which is inefficient.

However, if we're not using sandboxing — and we're currently not yet, on Android — then this doesn't matter. So for now we can fall back to regular shared memory #ifndef MOZ_SANDBOX. Longer term when we do have Android sandboxing, we'll need to decide how to handle this: not support sandboxing on older devices, or fall back to temporary files, or require the code that would use this to send copies of data instead.

This blocks bug 1550037, which in turn blocks bug 1533462, so should presumably have the same fission-milestone.

Fission Milestone: --- → ?

It looks like I was wrong about Android in bug 1479960 comment #8: the ASHMEM_SET_PROT_MASK ioctl applies to all future mmap calls but doesn't affect existing mappings.

I'm not aware of any public documentation for ashmem that covers this, but this capability was recently added to upstream Linux's memfd, for the specific purpose of feature parity with ashmem, and there doesn't appear to be any other operation that that could be referring to. (Note the Linux commit message's reference to a high-level use case similar to ours.) Empirical testing seems to confirm this, including that pages of a writeable mapping can be written after the mask was dropped to PROT_READ even if they hadn't been touched beforehand (i.e., the page fault handling doesn't seem to check the mask, only the mmap call).

This feature is a little weaker than what I had in mind for this: once the writeable mapping is unmapped, it can't be remapped, whereas the other potential backends could all keep around a writeable fd. (However, it does allow prevent write access by a process that's more weakly sandboxed: if it can access /proc but can't pass a ptrace check for the writing process.)

In particular, the operation that we can support everywhere is basically the current Freeze minus its included Unmap (which is actually something that was asked about during review but I thought it didn't make sense). It might make more sense to expose it as a “create read-only copy” (see also Mojo) that includes the side effects of Close(/* unmap_view = */ false), to avoid having an object that's both “read/write” in its mapping and “read-only” in its fd/handle.

Tracking for Fission Nightly (M6)

This sharing stylesheets and font lists is expected to reduce content process memory footprint.

Fission Milestone: ? → M6

Hi Jed: Just wanted to see if you have any thoughts or updates on when you might work on this. Is this likely to wait until later towards the M6 milestone (i.e. not in the first half of 2020)? I'm asking mostly to help us plan for bug 1550037 and bug 1533462.

Flags: needinfo?(jld)

This patch extends shared memory freezing to support the use case where
the parent process retains write access for incremental updates, while
other processes receive read-only access.

Note that, while some OSes allow independent read-only and read/write
capabilities for the same object, all we have on Android is an operation
that prevents future write mappings. Therefore, this allows an existing
writeable mapping to be retained, but if that is unmapped then even the
parent process can't re-create it.

As with freezing, the read-only restriction may not be enforceable if
the recipient process isn't adequately sandboxed (e.g., on Linux, if it
can use /proc/self/fd to reopen the inode for writing).

Pushed by jedavis@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/0b6bdb027546
Support "frozen" shared memory where the parent process retains write access. r=froydnj
Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla76

To answer the question in comment #4, I've actually had the patch more or less finished for a while, but other things kept interrupting.

Flags: needinfo?(jld)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: