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(a)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