[libvirt] [PATCH] RFC: security: Make sure to decrease ref count label value

Stefan Berger stefanb at linux.ibm.com
Thu Aug 1 17:45:21 UTC 2019


On 7/29/19 5:17 AM, Michal Privoznik wrote:
> On 7/26/19 8:38 PM, Stefan Berger wrote:
>> I noticed that if a domain fails to restore, the ref count in the xattr
>> 'trusted.libvirt.security.ref_selinux' keeps on increasing indefinitely
>> and the VM will never restore even if the root cause for the restore
>> failure has been removed. The reason seems to be that the code to 
>> decrease
>> the ref count never gets called because the block above it fails due
>> to virSecuritySELinuxTransactionAppend() failing. The simple solution
>> seems to be to revert the order in which things are done.
>>
>> Signed-off-by: Stefan Berger <stefanb at linux.ibm.com>
>> ---
>>   src/security/security_selinux.c | 19 +++++++++++--------
>>   1 file changed, 11 insertions(+), 8 deletions(-)
>
> So what was the root cause, did you ever find out?


The root cause of the failure was basically me (intentionally) changing 
the password for the encrypted vTPM to a wrong password and then QEMU 
cannot *resume* 'swtpm' since it cannot decrypt the state. The operation 
on virt-manager level was a restore of a saved VM.


>
>>
>> diff --git a/src/security/security_selinux.c 
>> b/src/security/security_selinux.c
>> index ea20373a90..9fd29e9bca 100644
>> --- a/src/security/security_selinux.c
>> +++ b/src/security/security_selinux.c
>> @@ -1499,14 +1499,9 @@ 
>> virSecuritySELinuxRestoreFileLabel(virSecurityManagerPtr mgr,
>>           goto cleanup;
>>       }
>>   -    if ((rc = virSecuritySELinuxTransactionAppend(path, NULL,
>> -                                                  false, recall, 
>> true)) < 0) {
>> -        goto cleanup;
>> -    } else if (rc > 0) {
>> -        ret = 0;
>> -        goto cleanup;
>> -    }
>> -
>> +    /* Recall the label so the ref count label decreases its counter
>> +     * even if transaction append below fails.
>> +     */
>>       if (recall) {
>>           rc = virSecuritySELinuxRecallLabel(newpath, &fcon);
>>           if (rc == -2) {
>> @@ -1519,6 +1514,14 @@ 
>> virSecuritySELinuxRestoreFileLabel(virSecurityManagerPtr mgr,
>>           }
>>       }
>>   +    if ((rc = virSecuritySELinuxTransactionAppend(path, NULL,
>> +                                                  false, recall, 
>> true)) < 0) {
>> +        goto cleanup;
>> +    } else if (rc > 0) {
>> +        ret = 0;
>> +        goto cleanup;
>> +    }
>> +
>>       if (!recall || rc == -2) {
>>           if (stat(newpath, &buf) != 0) {
>>               VIR_WARN("cannot stat %s: %s", newpath,
>>
>
> IIUC, this gets then called twice, doesn't it? I mean, transactions 
> are hackish a bit. We wanted chown() and setfilecon_raw() to run 
> inside the mount namespace of a domain. So instead of rewriting our 
> secdrivers and making them enter the namespace on every 
> chown()/setfilecon_raw() we put small code snippets just before these 
> calls that would record arguments for these functions in a thread 
> local variable and then transactionCommit() would enter the namespace 
> and replay all chown()/setfilecon_raw().
>
> That's why there can't be any code before transactionAppend(), because 
> it would be called twice - once from regular call and from 
> transactionCommit(). For instance:
>
> virSecuritySELinuxDomainSetPathLabel()
>  -> virSecuritySELinuxSetFilecon()
>    -> virSecuritySELinuxSetFileconHelper()
>      -> virSecuritySELinuxTransactionAppend()
>
> virSecuritySELinuxTransactionCommit()
>   -> virSecuritySELinuxTransactionRun()
>     -> virSecuritySELinuxSetFileconHelper()
>       -> virSecuritySELinuxSetFileconImpl()
>         -> setfilecon_raw()
>
> We need to find the root cause. Maybe our set is not on par with 
> restore, i.e. we are calling more set than restore and thus the 
> refcounter just keeps growing?


The root cause was as described above and I wanted to see how QEMU+SWTPM 
react if I do this.


What I noticed was that the ...TransactionAppend() failed and didn't get 
to the code to decrease the ref count, which then ended up increasing 
forever. So I created this patch, which did indeed solve this particular 
problem but then caused Signal 11's once I provoked an error with 
starting (rather than resuming) a VM where again I had changed the 
password (iirc).


    Stefan


>
> Michal
>




More information about the libvir-list mailing list