From c5a58efebb6d54c728b97ebb968eb40e5e628488 Mon Sep 17 00:00:00 2001 From: Dmitry Rozhkov Date: Mon, 8 Feb 2016 16:42:23 +0200 Subject: [PATCH] Add compatibility with libarchive's bsdtar command Since GNU tar fails to extract files with xattrs preserved when Integrity Measurement Architecture (IMA) is enabled some vendors may choose to install libarchive-based tar (bsdtar) on their embedded devices, so the swupd server needs to be able to create archives in its format. This patch adds one compile-time options --enable-bsdtar that is used to enable/disable GNU tar specific options. Signed-off-by: Dmitry Rozhkov --- configure.ac | 9 +++++++++ include/swupd-build-variant.h | 12 ++++++++++-- src/download.c | 4 ++-- src/manifest.c | 3 ++- src/packs.c | 2 +- src/staging.c | 8 ++++---- 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 60c3b075..e1927cb6 100644 --- a/configure.ac +++ b/configure.ac @@ -54,6 +54,15 @@ if test "$enable_coverage" = "yes" ; then fi AM_CONDITIONAL([COVERAGE], [test "$have_coverage" = "yes"]) +AC_ARG_ENABLE( + [bsdtar], + AS_HELP_STRING([--enable-bsdtar], [Use alternative bsdtar command (uses tar by default)]) +) +AS_IF([test "x$enable_bsdtar" = "xyes" ], + [AC_DEFINE(SWUPD_WITH_BSDTAR, 1, [Use bsdtar])], + [AC_DEFINE(SWUPD_WITHOUT_BSDTAR, 1, [Use default tar])] +) + AC_ARG_WITH([systemdsystemunitdir], AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [path to systemd system service dir @<:@default=/usr/lib/systemd/system@:>@]), [unitpath=${withval}], [unitpath="$($PKG_CONFIG --variable=systemdsystemunitdir systemd)"]) diff --git a/include/swupd-build-variant.h b/include/swupd-build-variant.h index c43fb3c8..c915730c 100644 --- a/include/swupd-build-variant.h +++ b/include/swupd-build-variant.h @@ -8,10 +8,18 @@ #include "list.h" #include "swupd.h" +#ifdef SWUPD_WITH_BSDTAR +#define TAR_COMMAND "bsdtar" +#define TAR_XATTR_ARGS "" +#else +#define TAR_COMMAND "tar" +#define TAR_XATTR_ARGS "--xattrs --xattrs-include='*'" +#endif + #ifdef SWUPD_WITH_SELINUX -#define TAR_PERM_ATTR_ARGS "--preserve-permissions --xattrs --xattrs-include='*' --selinux" +#define TAR_PERM_ATTR_ARGS "--preserve-permissions --selinux " TAR_XATTR_ARGS #else /* SWUPD_WITHOUT_SELINUX */ -#define TAR_PERM_ATTR_ARGS "--preserve-permissions --xattrs --xattrs-include='*'" +#define TAR_PERM_ATTR_ARGS "--preserve-permissions " TAR_XATTR_ARGS #endif #endif diff --git a/src/download.c b/src/download.c index 11f82cba..ed92e487 100644 --- a/src/download.c +++ b/src/download.c @@ -194,7 +194,7 @@ static int check_tarfile_content(struct file *file, const char *tarfilename) FILE *tar; int count = 0; - string_or_die(&tarcommand, "tar -tf %s/download/%s.tar 2> /dev/null", STATE_DIR, file->hash); + string_or_die(&tarcommand, TAR_COMMAND " -tf %s/download/%s.tar 2> /dev/null", STATE_DIR, file->hash); err = access(tarfilename, R_OK); if (err) { @@ -289,7 +289,7 @@ int untar_full_download(void *data) } /* modern tar will automatically determine the compression type used */ - string_or_die(&tarcommand, "tar -C %s/staged/ " TAR_PERM_ATTR_ARGS " -xf %s 2> /dev/null", + string_or_die(&tarcommand, TAR_COMMAND " -C %s/staged/ " TAR_PERM_ATTR_ARGS " -xf %s 2> /dev/null", STATE_DIR, tarfile); err = system(tarcommand); diff --git a/src/manifest.c b/src/manifest.c index 5f1248d3..f903425b 100644 --- a/src/manifest.c +++ b/src/manifest.c @@ -37,6 +37,7 @@ #include "config.h" #include "signature.h" #include "swupd.h" +#include "swupd-build-variant.h" #include "xattrs.h" #define MANIFEST_LINE_MAXLEN 8192 @@ -521,7 +522,7 @@ static int retrieve_manifests(int current, int version, char *component, struct goto out; } - string_or_die(&tar, "tar -C %s/%i -xf %s/%i/Manifest.%s.tar 2> /dev/null", + string_or_die(&tar, TAR_COMMAND " -C %s/%i -xf %s/%i/Manifest.%s.tar 2> /dev/null", STATE_DIR, version, STATE_DIR, version, component); /* this is is historically a point of odd errors */ diff --git a/src/packs.c b/src/packs.c index b43862cb..0c70c899 100644 --- a/src/packs.c +++ b/src/packs.c @@ -76,7 +76,7 @@ static int download_pack(int oldversion, int newversion, char *module) free(url); printf("Extracting pack.\n"); - string_or_die(&tar, "tar -C %s " TAR_PERM_ATTR_ARGS " -xf %s/pack-%s-from-%i-to-%i.tar 2> /dev/null", + string_or_die(&tar, TAR_COMMAND " -C %s " TAR_PERM_ATTR_ARGS " -xf %s/pack-%s-from-%i-to-%i.tar 2> /dev/null", STATE_DIR, STATE_DIR, module, oldversion, newversion); err = system(tar); diff --git a/src/staging.c b/src/staging.c index c5d6a514..cd4c3100 100644 --- a/src/staging.c +++ b/src/staging.c @@ -148,8 +148,8 @@ int do_staging(struct file *file, struct manifest *MoM) 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", + 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); ret = system(tarcommand); if (WIFEXITED(ret)) { @@ -186,8 +186,8 @@ int do_staging(struct file *file, struct manifest *MoM) 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", + 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); ret = system(tarcommand); if (WIFEXITED(ret)) {