[Libguestfs] [PATCH libldm 02/12] Change the way we sanitise LDM partition name.

Mykola Ivanets stenavin at gmail.com
Tue May 15 20:38:09 UTC 2018


libdevmapper limits allowed characters for device name.  Character
whitelist: 0-9, A-Z, a-z, #+-.:=@_.  LDM partition name is composed of
disk group name and partition name.  Disk group is named after the
machine, with a "DgN" suffix; partition name is a disk name with a
numerical suffix - partition number within a disk.  So, the only
variable part which might contain invalid characters is Windows machine
name.  Therefore g_uri_escape_string function was used to sanitise
partition name.  However its usage looks artificial because it is
unclear either g_uri_escape_string will sanitise invalid characters
defined by libdevmapper.  Most likely libdevmapper v1.0 didn't provide
any way to do that job on its own.  Now when we switched to v1.02 of
the library we can offload this work.

First of all explicitly set mangling mode for devmapper library to
DM_STRING_MANGLING_AUTO (mangle only if not already mangled with hex).
So, we can set device name as is and the library will mangle name for
us.  After that we can retrieve mangled name back.
---
 src/ldm.c | 59 ++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 34 insertions(+), 25 deletions(-)

diff --git a/src/ldm.c b/src/ldm.c
index 5c570a5..c701cbd 100644
--- a/src/ldm.c
+++ b/src/ldm.c
@@ -292,6 +292,8 @@ ldm_init(LDM * const o)
 {
     o->priv = LDM_GET_PRIVATE(o);
     bzero(o->priv, sizeof(*o->priv));
+
+    dm_set_name_mangling_mode(DM_STRING_MANGLING_AUTO);
 }
 
 static void
@@ -2378,6 +2380,17 @@ ldm_partition_get_disk(LDMPartition * const o)
     return o->priv->disk;
 }
 
+static GString *
+_dm_part_name(const LDMPartitionPrivate * const part)
+{
+    const LDMDiskPrivate * const disk = part->disk->priv;
+
+    GString * name = g_string_new("");
+    g_string_printf(name, "ldm_part_%s_%s", disk->dgname, part->name);
+
+    return name;
+}
+
 static GString *
 _dm_vol_name(const LDMVolumePrivate * const vol)
 {
@@ -2492,10 +2505,12 @@ _find_device_tree_node(struct dm_tree * const tree,
 gboolean
 _dm_create(const gchar * const name, uint32_t udev_cookie,
            const guint n_targets, const struct dm_target * const targets,
-           GError ** const err)
+           GString **mangled_name, GError ** const err)
 {
     gboolean r = TRUE;
 
+    if (mangled_name) *mangled_name = NULL;
+
     struct dm_task * const task = dm_task_create(DM_DEVICE_CREATE);
     if (!task) {
         g_set_error(err, LDM_ERROR, LDM_ERROR_EXTERNAL,
@@ -2540,6 +2555,12 @@ _dm_create(const gchar * const name, uint32_t udev_cookie,
         r = FALSE; goto out;
     }
 
+    if (mangled_name) {
+        char *tmp = dm_task_get_name_mangled(task);
+        *mangled_name = g_string_new(tmp);
+        dm_free(tmp);
+    }
+
 out:
     dm_task_destroy(task);
     return r;
@@ -2613,28 +2634,16 @@ _dm_create_part(const LDMPartitionPrivate * const part, uint32_t cookie,
     g_string_printf(target.params, "%s %" PRIu64,
                     disk->device, disk->data_start + part->start);
 
-    /* Ensure we sanitise table names */
-    char * dgname_esc =
-        g_uri_escape_string(disk->dgname,
-                            G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT,
-                            FALSE);
-    char * partname_esc =
-        g_uri_escape_string(part->name,
-                            G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT,
-                            FALSE);
-
-    GString *name = g_string_new("");
-    g_string_printf(name, "ldm_part_%s_%s", dgname_esc, partname_esc);
-    g_free(dgname_esc);
-    g_free(partname_esc);
-
-    if (!_dm_create(name->str, cookie, 1, &target, err)) {
-        g_string_free(name, TRUE);
-        name = NULL;
+    GString *name = _dm_part_name(part);
+    GString *mangled_name = NULL;
+
+    if (!_dm_create(name->str, cookie, 1, &target, &mangled_name, err)) {
+        mangled_name = NULL;
     }
 
+    g_string_free(name, TRUE);
     g_string_free(target.params, TRUE);
-    return name;
+    return mangled_name;
 }
 
 static GString *
@@ -2687,7 +2696,7 @@ _dm_create_spanned(const LDMVolumePrivate * const vol, GError ** const err)
 
     name = _dm_vol_name(vol);
 
-    if (!_dm_create(name->str, cookie, vol->parts->len, targets, err)) {
+    if (!_dm_create(name->str, cookie, vol->parts->len, targets, NULL, err)) {
         g_string_free(name, TRUE);
         name = NULL;
     }
@@ -2744,7 +2753,7 @@ _dm_create_striped(const LDMVolumePrivate * const vol, GError ** const err)
 
     name = _dm_vol_name(vol);
 
-    if (!_dm_create(name->str, cookie, 1, &target, err)) {
+    if (!_dm_create(name->str, cookie, 1, &target, NULL, err)) {
         g_string_free(name, TRUE);
         name = NULL;
     }
@@ -2818,7 +2827,7 @@ _dm_create_mirrored(const LDMVolumePrivate * const vol, GError ** const err)
 
     name = _dm_vol_name(vol);
 
-    if (!_dm_create(name->str, cookie, 1, &target, err)) {
+    if (!_dm_create(name->str, cookie, 1, &target, NULL, err)) {
         g_string_free(name, TRUE);
         name = NULL;
     }
@@ -2906,7 +2915,7 @@ _dm_create_raid5(const LDMVolumePrivate * const vol, GError ** const err)
 
     name = _dm_vol_name(vol);
 
-    if (!_dm_create(name->str, cookie, 1, &target, err)) {
+    if (!_dm_create(name->str, cookie, 1, &target, NULL, err)) {
         g_string_free(name, TRUE); name = NULL;
         goto out;
     }
@@ -2986,7 +2995,7 @@ ldm_volume_dm_create(const LDMVolume * const o, GString **created,
         return TRUE;
     }
     dm_tree_free(tree); tree = NULL;
-    g_string_free(name, TRUE);
+    g_string_free(name, TRUE); name = NULL;
 
     switch (vol->type) {
     case LDM_VOLUME_TYPE_SIMPLE:
-- 
2.17.0




More information about the Libguestfs mailing list