[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen master] tools/libfsimage: Export a new function to preload all plugins



commit 990e65c3ad9ac08642ce62a92852c80be6c83e96
Author:     Alejandro Vallejo <alejandro.vallejo@xxxxxxxxx>
AuthorDate: Mon Sep 25 18:32:24 2023 +0100
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Wed Oct 11 06:36:50 2023 +0100

    tools/libfsimage: Export a new function to preload all plugins
    
    This is work required in order to let pygrub operate in highly deprivileged
    chroot mode. This patch adds a function that preloads every plugin, hence
    ensuring that a on function exit, every shared library is loaded in memory.
    
    The new "init" function is supposed to be used before depriv, but that's
    fine because it's not acting on untrusted data.
    
    This is part of XSA-443 / CVE-2023-34325
    
    Signed-off-by: Alejandro Vallejo <alejandro.vallejo@xxxxxxxxx>
---
 tools/libfsimage/common/fsimage_plugin.c |  4 ++--
 tools/libfsimage/common/mapfile-GNU      |  1 +
 tools/libfsimage/common/mapfile-SunOS    |  1 +
 tools/libfsimage/common/xenfsimage.h     |  8 ++++++++
 tools/pygrub/src/fsimage/fsimage.c       | 15 +++++++++++++++
 5 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/tools/libfsimage/common/fsimage_plugin.c 
b/tools/libfsimage/common/fsimage_plugin.c
index de1412b423..d0cb9e96a6 100644
--- a/tools/libfsimage/common/fsimage_plugin.c
+++ b/tools/libfsimage/common/fsimage_plugin.c
@@ -119,7 +119,7 @@ fail:
        return (-1);
 }
 
-static int load_plugins(void)
+int fsi_init(void)
 {
        const char *fsdir = getenv("XEN_FSIMAGE_FSDIR");
        struct dirent *dp = NULL;
@@ -180,7 +180,7 @@ int find_plugin(fsi_t *fsi, const char *path, const char 
*options)
        fsi_plugin_t *fp;
        int ret = 0;
 
-       if (plugins == NULL && (ret = load_plugins()) != 0)
+       if (plugins == NULL && (ret = fsi_init()) != 0)
                goto out;
 
        for (fp = plugins; fp != NULL; fp = fp->fp_next) {
diff --git a/tools/libfsimage/common/mapfile-GNU 
b/tools/libfsimage/common/mapfile-GNU
index 26d4d7a69e..2d54d527d7 100644
--- a/tools/libfsimage/common/mapfile-GNU
+++ b/tools/libfsimage/common/mapfile-GNU
@@ -1,6 +1,7 @@
 VERSION {
        libfsimage.so.1.0 {
                global:
+                       fsi_init;
                        fsi_open_fsimage;
                        fsi_close_fsimage;
                        fsi_file_exists;
diff --git a/tools/libfsimage/common/mapfile-SunOS 
b/tools/libfsimage/common/mapfile-SunOS
index e99b90b650..48deedb425 100644
--- a/tools/libfsimage/common/mapfile-SunOS
+++ b/tools/libfsimage/common/mapfile-SunOS
@@ -1,5 +1,6 @@
 libfsimage.so.1.0 {
        global:
+               fsi_init;
                fsi_open_fsimage;
                fsi_close_fsimage;
                fsi_file_exists;
diff --git a/tools/libfsimage/common/xenfsimage.h 
b/tools/libfsimage/common/xenfsimage.h
index 201abd54f2..341883b2d7 100644
--- a/tools/libfsimage/common/xenfsimage.h
+++ b/tools/libfsimage/common/xenfsimage.h
@@ -35,6 +35,14 @@ extern C {
 typedef struct fsi fsi_t;
 typedef struct fsi_file fsi_file_t;
 
+/*
+ * Optional initialization function. If invoked it loads the associated
+ * dynamic libraries for the backends ahead of time. This is required if
+ * the library is to run as part of a highly deprivileged executable, as
+ * the libraries may not be reachable after depriv.
+ */
+int fsi_init(void);
+
 fsi_t *fsi_open_fsimage(const char *, uint64_t, const char *);
 void fsi_close_fsimage(fsi_t *);
 
diff --git a/tools/pygrub/src/fsimage/fsimage.c 
b/tools/pygrub/src/fsimage/fsimage.c
index fdcfa1a3c0..12dfcff6e3 100644
--- a/tools/pygrub/src/fsimage/fsimage.c
+++ b/tools/pygrub/src/fsimage/fsimage.c
@@ -286,6 +286,15 @@ fsimage_getbootstring(PyObject *o, PyObject *args)
        return Py_BuildValue("s", bootstring);
 }
 
+static PyObject *
+fsimage_init(PyObject *o, PyObject *args)
+{
+       if (!PyArg_ParseTuple(args, ""))
+               return (NULL);
+
+       return Py_BuildValue("i", fsi_init());
+}
+
 PyDoc_STRVAR(fsimage_open__doc__,
     "open(name, [offset=off]) - Open the given file as a filesystem image.\n"
     "\n"
@@ -297,7 +306,13 @@ PyDoc_STRVAR(fsimage_getbootstring__doc__,
     "getbootstring(fs) - Return the boot string needed for this file system "
     "or NULL if none is needed.\n");
 
+PyDoc_STRVAR(fsimage_init__doc__,
+    "init() - Loads every dynamic library contained in xenfsimage "
+    "into memory so that it can be used in chrooted environments.\n");
+
 static struct PyMethodDef fsimage_module_methods[] = {
+       { "init", (PyCFunction)fsimage_init,
+           METH_VARARGS, fsimage_init__doc__ },
        { "open", (PyCFunction)fsimage_open,
            METH_VARARGS|METH_KEYWORDS, fsimage_open__doc__ },
        { "getbootstring", (PyCFunction)fsimage_getbootstring,
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.