diff --git a/trunk/CVE-2020-14339.patch b/trunk/CVE-2020-14339.patch index 71e91b2..724d160 100644 --- a/trunk/CVE-2020-14339.patch +++ b/trunk/CVE-2020-14339.patch @@ -10,6 +10,28 @@ index af52054aa4..eb1ffd1dbd 100644 @SRCDIR@/src/util/virdnsmasq.c @SRCDIR@/src/util/virerror.c @SRCDIR@/src/util/virerror.h +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 0c883cd834..9e7d8a01a8 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -8830,8 +8830,6 @@ virDomainHostdevDefParseXMLCaps(xmlNodePtr node G_GNUC_UNUSED, + const char *type, + virDomainHostdevDefPtr def) + { +- xmlNodePtr sourcenode; +- + /* @type is passed in from the caller rather than read from the + * xml document, because it is specified in different places for + * different kinds of defs - it is an attribute of +@@ -8854,7 +8852,7 @@ virDomainHostdevDefParseXMLCaps(xmlNodePtr node G_GNUC_UNUSED, + return -1; + } + +- if (!(sourcenode = virXPathNode("./source", ctxt))) { ++ if (!virXPathNode("./source", ctxt)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing element in hostdev device")); + return -1; diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 914bf640ca..e88da02341 100644 --- a/src/qemu/qemu_cgroup.c @@ -46,10 +68,10 @@ index c5b8d91f9a..088d711ae3 100644 _("Unable to get devmapper targets for %s"), next->path); diff --git a/src/util/virdevmapper.c b/src/util/virdevmapper.c -index 40a82285f9..a471504176 100644 +index 40a82285f9..7c89c2a952 100644 --- a/src/util/virdevmapper.c +++ b/src/util/virdevmapper.c -@@ -20,38 +20,67 @@ +@@ -20,143 +20,267 @@ #include @@ -72,18 +94,7 @@ index 40a82285f9..a471504176 100644 +# include "viralloc.h" +# include "virstring.h" +# include "virfile.h" -+ -+# define VIR_FROM_THIS VIR_FROM_STORAGE -+ -+# define PROC_DEVICES "/proc/devices" -+# define DM_NAME "device-mapper" -+# define DEV_DM_DIR "/dev/" DM_DIR -+# define CONTROL_PATH DEV_DM_DIR "/" DM_CONTROL_NODE -+# define BUF_SIZE (16 * 1024) -+ -+G_STATIC_ASSERT(BUF_SIZE > sizeof(struct dm_ioctl)); -+ -+static unsigned int virDMMajor; ++# include "virlog.h" -#include "virdevmapper.h" -#include "internal.h" @@ -99,20 +110,30 @@ index 40a82285f9..a471504176 100644 - int dm_errno G_GNUC_UNUSED, - const char *fmt G_GNUC_UNUSED, - ...) --{ -- return; --} - - static int - virDevMapperOnceInit(void) ++# define VIR_FROM_THIS VIR_FROM_STORAGE ++ ++VIR_LOG_INIT("util.virdevmapper"); ++ ++# define PROC_DEVICES "/proc/devices" ++# define DM_NAME "device-mapper" ++# define DEV_DM_DIR "/dev/" DM_DIR ++# define CONTROL_PATH DEV_DM_DIR "/" DM_CONTROL_NODE ++# define BUF_SIZE (16 * 1024) ++ ++G_STATIC_ASSERT(BUF_SIZE > sizeof(struct dm_ioctl)); ++ ++ ++static int ++virDevMapperGetMajor(unsigned int *major) { -- /* Ideally, we would not need this. But libdevmapper prints -- * error messages to stderr by default. Sad but true. */ -- dm_log_with_errno_init(virDevMapperDummyLogger); +- return; + g_autofree char *buf = NULL; + VIR_AUTOSTRINGLIST lines = NULL; + size_t i; + ++ if (!virFileExists(CONTROL_PATH)) ++ return -2; ++ + if (virFileReadAll(PROC_DEVICES, BUF_SIZE, &buf) < 0) + return -1; + @@ -126,7 +147,7 @@ index 40a82285f9..a471504176 100644 + + if (sscanf(lines[i], "%u %ms\n", &maj, &dev) == 2 && + STREQ(dev, DM_NAME)) { -+ virDMMajor = maj; ++ *major = maj; + break; + } + } @@ -138,13 +159,10 @@ index 40a82285f9..a471504176 100644 + return -1; + } + - return 0; ++ return 0; } -@@ -59,104 +88,190 @@ virDevMapperOnceInit(void) - VIR_ONCE_GLOBAL_INIT(virDevMapper); - - ++ +static void * +virDMIoctl(int controlFD, int cmd, struct dm_ioctl *dm, char **buf) +{ @@ -179,9 +197,13 @@ index 40a82285f9..a471504176 100644 + + static int --virDevMapperGetTargetsImpl(const char *path, +-virDevMapperOnceInit(void) +virDMOpen(void) -+{ + { +- /* Ideally, we would not need this. But libdevmapper prints +- * error messages to stderr by default. Sad but true. */ +- dm_log_with_errno_init(virDevMapperDummyLogger); +- return 0; + VIR_AUTOCLOSE controlFD = -1; + struct dm_ioctl dm; + g_autofree char *tmp = NULL; @@ -189,8 +211,17 @@ index 40a82285f9..a471504176 100644 + + memset(&dm, 0, sizeof(dm)); + -+ if ((controlFD = open(CONTROL_PATH, O_RDWR)) < 0) -+ return -1; ++ if ((controlFD = open(CONTROL_PATH, O_RDWR)) < 0) { ++ /* We can't talk to devmapper. Produce a warning and let ++ * the caller decide what to do next. */ ++ if (errno == ENOENT) { ++ VIR_DEBUG("device mapper not available"); ++ } else { ++ VIR_WARN("unable to open %s: %s", ++ CONTROL_PATH, g_strerror(errno)); ++ } ++ return -2; ++ } + + if (!virDMIoctl(controlFD, DM_VERSION, &dm, &tmp)) { + virReportSystemError(errno, "%s", @@ -208,9 +239,10 @@ index 40a82285f9..a471504176 100644 + ret = controlFD; + controlFD = -1; + return ret; -+} -+ -+ + } + + +-VIR_ONCE_GLOBAL_INIT(virDevMapper); +static char * +virDMSanitizepath(const char *path) +{ @@ -220,7 +252,6 @@ index 40a82285f9..a471504176 100644 + DIR *dh = NULL; + const char *p; + char *ret = NULL; -+ int rc; + + /* If a path is NOT provided then assume it's DM name */ + p = strrchr(path, '/'); @@ -250,7 +281,7 @@ index 40a82285f9..a471504176 100644 + if (virDirOpen(&dh, DEV_DM_DIR) < 0) + return NULL; + -+ while ((rc = virDirRead(dh, &ent, DEV_DM_DIR)) > 0) { ++ while (virDirRead(dh, &ent, DEV_DM_DIR) > 0) { + g_autofree char *tmp = g_strdup_printf(DEV_DM_DIR "/%s", ent->d_name); + + if (stat(tmp, &sb[1]) == 0 && @@ -263,9 +294,10 @@ index 40a82285f9..a471504176 100644 + virDirClose(&dh); + return ret; +} -+ -+ -+static int + + + static int +-virDevMapperGetTargetsImpl(const char *path, +virDevMapperGetTargetsImpl(int controlFD, + const char *path, char ***devPaths_ret, @@ -397,7 +429,7 @@ index 40a82285f9..a471504176 100644 } -@@ -175,9 +290,6 @@ virDevMapperGetTargetsImpl(const char *path, +@@ -175,9 +299,6 @@ virDevMapperGetTargetsImpl(const char *path, * If @path consists of yet another devmapper targets these are * consulted recursively. * @@ -407,7 +439,7 @@ index 40a82285f9..a471504176 100644 * Returns 0 on success, * -1 otherwise (with errno set, no libvirt error is * reported) -@@ -186,46 +298,53 @@ int +@@ -186,46 +307,59 @@ int virDevMapperGetTargets(const char *path, char ***devPaths) { @@ -420,12 +452,17 @@ index 40a82285f9..a471504176 100644 - return virDevMapperGetTargetsImpl(path, devPaths, ttl); -} -+ if (virDevMapperInitialize() < 0) -+ return -1; ++ if ((controlFD = virDMOpen()) < 0) { ++ if (controlFD == -2) { ++ /* The CONTROL_PATH doesn't exist or is unusable. ++ * Probably the module isn't loaded, yet. Don't error ++ * out, just exit. */ ++ return 0; ++ } -#else /* ! WITH_DEVMAPPER */ -+ if ((controlFD = virDMOpen()) < 0) + return -1; ++ } -int -virDevMapperGetTargets(const char *path G_GNUC_UNUSED, @@ -443,15 +480,16 @@ index 40a82285f9..a471504176 100644 virIsDevMapperDevice(const char *dev_name) { struct stat buf; - -+ if (virDevMapperInitialize() < 0) -+ return false; ++ unsigned int major; + ++ if (virDevMapperGetMajor(&major) < 0) ++ return false; + if (!stat(dev_name, &buf) && S_ISBLK(buf.st_mode) && - dm_is_dm_major(major(buf.st_rdev))) - return true; -+ major(buf.st_rdev) == virDMMajor) ++ major(buf.st_rdev) == major) + return true; return false; diff --git a/trunk/PKGBUILD b/trunk/PKGBUILD index a771017..a615ccd 100644 --- a/trunk/PKGBUILD +++ b/trunk/PKGBUILD @@ -89,7 +89,7 @@ source=("https://libvirt.org/sources/$pkgname-$pkgver.tar.xz"{,.asc} "CVE-2020-14339.patch") sha256sums=('4915d9eab299ed79288d7598b717c587156708c05f701fe55a72293f32eb3182' 'SKIP' - 'af90e325ae5f6f3f946695a8900ef2ea8cd579da61c608d69c4c550a8bc1b9db') + 'e29ad348f3edce69d7f7c739108868babd976c743b11fadbba5f70f37495b7e8') validpgpkeys=('C74415BA7C9C7F78F02E1DC34606B8A5DE95BC1F') # Daniel Veillard prepare() {