[meta-virtualization] [PATCH] libvirt: Try to fix selinux/securityfs mount handling in LXC

Bruce Ashfield bruce.ashfield at gmail.com
Thu Oct 10 20:33:32 PDT 2013


On Tue, Oct 8, 2013 at 10:17 AM, Bogdan Purcareata
<bogdan.purcareata at freescale.com> wrote:
> The current behavior for libvirt containers is to
> configure a set of "basic" mounts in the new container
> environment by default. Some of these mounts, such as
> securityfs or selinux, might not have kernel support on
> all running platforms. The added patchset implements
> proper handling for this case and makes some additional
> cleanups and refactoring.
>
> The patchset is taken from the upstream libvirt mailing
> list. Please refer to:
>
> https://www.redhat.com/archives/libvir-list/2013-October/msg00270.html

Looks fine to me, let's see how it behaves in the layer :)

merged.

Bruce

>
> Signed-off-by: Bogdan Purcareata <bogdan.purcareata at freescale.com>
> ---
>  .../0001-Add-virFileIsMountPoint-function.patch    | 135 +++++++++++++++++++++
>  ...2-Remove-unused-opts-field-from-LXC-basic.patch |  97 +++++++++++++++
>  ...path-variable-in-lxcContainerMountBasicFS.patch |  78 ++++++++++++
>  ...duplicate-entries-in-lxcBasicMounts-array.patch | 117 ++++++++++++++++++
>  ...cMounts-to-control-use-in-user-namespaces.patch |  83 +++++++++++++
>  ...y-files-which-are-not-mounted-on-the-host.patch | 106 ++++++++++++++++
>  recipes-extended/libvirt/libvirt_1.1.2.bb          |   6 +
>  7 files changed, 622 insertions(+)
>  create mode 100644 recipes-extended/libvirt/libvirt/0001-Add-virFileIsMountPoint-function.patch
>  create mode 100644 recipes-extended/libvirt/libvirt/0002-Remove-unused-opts-field-from-LXC-basic.patch
>  create mode 100644 recipes-extended/libvirt/libvirt/0003-Remove-pointless-srcpath-variable-in-lxcContainerMountBasicFS.patch
>  create mode 100644 recipes-extended/libvirt/libvirt/0004-Remove-duplicate-entries-in-lxcBasicMounts-array.patch
>  create mode 100644 recipes-extended/libvirt/libvirt/0005-Add-flag-to-lxcBasicMounts-to-control-use-in-user-namespaces.patch
>  create mode 100644 recipes-extended/libvirt/libvirt/0006-Skip-any-files-which-are-not-mounted-on-the-host.patch
>
> diff --git a/recipes-extended/libvirt/libvirt/0001-Add-virFileIsMountPoint-function.patch b/recipes-extended/libvirt/libvirt/0001-Add-virFileIsMountPoint-function.patch
> new file mode 100644
> index 0000000..0affcbe
> --- /dev/null
> +++ b/recipes-extended/libvirt/libvirt/0001-Add-virFileIsMountPoint-function.patch
> @@ -0,0 +1,135 @@
> +From: "Daniel P. Berrange" <berrange at redhat.com>
> +To: libvir-list at redhat.com
> +Date: Mon,  7 Oct 2013 14:06:46 +0100
> +Message-Id: <1381151211-27111-2-git-send-email-berrange at redhat.com>
> +In-Reply-To: <1381151211-27111-1-git-send-email-berrange at redhat.com>
> +References: <1381151211-27111-1-git-send-email-berrange at redhat.com>
> +X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25
> +X-loop: libvir-list at redhat.com
> +Subject: [libvirt] [PATCH 1/6] Add virFileIsMountPoint function
> +X-BeenThere: libvir-list at redhat.com
> +X-Mailman-Version: 2.1.12
> +Precedence: junk
> +List-Id: Development discussions about the libvirt library & tools
> +       <libvir-list.redhat.com>
> +List-Unsubscribe: <https://www.redhat.com/mailman/options/libvir-list>,
> +       <mailto:libvir-list-request at redhat.com?subject=unsubscribe>
> +List-Archive: <https://www.redhat.com/archives/libvir-list>
> +List-Post: <mailto:libvir-list at redhat.com>
> +List-Help: <mailto:libvir-list-request at redhat.com?subject=help>
> +List-Subscribe: <https://www.redhat.com/mailman/listinfo/libvir-list>,
> +       <mailto:libvir-list-request at redhat.com?subject=subscribe>
> +X-List-Received-Date: Mon, 07 Oct 2013 13:06:56 -0000
> +
> +From: "Daniel P. Berrange" <berrange at redhat.com>
> +
> +Add a function for efficiently checking if a path is a filesystem
> +mount point.
> +
> +NB will not work for bind mounts, only true filesystem mounts.
> +
> +Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> +---
> + src/libvirt_private.syms |  1 +
> + src/util/virfile.c       | 58 ++++++++++++++++++++++++++++++++++++++++++++++++
> + src/util/virfile.h       |  2 ++
> + 3 files changed, 61 insertions(+)
> +
> +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> +index fe40834..31fa604 100644
> +--- a/src/libvirt_private.syms
> ++++ b/src/libvirt_private.syms
> +@@ -1182,6 +1182,7 @@ virFileIsAbsPath;
> + virFileIsDir;
> + virFileIsExecutable;
> + virFileIsLink;
> ++virFileIsMountPoint;
> + virFileLinkPointsTo;
> + virFileLock;
> + virFileLoopDeviceAssociate;
> +diff --git a/src/util/virfile.c b/src/util/virfile.c
> +index e10de5a..fa21aeb 100644
> +--- a/src/util/virfile.c
> ++++ b/src/util/virfile.c
> +@@ -1513,6 +1513,64 @@ virFileIsExecutable(const char *file)
> +     return false;
> + }
> +
> ++
> ++/*
> ++ * Check that a file refers to a mount point. Trick is that for
> ++ * a mount point, the st_dev field will differ from the parent
> ++ * directory.
> ++ *
> ++ * Note that this will not detect bind mounts of dirs/files,
> ++ * only true filesystem mounts.
> ++ */
> ++int virFileIsMountPoint(const char *file)
> ++{
> ++    char *parent = NULL;
> ++    char *tmp;
> ++    int ret = -1;
> ++    struct stat sb1, sb2;
> ++
> ++    if (VIR_STRDUP_QUIET(parent, file) < 0)
> ++        goto cleanup;
> ++
> ++    if (!(tmp = strrchr(parent, '/'))) {
> ++        virReportError(VIR_ERR_INTERNAL_ERROR,
> ++                       _("Could not find '/' in '%s'"),
> ++                       file);
> ++        goto cleanup;
> ++    }
> ++
> ++    *tmp = '\0';
> ++
> ++    VIR_DEBUG("Comparing '%s' to '%s'", file, parent);
> ++
> ++    if (stat(file, &sb1) < 0) {
> ++        if (errno == ENOENT)
> ++            ret = 0;
> ++        else
> ++            virReportSystemError(errno,
> ++                                 _("Cannot stat '%s'"),
> ++                                 file);
> ++        goto cleanup;
> ++    }
> ++
> ++    if (stat(parent, &sb2) < 0) {
> ++        virReportSystemError(errno,
> ++                             _("Cannot stat '%s'"),
> ++                             parent);
> ++        goto cleanup;
> ++    }
> ++
> ++    if (!S_ISDIR(sb1.st_mode))
> ++        return false;
> ++
> ++    ret = sb1.st_dev != sb2.st_dev;
> ++    VIR_DEBUG("Is mount %d", ret);
> ++
> ++ cleanup:
> ++    VIR_FREE(parent);
> ++    return ret;
> ++}
> ++
> + #ifndef WIN32
> + /* Check that a file is accessible under certain
> +  * user & gid.
> +diff --git a/src/util/virfile.h b/src/util/virfile.h
> +index 72d35ce..ff84719 100644
> +--- a/src/util/virfile.h
> ++++ b/src/util/virfile.h
> +@@ -156,6 +156,8 @@ bool virFileIsDir (const char *file) ATTRIBUTE_NONNULL(1);
> + bool virFileExists(const char *file) ATTRIBUTE_NONNULL(1);
> + bool virFileIsExecutable(const char *file) ATTRIBUTE_NONNULL(1);
> +
> ++int virFileIsMountPoint(const char *file) ATTRIBUTE_NONNULL(1);
> ++
> + char *virFileSanitizePath(const char *path);
> +
> + enum {
> +--
> +1.8.3.1
> +
> +
> diff --git a/recipes-extended/libvirt/libvirt/0002-Remove-unused-opts-field-from-LXC-basic.patch b/recipes-extended/libvirt/libvirt/0002-Remove-unused-opts-field-from-LXC-basic.patch
> new file mode 100644
> index 0000000..2a3d3ef
> --- /dev/null
> +++ b/recipes-extended/libvirt/libvirt/0002-Remove-unused-opts-field-from-LXC-basic.patch
> @@ -0,0 +1,97 @@
> +From: "Daniel P. Berrange" <berrange at redhat.com>
> +To: libvir-list at redhat.com
> +Date: Mon,  7 Oct 2013 14:06:47 +0100
> +Message-Id: <1381151211-27111-3-git-send-email-berrange at redhat.com>
> +In-Reply-To: <1381151211-27111-1-git-send-email-berrange at redhat.com>
> +References: <1381151211-27111-1-git-send-email-berrange at redhat.com>
> +X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25
> +X-loop: libvir-list at redhat.com
> +Subject: [libvirt] [PATCH 2/6] Remove unused 'opts' field from LXC basic
> +       mounts struct
> +X-BeenThere: libvir-list at redhat.com
> +X-Mailman-Version: 2.1.12
> +Precedence: junk
> +List-Id: Development discussions about the libvirt library & tools
> +       <libvir-list.redhat.com>
> +List-Unsubscribe: <https://www.redhat.com/mailman/options/libvir-list>,
> +       <mailto:libvir-list-request at redhat.com?subject=unsubscribe>
> +List-Archive: <https://www.redhat.com/archives/libvir-list>
> +List-Post: <mailto:libvir-list at redhat.com>
> +List-Help: <mailto:libvir-list-request at redhat.com?subject=help>
> +List-Subscribe: <https://www.redhat.com/mailman/listinfo/libvir-list>,
> +       <mailto:libvir-list-request at redhat.com?subject=subscribe>
> +X-List-Received-Date: Mon, 07 Oct 2013 13:06:57 -0000
> +
> +From: "Daniel P. Berrange" <berrange at redhat.com>
> +
> +The virLXCBasicMountInfo struct contains a 'char *opts'
> +field passed onto the mount() syscall. Every entry in the
> +list sets this to NULL though, so it can be removed to
> +simplify life.
> +
> +Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> +---
> + src/lxc/lxc_container.c | 29 ++++++++++++++---------------
> + 1 file changed, 14 insertions(+), 15 deletions(-)
> +
> +diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
> +index b1f429c..3c89ed7 100644
> +--- a/src/lxc/lxc_container.c
> ++++ b/src/lxc/lxc_container.c
> +@@ -752,7 +752,6 @@ typedef struct {
> +     const char *src;
> +     const char *dst;
> +     const char *type;
> +-    const char *opts;
> +     int mflags;
> + } virLXCBasicMountInfo;
> +
> +@@ -763,16 +762,16 @@ static const virLXCBasicMountInfo lxcBasicMounts[] = {
> +      * mount point in the main OS becomes readonly too which is not what
> +      * we want. Hence some things have two entries here.
> +      */
> +-    { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV },
> +-    { "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND },
> +-    { "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
> +-    { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV },
> +-    { "sysfs", "/sys", "sysfs", NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
> +-    { "securityfs", "/sys/kernel/security", "securityfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV },
> +-    { "securityfs", "/sys/kernel/security", "securityfs", NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
> ++    { "proc", "/proc", "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV },
> ++    { "/proc/sys", "/proc/sys", NULL, MS_BIND },
> ++    { "/proc/sys", "/proc/sys", NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
> ++    { "sysfs", "/sys", "sysfs", MS_NOSUID|MS_NOEXEC|MS_NODEV },
> ++    { "sysfs", "/sys", "sysfs", MS_BIND|MS_REMOUNT|MS_RDONLY },
> ++    { "securityfs", "/sys/kernel/security", "securityfs", MS_NOSUID|MS_NOEXEC|MS_NODEV },
> ++    { "securityfs", "/sys/kernel/security", "securityfs", MS_BIND|MS_REMOUNT|MS_RDONLY },
> + #if WITH_SELINUX
> +-    { SELINUX_MOUNT, SELINUX_MOUNT, "selinuxfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV },
> +-    { SELINUX_MOUNT, SELINUX_MOUNT, NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
> ++    { SELINUX_MOUNT, SELINUX_MOUNT, "selinuxfs", MS_NOSUID|MS_NOEXEC|MS_NODEV },
> ++    { SELINUX_MOUNT, SELINUX_MOUNT, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
> + #endif
> + };
> +
> +@@ -882,13 +881,13 @@ static int lxcContainerMountBasicFS(bool userns_enabled)
> +             goto cleanup;
> +         }
> +
> +-        VIR_DEBUG("Mount %s on %s type=%s flags=%x, opts=%s",
> +-                  srcpath, mnt->dst, mnt->type, mnt->mflags, mnt->opts);
> +-        if (mount(srcpath, mnt->dst, mnt->type, mnt->mflags, mnt->opts) < 0) {
> ++        VIR_DEBUG("Mount %s on %s type=%s flags=%x",
> ++                  srcpath, mnt->dst, mnt->type, mnt->mflags);
> ++        if (mount(srcpath, mnt->dst, mnt->type, mnt->mflags, NULL) < 0) {
> +             virReportSystemError(errno,
> +-                                 _("Failed to mount %s on %s type %s flags=%x opts=%s"),
> ++                                 _("Failed to mount %s on %s type %s flags=%x"),
> +                                  srcpath, mnt->dst, NULLSTR(mnt->type),
> +-                                 mnt->mflags, NULLSTR(mnt->opts));
> ++                                 mnt->mflags);
> +             goto cleanup;
> +         }
> +     }
> +--
> +1.8.3.1
> +
> +
> diff --git a/recipes-extended/libvirt/libvirt/0003-Remove-pointless-srcpath-variable-in-lxcContainerMountBasicFS.patch b/recipes-extended/libvirt/libvirt/0003-Remove-pointless-srcpath-variable-in-lxcContainerMountBasicFS.patch
> new file mode 100644
> index 0000000..5135fb0
> --- /dev/null
> +++ b/recipes-extended/libvirt/libvirt/0003-Remove-pointless-srcpath-variable-in-lxcContainerMountBasicFS.patch
> @@ -0,0 +1,78 @@
> +From: "Daniel P. Berrange" <berrange at redhat.com>
> +To: libvir-list at redhat.com
> +Date: Mon,  7 Oct 2013 14:06:48 +0100
> +Message-Id: <1381151211-27111-4-git-send-email-berrange at redhat.com>
> +In-Reply-To: <1381151211-27111-1-git-send-email-berrange at redhat.com>
> +References: <1381151211-27111-1-git-send-email-berrange at redhat.com>
> +X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25
> +X-loop: libvir-list at redhat.com
> +Subject: [libvirt] [PATCH 3/6] Remove pointless 'srcpath' variable in
> +       lxcContainerMountBasicFS
> +X-BeenThere: libvir-list at redhat.com
> +X-Mailman-Version: 2.1.12
> +Precedence: junk
> +List-Id: Development discussions about the libvirt library & tools
> +       <libvir-list.redhat.com>
> +List-Unsubscribe: <https://www.redhat.com/mailman/options/libvir-list>,
> +       <mailto:libvir-list-request at redhat.com?subject=unsubscribe>
> +List-Archive: <https://www.redhat.com/archives/libvir-list>
> +List-Post: <mailto:libvir-list at redhat.com>
> +List-Help: <mailto:libvir-list-request at redhat.com?subject=help>
> +List-Subscribe: <https://www.redhat.com/mailman/listinfo/libvir-list>,
> +       <mailto:libvir-list-request at redhat.com?subject=subscribe>
> +X-List-Received-Date: Mon, 07 Oct 2013 13:06:59 -0000
> +
> +From: "Daniel P. Berrange" <berrange at redhat.com>
> +
> +The 'srcpath' variable is initialized from 'mnt->src' and never
> +changed thereafter. Some places continue to use 'mnt->src' and
> +others use 'srcpath'. Remove the pointless 'srcpath' variable
> +and use 'mnt->src' everywhere.
> +
> +Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> +---
> + src/lxc/lxc_container.c | 13 +++++--------
> + 1 file changed, 5 insertions(+), 8 deletions(-)
> +
> +diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
> +index 3c89ed7..1b1c93b 100644
> +--- a/src/lxc/lxc_container.c
> ++++ b/src/lxc/lxc_container.c
> +@@ -853,16 +853,13 @@ static int lxcContainerMountBasicFS(bool userns_enabled)
> +
> +     for (i = 0; i < ARRAY_CARDINALITY(lxcBasicMounts); i++) {
> +         virLXCBasicMountInfo const *mnt = &lxcBasicMounts[i];
> +-        const char *srcpath = NULL;
> +
> +         VIR_DEBUG("Processing %s -> %s",
> +                   mnt->src, mnt->dst);
> +
> +-        srcpath = mnt->src;
> +-
> +         /* Skip if mount doesn't exist in source */
> +-        if ((srcpath[0] == '/') &&
> +-            (access(srcpath, R_OK) < 0))
> ++        if ((mnt->src[0] == '/') &&
> ++            (access(mnt->src, R_OK) < 0))
> +             continue;
> +
> + #if WITH_SELINUX
> +@@ -882,11 +879,11 @@ static int lxcContainerMountBasicFS(bool userns_enabled)
> +         }
> +
> +         VIR_DEBUG("Mount %s on %s type=%s flags=%x",
> +-                  srcpath, mnt->dst, mnt->type, mnt->mflags);
> +-        if (mount(srcpath, mnt->dst, mnt->type, mnt->mflags, NULL) < 0) {
> ++                  mnt->src, mnt->dst, mnt->type, mnt->mflags);
> ++        if (mount(mnt->src, mnt->dst, mnt->type, mnt->mflags, NULL) < 0) {
> +             virReportSystemError(errno,
> +                                  _("Failed to mount %s on %s type %s flags=%x"),
> +-                                 srcpath, mnt->dst, NULLSTR(mnt->type),
> ++                                 mnt->src, mnt->dst, NULLSTR(mnt->type),
> +                                  mnt->mflags);
> +             goto cleanup;
> +         }
> +--
> +1.8.3.1
> +
> +
> diff --git a/recipes-extended/libvirt/libvirt/0004-Remove-duplicate-entries-in-lxcBasicMounts-array.patch b/recipes-extended/libvirt/libvirt/0004-Remove-duplicate-entries-in-lxcBasicMounts-array.patch
> new file mode 100644
> index 0000000..c02295e
> --- /dev/null
> +++ b/recipes-extended/libvirt/libvirt/0004-Remove-duplicate-entries-in-lxcBasicMounts-array.patch
> @@ -0,0 +1,117 @@
> +From: "Daniel P. Berrange" <berrange at redhat.com>
> +To: libvir-list at redhat.com
> +Date: Mon,  7 Oct 2013 14:06:49 +0100
> +Message-Id: <1381151211-27111-5-git-send-email-berrange at redhat.com>
> +In-Reply-To: <1381151211-27111-1-git-send-email-berrange at redhat.com>
> +References: <1381151211-27111-1-git-send-email-berrange at redhat.com>
> +X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25
> +X-loop: libvir-list at redhat.com
> +Subject: [libvirt] [PATCH 4/6] Remove duplicate entries in lxcBasicMounts
> +       array
> +X-BeenThere: libvir-list at redhat.com
> +X-Mailman-Version: 2.1.12
> +Precedence: junk
> +List-Id: Development discussions about the libvirt library & tools
> +       <libvir-list.redhat.com>
> +List-Unsubscribe: <https://www.redhat.com/mailman/options/libvir-list>,
> +       <mailto:libvir-list-request at redhat.com?subject=unsubscribe>
> +List-Archive: <https://www.redhat.com/archives/libvir-list>
> +List-Post: <mailto:libvir-list at redhat.com>
> +List-Help: <mailto:libvir-list-request at redhat.com?subject=help>
> +List-Subscribe: <https://www.redhat.com/mailman/listinfo/libvir-list>,
> +       <mailto:libvir-list-request at redhat.com?subject=subscribe>
> +X-List-Received-Date: Mon, 07 Oct 2013 13:07:00 -0000
> +
> +From: "Daniel P. Berrange" <berrange at redhat.com>
> +
> +Currently the lxcBasicMounts array has separate entries for
> +most mounts, to reflect that we must do a separate mount
> +operation to make mounts read-only. Remove the duplicate
> +entries and instead set the MS_RDONLY flag against the main
> +entry. Then change lxcContainerMountBasicFS to look for the
> +MS_RDONLY flag, mask it out & do a separate bind mount.
> +
> +Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> +---
> + src/lxc/lxc_container.c | 44 +++++++++++++++++++++++++++-----------------
> + 1 file changed, 27 insertions(+), 17 deletions(-)
> +
> +diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
> +index 1b1c93b..a7f71ef 100644
> +--- a/src/lxc/lxc_container.c
> ++++ b/src/lxc/lxc_container.c
> +@@ -756,22 +756,12 @@ typedef struct {
> + } virLXCBasicMountInfo;
> +
> + static const virLXCBasicMountInfo lxcBasicMounts[] = {
> +-    /* When we want to make a bind mount readonly, for unknown reasons,
> +-     * it is currently necessary to bind it once, and then remount the
> +-     * bind with the readonly flag. If this is not done, then the original
> +-     * mount point in the main OS becomes readonly too which is not what
> +-     * we want. Hence some things have two entries here.
> +-     */
> +     { "proc", "/proc", "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV },
> +-    { "/proc/sys", "/proc/sys", NULL, MS_BIND },
> +-    { "/proc/sys", "/proc/sys", NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
> +-    { "sysfs", "/sys", "sysfs", MS_NOSUID|MS_NOEXEC|MS_NODEV },
> +-    { "sysfs", "/sys", "sysfs", MS_BIND|MS_REMOUNT|MS_RDONLY },
> +-    { "securityfs", "/sys/kernel/security", "securityfs", MS_NOSUID|MS_NOEXEC|MS_NODEV },
> +-    { "securityfs", "/sys/kernel/security", "securityfs", MS_BIND|MS_REMOUNT|MS_RDONLY },
> ++    { "/proc/sys", "/proc/sys", NULL, MS_BIND|MS_RDONLY },
> ++    { "sysfs", "/sys", "sysfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY },
> ++    { "securityfs", "/sys/kernel/security", "securityfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY },
> + #if WITH_SELINUX
> +-    { SELINUX_MOUNT, SELINUX_MOUNT, "selinuxfs", MS_NOSUID|MS_NOEXEC|MS_NODEV },
> +-    { SELINUX_MOUNT, SELINUX_MOUNT, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY },
> ++    { SELINUX_MOUNT, SELINUX_MOUNT, "selinuxfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY },
> + #endif
> + };
> +
> +@@ -852,6 +842,7 @@ static int lxcContainerMountBasicFS(bool userns_enabled)
> +     VIR_DEBUG("Mounting basic filesystems");
> +
> +     for (i = 0; i < ARRAY_CARDINALITY(lxcBasicMounts); i++) {
> ++        bool bindOverReadonly;
> +         virLXCBasicMountInfo const *mnt = &lxcBasicMounts[i];
> +
> +         VIR_DEBUG("Processing %s -> %s",
> +@@ -878,13 +869,32 @@ static int lxcContainerMountBasicFS(bool userns_enabled)
> +             goto cleanup;
> +         }
> +
> ++        /*
> ++         * We can't immediately set the MS_RDONLY flag when mounting filesystems
> ++         * because (in at least some kernel versions) this will propagate back
> ++         * to the original mount in the host OS, turning it readonly too. This
> ++         * We mount the filesystem in read-write mode initially, and then do a
> ++         * separate read-only bind mount on top of that.
> ++         */
> ++        bindOverReadonly = !!(mnt->mflags & MS_RDONLY);
> ++
> +         VIR_DEBUG("Mount %s on %s type=%s flags=%x",
> +-                  mnt->src, mnt->dst, mnt->type, mnt->mflags);
> +-        if (mount(mnt->src, mnt->dst, mnt->type, mnt->mflags, NULL) < 0) {
> ++                  mnt->src, mnt->dst, mnt->type, mnt->mflags & ~MS_RDONLY);
> ++        if (mount(mnt->src, mnt->dst, mnt->type, mnt->mflags & ~MS_RDONLY, NULL) < 0) {
> +             virReportSystemError(errno,
> +                                  _("Failed to mount %s on %s type %s flags=%x"),
> +                                  mnt->src, mnt->dst, NULLSTR(mnt->type),
> +-                                 mnt->mflags);
> ++                                 mnt->mflags & ~MS_RDONLY);
> ++            goto cleanup;
> ++        }
> ++
> ++        if (bindOverReadonly &&
> ++            mount(mnt->src, mnt->dst, NULL,
> ++                  MS_BIND|MS_REMOUNT|MS_RDONLY, NULL) < 0) {
> ++            virReportSystemError(errno,
> ++                                 _("Failed to re-mount %s on %s flags=%x"),
> ++                                 mnt->src, mnt->dst,
> ++                                 MS_BIND|MS_REMOUNT|MS_RDONLY);
> +             goto cleanup;
> +         }
> +     }
> +--
> +1.8.3.1
> +
> +
> diff --git a/recipes-extended/libvirt/libvirt/0005-Add-flag-to-lxcBasicMounts-to-control-use-in-user-namespaces.patch b/recipes-extended/libvirt/libvirt/0005-Add-flag-to-lxcBasicMounts-to-control-use-in-user-namespaces.patch
> new file mode 100644
> index 0000000..c9e0afc
> --- /dev/null
> +++ b/recipes-extended/libvirt/libvirt/0005-Add-flag-to-lxcBasicMounts-to-control-use-in-user-namespaces.patch
> @@ -0,0 +1,83 @@
> +From: "Daniel P. Berrange" <berrange at redhat.com>
> +To: libvir-list at redhat.com
> +Date: Mon,  7 Oct 2013 14:06:50 +0100
> +Message-Id: <1381151211-27111-6-git-send-email-berrange at redhat.com>
> +In-Reply-To: <1381151211-27111-1-git-send-email-berrange at redhat.com>
> +References: <1381151211-27111-1-git-send-email-berrange at redhat.com>
> +X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25
> +X-loop: libvir-list at redhat.com
> +Subject: [libvirt] [PATCH 5/6] Add flag to lxcBasicMounts to control use in
> +       user namespaces
> +X-BeenThere: libvir-list at redhat.com
> +X-Mailman-Version: 2.1.12
> +Precedence: junk
> +List-Id: Development discussions about the libvirt library & tools
> +       <libvir-list.redhat.com>
> +List-Unsubscribe: <https://www.redhat.com/mailman/options/libvir-list>,
> +       <mailto:libvir-list-request at redhat.com?subject=unsubscribe>
> +List-Archive: <https://www.redhat.com/archives/libvir-list>
> +List-Post: <mailto:libvir-list at redhat.com>
> +List-Help: <mailto:libvir-list-request at redhat.com?subject=help>
> +List-Subscribe: <https://www.redhat.com/mailman/listinfo/libvir-list>,
> +       <mailto:libvir-list-request at redhat.com?subject=subscribe>
> +X-List-Received-Date: Mon, 07 Oct 2013 13:07:02 -0000
> +
> +From: "Daniel P. Berrange" <berrange at redhat.com>
> +
> +Some mounts must be skipped if running inside a user namespace,
> +since the kernel forbids their use. Instead of strcmp'ing the
> +filesystem type in the body of the loop, set an explicit flag
> +in the lxcBasicMounts table.
> +
> +Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> +---
> + src/lxc/lxc_container.c | 17 ++++++++++-------
> + 1 file changed, 10 insertions(+), 7 deletions(-)
> +
> +diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
> +index a7f71ef..05190bf 100644
> +--- a/src/lxc/lxc_container.c
> ++++ b/src/lxc/lxc_container.c
> +@@ -753,15 +753,16 @@ typedef struct {
> +     const char *dst;
> +     const char *type;
> +     int mflags;
> ++    bool skipUserNS;
> + } virLXCBasicMountInfo;
> +
> + static const virLXCBasicMountInfo lxcBasicMounts[] = {
> +-    { "proc", "/proc", "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV },
> +-    { "/proc/sys", "/proc/sys", NULL, MS_BIND|MS_RDONLY },
> +-    { "sysfs", "/sys", "sysfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY },
> +-    { "securityfs", "/sys/kernel/security", "securityfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY },
> ++    { "proc", "/proc", "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, false },
> ++    { "/proc/sys", "/proc/sys", NULL, MS_BIND|MS_RDONLY, false },
> ++    { "sysfs", "/sys", "sysfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, false },
> ++    { "securityfs", "/sys/kernel/security", "securityfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, true },
> + #if WITH_SELINUX
> +-    { SELINUX_MOUNT, SELINUX_MOUNT, "selinuxfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY },
> ++    { SELINUX_MOUNT, SELINUX_MOUNT, "selinuxfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, true },
> + #endif
> + };
> +
> +@@ -855,12 +856,14 @@ static int lxcContainerMountBasicFS(bool userns_enabled)
> +
> + #if WITH_SELINUX
> +         if (STREQ(mnt->src, SELINUX_MOUNT) &&
> +-            (!is_selinux_enabled() || userns_enabled))
> ++            !is_selinux_enabled())
> +             continue;
> + #endif
> +
> +-        if (STREQ(mnt->src, "securityfs") && userns_enabled)
> ++        if (mnt->skipUserNS && userns_enabled) {
> ++            VIR_DEBUG("Skipping due to user ns enablement");
> +             continue;
> ++        }
> +
> +         if (virFileMakePath(mnt->dst) < 0) {
> +             virReportSystemError(errno,
> +--
> +1.8.3.1
> +
> +
> diff --git a/recipes-extended/libvirt/libvirt/0006-Skip-any-files-which-are-not-mounted-on-the-host.patch b/recipes-extended/libvirt/libvirt/0006-Skip-any-files-which-are-not-mounted-on-the-host.patch
> new file mode 100644
> index 0000000..a0ac414
> --- /dev/null
> +++ b/recipes-extended/libvirt/libvirt/0006-Skip-any-files-which-are-not-mounted-on-the-host.patch
> @@ -0,0 +1,106 @@
> +From: "Daniel P. Berrange" <berrange at redhat.com>
> +To: libvir-list at redhat.com
> +Date: Mon,  7 Oct 2013 14:06:51 +0100
> +Message-Id: <1381151211-27111-7-git-send-email-berrange at redhat.com>
> +In-Reply-To: <1381151211-27111-1-git-send-email-berrange at redhat.com>
> +References: <1381151211-27111-1-git-send-email-berrange at redhat.com>
> +X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25
> +X-loop: libvir-list at redhat.com
> +Subject: [libvirt] [PATCH 6/6] Skip any files which are not mounted on the
> +       host
> +X-BeenThere: libvir-list at redhat.com
> +X-Mailman-Version: 2.1.12
> +Precedence: junk
> +List-Id: Development discussions about the libvirt library & tools
> +       <libvir-list.redhat.com>
> +List-Unsubscribe: <https://www.redhat.com/mailman/options/libvir-list>,
> +       <mailto:libvir-list-request at redhat.com?subject=unsubscribe>
> +List-Archive: <https://www.redhat.com/archives/libvir-list>
> +List-Post: <mailto:libvir-list at redhat.com>
> +List-Help: <mailto:libvir-list-request at redhat.com?subject=help>
> +List-Subscribe: <https://www.redhat.com/mailman/listinfo/libvir-list>,
> +       <mailto:libvir-list-request at redhat.com?subject=subscribe>
> +X-List-Received-Date: Mon, 07 Oct 2013 13:07:03 -0000
> +
> +From: "Daniel P. Berrange" <berrange at redhat.com>
> +
> +Currently the LXC container tries to skip selinux/securityfs
> +mounts if the directory does not exist in the filesystem,
> +or if SELinux is disabled.
> +
> +The former check is flawed because the /sys/fs/selinux
> +or /sys/kernel/securityfs directories may exist in sysfs
> +even if the mount type is disabled. Instead of just doing
> +an access() check, use an virFileIsMounted() to see if
> +the FS is actually present in the host OS. This also
> +avoids the need to check is_selinux_enabled().
> +
> +Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> +---
> + src/lxc/lxc_container.c | 37 +++++++++++++++++++++++--------------
> + 1 file changed, 23 insertions(+), 14 deletions(-)
> +
> +diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
> +index 05190bf..4ec7b67 100644
> +--- a/src/lxc/lxc_container.c
> ++++ b/src/lxc/lxc_container.c
> +@@ -754,15 +754,16 @@ typedef struct {
> +     const char *type;
> +     int mflags;
> +     bool skipUserNS;
> ++    bool skipUnmounted;
> + } virLXCBasicMountInfo;
> +
> + static const virLXCBasicMountInfo lxcBasicMounts[] = {
> +-    { "proc", "/proc", "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, false },
> +-    { "/proc/sys", "/proc/sys", NULL, MS_BIND|MS_RDONLY, false },
> +-    { "sysfs", "/sys", "sysfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, false },
> +-    { "securityfs", "/sys/kernel/security", "securityfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, true },
> ++    { "proc", "/proc", "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, false, false },
> ++    { "/proc/sys", "/proc/sys", NULL, MS_BIND|MS_RDONLY, false, false },
> ++    { "sysfs", "/sys", "sysfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, false, false },
> ++    { "securityfs", "/sys/kernel/security", "securityfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, true, true },
> + #if WITH_SELINUX
> +-    { SELINUX_MOUNT, SELINUX_MOUNT, "selinuxfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, true },
> ++    { SELINUX_MOUNT, SELINUX_MOUNT, "selinuxfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, true, true },
> + #endif
> + };
> +
> +@@ -849,16 +850,24 @@ static int lxcContainerMountBasicFS(bool userns_enabled)
> +         VIR_DEBUG("Processing %s -> %s",
> +                   mnt->src, mnt->dst);
> +
> +-        /* Skip if mount doesn't exist in source */
> +-        if ((mnt->src[0] == '/') &&
> +-            (access(mnt->src, R_OK) < 0))
> +-            continue;
> ++        if (mnt->skipUnmounted) {
> ++            char *hostdir;
> ++            int ret;
> +
> +-#if WITH_SELINUX
> +-        if (STREQ(mnt->src, SELINUX_MOUNT) &&
> +-            !is_selinux_enabled())
> +-            continue;
> +-#endif
> ++            if (virAsprintf(&hostdir, "/.oldroot%s", mnt->dst) < 0)
> ++                goto cleanup;
> ++
> ++            ret = virFileIsMountPoint(hostdir);
> ++            VIR_FREE(hostdir);
> ++            if (ret < 0)
> ++                goto cleanup;
> ++
> ++            if (ret == 0) {
> ++                VIR_DEBUG("Skipping '%s' which isn't mounted in host",
> ++                          mnt->dst);
> ++                continue;
> ++            }
> ++        }
> +
> +         if (mnt->skipUserNS && userns_enabled) {
> +             VIR_DEBUG("Skipping due to user ns enablement");
> +--
> +1.8.3.1
> +
> +
> diff --git a/recipes-extended/libvirt/libvirt_1.1.2.bb b/recipes-extended/libvirt/libvirt_1.1.2.bb
> index a12147a..819072d 100644
> --- a/recipes-extended/libvirt/libvirt_1.1.2.bb
> +++ b/recipes-extended/libvirt/libvirt_1.1.2.bb
> @@ -27,6 +27,12 @@ SRC_URI = "http://libvirt.org/sources/libvirt-${PV}.tar.gz \
>             file://LXC-Don-t-mount-securityfs-when-user-namespace-enabl.patch \
>             file://Move-array-of-mounts-out-of-lxcContainerMountBasicFS.patch \
>             file://LXC-don-t-try-to-mount-selinux-filesystem-when-user-.patch \
> +          file://0001-Add-virFileIsMountPoint-function.patch \
> +          file://0002-Remove-unused-opts-field-from-LXC-basic.patch \
> +          file://0003-Remove-pointless-srcpath-variable-in-lxcContainerMountBasicFS.patch \
> +          file://0004-Remove-duplicate-entries-in-lxcBasicMounts-array.patch \
> +          file://0005-Add-flag-to-lxcBasicMounts-to-control-use-in-user-namespaces.patch \
> +          file://0006-Skip-any-files-which-are-not-mounted-on-the-host.patch \
>            file://libvirtd.sh \
>            file://libvirtd.conf"
>
> --
> 1.7.11.7
>
>
> _______________________________________________
> meta-virtualization mailing list
> meta-virtualization at yoctoproject.org
> https://lists.yoctoproject.org/listinfo/meta-virtualization



-- 
"Thou shalt not follow the NULL pointer, for chaos and madness await
thee at its end"



More information about the meta-virtualization mailing list