
On 12/11/2014 05:45 PM, Ján Tomko wrote:
On 12/09/2014 09:33 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.
Signed-off-by: Luyao Huang <lhuang@redhat.com> --- v2 add support freeBSD. v3 use snprintf instead of VirAsprintf and move the error settings in virSecurityDACGetProcessLabelInternal. v4 remove errno.h include and thanks Eric advice move this version comment to this place.
src/security/security_dac.c | 84 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 3 deletions(-)
ACK and pushed. I reworded the commit message and included the bugzilla link and a reference to the other part of the fix that has already been pushed. Thanks for your help :)
diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 85253af..300b245 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,17 +1241,90 @@ virSecurityDACReserveLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, return 0; }
+#ifdef __linux__ +static int +virSecurityDACGetProcessLabelInternal(pid_t pid, + virSecurityLabelPtr seclabel) +{ + struct stat sb; + char *path = NULL; + int ret = -1; + + VIR_INFO("Getting DAC user and group on process '%d'", pid); + VIR_INFO is too noisy for this, I've changed it to VIR_DEBUG. + if (virAsprintf(&path, "/proc/%d", (int) pid) < 0) + goto cleanup; + + if (lstat(path, &sb) < 0) { + virReportSystemError(errno, + _("unable to get PID %d uid and gid via stat"), + pid); + goto cleanup; + } + + snprintf(seclabel->label, VIR_SECURITY_LABEL_BUFLEN, + "+%u:+%u", (unsigned int) sb.st_uid, (unsigned int) sb.st_gid); + ret = 0; + +cleanup: + VIR_FREE(path); + return ret; +} +#elif defined(__FreeBSD__) +static int +virSecurityDACGetProcessLabelInternal(pid_t pid, + virSecurityLabelPtr seclabel) +{ + struct kinfo_proc p; + int mib[4]; + size_t len = 4; + + sysctlnametomib("kern.proc.pid", mib, &len); + + len = sizeof(struct kinfo_proc); + mib[3] = pid; + + if (sysctl(mib, 4, &p, &len, NULL, 0) < 0) { + virReportSystemError(errno, + _("unable to get PID %d uid and gid via sysctl"), + pid); + return -1; + } + + snprintf(seclabel->label, VIR_SECURITY_LABEL_BUFLEN, + "+%u:+%u", (unsigned int) p.ki_ruid, (unsigned int) p.ki_rgid); This gets the real uid/gid, we want the effective ones like on Linux. Yes, this should use effective uid/gid after i check the doc. Thanks for pointing out + + return 0; +} +#else +static int +virSecurityDACGetProcessLabelInternal(pid_t pid, + virSecurityLabelPtr seclabel) +{ + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + "Cannot get proccess DAC label for pid %d on this platform", + (int) pid); This fails syntax check - the string needs to be marked for translation with _(). I've changed it to virReportSystemError(ENOSYS, ..), to match the use in other places. Oh, it's my fault, thanks. Jan
Luyao