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@xxxxxxxxxx> --- 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; + + 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; + 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; + + 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; + 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; + 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); + return -1; + } + + return 0; + } + if (secdef->label) ignore_value(virStrcpy(seclabel->label, secdef->label, VIR_SECURITY_LABEL_BUFLEN)); -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list