Bug 1667620 - Limit mounts that libffi will try to write to
Summary: Limit mounts that libffi will try to write to
Keywords:
Status: CLOSED EOL
Alias: None
Product: Fedora
Classification: Fedora
Component: libffi
Version: 33
Hardware: Unspecified
OS: Linux
unspecified
unspecified
Target Milestone: ---
Assignee: Carlos O'Donell
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2019-01-19 02:41 UTC by amurashkin@aimk.com
Modified: 2021-11-30 16:13 UTC (History)
8 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2021-11-30 16:13:51 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
An example of sealert regarding write attempt to /sys/kernel/config (1.85 KB, text/plain)
2019-01-19 02:41 UTC, amurashkin@aimk.com
no flags Details

Description amurashkin@aimk.com 2019-01-19 02:41:16 UTC
Created attachment 1521734 [details]
An example of sealert regarding write attempt to /sys/kernel/config

Description of problem:

When libffi cannot create temporary executable file in default directories (/tmp, /var/tmp, etc.), it tries to create such file in all mounted filesystems.

Programs shall not write to directories unless it is customary or they are configured to do so.

It is pretty scary as SElinux issues hundreds alerts about write attempts to various directories, for instance (plus a score of other filesystems)

/boot/efi
/dev/hugepages
/dev/mqueue
/dev/shm
/home
/opt
/run
/sys/fs/fuse/connections
/sys/fs/selinux
/sys/kernel/config
/sys/kernel/debug
/usr
/var/crash

Sealert example is attached.

Version-Release number of selected component (if applicable):

libffi-3.1-18.fc29.x86_64

How reproducible:

I found this problem happening when using NSS with certwatch and httpd

crypto-utils-2.5-4.fc29.x86_64
httpd-2.4.37-5.fc29.x86_64
mod_nss-1.0.17-3.fc29.x86_64
nss-3.41.0-1.fc29.x86_64.rpm
nss-softokn-3.41.0-1.fc29.x86_64
nss-softokn-freebl-3.41.0-1.fc29.x86_64.rpm
p11-kit-0.23.14-1.fc29.x86_64.rpm
p11-kit-trust-0.23.14-1.fc29.x86_64.rpm

Steps to Reproduce:

Install mod_nss, be sure that /etc/httpd/conf.d/nss.conf points to correct NSS database.

**** certwatch

1. Wait until /etc/cron.daily/certwatch is executed
2. Check sealerts

certwatch need to be run from cron, executing certwatch directly does not produce the errors.

**** httpd

1. Be sure to configure /etc/httpd/conf.d/nss.conf to use 

NSSPassPhraseHelper /usr/libexec/nss_pcache
 
2. systemctl restart httpd
3. Check sealerts

httpd needs to be run under systemd, executing httpd directly does not produce the errors.

------- Additional info: ----------

libffi-3.1/src/closures.c at line 370 has the following

  { open_temp_exec_file_env, "TMPDIR", 0 },
  { open_temp_exec_file_dir, "/tmp", 0 },
  { open_temp_exec_file_dir, "/var/tmp", 0 },
  { open_temp_exec_file_dir, "/dev/shm", 0 },
  { open_temp_exec_file_env, "HOME", 0 },

#ifdef HAVE_MNTENT
  { open_temp_exec_file_mnt, "/etc/mtab", 1 },
  { open_temp_exec_file_mnt, "/proc/mounts", 1 },
#endif /* HAVE_MNTENT */

Effectively, it means that if first 5 default directories cannot be used, libffi reads a list of mounted filesystems and tries to create the temporary file in each of them.

There is no reason for the default directories to fail under normal conditions. So reading the mounts shall be disabled. Some additional preprocessor macro shall be added to the source file and the configuration rules, for example

#ifdef HAVE_MNTENT && USE_MNTENT
  { open_temp_exec_file_mnt, "/etc/mtab", 1 },
  { open_temp_exec_file_mnt, "/proc/mounts", 1 },
#endif /* HAVE_MNTENT && USE_MNTENT */

There are two potential cases when libffi may fail if the reading mounts is disabled
- when the default directories are not mounted
- when the default directories are mounted read only 

------- Workaround: --------

This workaround will work, probably, only for applications using libffi through nss.

The SELinux sealerts disappeared after updating to the following packages

nss-3.41.0-3.fc29.x86_64
p11-kit-0.23.14-2.fc29.x86_64
p11-kit-trust-0.23.14-2.fc29.x86_64

Quite possible, that libffi issue is triggered by faulty logic in nss or p11. 

BTW Why libffi-3.1? Version 3.2.1 was released in 2014! Though the issue is still there.

Comment 1 Anthony Green 2019-01-19 03:04:56 UTC
I wonder if it makes sense to only examine the standard locations, and then check for a user-supplied location specified via environment variable before just aborting instead of rummaging through all of the possible mounts.  Opinions?

Comment 2 amurashkin@aimk.com 2019-01-19 21:12:32 UTC
> ... user-supplied location specified via environment variable ...

Maybe LIBFFI_TMPDIR? On another hand TMPDIR and HOME are already in the list. So LIBFFI_TMPDIR makes sense if we want to be able to keep libffi temporary files separate from other temporary files.

While we are talking about it, what about adding XDG_RUNTIME_DIR before HOME (https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)? On Fedora, it points to /run/user/UID (and by coincidence it is in the mount list).

One more thing, it seems thata race might happen

static int execfd = -1;

dlmmap_locked ...
  if (execfd == -1) 
    {
      open_temp_exec_file_opts_idx = 0;
      retry_open: execfd = open_temp_exec_file ();

    ptr = mmap (...);
    if (ptr == MFAIL)
       ...goto retry_open;

dlmmap_locked ...
  if (execsize == 0 || execfd == -1)
    {
      pthread_mutex_lock (&open_temp_exec_file_mutex);
      ptr = dlmmap_locked (start, length, prot, flags, offset);  <--- mutex locked
      ...return...
    }

  return dlmmap_locked (...);  <--- no mutex

So, if the first thread is still inside dlmmap_locked after execfd is assigned, the second thread will call dlmmap_locked without lock. The first thread meanwhile can go to retry_open and change execfd.

Comment 3 Mark Wielaard 2019-01-20 14:28:36 UTC
It might indeed me a good idea to add /var/run and XDG_RUNTIME_DIR to the default list and none of those work just give up.
Or maybe restrict the search to mounts with mnt_type == "tmpfs".

Also since glibc 2.27 there is memfd_create:
https://www.gnu.org/software/libc/manual/html_node/Memory_002dmapped-I_002fO.html#index-memfd_005fcreate

So if that is available it could be used instead of trying to create an actual file on disk.

Comment 4 amurashkin@aimk.com 2019-01-20 22:28:28 UTC
/var/run is a symbolic link to /run (at least, on Fedora 29). So it is better to add /run or both /run and /var/run.

Also user files are usually in /run/user/UID directory.

Comment 5 amurashkin@aimk.com 2019-01-20 22:34:37 UTC
> Or maybe restrict the search to mounts with mnt_type == "tmpfs".

If you decide to do it, I suggest, make it not by default. If a filesystem is used by an application that watches for file events, creating temporary file there may trigger such application activity.

Comment 6 Ben Cotton 2019-10-31 19:17:52 UTC
This message is a reminder that Fedora 29 is nearing its end of life.
Fedora will stop maintaining and issuing updates for Fedora 29 on 2019-11-26.
It is Fedora's policy to close all bug reports from releases that are no longer
maintained. At that time this bug will be closed as EOL if it remains open with a
Fedora 'version' of '29'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version' 
to a later Fedora version.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora 29 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora, you are encouraged  change the 'version' to a later Fedora 
version prior this bug is closed as described in the policy above.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events. Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.

Comment 7 Ben Cotton 2019-11-27 22:34:47 UTC
Fedora 29 changed to end-of-life (EOL) status on 2019-11-26. Fedora 29 is
no longer maintained, which means that it will not receive any further
security or bug fix updates. As a result we are closing this bug.

If you can reproduce this bug against a currently maintained version of
Fedora please feel free to reopen this bug against that version. If you
are unable to reopen this bug, please file a new report against the
current release. If you experience problems, please add a comment to this
bug.

Thank you for reporting this bug and we are sorry it could not be fixed.

Comment 8 Carlos O'Donell 2020-03-25 18:04:28 UTC
Reopening since this still applies.

Comment 9 Ben Cotton 2020-08-11 13:05:45 UTC
This bug appears to have been reported against 'rawhide' during the Fedora 33 development cycle.
Changing version to 33.

Comment 10 Ben Cotton 2021-11-04 17:41:22 UTC
This message is a reminder that Fedora 33 is nearing its end of life.
Fedora will stop maintaining and issuing updates for Fedora 33 on 2021-11-30.
It is Fedora's policy to close all bug reports from releases that are no longer
maintained. At that time this bug will be closed as EOL if it remains open with a
Fedora 'version' of '33'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version' 
to a later Fedora version.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora 33 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora, you are encouraged  change the 'version' to a later Fedora 
version prior this bug is closed as described in the policy above.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events. Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.

Comment 11 Ben Cotton 2021-11-30 16:13:51 UTC
Fedora 33 changed to end-of-life (EOL) status on 2021-11-30. Fedora 33 is
no longer maintained, which means that it will not receive any further
security or bug fix updates. As a result we are closing this bug.

If you can reproduce this bug against a currently maintained version of
Fedora please feel free to reopen this bug against that version. If you
are unable to reopen this bug, please file a new report against the
current release. If you experience problems, please add a comment to this
bug.

Thank you for reporting this bug and we are sorry it could not be fixed.


Note You need to log in before you can comment on or make changes to this bug.