Bug 2241366 - Restorecon not working correctly
Summary: Restorecon not working correctly
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: Fedora
Classification: Fedora
Component: selinux-policy
Version: 38
Hardware: Unspecified
OS: Linux
high
high
Target Milestone: ---
Assignee: Zdenek Pytela
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2023-09-29 14:31 UTC by Daniel Walsh
Modified: 2024-04-22 15:51 UTC (History)
10 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2024-04-22 15:51:05 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Daniel Walsh 2023-09-29 14:31:26 UTC
Matchcon and restorecon do not agree after setting a equivalency fcontext.

Reproducible: Always

Steps to Reproduce:
# semanage fcontext -a -e /etc /var/run/foo/bar
# mkdir -p /var/run/foo/bar
# ls -lZd  /var/run/foo/bar
drwxr-xr-x. 2 root root unconfined_u:object_r:var_run_t:s0 40 Sep 29 10:01 /var/run/foo/bar
# matchpathcon /var/run/foo/bar
/var/run/foo/bar	system_u:object_r:etc_t:s0

Everything looks correct except

# restorecon -v /var/run/foo/bar

The restorecon command does not fix the label.

# ls -lZd  /var/run/foo/bar
drwxr-xr-x. 2 root root unconfined_u:object_r:var_run_t:s0 40 Sep 29 10:01 /var/run/foo/bar
# chcon -t etc_t /var/run/foo/bar
# ls -lZd  /var/run/foo/bar
drwxr-xr-x. 2 root root unconfined_u:object_r:etc_t:s0 40 Sep 29 10:01 /var/run/foo/bar
# restorecon -v /var/run/foo/bar
Relabeled /run/foo/bar from unconfined_u:object_r:etc_t:s0 to unconfined_u:object_r:var_run_t:s0

Why is matchpathcon and restorecon different ideas on what the label should be?

Comment 1 Milos Malik 2023-10-02 06:50:30 UTC
# semanage fcontext -l | grep '^/run ='
/run = /var/run
# semanage fcontext -a -e /etc /var/run/foo/bar
# semanage fcontext -l -C

SELinux Local fcontext Equivalence 

/var/run/foo/bar = /etc
# matchpathcon /etc/
/etc	system_u:object_r:etc_t:s0
# matchpathcon /var/run/foo/bar
/var/run/foo/bar	system_u:object_r:etc_t:s0
# matchpathcon /run/foo/bar
/run/foo/bar	system_u:object_r:var_run_t:s0
#

As you can see above, the SELinux context changed by removing the "/var" prefix.

# ls -ild /run
1 drwxr-xr-x. 33 root root 980 Oct  2 02:41 /run
# ls -ild /var/run
402 lrwxrwxrwx. 1 root root 6 Sep 26 07:43 /var/run -> ../run
#

Comment 2 Alexander Larsson 2023-10-02 10:45:22 UTC
I can't make /etc equivalent to /run/foo/bar though.

# semanage fcontext -a -e /etc /run/foo/bar
ValueError: File spec /run/foo/bar conflicts with equivalency rule '/run /var/run'; Try adding '/var/run/foo/bar' instead

So, the only way this could work is as per the example. 

I was hoping it would resolve the equivalences in multiple steps though. 
Like /run/foo/bar => /var/run/foo/bar => /etc

Comment 3 Petr Lautrbach 2023-10-02 11:36:46 UTC
`restorecon` uses `realpath` before it evaluates a context. In this case:

    # realpath /var/run/foo/bar/
    /run/foo/bar

But it's not possible to add a new equivalency rule for "/run/foo/bar" as it's in conflict with already existing rule:

    # semanage fcontext -a -e /etc /run/foo/bar
    ValueError: File spec /run/foo/bar conflicts with equivalency rule '/run /var/run'; Try adding '/var/run/foo/bar' instead

    # semanage fcontext -l | sed '1,/SELinux Distribution fcontext Equivalence/d' | grep '/var/run'
    /run = /var/run

At this moment, I think it's time to change selinux policy equivalence rules so that they follows the fact that `/var/run` is a symlink to `/run`, i.e. change equivalence rules so that
"/var/run" => "/run"  instead of current "/run" => "/var/run"

Comment 4 Petr Lautrbach 2023-10-02 13:16:06 UTC
There's another tool - `setfiles` which can be used for setting SELinux file contexts and which does not expand paths via `realpath`, e.g.

# matchpathcon /var/run/foo/bar /run/foo/bar
/var/run/foo/bar        system_u:object_r:etc_t:s0
/run/foo/bar    system_u:object_r:var_run_t:s0

# setfiles -v /etc/selinux/targeted/contexts/files/file_contexts /var/run/foo/bar
Relabeled /var/run/foo/bar from system_u:object_r:var_run_t:s0 to system_u:object_r:etc_t:s0

# setfiles -v /etc/selinux/targeted/contexts/files/file_contexts /run/foo/bar
Relabeled /run/foo/bar from system_u:object_r:etc_t:s0 to system_u:object_r:var_run_t:s0


See https://github.com/SELinuxProject/selinux/blob/main/policycoreutils/setfiles/setfiles.c#L180 and https://github.com/SELinuxProject/selinux/blob/main/policycoreutils/setfiles/setfiles.c#L198

Comment 5 Alexander Larsson 2023-10-02 13:18:51 UTC
I'm not in control of how the relabeling is happening, because its systemd that triggers the relabeling of /run (from the initrd) after it has loaded the policy.

Comment 6 Petr Lautrbach 2023-10-02 13:45:26 UTC
Could you please share more details about your problem? From the reproducer in the description it's not clear when and why the relabeling happens

Comment 7 Alexander Larsson 2023-10-04 15:30:13 UTC
Well, the reproducer just showed what went wrong in a minimal way.

The actual usecase was that I wanted to use a directory in /run as an upperdir in an overlayfs mount for /etc. This is problematic, because /run is mounted in the initrd, so it has no initial labeling. Immediately after loading the selinux policy systemd then triggers a relabel, which makes my directory of type var_run_t.

This is not right, as the upper directory label will be the label of the overlayfs /etc mount, which needs to be etc_t, otherwise I get all sorts of errors.

In practice, I'm currently looking at other ways to handle /etc, so this isn't strictly a problem for me anymore. Still, it seems like a bug to me.

Comment 8 Daniel Walsh 2023-10-05 10:22:07 UTC
If the only file needed to be labeled etc_t is the top level file, you could force it, and then tell restorecon to not relabel it, by adding a file context:

semanage fcontext -a -t <<none>> /var/run/foo/bar

Comment 9 Zdenek Pytela 2024-04-22 15:51:05 UTC
I believe this issue is gone in F40+ with
https://github.com/fedora-selinux/selinux-policy/pull/2017


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