mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
dac: Add a new func to get DAC label of a running process
When using qemuProcessAttach to attach a qemu process, the DAC label is not filled correctly. Introduce a new function to get the uid:gid from the system and fill the label. This fixes the daemon crash when 'virsh screenshot' is called: https://bugzilla.redhat.com/show_bug.cgi?id=1161831 It also fixes qemu-attach after the prerequisite of this patch (commit f8c1fb3) was pushed out of order. Signed-off-by: Luyao Huang <lhuang@redhat.com> Signed-off-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
82977058f5
commit
c7c96647e9
@ -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,89 @@ 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_DEBUG("Getting DAC user and group on process '%d'", pid);
|
||||
|
||||
if (virAsprintf(&path, "/proc/%d", (int) pid) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (lstat(path, &sb) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("unable to get uid and gid for PID %d via procfs"),
|
||||
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_uid, (unsigned int) p.ki_groups[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int
|
||||
virSecurityDACGetProcessLabelInternal(pid_t pid,
|
||||
virSecurityLabelPtr seclabel)
|
||||
{
|
||||
virReportSystemError(ENOSYS, "%s",
|
||||
_("Cannot get process uid and gid on this platform"));
|
||||
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)
|
||||
return -1;
|
||||
if (secdef == NULL) {
|
||||
VIR_DEBUG("missing label for DAC security "
|
||||
"driver in domain %s", def->name);
|
||||
|
||||
if (virSecurityDACGetProcessLabelInternal(pid, seclabel) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (secdef->label)
|
||||
ignore_value(virStrcpy(seclabel->label, secdef->label,
|
||||
|
Loading…
x
Reference in New Issue
Block a user