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@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; A more specific error should be reported here via virReportSystemError. > + > + 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. > + 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. > + 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. > + 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. > > + 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. > + return -1; > + } > + > + return 0; > + } > + > if (secdef->label) > ignore_value(virStrcpy(seclabel->label, secdef->label, > VIR_SECURITY_LABEL_BUFLEN)); > Jan
Attachment:
signature.asc
Description: OpenPGP digital signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list