From a0136d4c34c1710ae6b38667674f4db6f6eedb9c Mon Sep 17 00:00:00 2001 From: Dmitry Rozhkov Date: Mon, 18 Apr 2016 11:59:58 +0300 Subject: [PATCH] staging.c: Protect tar command against special characters It may happen that a bundle contains a directory named '#' and other files under this directory, thus not only target files need to be escaped in tar commands, but also target directories where the files get installed. Also a target file may have a name with '@' as its first symbol. Since the symbol has a special meaning in case of bsdtar the name needs to escaped in tar commands with the prefix './'. Upstream-Status: Backport [v3.5.2+] Signed-off-by: Dmitry Rozhkov --- src/staging.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/staging.c b/src/staging.c index 742e8a2..6f7eafb 100644 --- a/src/staging.c +++ b/src/staging.c @@ -402,8 +402,8 @@ int do_staging(struct file *file) ret = -errno; goto out; } - string_or_die(&tarcommand, TAR_COMMAND " -C %s " TAR_PERM_ATTR_ARGS " -cf - %s 2> /dev/null | " - TAR_COMMAND " -C %s%s " TAR_PERM_ATTR_ARGS " -xf - 2> /dev/null", + string_or_die(&tarcommand, TAR_COMMAND " -C '%s' " TAR_PERM_ATTR_ARGS " -cf - './%s' 2> /dev/null | " + TAR_COMMAND " -C '%s%s' " TAR_PERM_ATTR_ARGS " -xf - 2> /dev/null", rename_tmpdir, base, path_prefix, rel_dir); LOG_DEBUG(file, "directory overwrite", class_osvol_staging, "%s", tarcommand); ret = system(tarcommand); @@ -440,8 +440,8 @@ int do_staging(struct file *file) ret = -errno; goto out; } - string_or_die(&tarcommand, TAR_COMMAND " -C %s/staged " TAR_PERM_ATTR_ARGS " -cf - .update.%s 2> /dev/null | " - TAR_COMMAND " -C %s%s " TAR_PERM_ATTR_ARGS " -xf - 2> /dev/null", + string_or_die(&tarcommand, TAR_COMMAND " -C '%s/staged' " TAR_PERM_ATTR_ARGS " -cf - '.update.%s' 2> /dev/null | " + TAR_COMMAND " -C '%s%s' " TAR_PERM_ATTR_ARGS " -xf - 2> /dev/null", STATE_DIR, base, path_prefix, rel_dir); LOG_DEBUG(file, "dotfile install", class_osvol_staging, "%s", tarcommand); ret = system(tarcommand); @@ -485,7 +485,7 @@ int do_staging(struct file *file) /* For initial simplicity replace the file. Ideally this would be * an intelligent btrfs reflink to maximize block level reuse. */ //TODO: prove btrfs reflink ioctl works in general, then try using them here - string_or_die(&tarcommand, TAR_COMMAND " -C %s/staged " TAR_PERM_ATTR_ARGS " -cf - %s 2> /dev/null | " + string_or_die(&tarcommand, TAR_COMMAND " -C '%s/staged' " TAR_PERM_ATTR_ARGS " -cf - './%s' 2> /dev/null | " TAR_COMMAND " -C %s/%s " TAR_PERM_ATTR_ARGS " -xf - --transform=\"s/%s/%s/\" 2> /dev/null", STATE_DIR, file->hash, STAGING_SUBVOL, rel_dir, file->hash, base); ret = system(tarcommand); -- 2.5.0