No way to use shm_open(3)

Bug #1578217 reported by Zygmunt Krynicki
16
This bug affects 2 people
Affects Status Importance Assigned to Milestone
snapd
Confirmed
Undecided
Zygmunt Krynicki

Bug Description

This bug collects all of the research about how programs using shm_open(3) operate within a snappy environment.

Currently snappy allows programs to open files under /dev/shm/snap/$SNAP_NAME/$SNAP_REVISION/. This is implemented as an entry in interfaces/apparmor/template.go. There are a few problems with this rule:

- Programs don't have any permissions to create /dev/shm/snap, /dev/shm/snap/$SNAP_NAME or /dev/shm/snap/$SNAP_NAME/$SNAP_REVISIONS and ubuntu-core-launcher does not create this directory either.

- The actual function shm_open(3) does not allow programs to choose the directory. The manual page says that at most one / character can be used (and glibc verifies this).

I have found a way to work around this by linking or pre-loading a helper [1] that defines a glibc function const char *__shm_directory(size_t *len) which is then used as a base for shm_open(3) but this feels like an invasive hack and it is only possible after the launcher is patched to create those directories in the first place.

It is my proposal to change ubuntu-core-launcher to bind-mount /dev/shm similarly to how we manage /tmp and relax the rules to freely manage that directory within a particular snap name.

[1] https://github.com/zyga/snappy-runtime-helper/blob/master/snappy.c

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

I think the proposal is generally fine but I wonder about its viability with pulseaudio which creates a number of shm files in /dev/shm. Eg:

$ ls -l /dev/shm/pulse-shm-*
-rwx------ 1 jamie jamie 67108904 May 2 19:11 /dev/shm/pulse-shm-1126818553
-rwx------ 1 jamie jamie 67108904 May 3 09:39 /dev/shm/pulse-shm-1225715323
-rwx------ 1 jamie jamie 67108904 May 3 16:40 /dev/shm/pulse-shm-145271673
-rwx------ 1 lightdm lightdm 67108904 May 2 19:11 /dev/shm/pulse-shm-147887719
-rwx------ 1 jamie jamie 67108904 May 4 08:35 /dev/shm/pulse-shm-1487298717
-rwx------ 1 jamie jamie 67108904 May 2 19:11 /dev/shm/pulse-shm-2387793072
-rwx------ 1 lightdm lightdm 67108904 May 2 19:11 /dev/shm/pulse-shm-2399721183
-rwx------ 1 jamie jamie 67108904 May 4 08:35 /dev/shm/pulse-shm-3323349813
-rwx------ 1 jamie jamie 67108904 May 3 14:14 /dev/shm/pulse-shm-3437821583
-rwx------ 1 lightdm lightdm 67108904 May 2 19:11 /dev/shm/pulse-shm-36248552
-rwx------ 1 jamie jamie 67108904 May 2 19:11 /dev/shm/pulse-shm-980235161

Have you tested this approach with an app that uses pulseaudio? (I understand there is no pulseaudio interface yet, but it can be tested by adjust the policy directly).

Revision history for this message
Zygmunt Krynicki (zyga) wrote :

As discussed on IRC I will first attempt to prototype this quickly to see if it works with pulseuadio and chromium/webkit.

Zygmunt Krynicki (zyga)
Changed in snappy:
assignee: nobody → Zygmunt Krynicki (zyga)
status: New → In Progress
Revision history for this message
Zygmunt Krynicki (zyga) wrote :

I'm still experimenting but some early observations:

 - pulseaudio on classic is a very simple interface that adds very little permissions and doesn't need any changes to ubuntu-core-launcher
 - a full blown pulseaudio snap needs research
 - shm_open(), in general, is still not solved due to POSIX design
 - more research is needed

I'm now looking at additional applications (chromium, dosbox)

Zygmunt Krynicki (zyga)
Changed in snappy:
status: In Progress → Triaged
Revision history for this message
Jamie Bennett (jamiebennett) wrote :

Zygmunt, what were you finding with Webkit and other applications? Can we take a look at this again now?

Revision history for this message
Zygmunt Krynicki (zyga) wrote : Re: [Bug 1578217] Re: No way to use shm_open(3)

> Wiadomość napisana przez Jamie Bennett <email address hidden> w dniu 14.11.2016, o godz. 11:48:
>
> Zygmunt, what were you finding with Webkit and other applications? Can
> we take a look at this again now?

AFAIK the bottom line for webkit is that it would require patching for explicit support of snappy confinement.

I can have a look, sure.

Changed in snappy:
status: Triaged → In Progress
Revision history for this message
Gustavo Niemeyer (niemeyer) wrote :

Note that unlike stated in the description above, our current template actually allows reading/writing to:

    /{dev,run}/shm/snap.@{SNAP_NAME}.**

That does not require creating any directories.

Revision history for this message
Penk Chen (penk) wrote :

In the case of WebKit, we've got log like:

audit(1479149116.415:327): apparmor="ALLOWED" operation="unlink" profile="snap.screenly-client.viewer" name="/dev/shm/WK2SharedMemory.2183036684" pid=3039 comm="ld-linux-armhf." requested_mask="d" denied_mask="d" fsuid=0 ouid=0 Context

According to the source [1], it's "/dev/shm/WK2SharedMemory.*".

[1] https://opensource.apple.com/source/WebKit2/WebKit2-7536.30.1/Platform/unix/SharedMemoryUnix.cpp

Revision history for this message
Zygmunt Krynicki (zyga) wrote :

I had a look at this last night and IMHO there's no easy way to solve this without expanding the kernel security features. My ideas fall into the following buckets:

1) Patching various pieces of software to understand $SNAP_NAME and use it for constructing shm_open() requests. The current confinement does allow /dev/shm/$SNAP_NAME.* which maps to C code like this:

int snap_aware_shm_open(const char *name, int oflag, mode_t mode)
{
  char *snap_name = getenv("SNAP_NAME");
  if (snap_name != NULL) {
    char shm_name[PATH_MAX];
    if (snprintf(shm_name, sizeof shm_name, "%s.%s", snap_name, name) < sizeof shm_name) {
      return shm_open(shm_name, oflag, mode);
    }
    errno = EOVERFLOW;
    return -1;
  } else {
    return shm_open(name, oflag, mode);
  }
}

This code provides an alternative to shm_open that is aware of snappy requirements. What this doesn't solve is any kind of use of shared memory as an IPC system as two interacting programs will attempt to open different names. On the up side this doesn't cause any issues for applications in one snap. I think this is interesting and worth exploring as it might "unbreak" a large class of programs.

2) Patching glibc to do something like this transparently. This is much more invasive as it breaks the IPC assumption. The up side is that it might have a chance to fix pre-built binary programs that people often use through snapcraft.

3) Patching the kernel to tag SHM memory segments with apparmor labels so that they can have any name and so that the actual label is what we can build confinement around.

Let me know if you want me to investigate this in more depth.

Revision history for this message
Zygmunt Krynicki (zyga) wrote :

I've added an extra rule that should make webkit happier. https://github.com/snapcore/snapd/pull/2275

Revision history for this message
Jamie Strandboge (jdstrand) wrote :
Zygmunt Krynicki (zyga)
Changed in snappy:
status: In Progress → Confirmed
Michael Vogt (mvo)
affects: snappy → snapd
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.