Failed to flush stdout: Permission denied

@tyhicks I don’t have the inside knowledge on this, but I would anticipate that an important question is whether rdmd is invoking the dmd binary inside the snap directly, or instead invoking /snap/bin/dmd.

I’ll try to put in some time today or tomorrow to confirm that.

I set up a test snap package where the dmd compiler binary is called dmd-compiler internally, with the external command exposed by the snap still being dmd:

apps:
  dmd:
    command: bin/dmd-compiler

Having installed this, I tried two different commands:

dmd.rdmd --compiler=/snap/bin/dmd hello.d

… produced the same Failed to flush stdout: Permission denied error as before, and the same apparmor error via snappy-debug.security.scanlog.

On the other hand,

dmd.rdmd --compiler=/snap/dmd/current/bin/dmd-compiler hello.d

… compiled and ran the hello.d source file as expected.

I tried to repeat the process switching back to the latest release in the store (revision=7 for amd64) and this time had slightly different results:

dmd.rdmd --compiler=/snap/dmd/current/bin/dmd hello.d

resulted in a different apparmor error, namely:

= AppArmor =
Time: Jun  3 16:23:37
Log: apparmor="DENIED" operation="open" profile="snap.dmd.rdmd" name="/home/username/code/test/D/hello.d" pid=6073 comm="dmd" requested_mask="r" denied_mask="r" fsuid=1000 ouid=1000
File: /home/username/code/test/D/hello.d (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

… which I guess might be related to which snapcraft was used to build the launchpad-built (and store-installed) package, versus the local cleanbuild.

In any case, I think it seems reasonable to assume that the original apparmor error is related to the fact that rdmd is invoking /snap/bin/dmd and not the dmd compiler binary internal to the snap package.

Note, the latest store-provided packages “work” if one uses,

rdmd --compiler=/snap/dmd/current/bin/dmd hello.d

It depends on how the binary is executed. If it is using PATH and goes through snap-confine then (even despite classic confinement) this would happen. If it is looking at $SNAP/bin (for example) then snap-confine would not be used and there would be no error here.

I think you are spot on!

As per my experiments above where I change the name of the compiler binary, or point rdmd directly to either /snap/bin/dmd or /snap/dmd/current/bin/dmd, I think this is almost certainly what is happening.

Note, the problem here is not limited to getting dmd alone to work. rdmd is designed to accept a --compiler flag that allows one to specify the particular D compiler to use. So if one installs the ldc2 snap and does, say,

rdmd --compiler=ldmd2 hello.d

… one gets the same AppArmor-related error, but if one does

rdmd --compiler=/snap/ldc2/current/bin/ldmd2 hello.d

… then again this works.

In other words, it won’t suffice (for the use-case) for this to be fixed just for rdmd invoking stuff from the snap package to which it belongs.

Yeah, I think this is an interesting problem that we never faced before. It is plausible and uncontroversial that snap-confine will be invoked with input / output redirection simply because it participates in interactions with other programs.

Can we add a rule that allows all file inheritance (but just inheritance) to the apparmor profile?

No, we can’t differentiate based on whether or not the file was inherited. Something like that will be possible in the future via a planned AppArmor “delegation” feature but that won’t be implemented before 18.04.

Does this mean that this may not be addressed for 16.04-based snap packages?

BTW is there a launchpad issue related to this? Might be worth taking discussion over there.

I wonder if I could ping on the status of this issue (and my last questions about it) … ? Thanks folks :slight_smile:

@zyga-snapd @tyhicks it’s been quite a long time with no update on this. Can I check status?

I don’t see any Launchpad bug report corresponding to this issue. Would it be helpful for me to create one? Or is the issue already being tracked somehow?

Hey @joseph.wakeling - I’m sorry for not having a better update at this time. I haven’t worked on this issue and I think there’s no (immediate) change coming to the kernel side. I’ll devote some time to this early next week to see if we can do any kind of workaround that would cure the immediate problem for you.

@zyga-snapd no need to apologize, I know that these things take the time they take, and that there are plenty of other priorities that need work. I wanted to check status because I think it may be worth looking into whether this can be worked around from the upstream side in the rdmd code – but that’s only worth doing if a fix is not about to land :wink:

Would we explicitly need to do something for the snap to not look outside of its read only confinement?

For example, I f I snap up an existing application, like a browser, or an editor,

How would / what would I need to do extra, to indicate to the snap to not look for libraries and binaries outside on the system? or

to indicate to the snap at runtime, to write here or read fromthere?

I see many env variables set, though I do not know, If the values are right.

because I am learning how to snap, and snapped up atom, to run into errors similar to ones in this post

where it says

Suggestion:
 adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

adjust program to write to $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

@retrocausal

It’s going to depend on the application. For binaries, ship them in your snap and use a wrapper script to adjust your PATH to find them. Similar for libraries, but adjust LD_LIBRARY_PATH. If you are using snapcraft, you can use ‘stage-packages’ to help with shipping files and some snapcraft ‘parts’ will help you with this (for example, the desktop part sets up quite a few environment variables for you).

Some things you might need to change how the application works (eg, code changes, setting environment variables specific to the application) or you can try using snapcraft preload: https://github.com/sergiusens/snapcraft-preload

This particular topic is about ‘Failed to flush stdout: Permission denied’ though. I suggest starting a new topic if you have specific questions or participating on rocketchat for realtime assistance.

Hope this helps :slight_smile:

1 Like

@zyga-snapd just to check in, was an explicit fix released for this? I ask because the problem is no longer occurring for me :wink:

Hey

Not fully, this will require more apparmor magic.
We have however mitigated it in some common cases.

1 Like

Good to know. It looks like mine falls under one of those mitigated cases – so thanks! :slight_smile:

1 Like