[GH-ISSUE #2685] Firefox 66: can't save downloaded files due to unwriteable /tmp/user/$UID #1691

Closed
opened 2026-05-05 08:20:24 -06:00 by gitea-mirror · 24 comments
Owner

Originally created by @chrsmrtnx on GitHub (May 9, 2019).
Original GitHub issue: https://github.com/netblue30/firejail/issues/2685

Originally assigned to: @smitsohu on GitHub.

Running Debian buster with Firefox 66 and firejail 0.9.58.2, I found that with firejail's default Firefox profile, I couldn't download files. When clicking on a link to a file in Firefox, I'd get an error that the file "could not be saved, because you cannot change the contents of that folder. Change the folder properties and try again, or try saving in a different location".

To solve the problem, I had to comment out "private-tmp" in firefox-common.profile or, alternatively, add the line "whitelist /tmp/user/1000" (1000 being the relevant userid).

I suspect that the problem is that Firefox wants to write the downloaded file to /tmp/user/$UID before it moves it to the final download folder, typically under $HOME. But it can't because /tmp/user/$UID is read-only when "private-tmp" is set, unless you explicitly whitelist /tmp/user/1000 or whatever. (If I run "firejail --profile=firefox /bin/bash", I can't write to /tmp/user/1000: "touch /tmp/user/1000/foo" fails, whereas of course it works fine outside of firejail.)

Thanks.

Originally created by @chrsmrtnx on GitHub (May 9, 2019). Original GitHub issue: https://github.com/netblue30/firejail/issues/2685 Originally assigned to: @smitsohu on GitHub. Running Debian buster with Firefox 66 and firejail 0.9.58.2, I found that with firejail's default Firefox profile, I couldn't download files. When clicking on a link to a file in Firefox, I'd get an error that the file "could not be saved, because you cannot change the contents of that folder. Change the folder properties and try again, or try saving in a different location". To solve the problem, I had to comment out "private-tmp" in firefox-common.profile or, alternatively, add the line "whitelist /tmp/user/1000" (1000 being the relevant userid). I suspect that the problem is that Firefox wants to write the downloaded file to /tmp/user/$UID before it moves it to the final download folder, typically under $HOME. But it can't because /tmp/user/$UID is read-only when "private-tmp" is set, unless you explicitly whitelist /tmp/user/1000 or whatever. (If I run "firejail --profile=firefox /bin/bash", I can't write to /tmp/user/1000: "touch /tmp/user/1000/foo" fails, whereas of course it works fine outside of firejail.) Thanks.
Author
Owner

@Vincent43 commented on GitHub (May 10, 2019):

Do you use pam-tmpdir?

<!-- gh-comment-id:491272773 --> @Vincent43 commented on GitHub (May 10, 2019): Do you use [pam-tmpdir](https://packages.debian.org/sid/libpam-tmpdir)?
Author
Owner

@chiraag-nataraj commented on GitHub (May 10, 2019):

Btw, one way to solve this is to right-click and hit "Save As...", which (I think) should work? I actually opened a related bug here.

<!-- gh-comment-id:491324795 --> @chiraag-nataraj commented on GitHub (May 10, 2019): Btw, one way to solve this is to right-click and hit "Save As...", which (I think) _should_ work? I actually opened a related bug [here](https://bugzilla.mozilla.org/show_bug.cgi?id=1497405).
Author
Owner

@chrsmrtnx commented on GitHub (May 11, 2019):

Do you use pam-tmpdir?

Yes, I do have libpam-tmpdir installed.

<!-- gh-comment-id:491466079 --> @chrsmrtnx commented on GitHub (May 11, 2019): > Do you use [pam-tmpdir](https://packages.debian.org/sid/libpam-tmpdir)? Yes, I do have libpam-tmpdir installed.
Author
Owner

@chrsmrtnx commented on GitHub (May 11, 2019):

Btw, one way to solve this is to right-click and hit "Save As...", which (I think) should work? I actually opened a related bug here.

I tested this, and it does work, oddly. But then clicking on a link to a file still fails as described before. Odd.

<!-- gh-comment-id:491467679 --> @chrsmrtnx commented on GitHub (May 11, 2019): > Btw, one way to solve this is to right-click and hit "Save As...", which (I think) _should_ work? I actually opened a related bug [here](https://bugzilla.mozilla.org/show_bug.cgi?id=1497405). I tested this, and it does work, oddly. But then clicking on a link to a file still fails as described before. Odd.
Author
Owner

@rusty-snake commented on GitHub (May 11, 2019):

@chrsmrtnx you can make this as an default. about:preferences -> always ask when downloading files (not sure about the correct english name) (browser.download.useDownloadDir = false)

<!-- gh-comment-id:491487993 --> @rusty-snake commented on GitHub (May 11, 2019): @chrsmrtnx you can make this as an default. about:preferences -> always ask when downloading files (not sure about the correct english name) (`browser.download.useDownloadDir = false`)
Author
Owner

@chrsmrtnx commented on GitHub (May 12, 2019):

@chrsmrtnx you can make this as an default. about:preferences -> always ask when downloading files (not sure about the correct english name) (browser.download.useDownloadDir = false)

Thanks - that's already the setting I was running with.

The error dialog ("could not be saved, because" etc.) pops up even before you get the dialog box that permits you to select the download folder.

<!-- gh-comment-id:491618858 --> @chrsmrtnx commented on GitHub (May 12, 2019): > @chrsmrtnx you can make this as an default. about:preferences -> always ask when downloading files (not sure about the correct english name) (`browser.download.useDownloadDir = false`) Thanks - that's already the setting I was running with. The error dialog ("could not be saved, because" etc.) pops up even before you get the dialog box that permits you to select the download folder.
Author
Owner

@SkewedZeppelin commented on GitHub (May 12, 2019):

If we want to be "dirty" we can include a vendor.js override for Firefox that enables that option by default.
Just add
pref("browser.download.useDownloadDir", false);
to
/usr/lib64/firefox/browser/defaults/preferences/firejail-fixes.js
or I think
/etc/firefox/pref/firejail-fixes.js

<!-- gh-comment-id:491629491 --> @SkewedZeppelin commented on GitHub (May 12, 2019): If we want to be "dirty" we can include a vendor.js override for Firefox that enables that option by default. Just add `pref("browser.download.useDownloadDir", false);` to `/usr/lib64/firefox/browser/defaults/preferences/firejail-fixes.js` or I think `/etc/firefox/pref/firejail-fixes.js`
Author
Owner

@Vincent43 commented on GitHub (May 12, 2019):

I think that's too intrusive and doesn't really work as posted above.

<!-- gh-comment-id:491633760 --> @Vincent43 commented on GitHub (May 12, 2019): I think that's too intrusive and doesn't really work as posted above.
Author
Owner

@chiraag-nataraj commented on GitHub (May 19, 2019):

I tested this, and it does work, oddly. But then clicking on a link to a file still fails as described before. Odd.

Yup, not entirely sure what's going on with Firefox. The bug I linked to kind of just...died, which is unfortunate.

The error dialog ("could not be saved, because" etc.) pops up even before you get the dialog box that permits you to select the download folder.

Yup, this happens before you're ever prompted for where to save the file to.

If we have a $UID variable that we can use in profiles, it might be worth it to whitelist /tmp/user/$UID by default...?

<!-- gh-comment-id:493797540 --> @chiraag-nataraj commented on GitHub (May 19, 2019): > I tested this, and it does work, oddly. But then clicking on a link to a file still fails as described before. Odd. Yup, not _entirely_ sure what's going on with Firefox. The bug I linked to kind of just...died, which is unfortunate. > The error dialog ("could not be saved, because" etc.) pops up even before you get the dialog box that permits you to select the download folder. Yup, this happens before you're ever prompted for where to save the file to. If we have a `$UID` variable that we can use in profiles, it might be worth it to whitelist `/tmp/user/$UID` by default...?
Author
Owner

@Vincent43 commented on GitHub (May 20, 2019):

because /tmp/user/$UID is read-only when "private-tmp" is set,

/tmp/user/$UID shouldn't exist when private-tmp is used. From where does it come from?

<!-- gh-comment-id:494099372 --> @Vincent43 commented on GitHub (May 20, 2019): > because /tmp/user/$UID is read-only when "private-tmp" is set, `/tmp/user/$UID` shouldn't exist when `private-tmp` is used. From where does it come from?
Author
Owner

@chiraag-nataraj commented on GitHub (May 20, 2019):

It's created within the sandbox because of libpam-tmpdir.

<!-- gh-comment-id:494117110 --> @chiraag-nataraj commented on GitHub (May 20, 2019): It's created within the sandbox because of `libpam-tmpdir`.
Author
Owner

@Vincent43 commented on GitHub (May 20, 2019):

Isn't libpam-tmpdir creating it only during login? How it can create it in firejail --private-tmp sandbox where /tmp is mount as new tmpfs filesystem?

<!-- gh-comment-id:494129214 --> @Vincent43 commented on GitHub (May 20, 2019): Isn't `libpam-tmpdir` creating it only during login? How it can create it in `firejail --private-tmp` sandbox where `/tmp` is mount as new tmpfs filesystem?
Author
Owner

@chiraag-nataraj commented on GitHub (May 20, 2019):

You're right. Maybe it's because the temporary directory variables are exported, so firefox automatically creates the necessary parent directory?

<!-- gh-comment-id:494143129 --> @chiraag-nataraj commented on GitHub (May 20, 2019): You're right. Maybe it's because the temporary directory variables are exported, so firefox automatically creates the necessary parent directory?
Author
Owner

@Vincent43 commented on GitHub (May 21, 2019):

That's possible but why /tmp/user/$UID would be read-only then?

<!-- gh-comment-id:494388716 --> @Vincent43 commented on GitHub (May 21, 2019): That's possible but why `/tmp/user/$UID` would be read-only then?
Author
Owner

@chiraag-nataraj commented on GitHub (May 21, 2019):

I'm not really sure, to be honest. But I know I've run into this when I whitelisted a subdirectory of /tmp/user/$UID, which does make sense.

Yeah, I'm not really sure what exactly is going on here, just that I've run into this in the past in other contexts. Somehow, I'm totally okay running with private-tmp (and I see the weird Temp-<blah> stuff in the sandbox), so I'm not quite sure what's going on here. My profile is quite a bit more restrictive (including private-bin and private-lib invocations as well as a whitelisting profile), which might inadvertently be helping here?

@chrsmrtnx If I run firejail --profile=/etc/firejail/firefox.profile bash and do mkdir -p /tmp/user/1000/ && touch /tmp/user/1000/test, it works just fine (I had to use the full path to the profile because I have my own profiles in ~/.config/firejail which it would have found otherwise).

<!-- gh-comment-id:494398504 --> @chiraag-nataraj commented on GitHub (May 21, 2019): I'm not really sure, to be honest. But I know I've run into this when I whitelisted a subdirectory of `/tmp/user/$UID`, which _does_ make sense. Yeah, I'm not really sure what exactly is going on here, just that I've run into this in the past in other contexts. Somehow, I'm totally okay running with `private-tmp` (and I see the weird `Temp-<blah>` stuff in the sandbox), so I'm not quite sure what's going on here. My profile _is_ quite a bit more restrictive (including `private-bin` and `private-lib` invocations as well as a whitelisting profile), which might inadvertently be helping here? @chrsmrtnx If I run `firejail --profile=/etc/firejail/firefox.profile bash` and do `mkdir -p /tmp/user/1000/ && touch /tmp/user/1000/test`, it works just fine (I had to use the full path to the profile because I have my own profiles in `~/.config/firejail` which it would have found otherwise).
Author
Owner

@chrsmrtnx commented on GitHub (May 21, 2019):

Interestingly, if I run firejail --profile=/etc/firejail/firefox.profile bash, then I find that the directory /tmp/user/1000 already exists; it contains a single file, namely, xauth-1000-_0.

ls -al /tmp/user/ yields drwxr-xr-x 2 root root etc.; touch /tmp/user/1000/test then of course fails.

<!-- gh-comment-id:494595984 --> @chrsmrtnx commented on GitHub (May 21, 2019): Interestingly, if I run `firejail --profile=/etc/firejail/firefox.profile bash`, then I find that the directory `/tmp/user/1000` already exists; it contains a single file, namely, `xauth-1000-_0`. `ls -al /tmp/user/` yields `drwxr-xr-x 2 root root` etc.; `touch /tmp/user/1000/test` then of course fails.
Author
Owner

@Vincent43 commented on GitHub (May 22, 2019):

firejail --profile=/etc/firejail/firefox.profile bash doesn't create /tmp/user/$UID on ubuntu with libpam-tmpdir in my testing. You have to find what creates it on your system.

<!-- gh-comment-id:494775321 --> @Vincent43 commented on GitHub (May 22, 2019): `firejail --profile=/etc/firejail/firefox.profile bash` doesn't create `/tmp/user/$UID` on ubuntu with `libpam-tmpdir` in my testing. You have to find what creates it on your system.
Author
Owner

@chiraag-nataraj commented on GitHub (May 22, 2019):

It doesn't on my system either, with the profile I use (custom hardened profile). I suspect firefox is the one creating the directory.

[edit] Never mind, looking at @chrsmrtnx's reply, it seems that something else is creating the directory on their system...

<!-- gh-comment-id:494788456 --> @chiraag-nataraj commented on GitHub (May 22, 2019): It doesn't on my system either, with the profile I use (custom hardened profile). I suspect `firefox` is the one creating the directory. [edit] Never mind, looking at @chrsmrtnx's reply, it seems that something else is creating the directory on their system...
Author
Owner

@chrsmrtnx commented on GitHub (May 25, 2019):

I've noticed that on my KDE desktop, $XAUTHORITY is set to /tmp/user/1000/xauth-1000-_0; apparently this is a KDE peculiarity (googling around yields lots of discussion). If I then run firejail --profile=/etc/firejail/firefox.profile bash, I find that I have a root-only-writable /tmp/user/1000 directory containing xauth-1000-_0, just as I've described above. Firefox then tries and fails to write the downloaded file to $TMP, which is /tmp/user/1000 - again, as described above.

But if, before running firejail, I set $XAUTHORITY to $HOME/.Xauthority, then the problem with firefox vanishes. Immediately after running firejail --profile=/etc/firejail/firefox.profile bash, there is no /tmp/user/1000 directory at all - just /tmp. The /tmp/user/1000 directory only appears when I run firefox, but instead of being writable only by root, it's writable by the user, and so downloading files works fine.

Another way to sidestep the problem is simply to set $TMP to /tmp before running firejail/firefox.

Based on all this, would I be correct in surmising that it's actually firejail that's creating the /tmp/user/1000 directory, based on $XAUTHORITY, in an attempt to setup a working environment? If so, one solution might just be to ensure that whatever $XAUTHORITY is set to, firejail makes sure the resulting path is user-writable.

<!-- gh-comment-id:495939819 --> @chrsmrtnx commented on GitHub (May 25, 2019): I've noticed that on my KDE desktop, `$XAUTHORITY` is set to `/tmp/user/1000/xauth-1000-_0`; apparently this is a KDE peculiarity (googling around yields lots of discussion). If I then run `firejail --profile=/etc/firejail/firefox.profile bash`, I find that I have a root-only-writable `/tmp/user/1000` directory containing `xauth-1000-_0`, just as I've described above. Firefox then tries and fails to write the downloaded file to `$TMP`, which is `/tmp/user/1000` - again, as described above. But if, before running firejail, I set `$XAUTHORITY` to `$HOME/.Xauthority`, then the problem with firefox vanishes. Immediately after running `firejail --profile=/etc/firejail/firefox.profile bash`, there is no `/tmp/user/1000` directory at all - just `/tmp`. The `/tmp/user/1000` directory only appears when I run firefox, but instead of being writable only by root, it's writable by the user, and so downloading files works fine. Another way to sidestep the problem is simply to set `$TMP` to `/tmp` before running firejail/firefox. Based on all this, would I be correct in surmising that it's actually firejail that's creating the `/tmp/user/1000` directory, based on `$XAUTHORITY`, in an attempt to setup a working environment? If so, one solution might just be to ensure that whatever `$XAUTHORITY` is set to, firejail makes sure the resulting path is user-writable.
Author
Owner

@chiraag-nataraj commented on GitHub (May 28, 2019):

@chrsmrtnx, ah, that would explain it (I'm running AwesomeWM myself, so I clearly wouldn't have this issue).

Based on all this, would I be correct in surmising that it's actually firejail that's creating the /tmp/user/1000 directory, based on $XAUTHORITY, in an attempt to setup a working environment? If so, one solution might just be to ensure that whatever $XAUTHORITY is set to, firejail makes sure the resulting path is user-writable.

Hmm, yeah, that might be useful...I'm just worried about any security implications. @netblue30 or others, thoughts?

<!-- gh-comment-id:496482973 --> @chiraag-nataraj commented on GitHub (May 28, 2019): @chrsmrtnx, _ah_, that would explain it (I'm running AwesomeWM myself, so I clearly wouldn't have this issue). > Based on all this, would I be correct in surmising that it's actually firejail that's creating the /tmp/user/1000 directory, based on $XAUTHORITY, in an attempt to setup a working environment? If so, one solution might just be to ensure that whatever $XAUTHORITY is set to, firejail makes sure the resulting path is user-writable. Hmm, yeah, that might be useful...I'm just worried about any security implications. @netblue30 or others, thoughts?
Author
Owner

@smitsohu commented on GitHub (May 28, 2019):

I can give it a stab.

<!-- gh-comment-id:496506481 --> @smitsohu commented on GitHub (May 28, 2019): I can give it a stab.
Author
Owner

@smitsohu commented on GitHub (May 28, 2019):

The problem is here:
286b270778/src/firejail/fs_whitelist.c (L246)

We just have to improve the way the path for the mount target is created.

<!-- gh-comment-id:496507409 --> @smitsohu commented on GitHub (May 28, 2019): The problem is here: https://github.com/netblue30/firejail/blob/286b2707785abc1c75afc8bb82d956c60c561057/src/firejail/fs_whitelist.c#L246 We just have to improve the way the path for the mount target is created.
Author
Owner

@smitsohu commented on GitHub (Jul 27, 2019):

Thanks for this bug! It should be working now in master.

<!-- gh-comment-id:515688732 --> @smitsohu commented on GitHub (Jul 27, 2019): Thanks for this bug! It should be working now in master.
Author
Owner

@chrsmrtnx commented on GitHub (Jul 28, 2019):

Pasting that snippet into 0.9.60 fixes the problem here. Many thanks.

<!-- gh-comment-id:515762530 --> @chrsmrtnx commented on GitHub (Jul 28, 2019): Pasting that snippet into 0.9.60 fixes the problem here. Many thanks.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/firejail#1691
No description provided.