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

AVC "setattr" on keepalived script gets generated when keepalived starts

    • Icon: Bug Bug
    • Resolution: Done-Errata
    • Icon: Minor Minor
    • rhel-9.4
    • rhel-9.2.0
    • selinux-policy
    • None
    • selinux-policy-38.1.25-1.el9
    • None
    • Low
    • sst_security_selinux
    • ssg_security
    • 10
    • None
    • QE ack, Dev ack
    • False
    • Hide

      None

      Show
      None
    • No
    • Red Hat Enterprise Linux
    • None
    • Hide

      The keepalived service does not trigger any SELinux denials when it is configured to run a script stored in the /usr/libexec/keepalived directory. The executed script works successfully in enforcing mode.

      Show
      The keepalived service does not trigger any SELinux denials when it is configured to run a script stored in the /usr/libexec/keepalived directory. The executed script works successfully in enforcing mode.
    • Pass
    • None
    • All
    • None

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

      Starting keepalived while having a custom checker script stored in standard path /usr/libexec/keepalived leads to getting an AVC on "setattr" SELinux operation:

      type=PROCTITLE msg=audit(10/17/2023 15:18:27.325:319) : proctitle=/usr/sbin/keepalived --dont-fork -D 
      type=SYSCALL msg=audit(10/17/2023 15:18:27.325:319) : arch=x86_64 syscall=utimensat success=no exit=EACCES(Permission denied) a0=AT_FDCWD a1=0x558d72a92910 a2=0x7ffc1277fb70 a3=0x0 items=0 ppid=3139 pid=3140 auid=unset uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=unset comm=keepalived exe=/usr/sbin/keepalived subj=system_u:system_r:keepalived_t:s0 key=(null) 
      type=AVC msg=audit(10/17/2023 15:18:27.325:319) : avc:  denied  { setattr } for  pid=3140 comm=keepalived name=test.sh dev="dm-0" ino=16784084 scontext=system_u:system_r:keepalived_t:s0 tcontext=system_u:object_r:keepalived_unconfined_script_exec_t:s0 tclass=file permissive=0  

      The root cause for this is keepalived does sanity checks on the script through calling check_script_secure() function, which, internally relies on libmagic magic_file() function on line 813:

       672 unsigned
       673 check_script_secure(notify_script_t *script,
       :
       678 {
       :
       811 #ifdef _HAVE_LIBMAGIC_
       812         if (magic && flags & SC_EXECUTABLE) {
       813                 const char *magic_desc = magic_file(magic, real_file_path ? real_file_path : script->args[0]);
       814                 if (!strstr(magic_desc, " executable") &&
       815                     !strstr(magic_desc, " shared object")) {
       816                         log_message(LOG_INFO, "Please add a #! shebang to script %s", script->args[0]);
       817                         script->flags &= ~SC_EXECABLE;
       818                 }
       819         }
       820 #endif
       :

      magic_file() function internally opens/reads the file, then closes it and tries restoring the access time, which makes the AVC pop up because there is no rule for this in the policy.

      I think the solution here is to hide the AVC through a new dontaudit rule, which may be very generic actually (because if a checker is stored in another directory than standard path, the AVC should also be avoided, whatever the label is), something like this below (CIL format):

      (dontaudit keepalived_t file_type (file (setattr))) 

      I'm creating this Jira against keepalived because developers have to be aware of this and probably this indicates a lack of testing in a SELinux environment since reproducer is very basic.

      Please provide the package NVR for which bug is seen:

      keepalived-2.2.4-6.el9.x86_64
      selinux-policy-38.1.11-2.el9_2.4.noarch

      How reproducible:

      Always

      Steps to reproduce

      1. Create a basic checker /usr/libexec/keepalived/test.sh
        #!/bin/sh
        echo "Hello"
      1. Make it executable and with proper context
        # chmod +x /usr/libexec/keepalived/test.sh
        # restorecon -Frv /usr/libexec/keepalived/test.sh
      1.  Create a basic keepalived configuration (/etc/keepalived/keepalived.conf)
        ! Configuration File for keepalived
        global_defs {
            router_id DUMMY
        }
        
        vrrp_sync_group haproxy {
            group {
              external
            }
        }
        
        vrrp_script check_haproxy {
            script "/usr/libexec/keepalived/test.sh"
            interval 2
            weight 2
            fall 3
            rise 6
        }
        
        vrrp_instance external {
            interface enp1s0
            state MASTER
            virtual_router_id 10
            priority 101
            advert_int 1
            virtual_ipaddress {
              192.168.122.12 dev enp1s0 label enp1s0:0
            }
            track_script {
              check_haproxy
            }
        }
      1.  Start the service
        # systemctl start keepalived

      Expected results

      No AVC

      Actual results

      AVC

            rhn-support-zpytela Zdenek Pytela
            rhn-support-rmetrich Renaud Métrich
            Nikola Kňažeková Nikola Kňažeková (Inactive)
            Milos Malik Milos Malik
            Votes:
            2 Vote for this issue
            Watchers:
            9 Start watching this issue

              Created:
              Updated:
              Resolved: