[libvirt] [PATCHv2 2/2] security: Add a new func use stat to get process DAC label

lhuang lhuang at redhat.com
Fri Dec 5 06:57:28 UTC 2014


On 12/05/2014 12:58 AM, Ján Tomko wrote:
> On 12/03/2014 11:08 AM, Luyao Huang wrote:
>> When use qemuProcessAttach to attach a qemu process, cannot
>> get a right DAC label. Add a new func to get process label
>> via stat func. Do not remove virDomainDefGetSecurityLabelDef
>> before try to use stat to get process DAC label, because
>> There are some other func call virSecurityDACGetProcessLabel.
>>
>> v2 add support freeBSD.
>>
>> Signed-off-by: Luyao Huang <lhuang at redhat.com>
>> ---
>>   src/security/security_dac.c | 95 ++++++++++++++++++++++++++++++++++++++++++++-
>>   1 file changed, 93 insertions(+), 2 deletions(-)
>>
>> diff --git a/src/security/security_dac.c b/src/security/security_dac.c
>> index 85253af..89cafa3 100644
>> --- a/src/security/security_dac.c
>> +++ b/src/security/security_dac.c
>> @@ -23,6 +23,11 @@
>>   #include <sys/stat.h>
>>   #include <fcntl.h>
>>   
>> +#ifdef  __FreeBSD__
>> +# include <sys/sysctl.h>
>> +# include <sys/user.h>
>> +#endif
>> +
>>   #include "security_dac.h"
>>   #include "virerror.h"
>>   #include "virfile.h"
>> @@ -1236,18 +1241,104 @@ virSecurityDACReserveLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
>>       return 0;
>>   }
>>   
>> +#ifdef __linux__
>> +static int
>> +virSecurityDACGetProcessLabelInternal(pid_t pid,
>> +                                      virSecurityLabelPtr seclabel)
>> +{
>> +    struct stat sb;
>> +    char *path = NULL;
>> +    char *label = NULL;
>> +    int ret = -1;
>> +
>> +    VIR_INFO("Getting DAC user and group on process '%d'", pid);
>> +
>> +    if (virAsprintf(&path, "/proc/%d", (int) pid) < 0)
>> +        goto cleanup;
>> +
>> +    if (lstat(path, &sb) < 0)
>> +        goto cleanup;
> A more specific error should be reported here via virReportSystemError.
Thanks, i will move error settings in this func.
>> +
>> +    if (virAsprintf(&label, "+%u:+%u",
>> +                    (unsigned int) sb.st_uid,
>> +                    (unsigned int) sb.st_gid) < 0)
>> +        goto cleanup;
>> +
>> +    if (virStrcpy(seclabel->label, label,VIR_SECURITY_LABEL_BUFLEN) == NULL)
>> +        goto cleanup;
> Using snprintf would simplify this code.
Oh, nice, i forgot this function, and thanks your pointing out.
>> +    ret = 0;
>> +
>> +cleanup:
>> +    VIR_FREE(path);
>> +    VIR_FREE(label);
>> +    return ret;
>> +}
>> +#elif defined(__FreeBSD__)
>> +static int
>> +virSecurityDACGetProcessLabelInternal(pid_t pid,
>> +                                      virSecurityLabelPtr seclabel)
>> +{
>> +    struct kinfo_proc p;
>> +    int mib[4];
>> +    size_t len = 4;
>> +    char *label = NULL;
>> +    int ret = -1;
>> +
>> +    sysctlnametomib("kern.proc.pid", mib, &len);
>> +
>> +    len = sizeof(struct kinfo_proc);
>> +    mib[3] = pid;
>> +
>> +    if (sysctl(mib, 4, &p, &len, NULL, 0) < 0)
>> +        goto cleanup;
>> +
> sysctlbyname would remove the need for a separate nametomib call and get rid
> of a few variables.
Actually, i tried to use this func (sysctlbyname) before, but i found i 
cannot make it
work well here...

If you have some good way to use it, please tell me, thanks a lot for 
your answer:)
>
>> +    if (virAsprintf(&label, "+%u:+%u",
>> +                    (unsigned int) p.ki_ruid,
>> +                    (unsigned int) p.ki_rgid) < 0)
>> +        goto cleanup;
>> +
>> +    if (virStrcpy(seclabel->label, label,VIR_SECURITY_LABEL_BUFLEN) == NULL)
>> +        goto cleanup;
> Same comment as above.
Thanks
>> +    ret = 0;
>> +
>> +cleanup:
>> +    VIR_FREE(label);
>> +    return ret;
>> +}
>> +#else
>> +static int
>> +virSecurityDACGetProcessLabelInternal(pid_t pid,
>> +                                      virSecurityLabelPtr seclabel)
>> +{
>> +    return -1;
>> +}
>> +#endif
>> +
>>   static int
>>   virSecurityDACGetProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
>>                                 virDomainDefPtr def,
>> -                              pid_t pid ATTRIBUTE_UNUSED,
>> +                              pid_t pid,
>>                                 virSecurityLabelPtr seclabel)
>>   {
>>       virSecurityLabelDefPtr secdef =
>>           virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
>>   
>> -    if (!secdef || !seclabel)
>> +    if (!seclabel)
>>           return -1;
> The SELinux version of this function does not check if seclabel is non-NULL, I
> think we can safely remove the check here as well.
Okay
>>   
>> +    if (secdef == NULL) {
>> +        VIR_DEBUG("missing label for DAC security "
>> +                  "driver in domain %s", def->name);
>> +
>> +        if (virSecurityDACGetProcessLabelInternal(pid, seclabel) < 0) {
>> +            virReportError(VIR_ERR_INTERNAL_ERROR,
>> +                           _("Cannot get process %d DAC label"),pid);
> This would overwrite the more-specific error message from the
> virSecurityDACGetProcessLabelInternal function.
Yes, got it, thanks for pointing out.
>> +            return -1;
>> +        }
>> +
>> +        return 0;
>> +    }
>> +
>>       if (secdef->label)
>>           ignore_value(virStrcpy(seclabel->label, secdef->label,
>>                                  VIR_SECURITY_LABEL_BUFLEN));
>>
> Jan
>
>




More information about the libvir-list mailing list