From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1544618491324368.8754091652663; Wed, 12 Dec 2018 04:41:31 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BF03830024D7; Wed, 12 Dec 2018 12:41:29 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7528E60C46; Wed, 12 Dec 2018 12:41:29 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 2E3D4181B9E9; Wed, 12 Dec 2018 12:41:29 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfBqs017122 for ; Wed, 12 Dec 2018 07:41:11 -0500 Received: by smtp.corp.redhat.com (Postfix) id 91F7E5D738; Wed, 12 Dec 2018 12:41:11 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1710F5D70A for ; Wed, 12 Dec 2018 12:41:10 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:40:45 +0100 Message-Id: <797bceea7c9814c33c121fee39227ac4a8c69a9c.1544618362.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 01/18] util: Introduce xattr getter/setter/remover X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Wed, 12 Dec 2018 12:41:30 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Signed-off-by: Michal Privoznik Reviewed-by: J=C3=A1n Tomko --- src/libvirt_private.syms | 3 + src/util/virfile.c | 121 +++++++++++++++++++++++++++++++++++++++ src/util/virfile.h | 11 ++++ 3 files changed, 135 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fd63c9ca61..9835e9a56c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1830,6 +1830,7 @@ virFileGetACLs; virFileGetHugepageSize; virFileGetMountReverseSubtree; virFileGetMountSubtree; +virFileGetXAttr; virFileHasSuffix; virFileInData; virFileIsAbsPath; @@ -1869,6 +1870,7 @@ virFileReadValueUint; virFileRelLinkPointsTo; virFileRemove; virFileRemoveLastComponent; +virFileRemoveXAttr; virFileResolveAllLinks; virFileResolveLink; virFileRewrite; @@ -1876,6 +1878,7 @@ virFileRewriteStr; virFileSanitizePath; virFileSetACLs; virFileSetupDev; +virFileSetXAttr; virFileSkipRoot; virFileStripSuffix; virFileTouch; diff --git a/src/util/virfile.c b/src/util/virfile.c index f6f9e4ceda..263c92667c 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -64,6 +64,10 @@ # include #endif =20 +#if HAVE_LIBATTR +# include +#endif + #include "configmake.h" #include "intprops.h" #include "vircommand.h" @@ -4354,3 +4358,120 @@ virFileWaitForExists(const char *path, =20 return 0; } + + +#if HAVE_LIBATTR +/** + * virFileGetXAttr; + * @path: a filename + * @name: name of xattr + * @value: read value + * + * Reads xattr with @name for given @path and stores it into + * @value. Caller is responsible for freeing @value. + * + * Returns: 0 on success, + * -1 otherwise (with errno set). + */ +int +virFileGetXAttr(const char *path, + const char *name, + char **value) +{ + char *buf =3D NULL; + int ret =3D -1; + + /* We might be racing with somebody who sets the same attribute. */ + while (1) { + ssize_t need; + ssize_t got; + + /* The first call determines how many bytes we need to allocate. */ + if ((need =3D getxattr(path, name, NULL, 0)) < 0) + goto cleanup; + + if (VIR_REALLOC_N_QUIET(buf, need + 1) < 0) + goto cleanup; + + if ((got =3D getxattr(path, name, buf, need)) < 0) { + if (errno =3D=3D ERANGE) + continue; + goto cleanup; + } + + buf[got] =3D '\0'; + break; + } + + VIR_STEAL_PTR(*value, buf); + ret =3D 0; + cleanup: + VIR_FREE(buf); + return ret; +} + +/** + * virFileSetXAttr: + * @path: a filename + * @name: name of xattr + * @value: value to set + * + * Sets xattr of @name and @value on @path. + * + * Returns: 0 on success, + * -1 otherwise (with errno set). + */ +int +virFileSetXAttr(const char *path, + const char *name, + const char *value) +{ + return setxattr(path, name, value, strlen(value), 0); +} + +/** + * virFileRemoveXAttr: + * @path: a filename + * @name: name of xattr + * + * Remove xattr of @name on @path. + * + * Returns: 0 on success, + * -1 otherwise (with errno set). + */ +int +virFileRemoveXAttr(const char *path, + const char *name) +{ + return removexattr(path, name); +} + +#else /* !HAVE_LIBATTR */ + +int +virFileGetXAttr(const char *path ATTRIBUTE_UNUSED, + const char *name ATTRIBUTE_UNUSED, + char **value ATTRIBUTE_UNUSED) +{ + errno =3D ENOSYS; + return -1; +} + +int +virFileSetXAttr(const char *path ATTRIBUTE_UNUSED, + const char *name ATTRIBUTE_UNUSED, + const char *value ATTRIBUTE_UNUSED) +{ + errno =3D ENOSYS; + return -1; +} + +int +virFileRemoveXAttr(const char *path ATTRIBUTE_UNUSED, + const char *name ATTRIBUTE_UNUSED) +{ + errno =3D ENOSYS; + return -1; +} + +#endif /* HAVE_LIBATTR */ diff --git a/src/util/virfile.h b/src/util/virfile.h index 0f7dece958..aa4c29dc40 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -383,4 +383,15 @@ int virFileInData(int fd, =20 VIR_DEFINE_AUTOPTR_FUNC(virFileWrapperFd, virFileWrapperFdFree) =20 +int virFileGetXAttr(const char *path, + const char *name, + char **value); + +int virFileSetXAttr(const char *path, + const char *name, + const char *value); + +int virFileRemoveXAttr(const char *path, + const char *name); + #endif /* __VIR_FILE_H */ --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1544618476663397.0801781030964; Wed, 12 Dec 2018 04:41:16 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BC2BB30014AA; Wed, 12 Dec 2018 12:41:14 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 559EC60C61; Wed, 12 Dec 2018 12:41:14 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 6FD11246E3; Wed, 12 Dec 2018 12:41:13 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfCY5017130 for ; Wed, 12 Dec 2018 07:41:12 -0500 Received: by smtp.corp.redhat.com (Postfix) id 63EA95D73F; Wed, 12 Dec 2018 12:41:12 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id DF47D5D70A for ; Wed, 12 Dec 2018 12:41:11 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:40:46 +0100 Message-Id: <4cd10bcaea41775bdfae63492c66bdf97bbaedc3.1544618362.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 02/18] security: Include security_util X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Wed, 12 Dec 2018 12:41:15 +0000 (UTC) Content-Type: text/plain; charset="utf-8" This file implements wrappers over XATTR getter/setter. It ensures the proper XATTR namespace is used. Signed-off-by: Michal Privoznik Reviewed-by: J=C3=A1n Tomko --- src/security/Makefile.inc.am | 2 + src/security/security_util.c | 256 +++++++++++++++++++++++++++++++++++ src/security/security_util.h | 32 +++++ 3 files changed, 290 insertions(+) create mode 100644 src/security/security_util.c create mode 100644 src/security/security_util.h diff --git a/src/security/Makefile.inc.am b/src/security/Makefile.inc.am index f88b82df7b..0ade97d355 100644 --- a/src/security/Makefile.inc.am +++ b/src/security/Makefile.inc.am @@ -14,6 +14,8 @@ SECURITY_DRIVER_SOURCES =3D \ security/security_dac.c \ security/security_manager.h \ security/security_manager.c \ + security/security_util.h \ + security/security_util.c \ $(NULL) =20 SECURITY_DRIVER_SELINUX_SOURCES =3D \ diff --git a/src/security/security_util.c b/src/security/security_util.c new file mode 100644 index 0000000000..194343c407 --- /dev/null +++ b/src/security/security_util.c @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include "viralloc.h" +#include "virfile.h" +#include "virstring.h" +#include "virerror.h" + +#include "security_util.h" + +#define VIR_FROM_THIS VIR_FROM_SECURITY + +/* There are four namespaces available on Linux (xattr(7)): + * + * user - can be modified by anybody, + * system - used by ACLs + * security - used by SELinux + * trusted - accessibly by CAP_SYS_ADMIN processes only + * + * Looks like the last one is way to go. + * Unfortunately, FreeBSD only supports: + * + * user - can be modified by anybody, + * system - accessible by CAP_SYS_ADMIN processes only + * + * Note that 'system' on FreeBSD corresponds to 'trusted' on + * Linux. So far the only point where FreeBSD and Linux can meet + * is NFS which still doesn't support XATTRs. Therefore we can + * use different namespace on each system. If NFS gains support + * for XATTRs then we have to find a way to deal with the + * different namespaces. But that is a problem for future me. + */ +#if defined(__linux__) +# define XATTR_NAMESPACE "trusted" +#elif defined(__FreeBSD__) +# define XATTR_NAMESPACE "system" +#endif + +static char * +virSecurityGetAttrName(const char *name ATTRIBUTE_UNUSED) +{ + char *ret =3D NULL; +#ifdef XATTR_NAMESPACE + ignore_value(virAsprintf(&ret, XATTR_NAMESPACE".libvirt.security.%s", = name)); +#else + errno =3D ENOSYS; + virReportSystemError(errno, "%s", + _("Extended attributes are not supported on this = system")); +#endif + return ret; +} + + +static char * +virSecurityGetRefCountAttrName(const char *name ATTRIBUTE_UNUSED) +{ + char *ret =3D NULL; +#ifdef XATTR_NAMESPACE + ignore_value(virAsprintf(&ret, XATTR_NAMESPACE".libvirt.security.ref_%= s", name)); +#else + errno =3D ENOSYS; + virReportSystemError(errno, "%s", + _("Extended attributes are not supported on this = system")); +#endif + return ret; +} + + +/** + * virSecurityGetRememberedLabel: + * @name: security driver name + * @path: file name + * @label: label + * + * For given @path and security driver (@name) fetch remembered + * @label. The caller must not restore label if an error is + * indicated or if @label is NULL upon return. + * + * The idea is that the first time + * virSecuritySetRememberedLabel() is called over @path the + * @label is recorded and refcounter is set to 1. Each subsequent + * call to virSecuritySetRememberedLabel() increases the counter. + * Counterpart to this is virSecurityGetRememberedLabel() which + * decreases the counter and reads the @label only if the counter + * reached value of zero. For any other call (i.e. when the + * counter is not zero), virSecurityGetRememberedLabel() set + * @label to NULL (to notify the caller that the refcount is not + * zero) and returns zero. + * + * Returns: 0 on success, + * -1 otherwise (with error reported) + */ +int +virSecurityGetRememberedLabel(const char *name, + const char *path, + char **label) +{ + char *ref_name =3D NULL; + char *attr_name =3D NULL; + char *value =3D NULL; + unsigned int refcount =3D 0; + int ret =3D -1; + + *label =3D NULL; + + if (!(ref_name =3D virSecurityGetRefCountAttrName(name))) + goto cleanup; + + if (virFileGetXAttr(path, ref_name, &value) < 0) { + if (errno =3D=3D ENOSYS || errno =3D=3D ENODATA || errno =3D=3D EN= OTSUP) { + ret =3D 0; + } else { + virReportSystemError(errno, + _("Unable to get XATTR %s on %s"), + ref_name, + path); + } + goto cleanup; + } + + if (virStrToLong_ui(value, NULL, 10, &refcount) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("malformed refcount %s on %s"), + value, path); + goto cleanup; + } + + VIR_FREE(value); + + refcount--; + + if (refcount > 0) { + if (virAsprintf(&value, "%u", refcount) < 0) + goto cleanup; + + if (virFileSetXAttr(path, ref_name, value) < 0) + goto cleanup; + } else { + if (virFileRemoveXAttr(path, ref_name) < 0) + goto cleanup; + + if (!(attr_name =3D virSecurityGetAttrName(name))) + goto cleanup; + + if (virFileGetXAttr(path, attr_name, label) < 0) + goto cleanup; + + if (virFileRemoveXAttr(path, attr_name) < 0) + goto cleanup; + } + + ret =3D 0; + cleanup: + VIR_FREE(value); + VIR_FREE(attr_name); + VIR_FREE(ref_name); + return ret; +} + + +/** + * virSecuritySetRememberedLabel: + * @name: security driver name + * @path: file name + * @label: label + * + * For given @path and security driver (@name), if called the + * first time over @path, set the @label to remember (i.e. the + * original owner of the @path). Any subsequent call over @path + * will increment refcounter. It is strongly recommended that the + * caller checks for the return value and if it is greater than 1 + * (meaning that some domain is already using @path) the current + * label is required instead of setting a new one. + * + * See also virSecurityGetRememberedLabel. + * + * Returns: the new refcount value on success, + * -1 otherwise (with error reported) + */ +int +virSecuritySetRememberedLabel(const char *name, + const char *path, + const char *label) +{ + char *ref_name =3D NULL; + char *attr_name =3D NULL; + char *value =3D NULL; + unsigned int refcount =3D 0; + int ret =3D -1; + + if (!(ref_name =3D virSecurityGetRefCountAttrName(name))) + goto cleanup; + + if (virFileGetXAttr(path, ref_name, &value) < 0) { + if (errno =3D=3D ENOSYS || errno =3D=3D ENOTSUP) { + ret =3D 0; + goto cleanup; + } else if (errno !=3D ENODATA) { + virReportSystemError(errno, + _("Unable to get XATTR %s on %s"), + ref_name, + path); + goto cleanup; + } + } + + if (value && + virStrToLong_ui(value, NULL, 10, &refcount) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("malformed refcount %s on %s"), + value, path); + goto cleanup; + } + + VIR_FREE(value); + + refcount++; + + if (refcount =3D=3D 1) { + if (!(attr_name =3D virSecurityGetAttrName(name))) + goto cleanup; + + if (virFileSetXAttr(path, attr_name, label) < 0) + goto cleanup; + } + + if (virAsprintf(&value, "%u", refcount) < 0) + goto cleanup; + + if (virFileSetXAttr(path, ref_name, value) < 0) + goto cleanup; + + ret =3D refcount; + cleanup: + VIR_FREE(value); + VIR_FREE(attr_name); + VIR_FREE(ref_name); + return ret; +} diff --git a/src/security/security_util.h b/src/security/security_util.h new file mode 100644 index 0000000000..a6e67f4390 --- /dev/null +++ b/src/security/security_util.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#ifndef __SECURITY_UTIL_H__ +# define __SECURITY_UTIL_H__ + +int +virSecurityGetRememberedLabel(const char *name, + const char *path, + char **label); + +int +virSecuritySetRememberedLabel(const char *name, + const char *path, + const char *label); + +#endif /* __SECURITY_UTIL_H__ */ --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1544618477818207.7689163305547; Wed, 12 Dec 2018 04:41:17 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DA61C394D40; Wed, 12 Dec 2018 12:41:15 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5A07860C66; Wed, 12 Dec 2018 12:41:15 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id EF075246F1; Wed, 12 Dec 2018 12:41:14 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfDxx017137 for ; Wed, 12 Dec 2018 07:41:13 -0500 Received: by smtp.corp.redhat.com (Postfix) id 36AD55D70A; Wed, 12 Dec 2018 12:41:13 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id B1B845D757 for ; Wed, 12 Dec 2018 12:41:12 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:40:47 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 03/18] security_dac: Restore label on failed chown() attempt X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 12 Dec 2018 12:41:16 +0000 (UTC) It's important to keep XATTRs untouched (well, in the same state they were in when entering the function). Otherwise our refcounting would be messed up. Signed-off-by: Michal Privoznik Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: J=C3=A1n Tomko --- src/security/security_dac.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 4bdc6ed213..f01d0b4732 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -718,7 +718,25 @@ virSecurityDACSetOwnership(virSecurityManagerPtr mgr, VIR_INFO("Setting DAC user and group on '%s' to '%ld:%ld'", NULLSTR(src ? src->path : path), (long)uid, (long)gid); =20 - return virSecurityDACSetOwnershipInternal(priv, src, path, uid, gid); + if (virSecurityDACSetOwnershipInternal(priv, src, path, uid, gid) < 0)= { + virErrorPtr origerr; + + virErrorPreserveLast(&origerr); + /* Try to restore the label. This is done so that XATTRs + * are left in the same state as when the control entered + * this function. However, if our attempt fails, there's + * not much we can do. XATTRs refcounting is fubar'ed and + * the only option we have is warn users. */ + if (virSecurityDACRestoreFileLabelInternal(mgr, src, path) < 0) + VIR_WARN("Unable to restore label on '%s'. " + "XATTRs might have been left in inconsistent state.", + NULLSTR(src ? src->path : path)); + + virErrorRestore(&origerr); + return -1; + } + + return 0; } =20 =20 --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1544618491453951.262991185187; Wed, 12 Dec 2018 04:41:31 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DD86CB947; Wed, 12 Dec 2018 12:41:29 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8AEA860C61; Wed, 12 Dec 2018 12:41:29 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 3620D246E3; Wed, 12 Dec 2018 12:41:29 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfEZb017150 for ; Wed, 12 Dec 2018 07:41:14 -0500 Received: by smtp.corp.redhat.com (Postfix) id 0B9B95D70A; Wed, 12 Dec 2018 12:41:14 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id 84C4D5D738 for ; Wed, 12 Dec 2018 12:41:13 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:40:48 +0100 Message-Id: <6eaf79255703a697cd5c663769d2939fe33985df.1544618362.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 04/18] virSecurityDACTransactionRun: Implement rollback X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Wed, 12 Dec 2018 12:41:30 +0000 (UTC) When iterating over list of paths/disk sources to relabel it may happen that the process fails at some point. In that case, for the sake of keeping seclabel refcount (stored in XATTRs) in sync with reality we have to perform rollback. However, if that fails too the only thing we can do is warn user. Signed-off-by: Michal Privoznik Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: J=C3=A1n Tomko --- src/security/security_dac.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/security/security_dac.c b/src/security/security_dac.c index f01d0b4732..7be555903d 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -229,7 +229,6 @@ virSecurityDACTransactionRun(pid_t pid ATTRIBUTE_UNUSED, for (i =3D 0; i < list->nItems; i++) { virSecurityDACChownItemPtr item =3D list->items[i]; =20 - /* TODO Implement rollback */ if (!item->restore) { rv =3D virSecurityDACSetOwnership(list->manager, item->src, @@ -246,6 +245,19 @@ virSecurityDACTransactionRun(pid_t pid ATTRIBUTE_UNUSE= D, break; } =20 + for (; rv < 0 && i > 0; i--) { + virSecurityDACChownItemPtr item =3D list->items[i - 1]; + + if (!item->restore) { + virSecurityDACRestoreFileLabelInternal(list->manager, + item->src, + item->path); + } else { + VIR_WARN("Ignoring failed restore attempt on %s", + NULLSTR(item->src ? item->src->path : item->path)); + } + } + if (list->lock) virSecurityManagerMetadataUnlock(list->manager, &state); =20 --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1544618491923738.651944102107; Wed, 12 Dec 2018 04:41:31 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B2C703097066; Wed, 12 Dec 2018 12:41:29 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 757681974F; Wed, 12 Dec 2018 12:41:29 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 2F9EA181B9EA; Wed, 12 Dec 2018 12:41:29 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfEnF017157 for ; Wed, 12 Dec 2018 07:41:14 -0500 Received: by smtp.corp.redhat.com (Postfix) id D21565D738; Wed, 12 Dec 2018 12:41:14 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id 58F695D70A for ; Wed, 12 Dec 2018 12:41:14 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:40:49 +0100 Message-Id: <0cf73925cb14bbb0d342556b3fd5f6bfbfe0489a.1544618362.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 05/18] virSecurityDACRestoreAllLabel: Reorder device relabeling X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Wed, 12 Dec 2018 12:41:30 +0000 (UTC) It helps whe trying to match calls with virSecurityDACSetAllLabel if the order in which devices are set/restored is the same in both functions. Signed-off-by: Michal Privoznik Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: J=C3=A1n Tomko --- src/security/security_dac.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 7be555903d..4935c962b9 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1664,24 +1664,6 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr = mgr, VIR_DEBUG("Restoring security label on %s migrated=3D%d", def->name, migrated); =20 - for (i =3D 0; i < def->nhostdevs; i++) { - if (virSecurityDACRestoreHostdevLabel(mgr, - def, - def->hostdevs[i], - NULL) < 0) - rc =3D -1; - } - - for (i =3D 0; i < def->ngraphics; i++) { - if (virSecurityDACRestoreGraphicsLabel(mgr, def, def->graphics[i])= < 0) - return -1; - } - - for (i =3D 0; i < def->ninputs; i++) { - if (virSecurityDACRestoreInputLabel(mgr, def, def->inputs[i]) < 0) - rc =3D -1; - } - for (i =3D 0; i < def->ndisks; i++) { if (virSecurityDACRestoreImageLabelInt(mgr, def, @@ -1690,6 +1672,24 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr = mgr, rc =3D -1; } =20 + for (i =3D 0; i < def->ngraphics; i++) { + if (virSecurityDACRestoreGraphicsLabel(mgr, def, def->graphics[i])= < 0) + return -1; + } + + for (i =3D 0; i < def->ninputs; i++) { + if (virSecurityDACRestoreInputLabel(mgr, def, def->inputs[i]) < 0) + rc =3D -1; + } + + for (i =3D 0; i < def->nhostdevs; i++) { + if (virSecurityDACRestoreHostdevLabel(mgr, + def, + def->hostdevs[i], + NULL) < 0) + rc =3D -1; + } + for (i =3D 0; i < def->nmems; i++) { if (virSecurityDACRestoreMemoryLabel(mgr, def, --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1544618495529826.573181950288; Wed, 12 Dec 2018 04:41:35 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B3674307D856; Wed, 12 Dec 2018 12:41:33 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7A9C91057076; Wed, 12 Dec 2018 12:41:33 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 1F922245FB; Wed, 12 Dec 2018 12:41:33 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfF0I017168 for ; Wed, 12 Dec 2018 07:41:15 -0500 Received: by smtp.corp.redhat.com (Postfix) id A4DCB5D738; Wed, 12 Dec 2018 12:41:15 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2AE135D70A for ; Wed, 12 Dec 2018 12:41:15 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:40:50 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 06/18] virSecurityDACRestoreAllLabel: Restore more labels X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.48]); Wed, 12 Dec 2018 12:41:34 +0000 (UTC) We are setting label on kernel, initrd, dtb and slic_table files. But we never restored it. Signed-off-by: Michal Privoznik Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: J=C3=A1n Tomko --- src/security/security_dac.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 4935c962b9..dcd0bb558a 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1719,6 +1719,22 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr = mgr, virSecurityDACRestoreFileLabel(mgr, def->os.loader->nvram) < 0) rc =3D -1; =20 + if (def->os.kernel && + virSecurityDACRestoreFileLabel(mgr, def->os.kernel) < 0) + rc =3D -1; + + if (def->os.initrd && + virSecurityDACRestoreFileLabel(mgr, def->os.initrd) < 0) + rc =3D -1; + + if (def->os.dtb && + virSecurityDACRestoreFileLabel(mgr, def->os.dtb) < 0) + rc =3D -1; + + if (def->os.slic_table && + virSecurityDACRestoreFileLabel(mgr, def->os.slic_table) < 0) + rc =3D -1; + return rc; } =20 --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1544618499158477.48272756308165; Wed, 12 Dec 2018 04:41:39 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8D8A2C02938F; Wed, 12 Dec 2018 12:41:37 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 57E4E5D762; Wed, 12 Dec 2018 12:41:37 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 0B1C3247F8; Wed, 12 Dec 2018 12:41:37 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfGV9017178 for ; Wed, 12 Dec 2018 07:41:16 -0500 Received: by smtp.corp.redhat.com (Postfix) id 792DE5D738; Wed, 12 Dec 2018 12:41:16 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id F1F305D70A for ; Wed, 12 Dec 2018 12:41:15 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:40:51 +0100 Message-Id: <4804743dd503241e76f5b67c2d2ce027f643ac9c.1544618362.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 07/18] security_dac: Allow callers to enable/disable label remembering/recall X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Wed, 12 Dec 2018 12:41:38 +0000 (UTC) Because the implementation that will be used for label remembering/recall is not atomic we have to give callers a chance to enable or disable it. That is, enable it if and only if metadata locking is enabled. Otherwise the feature MUST be turned off. Signed-off-by: Michal Privoznik Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: J=C3=A1n Tomko --- src/security/security_dac.c | 74 ++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 29 deletions(-) diff --git a/src/security/security_dac.c b/src/security/security_dac.c index dcd0bb558a..e5899c1746 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -182,11 +182,13 @@ static int virSecurityDACSetOwnership(virSecurityMana= gerPtr mgr, const virStorageSource *src, const char *path, uid_t uid, - gid_t gid); + gid_t gid, + bool remember); =20 static int virSecurityDACRestoreFileLabelInternal(virSecurityManagerPtr mg= r, const virStorageSource *= src, - const char *path); + const char *path, + bool recall); /** * virSecurityDACTransactionRun: * @pid: process pid @@ -234,11 +236,13 @@ virSecurityDACTransactionRun(pid_t pid ATTRIBUTE_UNUS= ED, item->src, item->path, item->uid, - item->gid); + item->gid, + list->lock); } else { rv =3D virSecurityDACRestoreFileLabelInternal(list->manager, item->src, - item->path); + item->path, + list->lock); } =20 if (rv < 0) @@ -251,7 +255,8 @@ virSecurityDACTransactionRun(pid_t pid ATTRIBUTE_UNUSED, if (!item->restore) { virSecurityDACRestoreFileLabelInternal(list->manager, item->src, - item->path); + item->path, + list->lock); } else { VIR_WARN("Ignoring failed restore attempt on %s", NULLSTR(item->src ? item->src->path : item->path)); @@ -699,7 +704,8 @@ virSecurityDACSetOwnership(virSecurityManagerPtr mgr, const virStorageSource *src, const char *path, uid_t uid, - gid_t gid) + gid_t gid, + bool remember) { virSecurityDACDataPtr priv =3D virSecurityManagerGetPrivateData(mgr); struct stat sb; @@ -717,7 +723,7 @@ virSecurityDACSetOwnership(virSecurityManagerPtr mgr, else if (rc > 0) return 0; =20 - if (path) { + if (remember && path) { if (stat(path, &sb) < 0) { virReportSystemError(errno, _("unable to stat: %s"), path); return -1; @@ -739,7 +745,7 @@ virSecurityDACSetOwnership(virSecurityManagerPtr mgr, * this function. However, if our attempt fails, there's * not much we can do. XATTRs refcounting is fubar'ed and * the only option we have is warn users. */ - if (virSecurityDACRestoreFileLabelInternal(mgr, src, path) < 0) + if (virSecurityDACRestoreFileLabelInternal(mgr, src, path, remembe= r) < 0) VIR_WARN("Unable to restore label on '%s'. " "XATTRs might have been left in inconsistent state.", NULLSTR(src ? src->path : path)); @@ -755,7 +761,8 @@ virSecurityDACSetOwnership(virSecurityManagerPtr mgr, static int virSecurityDACRestoreFileLabelInternal(virSecurityManagerPtr mgr, const virStorageSource *src, - const char *path) + const char *path, + bool recall) { virSecurityDACDataPtr priv =3D virSecurityManagerGetPrivateData(mgr); int rv; @@ -774,7 +781,7 @@ virSecurityDACRestoreFileLabelInternal(virSecurityManag= erPtr mgr, else if (rv > 0) return 0; =20 - if (path) { + if (recall && path) { rv =3D virSecurityDACRecallLabel(priv, path, &uid, &gid); if (rv < 0) return -1; @@ -793,7 +800,7 @@ static int virSecurityDACRestoreFileLabel(virSecurityManagerPtr mgr, const char *path) { - return virSecurityDACRestoreFileLabelInternal(mgr, NULL, path); + return virSecurityDACRestoreFileLabelInternal(mgr, NULL, path, false); } =20 =20 @@ -840,7 +847,7 @@ virSecurityDACSetImageLabelInternal(virSecurityManagerP= tr mgr, return -1; } =20 - return virSecurityDACSetOwnership(mgr, src, NULL, user, group); + return virSecurityDACSetOwnership(mgr, src, NULL, user, group, false); } =20 =20 @@ -920,7 +927,7 @@ virSecurityDACRestoreImageLabelInt(virSecurityManagerPt= r mgr, } } =20 - return virSecurityDACRestoreFileLabelInternal(mgr, src, NULL); + return virSecurityDACRestoreFileLabelInternal(mgr, src, NULL, false); } =20 =20 @@ -956,7 +963,7 @@ virSecurityDACSetHostdevLabelHelper(const char *file, if (virSecurityDACGetIds(secdef, priv, &user, &group, NULL, NULL) < 0) return -1; =20 - return virSecurityDACSetOwnership(mgr, NULL, file, user, group); + return virSecurityDACSetOwnership(mgr, NULL, file, user, group, false); } =20 =20 @@ -1332,7 +1339,7 @@ virSecurityDACSetChardevLabel(virSecurityManagerPtr m= gr, case VIR_DOMAIN_CHR_TYPE_FILE: ret =3D virSecurityDACSetOwnership(mgr, NULL, dev_source->data.file.path, - user, group); + user, group, false); break; =20 case VIR_DOMAIN_CHR_TYPE_PIPE: @@ -1340,12 +1347,12 @@ virSecurityDACSetChardevLabel(virSecurityManagerPtr= mgr, virAsprintf(&out, "%s.out", dev_source->data.file.path) < 0) goto done; if (virFileExists(in) && virFileExists(out)) { - if (virSecurityDACSetOwnership(mgr, NULL, in, user, group) < 0= || - virSecurityDACSetOwnership(mgr, NULL, out, user, group) < = 0) + if (virSecurityDACSetOwnership(mgr, NULL, in, user, group, fal= se) < 0 || + virSecurityDACSetOwnership(mgr, NULL, out, user, group, fa= lse) < 0) goto done; } else if (virSecurityDACSetOwnership(mgr, NULL, dev_source->data.file.path, - user, group) < 0) { + user, group, false) < 0) { goto done; } ret =3D 0; @@ -1360,7 +1367,7 @@ virSecurityDACSetChardevLabel(virSecurityManagerPtr m= gr, * and passed via FD */ if (virSecurityDACSetOwnership(mgr, NULL, dev_source->data.nix.path, - user, group) < 0) + user, group, false) < 0) goto done; } ret =3D 0; @@ -1543,7 +1550,7 @@ virSecurityDACSetGraphicsLabel(virSecurityManagerPtr = mgr, if (virSecurityDACGetIds(seclabel, priv, &user, &group, NULL, NULL) < = 0) return -1; =20 - if (virSecurityDACSetOwnership(mgr, NULL, rendernode, user, group) < 0) + if (virSecurityDACSetOwnership(mgr, NULL, rendernode, user, group, fal= se) < 0) return -1; =20 return 0; @@ -1584,7 +1591,9 @@ virSecurityDACSetInputLabel(virSecurityManagerPtr mgr, if (virSecurityDACGetIds(seclabel, priv, &user, &group, NULL, NULL= ) < 0) return -1; =20 - ret =3D virSecurityDACSetOwnership(mgr, NULL, input->source.evdev,= user, group); + ret =3D virSecurityDACSetOwnership(mgr, NULL, + input->source.evdev, + user, group, false); break; =20 case VIR_DOMAIN_INPUT_TYPE_MOUSE: @@ -1772,7 +1781,9 @@ virSecurityDACSetMemoryLabel(virSecurityManagerPtr mg= r, if (virSecurityDACGetIds(seclabel, priv, &user, &group, NULL, NULL= ) < 0) return -1; =20 - ret =3D virSecurityDACSetOwnership(mgr, NULL, mem->nvdimmPath, use= r, group); + ret =3D virSecurityDACSetOwnership(mgr, NULL, + mem->nvdimmPath, + user, group, false); break; =20 case VIR_DOMAIN_MEMORY_MODEL_DIMM: @@ -1861,27 +1872,32 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr, =20 if (def->os.loader && def->os.loader->nvram && virSecurityDACSetOwnership(mgr, NULL, - def->os.loader->nvram, user, group) < 0) + def->os.loader->nvram, + user, group, false) < 0) return -1; =20 if (def->os.kernel && virSecurityDACSetOwnership(mgr, NULL, - def->os.kernel, user, group) < 0) + def->os.kernel, + user, group, false) < 0) return -1; =20 if (def->os.initrd && virSecurityDACSetOwnership(mgr, NULL, - def->os.initrd, user, group) < 0) + def->os.initrd, + user, group, false) < 0) return -1; =20 if (def->os.dtb && virSecurityDACSetOwnership(mgr, NULL, - def->os.dtb, user, group) < 0) + def->os.dtb, + user, group, false) < 0) return -1; =20 if (def->os.slic_table && virSecurityDACSetOwnership(mgr, NULL, - def->os.slic_table, user, group) < 0) + def->os.slic_table, + user, group, false) < 0) return -1; =20 return 0; @@ -1903,7 +1919,7 @@ virSecurityDACSetSavedStateLabel(virSecurityManagerPt= r mgr, if (virSecurityDACGetImageIds(secdef, priv, &user, &group) < 0) return -1; =20 - return virSecurityDACSetOwnership(mgr, NULL, savefile, user, group); + return virSecurityDACSetOwnership(mgr, NULL, savefile, user, group, fa= lse); } =20 =20 @@ -2223,7 +2239,7 @@ virSecurityDACDomainSetPathLabel(virSecurityManagerPt= r mgr, if (virSecurityDACGetIds(seclabel, priv, &user, &group, NULL, NULL) < = 0) return -1; =20 - return virSecurityDACSetOwnership(mgr, NULL, path, user, group); + return virSecurityDACSetOwnership(mgr, NULL, path, user, group, false); } =20 virSecurityDriver virSecurityDriverDAC =3D { --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1544618500643961.8823793537304; Wed, 12 Dec 2018 04:41:40 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 95878C05D412; Wed, 12 Dec 2018 12:41:38 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5FB361054FDD; Wed, 12 Dec 2018 12:41:38 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 11CB5247FA; Wed, 12 Dec 2018 12:41:38 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfHYj017183 for ; Wed, 12 Dec 2018 07:41:17 -0500 Received: by smtp.corp.redhat.com (Postfix) id 4CD4B5D738; Wed, 12 Dec 2018 12:41:17 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id C676D5D70A for ; Wed, 12 Dec 2018 12:41:16 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:40:52 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 08/18] security_dac: Remember old labels X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Wed, 12 Dec 2018 12:41:40 +0000 (UTC) Content-Type: text/plain; charset="utf-8" This also requires the same DAC label to be used for shared paths. If a path is already in use by a domain (or domains) then and the domain we are starting now wants to access the path it has to have the same DAC label. This might look too restrictive as the new label can still guarantee access to already running domains but in reality it is very unlikely and usually an admin mistake. This requirement also simplifies seclabel remembering, because we can store only one seclabel and have a refcounter for how many times the path is in use. If we were to allow different labels and store them in some sort of array the algorithm to match labels to domains would be needlessly complicated. Signed-off-by: Michal Privoznik Reviewed-by: J=C3=A1n Tomko --- src/security/security_dac.c | 63 +++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 10 deletions(-) diff --git a/src/security/security_dac.c b/src/security/security_dac.c index e5899c1746..3264a2967c 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -29,6 +29,7 @@ #endif =20 #include "security_dac.h" +#include "security_util.h" #include "virerror.h" #include "virfile.h" #include "viralloc.h" @@ -411,15 +412,26 @@ virSecurityDACGetImageIds(virSecurityLabelDefPtr secl= abel, * * Remember the owner of @path (represented by @uid:@gid). * - * Returns: 0 on success, -1 on failure + * Returns: the @path refcount, or + * -1 on failure */ static int virSecurityDACRememberLabel(virSecurityDACDataPtr priv ATTRIBUTE_UNUSED, - const char *path ATTRIBUTE_UNUSED, - uid_t uid ATTRIBUTE_UNUSED, - gid_t gid ATTRIBUTE_UNUSED) + const char *path, + uid_t uid, + gid_t gid) { - return 0; + char *label =3D NULL; + int ret =3D -1; + + if (virAsprintf(&label, "+%u:+%u", + (unsigned int)uid, + (unsigned int)gid) < 0) + return -1; + + ret =3D virSecuritySetRememberedLabel(SECURITY_DAC_NAME, path, label); + VIR_FREE(label); + return ret; } =20 /** @@ -439,11 +451,27 @@ virSecurityDACRememberLabel(virSecurityDACDataPtr pri= v ATTRIBUTE_UNUSED, */ static int virSecurityDACRecallLabel(virSecurityDACDataPtr priv ATTRIBUTE_UNUSED, - const char *path ATTRIBUTE_UNUSED, - uid_t *uid ATTRIBUTE_UNUSED, - gid_t *gid ATTRIBUTE_UNUSED) + const char *path, + uid_t *uid, + gid_t *gid) { - return 0; + char *label; + int ret =3D -1; + + if (virSecurityGetRememberedLabel(SECURITY_DAC_NAME, + path, &label) < 0) + goto cleanup; + + if (!label) + return 1; + + if (virParseOwnershipIds(label, uid, gid) < 0) + goto cleanup; + + ret =3D 0; + cleanup: + VIR_FREE(label); + return ret; } =20 static virSecurityDriverStatus @@ -709,6 +737,7 @@ virSecurityDACSetOwnership(virSecurityManagerPtr mgr, { virSecurityDACDataPtr priv =3D virSecurityManagerGetPrivateData(mgr); struct stat sb; + int refcount; int rc; =20 if (!path && src && src->path && @@ -729,8 +758,22 @@ virSecurityDACSetOwnership(virSecurityManagerPtr mgr, return -1; } =20 - if (virSecurityDACRememberLabel(priv, path, sb.st_uid, sb.st_gid) = < 0) + refcount =3D virSecurityDACRememberLabel(priv, path, sb.st_uid, sb= .st_gid); + if (refcount < 0) { return -1; + } else if (refcount > 1) { + /* Refcount is greater than 1 which means that there + * is @refcount domains using the @path. Do not + * change the label (as it would almost certainly + * cause the other domains to lose access to the + * @path). */ + if (sb.st_uid !=3D uid || sb.st_gid !=3D gid) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("Setting different DAC user or group on %= s " + "which is already in use"), path); + return -1; + } + } } =20 VIR_INFO("Setting DAC user and group on '%s' to '%ld:%ld'", --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 154461849503495.72363273500673; Wed, 12 Dec 2018 04:41:35 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AD98A30820E3; Wed, 12 Dec 2018 12:41:33 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7463D5FC34; Wed, 12 Dec 2018 12:41:33 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 2D249181BA1B; Wed, 12 Dec 2018 12:41:33 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfIdR017211 for ; Wed, 12 Dec 2018 07:41:18 -0500 Received: by smtp.corp.redhat.com (Postfix) id 1F4895D738; Wed, 12 Dec 2018 12:41:18 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9A4565D70A for ; Wed, 12 Dec 2018 12:41:17 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:40:53 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 09/18] virSecurityDACRestoreImageLabelInt: Restore even shared/RO disks X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Wed, 12 Dec 2018 12:41:34 +0000 (UTC) Now that we have seclabel remembering we can safely restore labels for shared and RO disks. In fact we need to do that to keep seclabel refcount stored in XATTRs in sync with reality. Signed-off-by: Michal Privoznik Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: J=C3=A1n Tomko --- src/security/security_dac.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 3264a2967c..533d990de1 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -932,14 +932,6 @@ virSecurityDACRestoreImageLabelInt(virSecurityManagerP= tr mgr, if (!priv->dynamicOwnership) return 0; =20 - /* Don't restore labels on readoly/shared disks, because other VMs may - * still be accessing these. Alternatively we could iterate over all - * running domains and try to figure out if it is in use, but this wou= ld - * not work for clustered filesystems, since we can't see running VMs = using - * the file on other nodes. Safest bet is thus to skip the restore ste= p. */ - if (src->readonly || src->shared) - return 0; - secdef =3D virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME); if (secdef && !secdef->relabel) return 0; --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1544618499683877.0721996679775; Wed, 12 Dec 2018 04:41:39 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3DB2E8830C; Wed, 12 Dec 2018 12:41:37 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 098A719940; Wed, 12 Dec 2018 12:41:37 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id B5CCD1832E8F; Wed, 12 Dec 2018 12:41:36 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfIwB017329 for ; Wed, 12 Dec 2018 07:41:18 -0500 Received: by smtp.corp.redhat.com (Postfix) id E81A75D738; Wed, 12 Dec 2018 12:41:18 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6DAB45D70A for ; Wed, 12 Dec 2018 12:41:18 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:40:54 +0100 Message-Id: <870360dc272828c4d57dd016fc828af2973942ff.1544618362.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 10/18] security_selinux: Track if transaction is restore X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 12 Dec 2018 12:41:39 +0000 (UTC) It is going to be important to know if the current transaction we are running is a restore operation or set label operation so that we know whether to call virSecurityGetRememberedLabel() or virSecuritySetRememberedLabel(). That is, whether we are in a restore and therefore have to fetch the remembered label, or we are in set operation and therefore have to store the original label. Signed-off-by: Michal Privoznik Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: J=C3=A1n Tomko --- src/security/security_selinux.c | 36 +++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/security/security_selinux.c b/src/security/security_selinu= x.c index 95e9a1b0c7..715d9a428b 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -85,6 +85,7 @@ struct _virSecuritySELinuxContextItem { char *path; char *tcon; bool optional; + bool restore; }; =20 typedef struct _virSecuritySELinuxContextList virSecuritySELinuxContextLis= t; @@ -123,7 +124,8 @@ static int virSecuritySELinuxContextListAppend(virSecuritySELinuxContextListPtr list, const char *path, const char *tcon, - bool optional) + bool optional, + bool restore) { int ret =3D -1; virSecuritySELinuxContextItemPtr item =3D NULL; @@ -135,6 +137,7 @@ virSecuritySELinuxContextListAppend(virSecuritySELinuxC= ontextListPtr list, goto cleanup; =20 item->optional =3D optional; + item->restore =3D restore; =20 if (VIR_APPEND_ELEMENT(list->items, list->nItems, item) < 0) goto cleanup; @@ -178,7 +181,8 @@ virSecuritySELinuxContextListFree(void *opaque) static int virSecuritySELinuxTransactionAppend(const char *path, const char *tcon, - bool optional) + bool optional, + bool restore) { virSecuritySELinuxContextListPtr list; =20 @@ -186,7 +190,7 @@ virSecuritySELinuxTransactionAppend(const char *path, if (!list) return 0; =20 - if (virSecuritySELinuxContextListAppend(list, path, tcon, optional) < = 0) + if (virSecuritySELinuxContextListAppend(list, path, tcon, optional, re= store) < 0) return -1; =20 return 1; @@ -198,6 +202,11 @@ static int virSecuritySELinuxSetFileconHelper(const ch= ar *path, bool optional, bool privileged); =20 + +static int virSecuritySELinuxRestoreFileLabel(virSecurityManagerPtr mgr, + const char *path); + + /** * virSecuritySELinuxTransactionRun: * @pid: process pid @@ -242,13 +251,18 @@ virSecuritySELinuxTransactionRun(pid_t pid ATTRIBUTE_= UNUSED, virSecuritySELinuxContextItemPtr item =3D list->items[i]; =20 /* TODO Implement rollback */ - if (virSecuritySELinuxSetFileconHelper(item->path, - item->tcon, - item->optional, - privileged) < 0) { - rv =3D -1; - break; + if (!item->restore) { + rv =3D virSecuritySELinuxSetFileconHelper(item->path, + item->tcon, + item->optional, + privileged); + } else { + rv =3D virSecuritySELinuxRestoreFileLabel(list->manager, + item->path); } + + if (rv < 0) + break; } =20 if (list->lock) @@ -1265,7 +1279,7 @@ virSecuritySELinuxSetFileconHelper(const char *path, = const char *tcon, { int rc; =20 - if ((rc =3D virSecuritySELinuxTransactionAppend(path, tcon, optional))= < 0) + if ((rc =3D virSecuritySELinuxTransactionAppend(path, tcon, optional, = false)) < 0) return -1; else if (rc > 0) return 0; @@ -1387,7 +1401,7 @@ virSecuritySELinuxRestoreFileLabel(virSecurityManager= Ptr mgr, goto cleanup; } =20 - if ((rc =3D virSecuritySELinuxTransactionAppend(path, fcon, false)) < = 0) + if ((rc =3D virSecuritySELinuxTransactionAppend(path, fcon, false, tru= e)) < 0) return -1; else if (rc > 0) return 0; --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1544618504971580.0711571167097; Wed, 12 Dec 2018 04:41:44 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2C57E31256B9; Wed, 12 Dec 2018 12:41:43 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id DCF2360C64; Wed, 12 Dec 2018 12:41:42 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 8E50F249A6; Wed, 12 Dec 2018 12:41:42 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfMce017536 for ; Wed, 12 Dec 2018 07:41:22 -0500 Received: by smtp.corp.redhat.com (Postfix) id 29FA25D73F; Wed, 12 Dec 2018 12:41:22 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id A356F5D70A for ; Wed, 12 Dec 2018 12:41:19 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:40:55 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 11/18] security_selinux: Remember old labels X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Wed, 12 Dec 2018 12:41:44 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Similarly to what I did in DAC driver, this also requires the same SELinux label to be used for shared paths. If a path is already in use by a domain (or domains) then and the domain we are starting now wants to access the path it has to have the same SELinux label. This might look too restrictive as the new label can still guarantee access to already running domains but in reality it is very unlikely and usually an admin mistake. Signed-off-by: Michal Privoznik Reviewed-by: J=C3=A1n Tomko --- src/security/security_selinux.c | 177 +++++++++++++++++++++++--------- 1 file changed, 130 insertions(+), 47 deletions(-) diff --git a/src/security/security_selinux.c b/src/security/security_selinu= x.c index 715d9a428b..43d2ef32a5 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -33,6 +33,7 @@ =20 #include "security_driver.h" #include "security_selinux.h" +#include "security_util.h" #include "virerror.h" #include "viralloc.h" #include "virlog.h" @@ -197,14 +198,40 @@ virSecuritySELinuxTransactionAppend(const char *path, } =20 =20 +static int +virSecuritySELinuxRememberLabel(const char *path, + const security_context_t con) +{ + return virSecuritySetRememberedLabel(SECURITY_SELINUX_NAME, + path, con); +} + + +static int +virSecuritySELinuxRecallLabel(const char *path, + security_context_t *con) +{ + if (virSecurityGetRememberedLabel(SECURITY_SELINUX_NAME, + path, con) < 0) + return -1; + + if (!con) + return 1; + + return 0; +} + + static int virSecuritySELinuxSetFileconHelper(const char *path, const char *tcon, bool optional, - bool privileged); + bool privileged, + bool remember); =20 =20 static int virSecuritySELinuxRestoreFileLabel(virSecurityManagerPtr mgr, - const char *path); + const char *path, + bool recall); =20 =20 /** @@ -255,10 +282,12 @@ virSecuritySELinuxTransactionRun(pid_t pid ATTRIBUTE_= UNUSED, rv =3D virSecuritySELinuxSetFileconHelper(item->path, item->tcon, item->optional, - privileged); + privileged, + list->lock); } else { rv =3D virSecuritySELinuxRestoreFileLabel(list->manager, - item->path); + item->path, + list->lock); } =20 if (rv < 0) @@ -1275,16 +1304,54 @@ virSecuritySELinuxSetFileconImpl(const char *path, = const char *tcon, =20 static int virSecuritySELinuxSetFileconHelper(const char *path, const char *tcon, - bool optional, bool privileged) + bool optional, bool privileged, bool re= member) { + security_context_t econ =3D NULL; + int refcount; int rc; + int ret =3D -1; =20 if ((rc =3D virSecuritySELinuxTransactionAppend(path, tcon, optional, = false)) < 0) return -1; else if (rc > 0) return 0; =20 - return virSecuritySELinuxSetFileconImpl(path, tcon, optional, privileg= ed); + if (remember) { + if (getfilecon_raw(path, &econ) < 0 && + errno !=3D ENOTSUP && errno !=3D ENODATA) { + virReportSystemError(errno, + _("unable to get SELinux context of %s"), + path); + goto cleanup; + } + + if (econ) { + refcount =3D virSecuritySELinuxRememberLabel(path, econ); + if (refcount < 0) { + goto cleanup; + } else if (refcount > 1) { + /* Refcount is greater than 1 which means that there + * is @refcount domains using the @path. Do not + * change the label (as it would almost certainly + * cause the other domains to lose access to the + * @path). */ + if (STRNEQ(econ, tcon)) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("Setting different SELinux label on %= s " + "which is already in use"), path); + goto cleanup; + } + } + } + } + + if (virSecuritySELinuxSetFileconImpl(path, tcon, optional, privileged)= < 0) + goto cleanup; + + ret =3D 0; + cleanup: + freecon(econ); + return ret; } =20 =20 @@ -1293,7 +1360,7 @@ virSecuritySELinuxSetFileconOptional(virSecurityManag= erPtr mgr, const char *path, const char *tcon) { bool privileged =3D virSecurityManagerGetPrivileged(mgr); - return virSecuritySELinuxSetFileconHelper(path, tcon, true, privileged= ); + return virSecuritySELinuxSetFileconHelper(path, tcon, true, privileged= , false); } =20 static int @@ -1301,7 +1368,7 @@ virSecuritySELinuxSetFilecon(virSecurityManagerPtr mg= r, const char *path, const char *tcon) { bool privileged =3D virSecurityManagerGetPrivileged(mgr); - return virSecuritySELinuxSetFileconHelper(path, tcon, false, privilege= d); + return virSecuritySELinuxSetFileconHelper(path, tcon, false, privilege= d, false); } =20 static int @@ -1362,7 +1429,8 @@ getContext(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, * errors that the caller(s) are already dealing with */ static int virSecuritySELinuxRestoreFileLabel(virSecurityManagerPtr mgr, - const char *path) + const char *path, + bool recall) { bool privileged =3D virSecurityManagerGetPrivileged(mgr); struct stat buf; @@ -1386,26 +1454,35 @@ virSecuritySELinuxRestoreFileLabel(virSecurityManag= erPtr mgr, goto cleanup; } =20 - if (stat(newpath, &buf) !=3D 0) { - VIR_WARN("cannot stat %s: %s", newpath, - virStrerror(errno, ebuf, sizeof(ebuf))); - goto cleanup; - } - - if (getContext(mgr, newpath, buf.st_mode, &fcon) < 0) { - /* Any user created path likely does not have a default label, - * which makes this an expected non error - */ - VIR_WARN("cannot lookup default selinux label for %s", newpath); - ret =3D 0; - goto cleanup; - } - - if ((rc =3D virSecuritySELinuxTransactionAppend(path, fcon, false, tru= e)) < 0) + if ((rc =3D virSecuritySELinuxTransactionAppend(path, NULL, false, tru= e)) < 0) return -1; else if (rc > 0) return 0; =20 + if (recall) { + if ((rc =3D virSecuritySELinuxRecallLabel(newpath, &fcon)) < 0) { + goto cleanup; + } else if (rc > 0) { + ret =3D 0; + goto cleanup; + } + } else { + if (stat(newpath, &buf) !=3D 0) { + VIR_WARN("cannot stat %s: %s", newpath, + virStrerror(errno, ebuf, sizeof(ebuf))); + goto cleanup; + } + + if (getContext(mgr, newpath, buf.st_mode, &fcon) < 0) { + /* Any user created path likely does not have a default label, + * which makes this an expected non error + */ + VIR_WARN("cannot lookup default selinux label for %s", newpath= ); + ret =3D 0; + goto cleanup; + } + } + if (virSecuritySELinuxSetFileconImpl(newpath, fcon, false, privileged)= < 0) goto cleanup; =20 @@ -1460,7 +1537,7 @@ virSecuritySELinuxRestoreInputLabel(virSecurityManage= rPtr mgr, =20 switch ((virDomainInputType)input->type) { case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH: - rc =3D virSecuritySELinuxRestoreFileLabel(mgr, input->source.evdev= ); + rc =3D virSecuritySELinuxRestoreFileLabel(mgr, input->source.evdev= , false); break; =20 case VIR_DOMAIN_INPUT_TYPE_MOUSE: @@ -1516,7 +1593,7 @@ virSecuritySELinuxRestoreMemoryLabel(virSecurityManag= erPtr mgr, if (!seclabel || !seclabel->relabel) return 0; =20 - ret =3D virSecuritySELinuxRestoreFileLabel(mgr, mem->nvdimmPath); + ret =3D virSecuritySELinuxRestoreFileLabel(mgr, mem->nvdimmPath, f= alse); break; =20 case VIR_DOMAIN_MEMORY_MODEL_DIMM: @@ -1595,10 +1672,10 @@ virSecuritySELinuxRestoreTPMFileLabelInt(virSecurit= yManagerPtr mgr, switch (tpm->type) { case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH: tpmdev =3D tpm->data.passthrough.source.data.file.path; - rc =3D virSecuritySELinuxRestoreFileLabel(mgr, tpmdev); + rc =3D virSecuritySELinuxRestoreFileLabel(mgr, tpmdev, false); =20 if ((cancel_path =3D virTPMCreateCancelPath(tpmdev)) !=3D NULL) { - if (virSecuritySELinuxRestoreFileLabel(mgr, cancel_path) < 0) + if (virSecuritySELinuxRestoreFileLabel(mgr, cancel_path, false= ) < 0) rc =3D -1; VIR_FREE(cancel_path); } @@ -1665,7 +1742,7 @@ virSecuritySELinuxRestoreImageLabelInt(virSecurityMan= agerPtr mgr, } } =20 - return virSecuritySELinuxRestoreFileLabel(mgr, src->path); + return virSecuritySELinuxRestoreFileLabel(mgr, src->path, false); } =20 =20 @@ -2053,7 +2130,7 @@ virSecuritySELinuxRestorePCILabel(virPCIDevicePtr dev= ATTRIBUTE_UNUSED, { virSecurityManagerPtr mgr =3D opaque; =20 - return virSecuritySELinuxRestoreFileLabel(mgr, file); + return virSecuritySELinuxRestoreFileLabel(mgr, file, false); } =20 static int @@ -2063,7 +2140,7 @@ virSecuritySELinuxRestoreUSBLabel(virUSBDevicePtr dev= ATTRIBUTE_UNUSED, { virSecurityManagerPtr mgr =3D opaque; =20 - return virSecuritySELinuxRestoreFileLabel(mgr, file); + return virSecuritySELinuxRestoreFileLabel(mgr, file, false); } =20 =20 @@ -2080,7 +2157,7 @@ virSecuritySELinuxRestoreSCSILabel(virSCSIDevicePtr d= ev, if (virSCSIDeviceGetShareable(dev) || virSCSIDeviceGetReadonly(dev)) return 0; =20 - return virSecuritySELinuxRestoreFileLabel(mgr, file); + return virSecuritySELinuxRestoreFileLabel(mgr, file, false); } =20 static int @@ -2090,7 +2167,7 @@ virSecuritySELinuxRestoreHostLabel(virSCSIVHostDevice= Ptr dev ATTRIBUTE_UNUSED, { virSecurityManagerPtr mgr =3D opaque; =20 - return virSecuritySELinuxRestoreFileLabel(mgr, file); + return virSecuritySELinuxRestoreFileLabel(mgr, file, false); } =20 =20 @@ -2194,7 +2271,7 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecuri= tyManagerPtr mgr, if (!(vfiodev =3D virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuids= tr))) goto done; =20 - ret =3D virSecuritySELinuxRestoreFileLabel(mgr, vfiodev); + ret =3D virSecuritySELinuxRestoreFileLabel(mgr, vfiodev, false); =20 VIR_FREE(vfiodev); break; @@ -2228,7 +2305,7 @@ virSecuritySELinuxRestoreHostdevCapsLabel(virSecurity= ManagerPtr mgr, if (VIR_STRDUP(path, dev->source.caps.u.storage.block) < 0) return -1; } - ret =3D virSecuritySELinuxRestoreFileLabel(mgr, path); + ret =3D virSecuritySELinuxRestoreFileLabel(mgr, path, false); VIR_FREE(path); break; } @@ -2242,7 +2319,7 @@ virSecuritySELinuxRestoreHostdevCapsLabel(virSecurity= ManagerPtr mgr, if (VIR_STRDUP(path, dev->source.caps.u.misc.chardev) < 0) return -1; } - ret =3D virSecuritySELinuxRestoreFileLabel(mgr, path); + ret =3D virSecuritySELinuxRestoreFileLabel(mgr, path, false); VIR_FREE(path); break; } @@ -2390,14 +2467,18 @@ virSecuritySELinuxRestoreChardevLabel(virSecurityMa= nagerPtr mgr, switch (dev_source->type) { case VIR_DOMAIN_CHR_TYPE_DEV: case VIR_DOMAIN_CHR_TYPE_FILE: - if (virSecuritySELinuxRestoreFileLabel(mgr, dev_source->data.file.= path) < 0) + if (virSecuritySELinuxRestoreFileLabel(mgr, + dev_source->data.file.path, + false) < 0) goto done; ret =3D 0; break; =20 case VIR_DOMAIN_CHR_TYPE_UNIX: if (!dev_source->data.nix.listen) { - if (virSecuritySELinuxRestoreFileLabel(mgr, dev_source->data.f= ile.path) < 0) + if (virSecuritySELinuxRestoreFileLabel(mgr, + dev_source->data.file.p= ath, + false) < 0) goto done; } ret =3D 0; @@ -2408,11 +2489,13 @@ virSecuritySELinuxRestoreChardevLabel(virSecurityMa= nagerPtr mgr, (virAsprintf(&in, "%s.in", dev_source->data.file.path) < 0)) goto done; if (virFileExists(in) && virFileExists(out)) { - if ((virSecuritySELinuxRestoreFileLabel(mgr, out) < 0) || - (virSecuritySELinuxRestoreFileLabel(mgr, in) < 0)) { + if ((virSecuritySELinuxRestoreFileLabel(mgr, out, false) < 0) = || + (virSecuritySELinuxRestoreFileLabel(mgr, in, false) < 0)) { goto done; } - } else if (virSecuritySELinuxRestoreFileLabel(mgr, dev_source->dat= a.file.path) < 0) { + } else if (virSecuritySELinuxRestoreFileLabel(mgr, + dev_source->data.fil= e.path, + false) < 0) { goto done; } ret =3D 0; @@ -2464,7 +2547,7 @@ virSecuritySELinuxRestoreSecuritySmartcardCallback(vi= rDomainDefPtr def, database =3D dev->data.cert.database; if (!database) database =3D VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE; - return virSecuritySELinuxRestoreFileLabel(mgr, database); + return virSecuritySELinuxRestoreFileLabel(mgr, database, false); =20 case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH: return virSecuritySELinuxRestoreChardevLabel(mgr, def, @@ -2559,7 +2642,7 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManagerP= tr mgr, rc =3D -1; =20 if (def->os.loader && def->os.loader->nvram && - virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram) < 0) + virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram, fal= se) < 0) rc =3D -1; =20 return rc; @@ -2619,7 +2702,7 @@ virSecuritySELinuxRestoreSavedStateLabel(virSecurityM= anagerPtr mgr, if (!secdef || !secdef->relabel) return 0; =20 - return virSecuritySELinuxRestoreFileLabel(mgr, savefile); + return virSecuritySELinuxRestoreFileLabel(mgr, savefile, false); } =20 =20 @@ -3214,7 +3297,7 @@ virSecuritySELinuxRestoreFileLabels(virSecurityManage= rPtr mgr, char *filename =3D NULL; DIR *dir; =20 - if ((ret =3D virSecuritySELinuxRestoreFileLabel(mgr, path))) + if ((ret =3D virSecuritySELinuxRestoreFileLabel(mgr, path, false))) return ret; =20 if (!virFileIsDir(path)) @@ -3231,7 +3314,7 @@ virSecuritySELinuxRestoreFileLabels(virSecurityManage= rPtr mgr, ret =3D -1; break; } - ret =3D virSecuritySELinuxRestoreFileLabel(mgr, filename); + ret =3D virSecuritySELinuxRestoreFileLabel(mgr, filename, false); VIR_FREE(filename); if (ret < 0) break; --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1544618503480845.3865401154168; Wed, 12 Dec 2018 04:41:43 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0A80480494; Wed, 12 Dec 2018 12:41:42 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B2E03105705C; Wed, 12 Dec 2018 12:41:41 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 4850224822; Wed, 12 Dec 2018 12:41:41 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfN3v017541 for ; Wed, 12 Dec 2018 07:41:23 -0500 Received: by smtp.corp.redhat.com (Postfix) id F2E835D762; Wed, 12 Dec 2018 12:41:22 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id 76BFA5D756 for ; Wed, 12 Dec 2018 12:41:22 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:40:56 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 12/18] security_selinux: Restore label on failed setfilecon() attempt X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 12 Dec 2018 12:41:42 +0000 (UTC) It's important to keep XATTRs untouched (well, in the same state they were in when entering the function). Otherwise our refcounting would be messed up. Signed-off-by: Michal Privoznik Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: J=C3=A1n Tomko --- src/security/security_selinux.c | 40 +++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/security/security_selinux.c b/src/security/security_selinu= x.c index 43d2ef32a5..f52c88259d 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -222,10 +222,10 @@ virSecuritySELinuxRecallLabel(const char *path, } =20 =20 -static int virSecuritySELinuxSetFileconHelper(const char *path, +static int virSecuritySELinuxSetFileconHelper(virSecurityManagerPtr mgr, + const char *path, const char *tcon, bool optional, - bool privileged, bool remember); =20 =20 @@ -252,7 +252,6 @@ virSecuritySELinuxTransactionRun(pid_t pid ATTRIBUTE_UN= USED, { virSecuritySELinuxContextListPtr list =3D opaque; virSecurityManagerMetadataLockStatePtr state; - bool privileged =3D virSecurityManagerGetPrivileged(list->manager); const char **paths =3D NULL; size_t npaths =3D 0; size_t i; @@ -279,10 +278,10 @@ virSecuritySELinuxTransactionRun(pid_t pid ATTRIBUTE_= UNUSED, =20 /* TODO Implement rollback */ if (!item->restore) { - rv =3D virSecuritySELinuxSetFileconHelper(item->path, + rv =3D virSecuritySELinuxSetFileconHelper(list->manager, + item->path, item->tcon, item->optional, - privileged, list->lock); } else { rv =3D virSecuritySELinuxRestoreFileLabel(list->manager, @@ -1303,9 +1302,13 @@ virSecuritySELinuxSetFileconImpl(const char *path, c= onst char *tcon, =20 =20 static int -virSecuritySELinuxSetFileconHelper(const char *path, const char *tcon, - bool optional, bool privileged, bool re= member) +virSecuritySELinuxSetFileconHelper(virSecurityManagerPtr mgr, + const char *path, + const char *tcon, + bool optional, + bool remember) { + bool privileged =3D virSecurityManagerGetPrivileged(mgr); security_context_t econ =3D NULL; int refcount; int rc; @@ -1345,8 +1348,23 @@ virSecuritySELinuxSetFileconHelper(const char *path,= const char *tcon, } } =20 - if (virSecuritySELinuxSetFileconImpl(path, tcon, optional, privileged)= < 0) + if (virSecuritySELinuxSetFileconImpl(path, tcon, optional, privileged)= < 0) { + virErrorPtr origerr; + + virErrorPreserveLast(&origerr); + /* Try to restore the label. This is done so that XATTRs + * are left in the same state as when the control entered + * this function. However, if our attempt fails, there's + * not much we can do. XATTRs refcounting is fubar'ed and + * the only option we have is warn users. */ + if (virSecuritySELinuxRestoreFileLabel(mgr, path, remember) < 0) + VIR_WARN("Unable to restore label on '%s'. " + "XATTRs might have been left in inconsistent state.", + path); + + virErrorRestore(&origerr); goto cleanup; + } =20 ret =3D 0; cleanup: @@ -1359,16 +1377,14 @@ static int virSecuritySELinuxSetFileconOptional(virSecurityManagerPtr mgr, const char *path, const char *tcon) { - bool privileged =3D virSecurityManagerGetPrivileged(mgr); - return virSecuritySELinuxSetFileconHelper(path, tcon, true, privileged= , false); + return virSecuritySELinuxSetFileconHelper(mgr, path, tcon, true, false= ); } =20 static int virSecuritySELinuxSetFilecon(virSecurityManagerPtr mgr, const char *path, const char *tcon) { - bool privileged =3D virSecurityManagerGetPrivileged(mgr); - return virSecuritySELinuxSetFileconHelper(path, tcon, false, privilege= d, false); + return virSecuritySELinuxSetFileconHelper(mgr, path, tcon, false, fals= e); } =20 static int --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 154461850763258.660829498450084; Wed, 12 Dec 2018 04:41:47 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2BD48300441E; Wed, 12 Dec 2018 12:41:46 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E9CC5608DC; Wed, 12 Dec 2018 12:41:45 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 97E123D39C; Wed, 12 Dec 2018 12:41:45 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfQWA017560 for ; Wed, 12 Dec 2018 07:41:26 -0500 Received: by smtp.corp.redhat.com (Postfix) id 0D85E5D73F; Wed, 12 Dec 2018 12:41:26 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id 85CD15D70A for ; Wed, 12 Dec 2018 12:41:23 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:40:57 +0100 Message-Id: <225dd0fcd33cfc8924206105671125561d8c4be2.1544618362.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 13/18] virSecuritySELinuxTransactionRun: Implement rollback X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Wed, 12 Dec 2018 12:41:47 +0000 (UTC) When iterating over list of paths/disk sources to relabel it may happen that the process fails at some point. In that case, for the sake of keeping seclabel refcount (stored in XATTRs) in sync with reality we have to perform rollback. However, if that fails too the only thing we can do is warn user. Signed-off-by: Michal Privoznik Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: J=C3=A1n Tomko --- src/security/security_selinux.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/security/security_selinux.c b/src/security/security_selinu= x.c index f52c88259d..4b68eb2717 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -276,7 +276,6 @@ virSecuritySELinuxTransactionRun(pid_t pid ATTRIBUTE_UN= USED, for (i =3D 0; i < list->nItems; i++) { virSecuritySELinuxContextItemPtr item =3D list->items[i]; =20 - /* TODO Implement rollback */ if (!item->restore) { rv =3D virSecuritySELinuxSetFileconHelper(list->manager, item->path, @@ -293,6 +292,18 @@ virSecuritySELinuxTransactionRun(pid_t pid ATTRIBUTE_U= NUSED, break; } =20 + for (; rv < 0 && i > 0; i--) { + virSecuritySELinuxContextItemPtr item =3D list->items[i - 1]; + + if (!item->restore) { + virSecuritySELinuxRestoreFileLabel(list->manager, + item->path, + list->lock); + } else { + VIR_WARN("Ignoring failed restore attempt on %s", item->path); + } + } + if (list->lock) virSecurityManagerMetadataUnlock(list->manager, &state); =20 --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1544618512424263.27624112344506; Wed, 12 Dec 2018 04:41:52 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5035F8B10D; Wed, 12 Dec 2018 12:41:50 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E198E60C6D; Wed, 12 Dec 2018 12:41:49 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 969B51888BB8; Wed, 12 Dec 2018 12:41:49 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfUZF017579 for ; Wed, 12 Dec 2018 07:41:30 -0500 Received: by smtp.corp.redhat.com (Postfix) id E8EE35D756; Wed, 12 Dec 2018 12:41:30 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6AAF35D73F for ; Wed, 12 Dec 2018 12:41:26 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:40:58 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 14/18] virSecuritySELinuxRestoreAllLabel: Reorder device relabeling X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 12 Dec 2018 12:41:51 +0000 (UTC) It helps whe trying to match calls with virSecuritySELinuxSetAllLabel if the order in which devices are set/restored is the same in both functions. Signed-off-by: Michal Privoznik Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: J=C3=A1n Tomko --- src/security/security_selinux.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/security/security_selinux.c b/src/security/security_selinu= x.c index 4b68eb2717..4e30523e2c 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -2620,8 +2620,11 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManager= Ptr mgr, if (!secdef || !secdef->relabel || data->skipAllLabel) return 0; =20 - if (def->tpm) { - if (virSecuritySELinuxRestoreTPMFileLabelInt(mgr, def, def->tpm) <= 0) + for (i =3D 0; i < def->ndisks; i++) { + virDomainDiskDefPtr disk =3D def->disks[i]; + + if (virSecuritySELinuxRestoreImageLabelInt(mgr, def, disk->src, + migrated) < 0) rc =3D -1; } =20 @@ -2643,11 +2646,8 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManager= Ptr mgr, return -1; } =20 - for (i =3D 0; i < def->ndisks; i++) { - virDomainDiskDefPtr disk =3D def->disks[i]; - - if (virSecuritySELinuxRestoreImageLabelInt(mgr, def, disk->src, - migrated) < 0) + if (def->tpm) { + if (virSecuritySELinuxRestoreTPMFileLabelInt(mgr, def, def->tpm) <= 0) rc =3D -1; } =20 --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1544618503509767.2056207908607; Wed, 12 Dec 2018 04:41:43 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EFD02C050018; Wed, 12 Dec 2018 12:41:41 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B186A5ED36; Wed, 12 Dec 2018 12:41:41 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 5FF70181B9F6; Wed, 12 Dec 2018 12:41:41 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfXPj017589 for ; Wed, 12 Dec 2018 07:41:33 -0500 Received: by smtp.corp.redhat.com (Postfix) id 9651C5D762; Wed, 12 Dec 2018 12:41:33 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1D5D85D760 for ; Wed, 12 Dec 2018 12:41:31 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:40:59 +0100 Message-Id: <5d2b63c1007a8654640a34910e583e9599830bf8.1544618362.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 15/18] virSecuritySELinuxRestoreAllLabel: Restore more labels X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Wed, 12 Dec 2018 12:41:42 +0000 (UTC) We are setting label on kernel, initrd, dtb and slic_table files. But we never restored it. Signed-off-by: Michal Privoznik Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: J=C3=A1n Tomko --- src/security/security_selinux.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/security/security_selinux.c b/src/security/security_selinu= x.c index 4e30523e2c..2d32e65f13 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -2672,6 +2672,22 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManager= Ptr mgr, virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram, fal= se) < 0) rc =3D -1; =20 + if (def->os.kernel && + virSecuritySELinuxRestoreFileLabel(mgr, def->os.kernel, false) < 0) + rc =3D -1; + + if (def->os.initrd && + virSecuritySELinuxRestoreFileLabel(mgr, def->os.initrd, false) < 0) + rc =3D -1; + + if (def->os.dtb && + virSecuritySELinuxRestoreFileLabel(mgr, def->os.dtb, false) < 0) + rc =3D -1; + + if (def->os.slic_table && + virSecuritySELinuxRestoreFileLabel(mgr, def->os.slic_table, false)= < 0) + rc =3D -1; + return rc; } =20 --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1544618508037665.2287547784707; Wed, 12 Dec 2018 04:41:48 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 038A4C02835A; Wed, 12 Dec 2018 12:41:46 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B9D7260C6A; Wed, 12 Dec 2018 12:41:45 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 664D03D39A; Wed, 12 Dec 2018 12:41:45 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfaaX017599 for ; Wed, 12 Dec 2018 07:41:36 -0500 Received: by smtp.corp.redhat.com (Postfix) id 668FE5D760; Wed, 12 Dec 2018 12:41:36 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id B88555D756 for ; Wed, 12 Dec 2018 12:41:33 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:41:00 +0100 Message-Id: <1de583b1325495353866c78a918d286af22e755f.1544618362.git.mprivozn@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 16/18] tests: Introduce qemusecuritytest X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Wed, 12 Dec 2018 12:41:46 +0000 (UTC) Content-Type: text/plain; charset="utf-8" This test checks if security label remembering works correctly. It uses qemuSecurity* APIs to do that. And some mocking (even though it's not real mocking as we are used to from other tests like virpcitest). So far, only DAC driver is tested. Signed-off-by: Michal Privoznik Reviewed-by: J=C3=A1n Tomko --- cfg.mk | 4 +- src/util/virfile.h | 15 +- tests/Makefile.am | 10 + tests/qemusecuritymock.c | 480 +++++++++++++++++++++++++++++++++++++++ tests/qemusecuritytest.c | 173 ++++++++++++++ tests/qemusecuritytest.h | 28 +++ 6 files changed, 703 insertions(+), 7 deletions(-) create mode 100644 tests/qemusecuritymock.c create mode 100644 tests/qemusecuritytest.c create mode 100644 tests/qemusecuritytest.h diff --git a/cfg.mk b/cfg.mk index c468d153eb..bd67cfd940 100644 --- a/cfg.mk +++ b/cfg.mk @@ -1178,7 +1178,7 @@ exclude_file_name_regexp--sc_copyright_usage =3D \ ^COPYING(|\.LESSER)$$ =20 exclude_file_name_regexp--sc_flags_usage =3D \ - ^(cfg\.mk|docs/|src/util/virnetdevtap\.c$$|tests/((vir(cgroup|pci|test|u= sb)|nss|qemuxml2argv)mock|virfilewrapper)\.c$$) + ^(cfg\.mk|docs/|src/util/virnetdevtap\.c$$|tests/((vir(cgroup|pci|test|u= sb)|nss|qemuxml2argv|qemusecurity)mock|virfilewrapper)\.c$$) =20 exclude_file_name_regexp--sc_libvirt_unmarked_diagnostics =3D \ ^(src/rpc/gendispatch\.pl$$|tests/) @@ -1201,7 +1201,7 @@ exclude_file_name_regexp--sc_prohibit_strdup =3D \ ^(docs/|examples/|src/util/virstring\.c|tests/vir(netserverclient|cgroup= )mock.c|tests/commandhelper\.c$$) =20 exclude_file_name_regexp--sc_prohibit_close =3D \ - (\.p[yl]$$|\.spec\.in$$|^docs/|^(src/util/virfile\.c|src/libvirt-stream\= .c|tests/vir.+mock\.c|tests/commandhelper\.c)$$) + (\.p[yl]$$|\.spec\.in$$|^docs/|^(src/util/virfile\.c|src/libvirt-stream\= .c|tests/(vir.+mock\.c|commandhelper\.c|qemusecuritymock\.c))$$) =20 exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF =3D \ (^tests/(virhostcpu|virpcitest)data/|docs/js/.*\.js|docs/fonts/.*\.woff|= \.diff|tests/virconfdata/no-newline\.conf$$) diff --git a/src/util/virfile.h b/src/util/virfile.h index aa4c29dc40..9304d69349 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -115,8 +115,10 @@ int virFileWrapperFdClose(virFileWrapperFdPtr dfd); =20 void virFileWrapperFdFree(virFileWrapperFdPtr dfd); =20 -int virFileLock(int fd, bool shared, off_t start, off_t len, bool waitForL= ock); -int virFileUnlock(int fd, off_t start, off_t len); +int virFileLock(int fd, bool shared, off_t start, off_t len, bool waitForL= ock) + ATTRIBUTE_NOINLINE; +int virFileUnlock(int fd, off_t start, off_t len) + ATTRIBUTE_NOINLINE; =20 int virFileFlock(int fd, bool lock, bool shared); =20 @@ -385,13 +387,16 @@ VIR_DEFINE_AUTOPTR_FUNC(virFileWrapperFd, virFileWrap= perFdFree) =20 int virFileGetXAttr(const char *path, const char *name, - char **value); + char **value) + ATTRIBUTE_NOINLINE; =20 int virFileSetXAttr(const char *path, const char *name, - const char *value); + const char *value) + ATTRIBUTE_NOINLINE; =20 int virFileRemoveXAttr(const char *path, - const char *name); + const char *name) + ATTRIBUTE_NOINLINE; =20 #endif /* __VIR_FILE_H */ diff --git a/tests/Makefile.am b/tests/Makefile.am index d7ec7e3a6f..fbecf4179d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -289,6 +289,7 @@ test_programs +=3D qemuxml2argvtest qemuxml2xmltest \ qemucommandutiltest \ qemublocktest \ qemumigparamstest \ + qemusecuritytest \ $(NULL) test_helpers +=3D qemucapsprobe test_libraries +=3D libqemumonitortestutils.la \ @@ -683,6 +684,13 @@ qemumigparamstest_SOURCES =3D \ qemumigparamstest_LDADD =3D libqemumonitortestutils.la \ $(qemu_LDADDS) $(LDADDS) =20 +qemusecuritytest_SOURCES =3D \ + qemusecuritytest.c qemusecuritytest.h \ + qemusecuritymock.c \ + testutils.h testutils.c \ + testutilsqemu.h testutilsqemu.c +qemusecuritytest_LDADD =3D $(qemu_LDADDS) $(LDADDS) + else ! WITH_QEMU EXTRA_DIST +=3D qemuxml2argvtest.c qemuxml2xmltest.c qemuargv2xmltest.c \ domainsnapshotxml2xmltest.c \ @@ -694,6 +702,8 @@ EXTRA_DIST +=3D qemuxml2argvtest.c qemuxml2xmltest.c qe= muargv2xmltest.c \ qemumemlocktest.c qemucpumock.c testutilshostcpus.h \ qemublocktest.c \ qemumigparamstest.c \ + qemusecuritytest.c qemusecuritytest.h \ + qemusecuritymock.c \ $(QEMUMONITORTESTUTILS_SOURCES) endif ! WITH_QEMU =20 diff --git a/tests/qemusecuritymock.c b/tests/qemusecuritymock.c new file mode 100644 index 0000000000..6148d02cb0 --- /dev/null +++ b/tests/qemusecuritymock.c @@ -0,0 +1,480 @@ +/* + * Copyright (C) 2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + * Author: Michal Privoznik + */ + +#include + +#include +#include +#include +#include +#include + +#include "virmock.h" +#include "virfile.h" +#include "virthread.h" +#include "virhash.h" +#include "virstring.h" +#include "qemusecuritytest.h" +#include "security/security_manager.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +/* Okay, here's the deal. The qemusecuritytest calls several + * virSecurityManager public APIs in order to check if XATTRs + * work as expected. Therefore there is a lot we have to mock + * (chown, stat, XATTR APIs, etc.). Since the test won't run as + * root chown() would fail, therefore we have to keep everything + * in memory. By default, all files are owned by 1:2. + * By the way, since there are some cases where real stat needs + * to be called, the mocked functions are effective only if + * $ENVVAR is set. + */ + +#define DEFAULT_UID 1 +#define DEFAULT_GID 2 + + +static int (*real_chown)(const char *path, uid_t uid, gid_t gid); +static int (*real_lstat)(const char *path, struct stat *sb); +static int (*real___lxstat)(int ver, const char *path, struct stat *sb); +static int (*real_stat)(const char *path, struct stat *sb); +static int (*real___xstat)(int ver, const char *path, struct stat *sb); +static int (*real_open)(const char *path, int flags, ...); +static int (*real_close)(int fd); + + +/* Global mutex to avoid races */ +virMutex m =3D VIR_MUTEX_INITIALIZER; + +/* Hash table to store XATTRs for paths. For simplicity, key is + * "$path:$name" and value is just XATTR "$value". We don't need + * to list XATTRs a path has, therefore we don't need something + * more clever. */ +virHashTablePtr xattr_paths =3D NULL; + + +/* The UID:GID is stored in a hash table. Again, for simplicity, + * the path is the key and the value is an uint32_t , where + * the lower half is UID and the higher is GID. */ +virHashTablePtr chown_paths =3D NULL; + + +static void +init_hash(void) +{ + /* The reason the init is split is that virHash calls + * virRandomBits() which in turn calls a gnutls function. + * However, when gnutls is initializing itself it calls + * stat() so we would call a gnutls function before it is + * initialized which will lead to a crash. + */ + + if (xattr_paths) + return; + + if (!(xattr_paths =3D virHashCreate(10, virHashValueFree))) { + fprintf(stderr, "Unable to create hash table for XATTR paths\n"); + abort(); + } + + if (!(chown_paths =3D virHashCreate(10, virHashValueFree))) { + fprintf(stderr, "Unable to create hash table for chowned paths\n"); + abort(); + } +} + + +static void +init_syms(void) +{ + if (real_chown) + return; + + VIR_MOCK_REAL_INIT(chown); + VIR_MOCK_REAL_INIT_ALT(lstat, __lxstat); + VIR_MOCK_REAL_INIT_ALT(stat, __xstat); + VIR_MOCK_REAL_INIT(open); + VIR_MOCK_REAL_INIT(close); + + /* Intentionally not calling init_hash() here */ +} + + +static char * +get_key(const char *path, + const char *name) +{ + char *ret; + + if (virAsprintf(&ret, "%s:%s", path, name) < 0) { + fprintf(stderr, "Unable to create hash table key\n"); + abort(); + } + + return ret; +} + + +int +virFileGetXAttr(const char *path, + const char *name, + char **value) +{ + int ret =3D -1; + char *key; + char *val; + + key =3D get_key(path, name); + + virMutexLock(&m); + init_syms(); + init_hash(); + + if (!(val =3D virHashLookup(xattr_paths, key))) { + errno =3D ENODATA; + goto cleanup; + } + + if (VIR_STRDUP(*value, val) < 0) + goto cleanup; + + ret =3D 0; + cleanup: + virMutexUnlock(&m); + VIR_FREE(key); + return ret; +} + + +int virFileSetXAttr(const char *path, + const char *name, + const char *value) +{ + int ret =3D -1; + char *key; + char *val; + + key =3D get_key(path, name); + if (VIR_STRDUP(val, value) < 0) + return -1; + + virMutexLock(&m); + init_syms(); + init_hash(); + + if (virHashUpdateEntry(xattr_paths, key, val) < 0) + goto cleanup; + val =3D NULL; + + ret =3D 0; + cleanup: + virMutexUnlock(&m); + VIR_FREE(val); + VIR_FREE(key); + return ret; +} + + +int virFileRemoveXAttr(const char *path, + const char *name) +{ + int ret =3D -1; + char *key; + + key =3D get_key(path, name); + + virMutexLock(&m); + init_syms(); + init_hash(); + + if ((ret =3D virHashRemoveEntry(xattr_paths, key)) < 0) + errno =3D ENODATA; + + virMutexUnlock(&m); + VIR_FREE(key); + return ret; +} + + +static int +mock_stat(const char *path, + struct stat *sb) +{ + uint32_t *val; + + virMutexLock(&m); + init_hash(); + + memset(sb, 0, sizeof(*sb)); + + sb->st_mode =3D S_IFREG | 0666; + sb->st_size =3D 123456; + sb->st_ino =3D 1; + + if (!(val =3D virHashLookup(chown_paths, path))) { + /* New path. Set the defaults */ + sb->st_uid =3D DEFAULT_UID; + sb->st_gid =3D DEFAULT_GID; + } else { + /* Known path. Set values passed to chown() earlier */ + sb->st_uid =3D *val % 16; + sb->st_gid =3D *val >> 16; + } + + virMutexUnlock(&m); + + return 0; +} + + +static int +mock_chown(const char *path, + uid_t uid, + gid_t gid) +{ + uint32_t *val =3D NULL; + int ret =3D -1; + + if (gid >> 16 || uid >> 16) { + fprintf(stderr, "Attempt to set too high UID or GID: %lld %lld", + (unsigned long long) uid, (unsigned long long) gid); + abort(); + } + + if (VIR_ALLOC(val) < 0) + return -1; + + *val =3D (gid << 16) + uid; + + virMutexLock(&m); + init_hash(); + + if (virHashUpdateEntry(chown_paths, path, val) < 0) + goto cleanup; + val =3D NULL; + + ret =3D 0; + cleanup: + virMutexUnlock(&m); + VIR_FREE(val); + return ret; +} + + +#ifdef HAVE___LXSTAT +int +__lxstat(int ver, const char *path, struct stat *sb) +{ + int ret; + + init_syms(); + + if (getenv(ENVVAR)) + ret =3D mock_stat(path, sb); + else + ret =3D real___lxstat(ver, path, sb); + + return ret; +} +#endif /* HAVE___LXSTAT */ + +int +lstat(const char *path, struct stat *sb) +{ + int ret; + + init_syms(); + + if (getenv(ENVVAR)) + ret =3D mock_stat(path, sb); + else + ret =3D real_lstat(path, sb); + + return ret; +} + +#ifdef HAVE___XSTAT +int +__xstat(int ver, const char *path, struct stat *sb) +{ + int ret; + + init_syms(); + + if (getenv(ENVVAR)) + ret =3D mock_stat(path, sb); + else + ret =3D real___xstat(ver, path, sb); + + return ret; +} +#endif /* HAVE___XSTAT */ + +int +stat(const char *path, struct stat *sb) +{ + int ret; + + init_syms(); + + if (getenv(ENVVAR)) + ret =3D mock_stat(path, sb); + else + ret =3D real_stat(path, sb); + + return ret; +} + + +int +chown(const char *path, uid_t uid, gid_t gid) +{ + int ret; + + init_syms(); + + if (getenv(ENVVAR)) + ret =3D mock_chown(path, uid, gid); + else + ret =3D real_chown(path, uid, gid); + + return ret; +} + + +int +open(const char *path, int flags, ...) +{ + int ret; + + init_syms(); + + if (getenv(ENVVAR)) { + ret =3D 42; /* Some dummy FD */ + } else if (flags & O_CREAT) { + va_list ap; + mode_t mode; + va_start(ap, flags); + mode =3D (mode_t) va_arg(ap, int); + va_end(ap); + ret =3D real_open(path, flags, mode); + } else { + ret =3D real_open(path, flags); + } + + return ret; +} + + +int +close(int fd) +{ + int ret; + + if (fd =3D=3D 42 && getenv(ENVVAR)) + ret =3D 0; + else + ret =3D real_close(fd); + + return ret; +} + + +int virFileLock(int fd ATTRIBUTE_UNUSED, + bool shared ATTRIBUTE_UNUSED, + off_t start ATTRIBUTE_UNUSED, + off_t len ATTRIBUTE_UNUSED, + bool waitForLock ATTRIBUTE_UNUSED) +{ + return 0; +} + + +int virFileUnlock(int fd ATTRIBUTE_UNUSED, + off_t start ATTRIBUTE_UNUSED, + off_t len ATTRIBUTE_UNUSED) +{ + return 0; +} + + +static int +checkOwner(void *payload, + const void *name, + void *data) +{ + bool *chown_fail =3D data; + uint32_t owner =3D *((uint32_t*) payload); + + if (owner % 16 !=3D DEFAULT_UID || + owner >> 16 !=3D DEFAULT_GID) { + fprintf(stderr, + "Path %s wasn't restored back to its original owner\n", + (const char *) name); + *chown_fail =3D false; + } + + return 0; +} + + +static int +printXATTR(void *payload, + const void *name, + void *data) +{ + bool *xattr_fail =3D data; + + /* The fact that we are in this function means that there are + * some XATTRs left behind. This is enough to claim an error. */ + *xattr_fail =3D false; + + /* Hash table key consists of "$path:$xattr_name", xattr + * value is then the value stored in the hash table. */ + printf("key=3D%s val=3D%s\n", (const char *) name, (const char *) payl= oad); + return 0; +} + + +int checkPaths(void) +{ + int ret =3D -1; + bool chown_fail =3D false; + bool xattr_fail =3D false; + + virMutexLock(&m); + init_hash(); + + if ((virHashForEach(chown_paths, checkOwner, &chown_fail)) < 0) + goto cleanup; + + if ((virHashForEach(xattr_paths, printXATTR, &xattr_fail)) < 0) + goto cleanup; + + if (chown_fail || xattr_fail) + goto cleanup; + + ret =3D 0; + cleanup: + virHashRemoveAll(chown_paths); + virHashRemoveAll(xattr_paths); + virMutexUnlock(&m); + return ret; +} diff --git a/tests/qemusecuritytest.c b/tests/qemusecuritytest.c new file mode 100644 index 0000000000..4d835f83e1 --- /dev/null +++ b/tests/qemusecuritytest.c @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + * Author: Michal Privoznik + */ + +#include + +#include "qemusecuritytest.h" +#include "testutils.h" +#include "testutilsqemu.h" +#include "security/security_manager.h" +#include "conf/domain_conf.h" +#include "qemu/qemu_domain.h" +#include "qemu/qemu_security.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +struct testData { + virQEMUDriverPtr driver; + const char *file; /* file name to load VM def XML from; qemuxml2argvda= ta/ */ +}; + + +static int +prepareObjects(virQEMUDriverPtr driver, + const char *xmlname, + virDomainObjPtr *vm) +{ + qemuDomainObjPrivatePtr priv; + char *filename =3D NULL; + char *domxml =3D NULL; + int ret =3D -1; + + if (virAsprintf(&filename, "%s/qemuxml2argvdata/%s.xml", abs_srcdir, x= mlname) < 0) + return -1; + + if (virTestLoadFile(filename, &domxml) < 0) + goto cleanup; + + if (!(*vm =3D virDomainObjNew(driver->xmlopt))) + goto cleanup; + + (*vm)->pid =3D -1; + priv =3D (*vm)->privateData; + priv->chardevStdioLogd =3D false; + priv->rememberOwner =3D true; + + if (!(priv->qemuCaps =3D virQEMUCapsNew())) + goto cleanup; + + virQEMUCapsSetList(priv->qemuCaps, + QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, + QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, + QEMU_CAPS_DEVICE_IOH3420, + QEMU_CAPS_DEVICE_PCI_BRIDGE, + QEMU_CAPS_DEVICE_PCI_BRIDGE, + QEMU_CAPS_DEVICE_VIRTIO_MMIO, + QEMU_CAPS_DEVICE_VIRTIO_RNG, + QEMU_CAPS_OBJECT_GPEX, + QEMU_CAPS_OBJECT_RNG_RANDOM, + QEMU_CAPS_VIRTIO_SCSI, + QEMU_CAPS_LAST); + + if (qemuTestCapsCacheInsert(driver->qemuCapsCache, priv->qemuCaps) < 0) + goto cleanup; + + if (!((*vm)->def =3D virDomainDefParseString(domxml, + driver->caps, + driver->xmlopt, + NULL, + 0))) + goto cleanup; + + ret =3D 0; + cleanup: + if (ret < 0) { + virObjectUnref(*vm); + *vm =3D NULL; + } + VIR_FREE(domxml); + VIR_FREE(filename); + return ret; +} + + +static int +testDomain(const void *opaque) +{ + const struct testData *data =3D opaque; + virSecurityManagerPtr securityManager =3D NULL; + virDomainObjPtr vm =3D NULL; + int ret =3D -1; + + if (prepareObjects(data->driver, data->file, &vm) < 0) + return -1; + + /* Mocking is enabled only when this env variable is set. + * See mock code for explanation. */ + if (setenv(ENVVAR, "1", 0) < 0) + goto cleanup; + + if (qemuSecuritySetAllLabel(data->driver, vm, NULL) < 0) + goto cleanup; + + qemuSecurityRestoreAllLabel(data->driver, vm, false); + + if (checkPaths() < 0) + goto cleanup; + + ret =3D 0; + cleanup: + unsetenv(ENVVAR); + virObjectUnref(vm); + virObjectUnref(securityManager); + return ret; +} + + +static int +mymain(void) +{ + virQEMUDriver driver; + int ret =3D 0; + + if (virInitialize() < 0 || + qemuTestDriverInit(&driver) < 0) + return -1; + + /* Now fix the secdriver */ + virObjectUnref(driver.securityManager); + if (!(driver.securityManager =3D virSecurityManagerNewDAC("test", 1000= , 1000, + VIR_SECURITY_M= ANAGER_PRIVILEGED | + VIR_SECURITY_M= ANAGER_DYNAMIC_OWNERSHIP, + NULL))) { + virFilePrintf(stderr, "Cannot initialize DAC security driver"); + ret =3D -1; + goto cleanup; + } + +#define DO_TEST_DOMAIN(f) \ + do { \ + struct testData data =3D {.driver =3D &driver, .file =3D f}; \ + if (virTestRun(f, testDomain, &data) < 0) \ + ret =3D -1; \ + } while (0) + + DO_TEST_DOMAIN("disk-virtio"); + DO_TEST_DOMAIN("pci-bridge-many-disks"); + DO_TEST_DOMAIN("arm-virt-virtio"); + DO_TEST_DOMAIN("aarch64-virtio-pci-manual-addresses"); + DO_TEST_DOMAIN("acpi-table"); + + cleanup: + qemuTestDriverFree(&driver); + return ret; +} + +VIR_TEST_MAIN(mymain) diff --git a/tests/qemusecuritytest.h b/tests/qemusecuritytest.h new file mode 100644 index 0000000000..235e05fec7 --- /dev/null +++ b/tests/qemusecuritytest.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + * Author: Michal Privoznik + */ + +#ifndef __QEMU_SECURITY_TEST_H__ +# define __QEMU_SECURITY_TEST_H__ + +# define ENVVAR "LIBVIRT_QEMU_SECURITY_TEST" + +extern int checkPaths(void); + +#endif /* __QEMU_SECURITY_TEST_H__ */ --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1544618509071776.9120808032854; Wed, 12 Dec 2018 04:41:49 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D91F488318; Wed, 12 Dec 2018 12:41:47 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A62ED1A7CE; Wed, 12 Dec 2018 12:41:47 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 5386B184B54D; Wed, 12 Dec 2018 12:41:47 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCfc79017610 for ; Wed, 12 Dec 2018 07:41:38 -0500 Received: by smtp.corp.redhat.com (Postfix) id C37B85D73F; Wed, 12 Dec 2018 12:41:38 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id 453295D760 for ; Wed, 12 Dec 2018 12:41:36 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:41:01 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 17/18] tools: Provide a script to recover fubar'ed XATTRs setup X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 12 Dec 2018 12:41:48 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Our code is not bug free. The refcounting I introduced will almost certainly not work in some use cases. Provide a script that will remove all the XATTRs set by libvirt so that it can start cleanly. Signed-off-by: Michal Privoznik Reviewed-by: J=C3=A1n Tomko --- tools/Makefile.am | 1 + tools/libvirt_recover_xattrs.sh | 96 +++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100755 tools/libvirt_recover_xattrs.sh diff --git a/tools/Makefile.am b/tools/Makefile.am index f069167acc..1dc009c4fb 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -75,6 +75,7 @@ EXTRA_DIST =3D \ virt-login-shell.conf \ virsh-edit.c \ bash-completion/vsh \ + libvirt_recover_xattrs.sh \ $(PODFILES) \ $(MANINFILES) \ $(NULL) diff --git a/tools/libvirt_recover_xattrs.sh b/tools/libvirt_recover_xattrs= .sh new file mode 100755 index 0000000000..69dfca0160 --- /dev/null +++ b/tools/libvirt_recover_xattrs.sh @@ -0,0 +1,96 @@ +#!/bin/bash + +function die { + echo $@ >&2 + exit 1 +} + +function show_help { + cat << EOF +Usage: ${0##*/} -[hqn] [PATH] + +Clear out any XATTRs set by libvirt on all files that have them. +The idea is to reset refcounting, should it break. + + -h display this help and exit + -q quiet (don't print which files are being fixed) + -n dry run; don't remove any XATTR just report the file name + +PATH can be specified to refine search to only to given path +instead of whole root ('/'), which is the default. +EOF +} + +QUIET=3D0 +DRY_RUN=3D0 +P=3D"/" + +# So far only qemu and lxc drivers use security driver. +URI=3D("qemu:///system" + "qemu:///session" + "lxc:///system") + +LIBVIRT_XATTR_PREFIX=3D"trusted.libvirt.security" + +if [ `whoami` !=3D "root" ]; then + die "Must be run as root" +fi + +while getopts hqn opt; do + case $opt in + h) + show_help + exit 0 + ;; + q) + QUIET=3D1 + ;; + n) + DRY_RUN=3D1 + ;; + *) + show_help >&2 + exit 1 + ;; + esac +done + +shift $((OPTIND - 1)) +if [ $# -gt 0 ]; then + P=3D$1 +fi + +if [ ${DRY_RUN} -eq 0 ]; then + for u in ${URI[*]} ; do + if [ -n "`virsh -q -c $u list 2>/dev/null`" ]; then + die "There are still some domains running for $u" + fi + done +fi + + +# On Linux we use 'trusted' namespace, on FreeBSD we use 'system' +# as there is no 'trusted'. +XATTRS=3D("trusted.libvirt.security.dac" + "trusted.libvirt.security.ref_dac" + "trusted.libvirt.security.selinux" + "trusted.libvirt.security.ref_selinux", + "system.libvirt.security.dac" + "system.libvirt.security.ref_dac" + "system.libvirt.security.selinux" + "system.libvirt.security.ref_selinux") + +for i in $(getfattr -R -d -m ${LIBVIRT_XATTR_PREFIX} --absolute-names ${P}= 2>/dev/null | grep "^# file:" | cut -d':' -f 2); do + if [ ${DRY_RUN} -ne 0 ]; then + echo $i + getfattr -d -m ${LIBVIRT_XATTR_PREFIX} $i + continue + fi + + if [ ${QUIET} -eq 0 ]; then + echo "Fixing $i"; + fi + for x in ${XATTRS[*]}; do + setfattr -x $x $i + done +done --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue May 7 06:16:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 154461851515850.98498798031278; Wed, 12 Dec 2018 04:41:55 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EC0423002F86; Wed, 12 Dec 2018 12:41:53 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id BAC525D756; Wed, 12 Dec 2018 12:41:53 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 77FBE3D3A2; Wed, 12 Dec 2018 12:41:53 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBCCffwp017620 for ; Wed, 12 Dec 2018 07:41:41 -0500 Received: by smtp.corp.redhat.com (Postfix) id 5FA2D5D762; Wed, 12 Dec 2018 12:41:41 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id DAC455D756 for ; Wed, 12 Dec 2018 12:41:38 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 12 Dec 2018 13:41:02 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 18/18] qemu.conf: Allow users to enable/disable label remembering X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Wed, 12 Dec 2018 12:41:54 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Signed-off-by: Michal Privoznik Reviewed-by: J=C3=A1n Tomko --- src/qemu/libvirtd_qemu.aug | 1 + src/qemu/qemu.conf | 4 ++++ src/qemu/qemu_conf.c | 4 ++++ src/qemu/test_libvirtd_qemu.aug.in | 1 + 4 files changed, 10 insertions(+) diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index ddc4bbfd1d..8a5b39e568 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -71,6 +71,7 @@ module Libvirtd_qemu =3D | str_entry "user" | str_entry "group" | bool_entry "dynamic_ownership" + | bool_entry "remember_owner" | str_array_entry "cgroup_controllers" | str_array_entry "cgroup_device_acl" | int_entry "seccomp_sandbox" diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 8391332cb4..29093f6329 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -450,6 +450,10 @@ # Set to 0 to disable file ownership changes. #dynamic_ownership =3D 1 =20 +# Whether libvirt should remember and restore the original +# ownership over files it is relabeling. Defaults to 1, set +# to 0 to disable the feature. +#remember_owner =3D 1 =20 # What cgroup controllers to make use of with QEMU guests # diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index a946b05d5d..89491a37b7 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -147,6 +147,7 @@ virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool priv= ileged) cfg->group =3D (gid_t)-1; } cfg->dynamicOwnership =3D privileged; + cfg->rememberOwner =3D true; =20 cfg->cgroupControllers =3D -1; /* -1 =3D=3D auto-detect */ =20 @@ -730,6 +731,9 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr = cfg, if (virConfGetValueBool(conf, "dynamic_ownership", &cfg->dynamicOwners= hip) < 0) goto cleanup; =20 + if (virConfGetValueBool(conf, "remember_owner", &cfg->rememberOwner) <= 0) + goto cleanup; + if (virConfGetValueStringList(conf, "cgroup_controllers", false, &controllers) < 0) goto cleanup; diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qe= mu.aug.in index f1e8806ad2..92a8ae1192 100644 --- a/src/qemu/test_libvirtd_qemu.aug.in +++ b/src/qemu/test_libvirtd_qemu.aug.in @@ -43,6 +43,7 @@ module Test_libvirtd_qemu =3D { "user" =3D "root" } { "group" =3D "root" } { "dynamic_ownership" =3D "1" } +{ "remember_owner" =3D "1" } { "cgroup_controllers" { "1" =3D "cpu" } { "2" =3D "devices" } --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list