Bug 2247221

Summary: passt-selinux policy prevents it from inheriting the socket file descriptor
Product: [Fedora] Fedora Reporter: Matej Hrica <mhrica>
Component: passtAssignee: Stefano Brivio <sbrivio>
Status: CLOSED ERRATA QA Contact:
Severity: medium Docs Contact:
Priority: unspecified    
Version: 38CC: sbrivio
Target Milestone: ---   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: passt-0^20231107.g56d9f6d-1.fc39 passt-0^20231107.g56d9f6d-1.fc37 passt-0^20231107.g56d9f6d-1.fc38 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2023-11-20 01:20:30 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Matej Hrica 2023-10-31 11:28:56 UTC
Passt has a `--fd` command line option to specify a file descriptor instead of using a socket in /tmp. However this option doesn't seem to be usable because of passt SELinux policy. It works with `setenforce 0`. It works with passt installed from upstream source - without passt specific SELinux policy (but SELinux enabled).

passt / passt-selinux version: 0^20231004.gf851084-1.fc38



Reproducible: Always

Can be reproduced using the following C code:
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>

#define HYPERVISOR 0
#define PASST 1

int main() {
    int socket_fds[2];
    if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds) < 0) {
        perror("socketpair");
        return -1;
    }

    int pid = fork();
    if (pid < 0){
        perror("fork");
        return -1;
    }

    if (pid == 0) { // child - executes passt
        if (close(socket_fds[HYPERVISOR]) < 0) {
            perror("close HYPERVISOR");
        }

        char fd_as_str[16]; 
        snprintf(fd_as_str, sizeof(fd_as_str), "%d", socket_fds[PASST]);

        printf("passing fd %s to passt\n", fd_as_str);

        if (execlp("passt", "passt", "--trace", "-f", "--fd", fd_as_str, NULL) < 0) {
            perror("execlp");
            return -1;
        }
    } else { // parent - would be a VM hypervisor
        if (close(socket_fds[PASST])) {
             perror("close PASST");
        }

        // now I would expect to be able to use socket_fds[HYPERVISOR] to send traffic to passt
        for(;;) {
            char msg[] = {0, 0, 0, 4, 0xff, 0xff, 0xff, 0xff};
            if (send(socket_fds[HYPERVISOR], msg, sizeof(msg), MSG_NOSIGNAL) < 0) {
                perror("send");
                return -1;
            }
        }
    }
    return 0;
}

Actual Results:  
send(socket_fds[HYPERVISOR],...) fails with ECONNRESET, "Connection reset by peer".

Expected Results:  
Passt inherits the file descriptor like it does with setenforce 0, and reads the packets. (and discards them because they are not valid - they are too small)

Comment 1 Stefano Brivio 2023-11-03 16:39:46 UTC
I'm still looking for possible ways to somehow reflect this into the SELinux policy. The fundamental issue here is that we can't readily associate a SELinux label to this descriptor, so we don't have a convenient way to allow passt to interact with it (and only this kind of file descriptor -- not arbitrary ones). One might even argue that your program would need its bit of policy, possibly using an interface exposed by passt's policy. But maybe there's a simpler way to cover this case itself.

By the way, we had a similar discussion about the ability of passing a pre-opened file descriptor as a proposed --log-fd option:

  https://archives.passt.top/passt-dev/20230606225836.63aecebe@elisabeth/

a slightly different problem, as here you're not opening an existing file, just a socket -- but still I was already raising potential issues with LSMs there.

Which brings me to the question: why don't you let passt create the UNIX domain socket instead, like it's done for QEMU (also with libvirt)? That makes things well manageable in LSM policies.

Comment 2 Matej Hrica 2023-11-07 11:58:42 UTC
I can make passt create the socket. I don't specifically need the `--fd` flag, it just seemed easier to get right (no race condition issues with the filename).
I noticed that it existed, wanted to use it and found that it seems to be unusable with SELinux and it seemed like a simple oversight in the SELinux policy. So if this is not possible or problematic security-wise to fix, maybe just document it in the manpage that it doesn't work with SELinux.

Comment 3 Stefano Brivio 2023-11-07 12:37:41 UTC
(In reply to Matej Hrica from comment #2)
> I can make passt create the socket. I don't specifically need the `--fd`
> flag, it just seemed easier to get right (no race condition issues with the
> filename).

I see. By the way, libvirt passes in its own filename:

  https://gitlab.com/libvirt/libvirt/-/blob/85f58711865385c3ba6414e398a7d08c60d362bd/src/qemu/qemu_passt.c#L54

you could probably use a similar approach.

> I noticed that it existed, wanted to use it and found that it seems to be
> unusable with SELinux

It is...

> and it seemed like a simple oversight in the SELinux
> policy.

...and it was.

> So if this is not possible or problematic security-wise to fix,

On a second thought, passt is anyway sandboxed in its own empty filesystem, so I guess allowing read and write access to an unconfined_t UNIX domain socket isn't a drama -- at least by design it can only happen to be the one from --fd.

> maybe just document it in the manpage that it doesn't work with SELinux.

I would rather not encourage users to disable SELinux and, perhaps, to accidentally forget to re-enable it. At the same time --fd should work. So I just posted this:

  https://archives.passt.top/passt-dev/20231107122850.1673680-1-sbrivio@redhat.com/

...it will reach Fedora 38 in a bit.

Comment 4 Fedora Update System 2023-11-07 15:39:25 UTC
FEDORA-2023-62773ee361 has been submitted as an update to Fedora 37. https://bodhi.fedoraproject.org/updates/FEDORA-2023-62773ee361

Comment 5 Fedora Update System 2023-11-07 15:39:29 UTC
FEDORA-2023-7809427a71 has been submitted as an update to Fedora 38. https://bodhi.fedoraproject.org/updates/FEDORA-2023-7809427a71

Comment 6 Fedora Update System 2023-11-07 15:39:29 UTC
FEDORA-2023-b0f55b9b9c has been submitted as an update to Fedora 39. https://bodhi.fedoraproject.org/updates/FEDORA-2023-b0f55b9b9c

Comment 7 Fedora Update System 2023-11-07 15:53:06 UTC
FEDORA-2023-38d5d06886 has been submitted as an update to Fedora 38. https://bodhi.fedoraproject.org/updates/FEDORA-2023-38d5d06886

Comment 8 Fedora Update System 2023-11-08 02:53:35 UTC
FEDORA-2023-38d5d06886 has been pushed to the Fedora 38 testing repository.
Soon you'll be able to install the update with the following command:
`sudo dnf upgrade --enablerepo=updates-testing --refresh --advisory=FEDORA-2023-38d5d06886`
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2023-38d5d06886

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

Comment 9 Fedora Update System 2023-11-08 02:58:19 UTC
FEDORA-2023-b0f55b9b9c has been pushed to the Fedora 39 testing repository.
Soon you'll be able to install the update with the following command:
`sudo dnf upgrade --enablerepo=updates-testing --refresh --advisory=FEDORA-2023-b0f55b9b9c`
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2023-b0f55b9b9c

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

Comment 10 Fedora Update System 2023-11-08 03:03:39 UTC
FEDORA-2023-62773ee361 has been pushed to the Fedora 37 testing repository.
Soon you'll be able to install the update with the following command:
`sudo dnf upgrade --enablerepo=updates-testing --refresh --advisory=FEDORA-2023-62773ee361`
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2023-62773ee361

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

Comment 11 Fedora Update System 2023-11-20 01:20:30 UTC
FEDORA-2023-b0f55b9b9c has been pushed to the Fedora 39 stable repository.
If problem still persists, please make note of it in this bug report.

Comment 12 Fedora Update System 2023-11-23 01:11:15 UTC
FEDORA-2023-62773ee361 has been pushed to the Fedora 37 stable repository.
If problem still persists, please make note of it in this bug report.

Comment 13 Fedora Update System 2023-11-23 03:07:04 UTC
FEDORA-2023-38d5d06886 has been pushed to the Fedora 38 stable repository.
If problem still persists, please make note of it in this bug report.