Uploaded image for project: 'RHEL'
  1. RHEL
  2. RHEL-75983

systemd cannot delete temporary directory and its content with service is started with "PrivateTmp=yes"

Linking RHIVOS CVEs to...Migration: Automation ...SWIFT: POC ConversionSync from "Extern...XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Normal Normal
    • None
    • rhel-8.10, rhel-9.5
    • systemd
    • No
    • Moderate
    • rhel-systemd
    • ssg_core_services
    • 5
    • False
    • False
    • Hide

      None

      Show
      None
    • None
    • Red Hat Enterprise Linux
    • None
    • None
    • None
    • None

      What were you trying to do that didn't work?

      When executing a service having PrivateTmp=yes property in the unit file, it's possible that systemd cannot remove the temporary content created as /tmp/systemd-private-<machineid>-<service>-<random> because it has no SELinux rules for that.
      This leads to filling /tmp with time and no cleanup ever occurs since systemd-tmpfiles-clean excludes /tmp/private-* from cleanup.

      What is the impact of this issue to you?

      High impact, filling /tmp until there is no space left on device.

      Please provide the package NVR for which the bug is seen:

      systemd-239
      systemd-252

      How reproducible is this bug?:

      Always

      Steps to reproduce

      1. Execute the transient service below
        # systemd-run -p PrivateTmp=yes --unit reproducer.service -- /bin/sh -c "touch /tmp/foo"

      Expected results

      No /tmp/systemd-private-<machineid>-reproducer.service-<random> after service exited.

      Actual results

      Presence of /tmp/systemd-private-<machineid>-reproducer.service-<random> and content inside.

      Additional information

      The reason systemd is not able to perform the cleanup is /tmp/foo got initrc_tmp_t label, which prevents init_t from deleting it:

      # sesearch -A -s init_t -c file -t initrc_tmp_t -p unlink
      --> no rule
      

      strace:

      4530  [init_t] 08:50:00.428351 unlinkat(20</tmp/systemd-private-51ac2e37948443d68a88be6c2d754ad1-reproducer.service-q7b3r1/tmp> [tmp_t], "foo" [initrc_tmp_t], 0 <unfinished ...>
      4530  [init_t] 08:50:00.428578 <... unlinkat resumed>) = -1 EACCES (Permission denied) <0.000203>
      4530  [init_t] 08:50:00.428763 unlinkat(18</tmp/systemd-private-51ac2e37948443d68a88be6c2d754ad1-reproducer.service-q7b3r1> [tmp_t], "tmp" [tmp_t], AT_REMOVEDIR <unfinished ...>
      4530  [init_t] 08:50:00.428805 <... unlinkat resumed>) = -1 ENOTEMPTY (Directory not empty) <0.000019>
      

      AVC:

      type=PROCTITLE msg=audit(01/23/2025 08:50:00.428:107) : proctitle=/usr/lib/systemd/systemd --switched-root --system --deserialize 31 
      type=SYSCALL msg=audit(01/23/2025 08:50:00.428:107) : arch=x86_64 syscall=unlinkat success=no exit=EACCES(Permission denied) a0=0x14 a1=0x7f05b0008c83 a2=0x0 a3=0x9b items=0 ppid=0 pid=1 auid=unset uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=unset comm=systemd exe=/usr/lib/systemd/systemd subj=system_u:system_r:init_t:s0 key=(null) 
      type=AVC msg=audit(01/23/2025 08:50:00.428:107) : avc:  denied  { unlink } for  pid=1 comm=systemd name=foo dev="dm-0" ino=50331887 scontext=system_u:system_r:init_t:s0 tcontext=system_u:object_r:initrc_tmp_t:s0 tclass=file permissive=0 
      

      I see 2 solutions:

      1. either make the child doing the cleanup run in an unconfined context
      2. or add rules in the SELinux policy to let init_t delete whatever it wants

              msekleta@redhat.com Michal Sekletar
              rhn-support-rmetrich Renaud Métrich
              systemd maint mailing list systemd maint mailing list
              Frantisek Sumsal Frantisek Sumsal
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Created:
                Updated: