提交 d72e79ed 编写于 作者: M Michal Privoznik 提交者: Cole Robinson

security_selinux: Don't relabel /dev/net/tun

https://bugzilla.redhat.com/show_bug.cgi?id=1147057

The code for relabelling the TAP FD is there due to a race. When
libvirt creates a /dev/tapN device it's labeled as
'system_u:object_r:device_t:s0' by default. Later, when
udev/systemd reacts to this device, it's relabelled to the
expected label 'system_u:object_r:tun_tap_device_t:s0'. Hence, we
have a code that relabels the device, to cut the race down. For
more info see ae368ebf.

But the problem is, the relabel function is called on all TUN/TAP
devices. Yes, on /dev/net/tun too. This is however a special kind
of device - other processes uses it too. We shouldn't touch it's
label then.

Ideally, there would an API in SELinux that would label just the
passed FD and not the underlying path. That way, we wouldn't need
to care as we would be not labeling /dev/net/tun but the FD
passed to the domain. Unfortunately, there's no such API so we
have to workaround until then.
Tested-by: NRichard W.M. Jones <rjones@redhat.com>
Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
(cherry picked from commit ebc05263)
上级 7caed3d4
...@@ -2352,7 +2352,7 @@ virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr, ...@@ -2352,7 +2352,7 @@ virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr,
struct stat buf; struct stat buf;
security_context_t fcon = NULL; security_context_t fcon = NULL;
virSecurityLabelDefPtr secdef; virSecurityLabelDefPtr secdef;
char *str = NULL; char *str = NULL, *proc = NULL, *fd_path = NULL;
int rc = -1; int rc = -1;
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME); secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
...@@ -2370,7 +2370,24 @@ virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr, ...@@ -2370,7 +2370,24 @@ virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr,
goto cleanup; goto cleanup;
} }
if (getContext(mgr, "/dev/tap.*", buf.st_mode, &fcon) < 0) { /* Label /dev/tap.* devices only. Leave /dev/net/tun alone! */
if (virAsprintf(&proc, "/proc/self/fd/%d", fd) == -1)
goto cleanup;
if (virFileResolveLink(proc, &fd_path) < 0) {
virReportSystemError(errno,
_("Unable to resolve link: %s"), proc);
goto cleanup;
}
if (!STRPREFIX(fd_path, "/dev/tap")) {
VIR_DEBUG("fd=%d points to %s not setting SELinux label",
fd, fd_path);
rc = 0;
goto cleanup;
}
if (getContext(mgr, "/dev/tap*", buf.st_mode, &fcon) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot lookup default selinux label for tap fd %d"), fd); _("cannot lookup default selinux label for tap fd %d"), fd);
goto cleanup; goto cleanup;
...@@ -2384,6 +2401,8 @@ virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr, ...@@ -2384,6 +2401,8 @@ virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr,
cleanup: cleanup:
freecon(fcon); freecon(fcon);
VIR_FREE(fd_path);
VIR_FREE(proc);
VIR_FREE(str); VIR_FREE(str);
return rc; return rc;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册