Resolve the given path within the chroot, so scrub can be invoked
outside the chroot on an already-resolved path.
Given that realpath is used, its availability is checked manually,
since scrub-file already depends on the "scrub" feature. Slightly ugly,
but on the other hand realpath is generally available nowadays, so the
check should not be failing.
Add few tests in scrub-file for this and other similar issues.
---
daemon/scrub.c | 24 +++++++++++++++++++++++-
generator/actions.ml | 13 ++++++++++++-
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/daemon/scrub.c b/daemon/scrub.c
index cd880b9..f500a08 100644
--- a/daemon/scrub.c
+++ b/daemon/scrub.c
@@ -54,12 +54,34 @@ do_scrub_device (const char *device)
int
do_scrub_file (const char *file)
{
+ CLEANUP_FREE char *rp = NULL;
CLEANUP_FREE char *buf = NULL;
CLEANUP_FREE char *err = NULL;
int r;
+ if (! optgroup_realpath_available ()) {
+ reply_with_error_errno (ENOTSUP,
+ "feature '%s' is not available in this\n"
+ "build of libguestfs. Read 'AVAILABILITY' in the guestfs(3) man page
for\n"
+ "how to check for the availability of features.",
+ "realpath");
+ return -1;
+ }
+
+ /* Resolve the path to the file. If it fails, then the file
+ * most probably does not exist or "file" is a symlink pointing
+ * outside the chroot.
+ */
+ CHROOT_IN;
+ rp = realpath (file, NULL);
+ CHROOT_OUT;
+ if (rp == NULL) {
+ reply_with_perror ("realpath: %s", file);
+ return -1;
+ }
+
/* Make the path relative to /sysroot. */
- buf = sysroot_path (file);
+ buf = sysroot_path (rp);
if (!buf) {
reply_with_perror ("malloc");
return -1;
diff --git a/generator/actions.ml b/generator/actions.ml
index 0826137..01f6ab5 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -5719,7 +5719,18 @@ manual page for more details." };
tests = [
InitScratchFS, Always, TestRun (
[["write"; "/scrub_file"; "content"];
- ["scrub_file"; "/scrub_file"]]), []
+ ["scrub_file"; "/scrub_file"]]), [];
+ InitScratchFS, Always, TestRun (
+ [["write"; "/scrub_file_2"; "content"];
+ ["ln_s"; "/scrub_file_2"; "/scrub_file_2_link"];
+ ["scrub_file"; "/scrub_file_2_link"]]), [];
+ InitScratchFS, Always, TestLastFail (
+ [["ln_s"; "/scrub_file_3_notexisting";
"/scrub_file_3_link"];
+ ["scrub_file"; "/scrub_file_3_link"]]), [];
+ InitScratchFS, Always, TestLastFail (
+ [["write"; "/scrub_file_4"; "content"];
+ ["ln_s"; "../sysroot/scrub_file_4";
"/scrub_file_4_link"];
+ ["scrub_file"; "/scrub_file_4_link"]]), [];
];
shortdesc = "scrub (securely wipe) a file";
longdesc = "\
--
1.9.0