Bug 1213331

Summary: AUDIT-1: fcitx: fixed socket in /tmp/fcitx-socket-:%d
Product: [openSUSE] openSUSE Tumbleweed Reporter: Matthias Gerstner <matthias.gerstner>
Component: SecurityAssignee: Matthias Gerstner <matthias.gerstner>
Status: RESOLVED FIXED QA Contact: E-mail List <qa-bugs>
Severity: Normal    
Priority: P5 - None CC: forgotten_PuR0ouFTCD, i
Version: Current   
Target Milestone: ---   
Hardware: Other   
OS: Other   
Whiteboard:
Found By: --- Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---

Description Matthias Gerstner 2023-07-14 12:37:43 UTC
+++ This bug was initially created as a clone of Bug #1204311

openSUSE:Factory/fcitx uses a UNIX domains ocket in

    /tmp/fcitx-socket-:%d

where %d is the X11 display number.

This allows other users in the system to precreate this socket, claiming the
interface and providing bogus data or receiving confidential data.

But it seems the socket is client wise only used for fcitx-remote, so the
socket is probably not used often (?).

Needs further looked into.
Comment 1 Matthias Gerstner 2023-08-24 08:38:02 UTC
This socket only uses a very primitive protocol, basically a single integer is
passed back and forth. So the confidentiality aspect is not really
problematic.

It has a DoS aspect, as pre-creating this path causes starting of fcitx to
fail.

There is no way to trick the daemon into making its interface accessible to
world. It uses a sequence like this:

    unlink(path);
    bind(path);
    chmod(path, 0600);

bind() always fails if the path already exists, thus pre-creating does not
work to trick this. If bind() fails then the daemon correctly stops processing
the remote API.

Although the chmod on the socket path is naive it should be save in this
context, since, if the bind() succeeded, the path must exist and be the socket
owned by the caller. No symlink attacks should be possible.

There is race condition also between bind() and chmod(), a time window, during
which the socket is visible with the default permissions. Unless there is an
insecure umask() set this should be no problem, though. A process calling
connect() on the socket needs write permissions on the socket. The default
umask will result in a socket with 0644 mode, thus other users than the
creator and root will not have connect() permission on the socket.

In summary, this fixed path only represents a local DoS vector, if another
user precreates this socket. Then fcitx cannot start. For reasons of
cleanliness I will try to get a patch into the package that places the socket
in $XDG_RUNTIME_DIR, if possible, or into $HOME, this will remove any
remaining worries there are.

Upstream has put fcitx major version 4 into maintenance mode. The codebase is
rather unclean is my feeling - there are error checks missing, the program
crashes easily with memory corruption. Upstream's recommendation is to switch
to fcitx major version 5 with a new architecture and backend libraries.

For this reason I won't involve upstream with this minor DoS issue. It should
be enough when we fix it in our packages.
Comment 2 Matthias Gerstner 2023-08-24 08:43:59 UTC
Adding fcitx maintainers to keep them in the loop.

I will submit a path to the package soon to improve the security posture of
this package.

On top of this you could consider migrating the package to fcitx major version
5, since fcitx version 4 has been put into maintenance mode by upstream and
seems no longer supported.
Comment 3 Matthias Gerstner 2023-08-24 09:53:48 UTC
I just submitted OBS sr#1105583 containing a patch to place this socket either
into $XDG_RUNTIME_DIR or into $HOME (as a hidden file). Once this is in
Factory this bug can be closed.
Comment 4 Matthias Gerstner 2023-09-05 08:02:46 UTC
The patch for the socket path is now in Factory. Closing this as fixed.