On 7/5/24 10:01, hongmianquan wrote:
> We have the stack security driver, which internally manages other security
> drivers,
> just call them "top" and "nested".
>
> We call virSecurityStackPreFork() to lock the top one, and it also locks
> and then unlocks the nested drivers prior to fork. Then in
> qemuSecurityPostFork(),
> it unlocks the top one, but not the nested ones. Thus, if one of the nested
> drivers ("dac" or "selinux") is still locked, it will cause a deadlock. If we
> always
> surround nested locks with top lock, it is always secure. Because we have got
> top lock
> before fork child libvirtd.
>
> However, it is not always the case in the current code, We discovered this
> case:
> the nested list obtained through the qemuSecurityGetNested() will be locked
> directly
> for subsequent use, such as in virQEMUDriverCreateCapabilities(), where the
> nested list
> is locked using qemuSecurityGetDOI, but the top one is not locked beforehand.
>
> The problem stack is as follows:
>
> libvirtd thread1 libvirtd thread2 child libvirtd
> | | |
> | | |
> virsh capabilities qemuProcessLanuch |
> | | |
> | lock top |
> | | |
> lock nested | |
> | | |
> | fork------------------->|(nested lock
> held by thread1)
> | | |
> | | |
> unlock nested unlock top unlock top
> |
> |
> qemuSecuritySetSocketLabel
> |
> |
> lock nested (deadlock)
>
> v3 changes:
> Made modifications based on Michal's comments
> - ensured matching qemuSecurityStackLock() and qemuSecurityStackUnlock()
> - modify the correct order in libvirt_private.syms
> - split the code streamlining part into a separate patch
>
> hongmianquan (2):
> security_manager: Ensure top lock is acquired before nested locks
> security_manager: Remove redundant qemuSecurityGetNested() call
>
> src/libvirt_private.syms | 2 ++
> src/qemu/qemu_conf.c | 13 +++++++++++--
> src/qemu/qemu_driver.c | 21 +++++++++++++--------
> src/qemu/qemu_security.h | 2 ++
> src/security/security_manager.c | 22 ++++++++++++++++++++++
> src/security/security_manager.h | 2 ++
> 6 files changed, 52 insertions(+), 10 deletions(-)
>
Reviewed-by: Michal Privoznik <[email protected]>
and merged. Congratulations on your first libvirt contribution!
Michal