[Libguestfs] [PATCH v2 1/2] New API: download_blocks

Matteo Cafasso noxdafox at gmail.com
Sun Jul 17 17:40:19 UTC 2016


This function allows to download file system data units (blocks) from
the given partition.

The API can be used to detect data hidden within filesystem bad blocks
or slack space.

Moreover for filesystems such as Ext3 and Ext4, this function is the
only way to retrieve deleted files. An example is given in the function
tests.

Signed-off-by: Matteo Cafasso <noxdafox at gmail.com>
---
 daemon/sleuthkit.c   | 41 ++++++++++++++++++++++++++++++++++++++++-
 generator/actions.ml | 24 ++++++++++++++++++++++++
 gobject/Makefile.inc |  2 ++
 src/MAX_PROC_NR      |  2 +-
 4 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/daemon/sleuthkit.c b/daemon/sleuthkit.c
index 1262b68..eb7f877 100644
--- a/daemon/sleuthkit.c
+++ b/daemon/sleuthkit.c
@@ -32,6 +32,7 @@
 static int send_command_output (const char *cmd);

 GUESTFSD_EXT_CMD(str_icat, icat);
+GUESTFSD_EXT_CMD(str_blkls, blkls);

 int
 do_download_inode (const mountable_t *mountable, int64_t inode)
@@ -46,7 +47,8 @@ do_download_inode (const mountable_t *mountable, int64_t inode)
   }

   /* Construct the command. */
-  ret = asprintf(&cmd, "%s -r %s %" PRIi64, str_icat, mountable->device, inode);
+  ret = asprintf (&cmd, "%s -r %s %" PRIi64,
+                  str_icat, mountable->device, inode);
   if (ret < 0) {
     reply_with_perror ("asprintf");
     return -1;
@@ -55,6 +57,43 @@ do_download_inode (const mountable_t *mountable, int64_t inode)
   return send_command_output (cmd);
 }

+/* Takes optional arguments, consult optargs_bitmask. */
+int
+do_download_blocks (const mountable_t *mountable, int64_t start, int64_t stop,
+                    int unallocated)
+{
+  int ret;
+  const char *params;
+  CLEANUP_FREE char *cmd = NULL;
+
+  /* Data unit address start must be greater than 0 */
+  if (start < 0) {
+    reply_with_error ("starting address must be greater than zero");
+    return -1;
+  }
+
+  /* Data unit address end must be greater than start */
+  if (stop <= start) {
+    reply_with_error ("stopping address must greater than starting address");
+    return -1;
+  }
+
+  if (!(optargs_bitmask & GUESTFS_DOWNLOAD_BLOCKS_UNALLOCATED_BITMASK))
+    params = " -e";
+  else
+    params = "";
+
+  /* Construct the command. */
+  ret = asprintf (&cmd, "%s %s %s %" PRIi64 "-%" PRIi64,
+                  str_blkls, mountable->device, params, start, stop);
+  if (ret < -0) {
+    reply_with_perror ("asprintf");
+    return -1;
+  }
+
+  return send_command_output (cmd);
+}
+
 /* Run the given command, collect the output and send it to the appliance.
  * Return 0 on success, -1 on error.
  */
diff --git a/generator/actions.ml b/generator/actions.ml
index 4423313..10f291f 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -13177,6 +13177,30 @@ The optional C<force> boolean controls whether the context
 is reset for customizable files, and also whether the
 user, role and range parts of the file context is changed." };

+  { defaults with
+    name = "download_blocks"; added = (1, 33, 44);
+    style = RErr, [Mountable "device"; Int64 "start"; Int64 "stop"; FileOut "filename"], [OBool "unallocated"];
+    proc_nr = Some 468;
+    optional = Some "sleuthkit";
+    progress = true; cancellable = true;
+    shortdesc = "download the given data units from the disk";
+    longdesc = "\
+Download the data units from F<start> address
+to F<stop> from the disk partition (eg. F</dev/sda1>)
+and save them as F<filename> on the local machine.
+
+The use of this API on sparse disk image formats such as QCOW,
+may result in large zero-filled files downloaded on the host.
+
+The size of a data unit varies across filesystem implementations.
+On NTFS filesystems data units are referred as clusters
+while on ExtX ones they are referred as fragments.
+
+If the optional C<unallocated> flag is true (default is false),
+only the unallocated blocks will be extracted.
+This is useful to detect hidden data or to retrieve deleted files
+which data units have not been overwritten yet." };
+
 ]

 (* Non-API meta-commands available only in guestfish.
diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc
index 797bb33..7698c2a 100644
--- a/gobject/Makefile.inc
+++ b/gobject/Makefile.inc
@@ -68,6 +68,7 @@ guestfs_gobject_headers= \
   include/guestfs-gobject/optargs-copy_file_to_file.h \
   include/guestfs-gobject/optargs-cpio_out.h \
   include/guestfs-gobject/optargs-disk_create.h \
+  include/guestfs-gobject/optargs-download_blocks.h \
   include/guestfs-gobject/optargs-e2fsck.h \
   include/guestfs-gobject/optargs-fstrim.h \
   include/guestfs-gobject/optargs-glob_expand.h \
@@ -157,6 +158,7 @@ guestfs_gobject_sources= \
   src/optargs-copy_file_to_file.c \
   src/optargs-cpio_out.c \
   src/optargs-disk_create.c \
+  src/optargs-download_blocks.c \
   src/optargs-e2fsck.c \
   src/optargs-fstrim.c \
   src/optargs-glob_expand.c \
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index 5873851..1023289 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-467
+468
--
2.8.1




More information about the Libguestfs mailing list