mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-24 14:45:24 +00:00
Add a function to the security driver API that sets the label of an open fd.
A need was found to set the SELinux context label on an open fd (a pipe, as a matter of fact). This patch adds a function to the security driver API that will set the label on an open fd to secdef.label. For all drivers other than the SELinux driver, it's a NOP. For the SElinux driver, it calls fsetfilecon(). If the return is a failure, it only returns error up to the caller if 1) the desired label is different from the existing label, 2) the destination fd is of a type that supports setting the selinux context, and 3) selinux is in enforcing mode. Otherwise it will return success. This follows the pattern of the existing function SELinuxSetFilecon().
This commit is contained in:
parent
413c88e773
commit
d89608f994
@ -723,6 +723,7 @@ virSecurityManagerRestoreAllLabel;
|
||||
virSecurityManagerRestoreHostdevLabel;
|
||||
virSecurityManagerRestoreSavedStateLabel;
|
||||
virSecurityManagerSetAllLabel;
|
||||
virSecurityManagerSetFDLabel;
|
||||
virSecurityManagerSetImageLabel;
|
||||
virSecurityManagerSetHostdevLabel;
|
||||
virSecurityManagerSetProcessLabel;
|
||||
|
@ -798,6 +798,14 @@ AppArmorRestoreSavedStateLabel(virSecurityManagerPtr mgr,
|
||||
return reload_profile(mgr, vm, NULL, false);
|
||||
}
|
||||
|
||||
static int
|
||||
AppArmorSetFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||
int fd ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virSecurityDriver virAppArmorSecurityDriver = {
|
||||
0,
|
||||
SECURITY_APPARMOR_NAME,
|
||||
@ -831,4 +839,6 @@ virSecurityDriver virAppArmorSecurityDriver = {
|
||||
|
||||
AppArmorSetSavedStateLabel,
|
||||
AppArmorRestoreSavedStateLabel,
|
||||
|
||||
AppArmorSetFDLabel,
|
||||
};
|
||||
|
@ -675,6 +675,14 @@ virSecurityDACClearSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
virSecurityDACSetFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||
virDomainObjPtr vm ATTRIBUTE_UNUSED,
|
||||
int fd ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virSecurityDriver virSecurityDriverDAC = {
|
||||
sizeof(virSecurityDACData),
|
||||
@ -710,4 +718,6 @@ virSecurityDriver virSecurityDriverDAC = {
|
||||
|
||||
virSecurityDACSetSavedStateLabel,
|
||||
virSecurityDACRestoreSavedStateLabel,
|
||||
|
||||
virSecurityDACSetFDLabel,
|
||||
};
|
||||
|
@ -79,7 +79,9 @@ typedef int (*virSecurityDomainSetProcessLabel) (virSecurityManagerPtr mgr,
|
||||
virDomainObjPtr vm);
|
||||
typedef int (*virSecurityDomainSecurityVerify) (virSecurityManagerPtr mgr,
|
||||
virDomainDefPtr def);
|
||||
|
||||
typedef int (*virSecurityDomainSetFDLabel) (virSecurityManagerPtr mgr,
|
||||
virDomainObjPtr vm,
|
||||
int fd);
|
||||
|
||||
struct _virSecurityDriver {
|
||||
size_t privateDataLen;
|
||||
@ -114,6 +116,8 @@ struct _virSecurityDriver {
|
||||
|
||||
virSecurityDomainSetSavedStateLabel domainSetSavedStateLabel;
|
||||
virSecurityDomainRestoreSavedStateLabel domainRestoreSavedStateLabel;
|
||||
|
||||
virSecurityDomainSetFDLabel domainSetSecurityFDLabel;
|
||||
};
|
||||
|
||||
virSecurityDriverPtr virSecurityDriverLookup(const char *name);
|
||||
|
@ -323,3 +323,14 @@ int virSecurityManagerVerify(virSecurityManagerPtr mgr,
|
||||
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int virSecurityManagerSetFDLabel(virSecurityManagerPtr mgr,
|
||||
virDomainObjPtr vm,
|
||||
int fd)
|
||||
{
|
||||
if (mgr->drv->domainSetSecurityFDLabel)
|
||||
return mgr->drv->domainSetSecurityFDLabel(mgr, vm, fd);
|
||||
|
||||
virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
@ -91,5 +91,8 @@ int virSecurityManagerSetProcessLabel(virSecurityManagerPtr mgr,
|
||||
virDomainObjPtr vm);
|
||||
int virSecurityManagerVerify(virSecurityManagerPtr mgr,
|
||||
virDomainDefPtr def);
|
||||
int virSecurityManagerSetFDLabel(virSecurityManagerPtr mgr,
|
||||
virDomainObjPtr vm,
|
||||
int fd);
|
||||
|
||||
#endif /* VIR_SECURITY_MANAGER_H__ */
|
||||
|
@ -149,6 +149,13 @@ static int virSecurityDomainVerifyNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int virSecurityDomainSetFDLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||
virDomainObjPtr sec ATTRIBUTE_UNUSED,
|
||||
int fd ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virSecurityDriver virSecurityDriverNop = {
|
||||
0,
|
||||
"none",
|
||||
@ -182,4 +189,6 @@ virSecurityDriver virSecurityDriverNop = {
|
||||
|
||||
virSecurityDomainSetSavedStateLabelNop,
|
||||
virSecurityDomainRestoreSavedStateLabelNop,
|
||||
|
||||
virSecurityDomainSetFDLabelNop,
|
||||
};
|
||||
|
@ -371,6 +371,45 @@ SELinuxSetFilecon(const char *path, char *tcon)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SELinuxFSetFilecon(int fd, char *tcon)
|
||||
{
|
||||
security_context_t econ;
|
||||
|
||||
VIR_INFO("Setting SELinux context on fd %d to '%s'", fd, tcon);
|
||||
|
||||
if (fsetfilecon(fd, tcon) < 0) {
|
||||
int fsetfilecon_errno = errno;
|
||||
|
||||
if (fgetfilecon(fd, &econ) >= 0) {
|
||||
if (STREQ(tcon, econ)) {
|
||||
freecon(econ);
|
||||
/* It's alright, there's nothing to change anyway. */
|
||||
return 0;
|
||||
}
|
||||
freecon(econ);
|
||||
}
|
||||
|
||||
/* if the error complaint is related to an image hosted on
|
||||
* an nfs mount, or a usbfs/sysfs filesystem not supporting
|
||||
* labelling, then just ignore it & hope for the best.
|
||||
* The user hopefully set one of the necessary SELinux
|
||||
* virt_use_{nfs,usb,pci} boolean tunables to allow it...
|
||||
*/
|
||||
if (fsetfilecon_errno != EOPNOTSUPP) {
|
||||
virReportSystemError(fsetfilecon_errno,
|
||||
_("unable to set security context '%s' on fd %d"),
|
||||
tcon, fd);
|
||||
if (security_getenforce() == 1)
|
||||
return -1;
|
||||
} else {
|
||||
VIR_INFO("Setting security context '%s' on fd %d not supported",
|
||||
tcon, fd);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set fcon to the appropriate label for path and mode, or return -1. */
|
||||
static int
|
||||
getContext(const char *newpath, mode_t mode, security_context_t *fcon)
|
||||
@ -1087,6 +1126,19 @@ SELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SELinuxSetFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||
virDomainObjPtr vm,
|
||||
int fd)
|
||||
{
|
||||
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
|
||||
|
||||
if (secdef->imagelabel == NULL)
|
||||
return 0;
|
||||
|
||||
return SELinuxFSetFilecon(fd, secdef->imagelabel);
|
||||
}
|
||||
|
||||
virSecurityDriver virSecurityDriverSELinux = {
|
||||
0,
|
||||
SECURITY_SELINUX_NAME,
|
||||
@ -1120,4 +1172,6 @@ virSecurityDriver virSecurityDriverSELinux = {
|
||||
|
||||
SELinuxSetSavedStateLabel,
|
||||
SELinuxRestoreSavedStateLabel,
|
||||
|
||||
SELinuxSetFDLabel,
|
||||
};
|
||||
|
@ -364,6 +364,22 @@ virSecurityStackClearSocketLabel(virSecurityManagerPtr mgr,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
virSecurityStackSetFDLabel(virSecurityManagerPtr mgr,
|
||||
virDomainObjPtr vm,
|
||||
int fd)
|
||||
{
|
||||
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
|
||||
int rc = 0;
|
||||
|
||||
if (virSecurityManagerSetFDLabel(priv->secondary, vm, fd) < 0)
|
||||
rc = -1;
|
||||
if (virSecurityManagerSetFDLabel(priv->primary, vm, fd) < 0)
|
||||
rc = -1;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
virSecurityDriver virSecurityDriverStack = {
|
||||
sizeof(virSecurityStackData),
|
||||
@ -398,4 +414,6 @@ virSecurityDriver virSecurityDriverStack = {
|
||||
|
||||
virSecurityStackSetSavedStateLabel,
|
||||
virSecurityStackRestoreSavedStateLabel,
|
||||
|
||||
virSecurityStackSetFDLabel,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user