• L
    util: virSetUIDGIDWithCaps - change uid while keeping caps · e11451f4
    Laine Stump 提交于
    Normally when a process' uid is changed to non-0, all the capabilities
    bits are cleared, even those explicitly set with calls to
    capng_update()/capng_apply() made immediately before setuid. And
    *after* the process' uid has been changed, it no longer has the
    necessary privileges to add capabilities back to the process.
    
    In order to set a non-0 uid while still maintaining any capabilities
    bits, it is necessary to either call capng_change_id() (which
    unfortunately doesn't currently call initgroups to setup auxiliary
    group membership), or to perform the small amount of calisthenics
    contained in the new utility function virSetUIDGIDWithCaps().
    
    Another very important difference between the capabilities
    setting/clearing in virSetUIDGIDWithCaps() and virCommand's
    virSetCapabilities() (which it will replace in the next patch) is that
    the new function properly clears the capabilities bounding set, so it
    will not be possible for a child process to set any new
    capabilities.
    
    A short description of what is done by virSetUIDGIDWithCaps():
    
    1) clear all capabilities then set all those desired by the caller (in
    capBits) plus CAP_SETGID, CAP_SETUID, and CAP_SETPCAP (which is needed
    to change the capabilities bounding set).
    
    2) call prctl(), telling it that we want to maintain current
    capabilities across an upcoming setuid().
    
    3) switch to the new uid/gid
    
    4) again call prctl(), telling it we will no longer want capabilities
    maintained if this process does another setuid().
    
    5) clear the capabilities that we added to allow us to
    setuid/setgid/change the bounding set (unless they were also requested
    by the caller via the virCommand API).
    
    Because the modification/maintaining of capabilities is intermingled
    with setting the uid, this is necessarily done in a single function,
    rather than having two independent functions.
    
    Note that, due to the way that effective capabilities are computed (at
    time of execve) for a process that has uid != 0, the *file*
    capabilities of the binary being executed must also have the desired
    capabilities bit(s) set (see "man 7 capabilities"). This can be done
    with the "filecap" command. (e.g. "filecap /usr/bin/qemu-kvm sys_rawio").
    e11451f4
libvirt_private.syms 42.3 KB