aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-core/swupd-client/swupd-client/0006-Backport-Use-rename-instead-of-tar-transform.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-core/swupd-client/swupd-client/0006-Backport-Use-rename-instead-of-tar-transform.patch')
-rw-r--r--recipes-core/swupd-client/swupd-client/0006-Backport-Use-rename-instead-of-tar-transform.patch157
1 files changed, 157 insertions, 0 deletions
diff --git a/recipes-core/swupd-client/swupd-client/0006-Backport-Use-rename-instead-of-tar-transform.patch b/recipes-core/swupd-client/swupd-client/0006-Backport-Use-rename-instead-of-tar-transform.patch
new file mode 100644
index 0000000..ab3a39f
--- /dev/null
+++ b/recipes-core/swupd-client/swupd-client/0006-Backport-Use-rename-instead-of-tar-transform.patch
@@ -0,0 +1,157 @@
+From e9ad32a273efe2d177c1bbd394ae944ae598fd50 Mon Sep 17 00:00:00 2001
+From: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
+Date: Mon, 8 Feb 2016 18:12:48 +0200
+Subject: [PATCH] Backport: Use rename instead of tar transform
+
+This patch is a backport from swupd-client v2.88
+Author: William Douglas <william.douglas@intel.com>
+Subject: Use rename instead of tar transform
+
+In order to prevent issues with transform name escaping, update logic
+for moving an object from staging. First rename the object in the
+staging path to its final name (in case of a directory the rename places
+it in a seperate directory first to avoid hash colisions), then use tar
+to update or create the object in the filesystem. Once finished rename
+the object back to the hash name so it can be reused as needed.
+
+This also fixes up some issues with the SWUPD_LINUX_ROOTFS checks not
+always encapsulating variable use within the do_staging function.
+
+Note: the SWUPD_LINUX_ROOTFS checks have been removed entirely, since
+they are not used anywhere in the code at present.
+
+Upstream-Status: Backported [v2.88]
+
+Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
+---
+ src/staging.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 67 insertions(+), 6 deletions(-)
+
+diff --git a/src/staging.c b/src/staging.c
+index b8545c1..16dafbb 100644
+--- a/src/staging.c
++++ b/src/staging.c
+@@ -36,6 +36,31 @@
+ #include "swupd-build-variant.h"
+ #include <swupd.h>
+
++/* clean then recreate temporary folder for tar renames */
++static int create_staging_renamedir(char *rename_tmpdir)
++{
++ int ret;
++ char *rmcommand = NULL;
++
++ string_or_die(&rmcommand, "rm -fr %s", rename_tmpdir);
++ if (!system(rmcommand)) {
++ /* Not fatal but pretty scary, likely to really fail at the
++ * next command too. Pass for now as printing may just cause
++ * confusion */
++ ;
++ }
++ free(rmcommand);
++
++ ret = mkdir(rename_tmpdir, S_IRWXU);
++ if (ret == -1 && errno != EEXIST) {
++ ret = -errno;
++ } else {
++ ret = 0;
++ }
++
++ return ret;
++}
++
+ #ifdef SWUPD_WITH_BTRFS
+ static int create_staging_subvol_from(const char *version)
+ {
+@@ -269,6 +294,9 @@ int prepare(bool UNUSED_PARAM *is_corrupted, int UNUSED_PARAM current_version, i
+ #endif
+
+ /* Do the staging of new files into the filesystem */
++#warning do_staging is currently not able to be run in parallel
++/* Consider adding a remove_leftovers() that runs in verify/fix in order to
++ * allow this function to mkdtemp create folders for parallel build */
+ int do_staging(struct file *file)
+ {
+ char *statfile = NULL, *tmp = NULL, *tmp2 = NULL;
+@@ -280,6 +308,8 @@ int do_staging(struct file *file)
+ char *targetpath = NULL;
+ char *symbase = NULL;
+ #endif
++ char *rename_target = NULL;
++ char *rename_tmpdir = NULL;
+ int ret;
+ struct stat s;
+
+@@ -360,12 +390,28 @@ int do_staging(struct file *file)
+ * attributes and it includes internal logic that does the
+ * right thing to overlay a directory onto something
+ * pre-existing: */
+- string_or_die(&tarcommand, "tar -C %s/staged " TAR_PERM_ATTR_ARGS " -cf - %s 2> /dev/null | "
+- "tar -C %s%s " TAR_PERM_ATTR_ARGS " -xf - --transform=\"s/%s/%s/\" 2> /dev/null",
+- STATE_DIR, file->hash, path_prefix, rel_dir, file->hash, base);
++ /* In order to avoid tar transforms with directories, rename
++ * the directory before and after the tar command */
++ string_or_die(&rename_tmpdir, "%s/tmprenamedir", STATE_DIR);
++ ret = create_staging_renamedir(rename_tmpdir);
++ if (ret) {
++ goto out;
++ }
++ string_or_die(&rename_target, "%s/%s", rename_tmpdir, base);
++ if (rename(original, rename_target)) {
++ ret = -errno;
++ goto out;
++ }
++ string_or_die(&tarcommand, "tar -C %s " TAR_PERM_ATTR_ARGS " -cf - %s 2> /dev/null | "
++ "tar -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);
+ free(tarcommand);
++ if (rename(rename_target, original)) {
++ ret = -errno;
++ goto out;
++ }
+ if (ret < 0) {
+ LOG_ERROR(file, "Failed directory overwrite", class_osvol_staging, "%s", strerror(errno));
+ ret = -EDIR_OVERWRITE;
+@@ -386,12 +432,25 @@ int do_staging(struct file *file)
+ }
+ if (ret < 0) {
+ /* either the hardlink failed, or it was undesirable (config), do a tar-tar dance */
+- string_or_die(&tarcommand, "tar -C %s/staged " TAR_PERM_ATTR_ARGS " -cf - %s 2> /dev/null | "
+- "tar -C %s%s " TAR_PERM_ATTR_ARGS " -xf - --transform=\"s/%s/.update.%s/\" 2> /dev/null",
+- STATE_DIR, file->hash, path_prefix, rel_dir, file->hash, base);
++ /* In order to avoid tar transforms, rename the file
++ * before and after the tar command */
++ string_or_die(&rename_target, "%s/staged/.update.%s", STATE_DIR, base);
++ ret = rename(original, rename_target);
++ if (ret) {
++ ret = -errno;
++ goto out;
++ }
++ string_or_die(&tarcommand, "tar -C %s/staged " TAR_PERM_ATTR_ARGS " -cf - .update.%s 2> /dev/null | "
++ "tar -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);
+ free(tarcommand);
++ ret = rename(rename_target, original);
++ if (ret) {
++ ret = -errno;
++ goto out;
++ }
+ }
+ if (ret < 0) {
+ LOG_ERROR(file, "Failed tar dotfile install", class_osvol_staging,
+@@ -436,6 +495,8 @@ int do_staging(struct file *file)
+ out:
+ free(target);
+ free(original);
++ free(rename_target);
++ free(rename_tmpdir);
+ free(tmp);
+ free(tmp2);
+
+--
+2.5.0
+