diff mbox series

[v2,1/1] no-reinstalling feature

Message ID 20190222212216.1850-1-james.hilliard1@gmail.com
State Accepted
Headers show
Series [v2,1/1] no-reinstalling feature | expand

Commit Message

James Hilliard Feb. 22, 2019, 9:22 p.m. UTC
From: James Hilliard <james.hilliard1@gmail.com>

Some projects require a way to prevent reinstallation of the current firmware
version to prevent repeated updates. For such cases, a new command line
parameter is introduced (-R <current version>) to inform SWUpdate about the
current version. SWUpdate performs a simple string comparision to determine
if the current version is the same as the installed version. We do this so
that no-reinstalling can be used with any versioning format.

We also ensure that the no-downgrading feature doesn't prevent installation
of the existing firmware, it's expected that the no-downgrading feature is
used to enforce a minimum firmware version as opposed to preventing
reinstallation of the existing firmware version, there may be cases where
the minimum version is not the same as the current version, for example a
device may have multiple firmware versions to choose from with the minimum
required version being lower than the current version. For this reason we
enforce the no-downgrading requirement separately from no-reinstalling.

Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
 core/parser.c           | 17 +++++++++++++++--
 core/swupdate.c         | 17 ++++++++++++++---
 doc/source/swupdate.rst |  7 ++++++-
 include/swupdate.h      |  2 ++
 4 files changed, 37 insertions(+), 6 deletions(-)

Comments

Stefano Babic Feb. 25, 2019, 8:44 a.m. UTC | #1
Hi James,

On 22/02/19 22:22, james.hilliard1@gmail.com wrote:
> From: James Hilliard <james.hilliard1@gmail.com>
> 
> Some projects require a way to prevent reinstallation of the current firmware
> version to prevent repeated updates. For such cases, a new command line
> parameter is introduced (-R <current version>) to inform SWUpdate about the
> current version. SWUpdate performs a simple string comparision to determine
> if the current version is the same as the installed version. We do this so
> that no-reinstalling can be used with any versioning format.
> 
> We also ensure that the no-downgrading feature doesn't prevent installation
> of the existing firmware, it's expected that the no-downgrading feature is
> used to enforce a minimum firmware version as opposed to preventing
> reinstallation of the existing firmware version, there may be cases where
> the minimum version is not the same as the current version, for example a
> device may have multiple firmware versions to choose from with the minimum
> required version being lower than the current version. For this reason we
> enforce the no-downgrading requirement separately from no-reinstalling.
> 
> Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
> ---


Applied to -master, thanks !

Best regards,
Stefano Babic
diff mbox series

Patch

diff --git a/core/parser.c b/core/parser.c
index 65dc8d1..313201f 100644
--- a/core/parser.c
+++ b/core/parser.c
@@ -257,11 +257,24 @@  int parse(struct swupdate_cfg *sw, const char *descfile)
 	 * newer version
 	 */
 	if (sw->globals.no_downgrading) {
-		__u64 currentversion = version_to_number(sw->globals.current_version);
+		__u64 minimum_version = version_to_number(sw->globals.minimum_version);
 		__u64 newversion = version_to_number(sw->version);
 
-		if (newversion <= currentversion) {
+		if (newversion < minimum_version) {
 			ERROR("No downgrading allowed: new version %s <= installed %s",
+				sw->version, sw->globals.minimum_version);
+			return -EPERM;
+		}
+	}
+
+	/*
+	 * If reinstalling is not allowed, compare
+	 * version strings
+	 */
+	if (sw->globals.no_reinstalling) {
+
+		if (strcmp(sw->version, sw->globals.current_version) == 0) {
+			ERROR("No reinstalling allowed: new version %s == installed %s",
 				sw->version, sw->globals.current_version);
 			return -EPERM;
 		}
diff --git a/core/swupdate.c b/core/swupdate.c
index 4f3d9d6..476358b 100644
--- a/core/swupdate.c
+++ b/core/swupdate.c
@@ -79,6 +79,7 @@  static struct option long_options[] = {
 	{"output", required_argument, NULL, 'o'},
 	{"dry-run", no_argument, NULL, 'n'},
 	{"no-downgrading", required_argument, NULL, 'N'},
+	{"no-reinstalling", required_argument, NULL, 'R'},
 #ifdef CONFIG_SIGNED_IMAGES
 	{"key", required_argument, NULL, 'k'},
 	{"ca-path", required_argument, NULL, 'k'},
@@ -140,6 +141,7 @@  static void usage(char *programname)
 #endif
 		" -n, --dry-run                  : run SWUpdate without installing the software\n"
 		" -N, --no-downgrading <version> : not install a release older as <version>\n"
+		" -R, --no-reinstalling <version>: not install a release same as <version>\n"
 		" -o, --output <output file>     : saves the incoming stream\n"
 		" -v, --verbose                  : be verbose, set maximum loglevel\n"
 		"     --version                  : print SWUpdate version and exit\n"
@@ -503,9 +505,13 @@  static int read_globals_settings(void *elem, void *data)
 	get_field(LIBCFG_PARSER, elem, "loglevel", &sw->globals.loglevel);
 	get_field(LIBCFG_PARSER, elem, "syslog", &sw->globals.syslog_enabled);
 	GET_FIELD_STRING(LIBCFG_PARSER, elem,
-				"no-downgrading", sw->globals.current_version);
-	if (strlen(sw->globals.current_version))
+				"no-downgrading", sw->globals.minimum_version);
+	if (strlen(sw->globals.minimum_version))
 		sw->globals.no_downgrading = 1;
+	GET_FIELD_STRING(LIBCFG_PARSER, elem,
+				"no-reinstalling", sw->globals.current_version);
+	if (strlen(sw->globals.current_version))
+		sw->globals.no_reinstalling = 1;
 	GET_FIELD_STRING(LIBCFG_PARSER, elem,
 				"cert-purpose", tmp);
 	if (tmp[0] != '\0')
@@ -598,7 +604,7 @@  int main(int argc, char **argv)
 #endif
 	memset(main_options, 0, sizeof(main_options));
 	memset(image_url, 0, sizeof(image_url));
-	strcpy(main_options, "vhni:e:l:Lcf:p:o:N:");
+	strcpy(main_options, "vhni:e:l:Lcf:p:o:N:R:");
 #ifdef CONFIG_MTD
 	strcat(main_options, "b:");
 #endif
@@ -741,6 +747,11 @@  int main(int argc, char **argv)
 #endif
 		case 'N':
 			swcfg.globals.no_downgrading = 1;
+			strncpy(swcfg.globals.minimum_version, optarg,
+				sizeof(swcfg.globals.minimum_version));
+			break;
+		case 'R':
+			swcfg.globals.no_reinstalling = 1;
 			strncpy(swcfg.globals.current_version, optarg,
 				sizeof(swcfg.globals.current_version));
 			break;
diff --git a/doc/source/swupdate.rst b/doc/source/swupdate.rst
index 9e36924..8d664b7 100644
--- a/doc/source/swupdate.rst
+++ b/doc/source/swupdate.rst
@@ -501,7 +501,7 @@  Command line parameters
 +-------------+----------+--------------------------------------------+
 | -n          |    -     | run SWUpdate in dry-run mode.              |
 +-------------+----------+--------------------------------------------+
-| -N          | string   | passed the current installed version of    |
+| -N          | string   | passed the minimum required version of     |
 |             |          | software. This will be checked with the    |
 |             |          | version of new software and forbids        |
 |             |          | downgrading.                               |
@@ -509,6 +509,11 @@  Command line parameters
 |             |          | major.minor.rev.build                      |
 |             |          | each field is in the range 0..65535        |
 +-------------+----------+--------------------------------------------+
+| -R          | string   | passed the current installed version of    |
+|             |          | software. This will be checked with the    |
+|             |          | version of new software and forbids        |
+|             |          | reinstalling.                              |
++-------------+----------+--------------------------------------------+
 | -o <file>   | string   | saves the stream (SWU) on a file           |
 +-------------+----------+--------------------------------------------+
 | -v          |    -     | activate verbose output                    |
diff --git a/include/swupdate.h b/include/swupdate.h
index b54b904..69f2a7f 100644
--- a/include/swupdate.h
+++ b/include/swupdate.h
@@ -111,9 +111,11 @@  struct swupdate_global_cfg {
 	int syslog_enabled;
 	int dry_run;
 	int no_downgrading;
+	int no_reinstalling;
 	char publickeyfname[SWUPDATE_GENERAL_STRING_SIZE];
 	char aeskeyfname[SWUPDATE_GENERAL_STRING_SIZE];
 	char postupdatecmd[SWUPDATE_GENERAL_STRING_SIZE];
+	char minimum_version[SWUPDATE_GENERAL_STRING_SIZE];
 	char current_version[SWUPDATE_GENERAL_STRING_SIZE];
 	int cert_purpose;
 	char forced_signer_name[SWUPDATE_GENERAL_STRING_SIZE];