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

"ip vrf exec" command fails when executed from a shell

Linking RHIVOS CVEs to...Migration: Automation ...Sync from "Extern...XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Normal Normal
    • None
    • rhel-9.6
    • iproute
    • None
    • Yes
    • Important
    • Customer Facing, Customer Reported
    • rhel-net-core
    • None
    • False
    • False
    • Hide

      None

      Show
      None
    • None
    • None
    • None
    • None
    • Unspecified
    • Unspecified
    • Unspecified
    • None

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

      Customers sometimes try to execute commands under a VRF.
      With iproute-6.2.0-6.el9_4, it was possible to execute any command from a shell, because ip vrf was executing in the context of the shell, usually unconfined_t.
      This caused the target command to execute in the context of the shell as well.

      This is however now different and fails with iproute-6.11.0-1.el9 because the new implementation is somehow SELinux-aware, in particular this code below:

      449 static int ipvrf_exec(int argc, char **argv)
      450 {
       :
      460         if (is_selinux_enabled() && setexecfilecon(argv[1], "ifconfig_t")) {
      461                 fprintf(stderr, "setexecfilecon for \"%s\" failed\n", argv[1]);
      462                 return -1;
      463         }
      464 
      465         return -cmd_exec(argv[1], argv + 1, !!batch_mode, do_switch, argv[0]);
      466 }
      

      This leads to executing the target command in ifconfig_t context, because usually there is no transition rule from caller (ip vrf process) context (unconfined_t.

      Example with new implementation:

      # ip link add vrf42 type vrf table 42
      # ip link set vrf42 up
      
      # strace -fttTvyy -s 128 --secontext -o new.strace -- ip vrf exec vrf42 /usr/bin/true
      exec of "/usr/bin/true" failed: Permission denied
      

      Strace shows:

      5139  [unconfined_t] 13:57:20.574539 execve("/usr/sbin/ip" [ifconfig_exec_t], ["ip", "vrf", "exec", "vrf42", "/usr/bin/true"], ...) = 0 <0.000124>
      5139  [unconfined_t] 13:57:20.574960 brk(NULL) = 0x55a02d10c000 <0.000005>
       :
      5139  [unconfined_t] 13:57:20.582785 openat(AT_FDCWD</root>, "/sys/fs/selinux/create" [security_t], O_RDWR|O_CLOEXEC) = 4</sys/fs/selinux/create> [security_t] <0.000007>
      5139  [unconfined_t] 13:57:20.582817 write(4</sys/fs/selinux/create> [security_t], "unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 system_u:object_r:bin_t:s0 2", 82) = 82 <0.000018>
      5139  [unconfined_t] 13:57:20.582853 read(4</sys/fs/selinux/create> [security_t], "unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023\0", 4095) = 54 <0.000005>
      5139  [unconfined_t] 13:57:20.582877 close(4</sys/fs/selinux/create> [security_t]) = 0 <0.000006>
      5139  [unconfined_t] 13:57:20.582901 openat(AT_FDCWD</root>, "/proc/thread-self/attr/exec" [unconfined_t], O_RDWR|O_CLOEXEC) = 4</proc/5139/task/5139/attr/exec> [unconfined_t] <0.000010>
      5139  [unconfined_t] 13:57:20.582937 write(4</proc/5139/task/5139/attr/exec> [unconfined_t], "unconfined_u:unconfined_r:ifconfig_t:s0-s0:c0.c1023\0", 52) = 52 <0.000012>
      5139  [unconfined_t] 13:57:20.582966 close(4</proc/5139/task/5139/attr/exec> [unconfined_t]) = 0 <0.000006>
       :
      5139  [unconfined_t] 13:57:20.593205 execve("/usr/bin/true" [bin_t], ["/usr/bin/true"], ...) = -1 EACCES (Permission denied) <0.000095>
      

      Here above ip vrf ... initially executes in the context of the shell, then the call to setexecfilecon() is performed, which returns nothing, ending up with trying to execute /usr/bin/true in ifconfig_t context (see the last write(4</proc/5139/task/5139/attr/exec> [unconfined_t], "unconfined_u:unconfined_r:ifconfig_t:s0-s0:c0.c1023\0", 52)).
      This fails because ifconfig_t cannot execute something labeled with bin_t without having an entrypoint rule, there is a SELinux AVC popping up:

      type=PROCTITLE msg=audit(08/26/2025 13:57:20.592:333) : proctitle=ip vrf exec vrf42 /usr/bin/true
      type=SYSCALL msg=audit(08/26/2025 13:57:20.592:333) : arch=x86_64 syscall=execve success=no exit=EACCES(Permission denied) a0=0x7ffd78f5a64a a1=0x7ffd78f58408 a2=0x7ffd78f58418 a3=0x1413 items=0 ppid=5136 pid=5139 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=3 comm=ip exe=/usr/sbin/ip subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
      type=AVC msg=audit(08/26/2025 13:57:20.592:333) : avc:  denied  { entrypoint } for  pid=5139 comm=ip path=/usr/bin/true dev="dm-0" ino=16811624 scontext=unconfined_u:unconfined_r:ifconfig_t:s0-s0:c0.c1023 tcontext=system_u:object_r:bin_t:s0 tclass=file permissive=0
      

      Even if there was some entrypoint, this wouldn't help execute in the proper context, since every command would then execute in ifconfig_t context, which is not what we want.

      Compared to old non-SELinux-aware implementation:

      # ip link add vrf42 type vrf table 42
      # ip link set vrf42 up
      
      # strace -fttTvyy -s 128 --secontext -o old.strace -- ip vrf exec vrf42 /usr/bin/true
      #
      

      Strace shows success because everything remained in unconfined_t context:

      5854  [unconfined_t] 13:57:30.520996 execve("/usr/sbin/ip" [ifconfig_exec_t], ["ip", "vrf", "exec", "vrf42", "/usr/bin/true"], ...) = 0 <0.000243>
      5854  [unconfined_t] 13:57:30.521440 brk(NULL) = 0x55ec4ba39000 <0.000018>
      --
      5854  [unconfined_t] 13:57:30.538243 execve("/usr/bin/true" [bin_t], ["/usr/bin/true"], ...) = 0 <0.000181>
      5854  [unconfined_t] 13:57:30.538471 brk(NULL) = 0x55b79abd3000 <0.000007>
      

      I'm actually quite confused by the new code, I don't see how it helps in the usual context which is running a service wrapped into ip vrf.
      Without that setexecfilecon() code, this worked already after rules for specific services were added into the policy.

      What is the impact of this issue to you?

      Customers cannot run commands in a VRF.

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

      iproute-6.11.0-1.el9

      How reproducible is this bug?:

      Always, see above example.

              nst-kernel-bugs nst-kernel-bugs
              rhn-support-rmetrich Renaud Métrich
              nst-kernel-bugs nst-kernel-bugs
              Ying Xu Ying Xu
              Votes:
              1 Vote for this issue
              Watchers:
              10 Start watching this issue

                Created:
                Updated: