Bug 1969918 - Weird process cmdline with usermode 1.114
Summary: Weird process cmdline with usermode 1.114
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: usermode
Version: 34
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Jiri Kucera
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: 1984404 1984417
TreeView+ depends on / blocked
 
Reported: 2021-06-09 13:12 UTC by Pavel Raiskup
Modified: 2021-07-21 11:59 UTC (History)
2 users (show)

Fixed In Version: usermode-1.114-2.fc33 usermode-1.114-2.fc34
Clone Of:
: 1984404 1984417 (view as bug list)
Environment:
Last Closed: 2021-06-24 16:46:28 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Pavel Raiskup 2021-06-09 13:12:12 UTC
The Mock utility depends on usermode.  When I have the latest version 1.114,
I observe this behavior:

1. In the first terminal window: Get a mock prompt by 'mock --shell'
2. In another terminal window: 'ps a | grep -- --shell | grep -v grep'
   I see this output:
   535299 pts/12   S+     0:01 /usr/bin/python3 -tt /dev/fd/4 --shell

When I downgrade to version-release '1.112-10', I see the expected output:

1. downgrade the package
2. restart the command in the first terminal window
3. ps a | grep -- --shell | grep -v grep
535832 pts/12   S+     0:01 /usr/bin/python3 -tt /usr/libexec/mock/mock --shell

Note the difference: /usr/libexec/mock/mock filename is now replaced with
/dev/fd/4 for some reason.

This not only breaks the expected 'ps' ouptut, but also many command-line
argument parsers that depend on argv[0].  Example report against mock
("Usage 4" instead of Usage mock"):
https://github.com/rpm-software-management/mock/issues/738

Comment 1 Miroslav Suchý 2021-06-09 13:28:34 UTC
I can reproduce it too.

Comment 2 Jiri Kucera 2021-06-09 19:43:05 UTC
Hi Pavel,

to silent Coverity TOCTOU warnings, I replaced access/execv with open/fexecve some time ago. What you are seeing now is that /usr/libexec/mock/mock has been opened under the file descriptor #4 that has been passed to fexecve and results to /dev/fd/4 as the script name.

The issue can be simply fixed by usermode rebuild with `%configure --with-fexecve=no` (and ignoring Coverity TOCTOU warings).

Comment 3 Pavel Raiskup 2021-06-10 05:31:27 UTC
Thank you for looking!  Fixing TOCTOU shouldn't require a behavior change,
can you share the affected code (file:line)?

Comment 4 Jiri Kucera 2021-06-10 07:45:11 UTC
Sure. The commit that introduced the change is here [1]. It is quite large, the fexecve is used at several places. It starts at userhelper.c:1735 and then occurs between #ifdef HAVE_FEXECVE guards.

(Looking back on it after ~2.5 years, some changes are redundant--introduced only to silence covscan--and they introduce only noise to the code. Will be reverted back the next round.)

[1] https://pagure.io/usermode/c/b569a58005022c869e4e7d6df9a4da0c8cd3b0d9?branch=master

Comment 5 Jiri Kucera 2021-06-10 07:54:10 UTC
Just a note, the behavior is described in execveat(2):

    In addition to the reasons explained in openat(2), the execveat() system call is also needed to allow fexecve(3) to be implemented on systems that do not have the /proc filesystem mounted.

    When  asked  to  execute a script file, the argv[0] that is passed to the script interpreter is a string of the form /dev/fd/N or /dev/fd/N/P, where N is the number of the file descriptor passed via
    the dirfd argument.  A string of the first form occurs when AT_EMPTY_PATH is employed.  A string of the second form occurs when the script is specified via both dirfd and pathname; in this  case,  P
    is the value given in pathname.

in fexecve(3), there is only:

    Since glibc  2.27,  if  the underlying kernel supports the execveat(2) system call, then fexecve() is implemented using that system call, with the benefit that /proc does not need to be mounted.

Comment 6 Pavel Raiskup 2021-06-11 12:05:02 UTC
Indeed, I don't see any obvious way out than either (a) return back to the
TOCTOU situation (well, at least in the /usr/libexec/mock/mock situation
it should be *just OK* because only root can write into /usr/libexec/mock,
and of course, consolehelper could heck it is a root-only path), or (b)
re-set the process title manually inside the client script (mock).
Alternatively, (c) we could provide our own binary wrapper.

But now, even my terminal window changes the title to the running script,
so to "4" when mock is executed, ... which is not nice, and it may hurt
some /bin/ps parsers, too.  So we should do something about it.  Please
tell us what we should do (and I bet not only mock is affected).

What could be done, IMVHO in theory at least, is that kernel/glibc could
give us the full argv[] (or at least argv[0]) somehow (e.g. env var?) as
we provide it in fexecve() call (we give there FD + full argv[] + envp).

Comment 7 Pavel Raiskup 2021-06-11 12:09:51 UTC
Sorry for the typo, "consolehelper could *check* it is a root-only path".

Comment 8 Jiri Kucera 2021-06-11 12:42:17 UTC
For now, I choose (a), since it is the fastest solution (involves only adding --without-fexecve option to configure). Then we can continue with the discussion at the kernel/glibc side and depending on the outcome return back to fexecve solution (or any other alternative proposed by kernel/glibc developers). Living with TOCTOU in usermode should not be so harmful as
(1) the accessing the path with access() before passing it to execv() is to check if path can be executed
(2) pathes passed to access() are /usr/bin/... or /sbin/... so one need to have root privileges to modify the content

Comment 9 Jiri Kucera 2021-06-16 07:21:05 UTC
Hi Pavel,

I did a scratch-build[1] and tested it on Fedora 34 and it works:

[root@fedora ~]# mock --help
Usage: mock [options]

[root@fedora ~]# rpm -q usermode
usermode-1.114-2.fc34.x86_64


Patch:
```
diff --git a/usermode.spec b/usermode.spec
index 5e07f58..61473e0 100644
--- a/usermode.spec
+++ b/usermode.spec
@@ -4,7 +4,7 @@
 Summary: Tools for certain user account management tasks
 Name: usermode
 Version: 1.114
-Release: 1%{?dist}
+Release: 2%{?dist}
 License: GPLv2+
 URL: https://pagure.io/%{name}/
 Source: https://releases.pagure.org/%{name}/%{name}-%{version}.tar.xz
@@ -50,7 +50,7 @@ graphical tools for certain account management tasks.
 %setup -q
 
 %build
-%configure --with-selinux %{!?with_gtk:--without-gtk}
+%configure --with-selinux --without-fexecve %{!?with_gtk:--without-gtk}
 
 %make_build
 
```

[1] https://koji.fedoraproject.org/koji/taskinfo?taskID=70213738

Comment 10 Pavel Raiskup 2021-06-16 08:14:14 UTC
Thank you for the quick update here, Jirko!

Comment 11 Fedora Update System 2021-06-16 20:28:57 UTC
FEDORA-2021-a3db781aa9 has been submitted as an update to Fedora 33. https://bodhi.fedoraproject.org/updates/FEDORA-2021-a3db781aa9

Comment 12 Fedora Update System 2021-06-16 20:28:58 UTC
FEDORA-2021-fed55b554e has been submitted as an update to Fedora 34. https://bodhi.fedoraproject.org/updates/FEDORA-2021-fed55b554e

Comment 13 Fedora Update System 2021-06-17 01:30:05 UTC
FEDORA-2021-fed55b554e has been pushed to the Fedora 34 testing repository.
Soon you'll be able to install the update with the following command:
`sudo dnf upgrade --enablerepo=updates-testing --advisory=FEDORA-2021-fed55b554e`
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2021-fed55b554e

See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.

Comment 14 Fedora Update System 2021-06-17 01:52:54 UTC
FEDORA-2021-a3db781aa9 has been pushed to the Fedora 33 testing repository.
Soon you'll be able to install the update with the following command:
`sudo dnf upgrade --enablerepo=updates-testing --advisory=FEDORA-2021-a3db781aa9`
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2021-a3db781aa9

See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.

Comment 15 Fedora Update System 2021-06-24 16:46:28 UTC
FEDORA-2021-a3db781aa9 has been pushed to the Fedora 33 stable repository.
If problem still persists, please make note of it in this bug report.

Comment 16 Fedora Update System 2021-06-24 16:52:34 UTC
FEDORA-2021-fed55b554e has been pushed to the Fedora 34 stable repository.
If problem still persists, please make note of it in this bug report.


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