diff mbox series

[V2] Same version must be discarded by no-downgrading

Message ID 20190206164819.28369-1-sbabic@denx.de
State Accepted
Headers show
Series [V2] Same version must be discarded by no-downgrading | expand

Commit Message

Stefano Babic Feb. 6, 2019, 4:48 p.m. UTC
no-downgrading means that only a newer version can be installed. If a
SWU contains the same version of what is already running, it must be
rejected.

Signed-off-by: Stefano Babic <sbabic@denx.de>
Reported-by: Matthias Schöpfer <matthias.schoepfer@googlemail.com>
---

Changes since V1:
	- adjust error message

 core/parser.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

James Hilliard Feb. 17, 2019, 11:03 p.m. UTC | #1
On Wednesday, February 6, 2019 at 9:48:25 AM UTC-7, Stefano Babic wrote:
> no-downgrading means that only a newer version can be installed. If a
> SWU contains the same version of what is already running, it must be
> rejected.
This behavior should probably be configurable, there are use cases where
it would make sense to allow flashing the same version as what is running
while not allowing older versions. For example my build system produces
installer images along side swu files generated from the same rootfs.

The installer images are used for initial automatic installation to the
internal hard disk from a USB flash drive, this is done by executing the
normal swu update from the running USB flash drive. I've designed the swu
so that it always tries to install to the embedded hard disk regardless
of where it is running from. This change would cause problems since due to
the installer images and swu files being built at the same time using the
same rootfs the versions will be the same and thus the automatic installation
will fail.

For firmware I built targeting a different embedded system I used a multi-stage
migration process which also required installation of a swu file where the
version being installed is the same as the running version, this was due to
re-partitioning of the NAND by way of a ramdisk image installed via the legacy
firmware update method, once running from the ramdisk the swu would then be
flashed which would install itself with the new partition layout to the NAND.
Since the ramdisk migration image is built at the same time as the swu, the
versions would also be the same causing the migration to fail.

If one is using a dual image A/B partitioning scheme installation to both
partitions would also require the ability to flash images with the same
version.

In cases where not all components of the swu are installed as read only it
would likely also make sense to allow installation of the same version as a
way to reset to default.

From my understanding the main use case for this feature is to prevent
installing older vulnerable and/or incompatible versions, I'm curious
in what situations it would even make sense to prevent installation of the
same versions.
> 
> Signed-off-by: Stefano Babic <sbabic@denx.de>
> Reported-by: Matthias Schöpfer <matthias.schoepfer@googlemail.com>
> ---
> 
> Changes since V1:
> 	- adjust error message
> 
>  core/parser.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/core/parser.c b/core/parser.c
> index 74375fd..65dc8d1 100644
> --- a/core/parser.c
> +++ b/core/parser.c
> @@ -260,8 +260,8 @@ int parse(struct swupdate_cfg *sw, const char *descfile)
>  		__u64 currentversion = version_to_number(sw->globals.current_version);
>  		__u64 newversion = version_to_number(sw->version);
>  
> -		if (newversion < currentversion) {
> -			ERROR("No downgrading allowed: new version %s < installed %s",
> +		if (newversion <= currentversion) {
> +			ERROR("No downgrading allowed: new version %s <= installed %s",
>  				sw->version, sw->globals.current_version);
>  			return -EPERM;
>  		}
> -- 
> 2.17.1
Stefano Babic Feb. 18, 2019, 9:04 a.m. UTC | #2
Hi James,

On 18/02/19 00:03, james.hilliard1@gmail.com wrote:
> On Wednesday, February 6, 2019 at 9:48:25 AM UTC-7, Stefano Babic wrote:
>> no-downgrading means that only a newer version can be installed. If a
>> SWU contains the same version of what is already running, it must be
>> rejected.
> This behavior should probably be configurable, there are use cases where
> it would make sense to allow flashing the same version as what is running
> while not allowing older versions.

Yes, it would be better if the behavior is configurable or even if it is
possible to pass to SWUpdate a generic rule for version detection.

> For example my build system produces
> installer images along side swu files generated from the same rootfs.
> 
> The installer images are used for initial automatic installation to the
> internal hard disk from a USB flash drive, this is done by executing the
> normal swu update from the running USB flash drive. I've designed the swu
> so that it always tries to install to the embedded hard disk regardless
> of where it is running from. This change would cause problems since due to
> the installer images and swu files being built at the same time using the
> same rootfs the versions will be the same and thus the automatic installation
> will fail.
> 
> For firmware I built targeting a different embedded system I used a multi-stage
> migration process which also required installation of a swu file where the
> version being installed is the same as the running version, this was due to
> re-partitioning of the NAND by way of a ramdisk image installed via the legacy
> firmware update method, once running from the ramdisk the swu would then be
> flashed which would install itself with the new partition layout to the NAND.
> Since the ramdisk migration image is built at the same time as the swu, the
> versions would also be the same causing the migration to fail.

This is mostly due to the split of the update in a multistage process.

> 
> If one is using a dual image A/B partitioning scheme installation to both
> partitions would also require the ability to flash images with the same
> version.

Well, in this case I diagree. In a A/B partitioning schema, just one
partition is considered valid because the stand-by can be in any
possible state, even half installed and then broken. There is no
advantages to install the same version on both copies.

> 
> In cases where not all components of the swu are installed as read only it
> would likely also make sense to allow installation of the same version as a
> way to reset to default.
> 
> From my understanding the main use case for this feature is to prevent
> installing older vulnerable

The requirement for this use case is to avoid to install a vulnerable
version and constrain to upgrade to a newer (hopefully better) version.
Installing the same version is considered useless and potentially dangerous.

> and/or incompatible versions,

No, this was not a requirement. This looks to me a more strict
requirement in your use case, because in a multi-stage process you
should check that the application (or following stages) are compatible
with the OS /rootfs. As this is a global check (the version apply to the
whole SWU), there is no incompatibility in case of one-stage process.

> I'm curious
> in what situations it would even make sense to prevent installation of the
> same versions.

We can consider a A/B approach. If the current copy is vulnerable, the
same copy can be installed in the spare storage. If the attacker is also
able to switch between copies, he could theoretically avoid to upgrade
in this copy to continue to use it to exploit the device. As I said, at
least theoretically.

Best regards,
Stefano Babic

>>
>> Signed-off-by: Stefano Babic <sbabic@denx.de>
>> Reported-by: Matthias Schöpfer <matthias.schoepfer@googlemail.com>
>> ---
>>
>> Changes since V1:
>> 	- adjust error message
>>
>>  core/parser.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/core/parser.c b/core/parser.c
>> index 74375fd..65dc8d1 100644
>> --- a/core/parser.c
>> +++ b/core/parser.c
>> @@ -260,8 +260,8 @@ int parse(struct swupdate_cfg *sw, const char *descfile)
>>  		__u64 currentversion = version_to_number(sw->globals.current_version);
>>  		__u64 newversion = version_to_number(sw->version);
>>  
>> -		if (newversion < currentversion) {
>> -			ERROR("No downgrading allowed: new version %s < installed %s",
>> +		if (newversion <= currentversion) {
>> +			ERROR("No downgrading allowed: new version %s <= installed %s",
>>  				sw->version, sw->globals.current_version);
>>  			return -EPERM;
>>  		}
>> -- 
>> 2.17.1
>
'Darko Komljenovic' via swupdate Feb. 18, 2019, 9:13 a.m. UTC | #3
Hi!

For the case of the initial install you mentioned, it would be a 
workaround to drop -N here, wouldn't it?

Nevertheless, I guess, to satisfy all needs, it would be easiest thing 
to make a separate commandline switch, one that does strict (i.e. > ) 
check and one that allows same version (i.e. >=) for whatever reasons.

@James, the use case for forcing strict ( > ) is update through USB 
thumb drive, that would start an update loop, since the swu file gets 
found on every reboot and triggers udev and systemd jobs...

Regards,

	Matthias

On 2/18/19 10:04 AM, Stefano Babic wrote:
> Hi James,
> 
> On 18/02/19 00:03, james.hilliard1@gmail.com wrote:
>> On Wednesday, February 6, 2019 at 9:48:25 AM UTC-7, Stefano Babic wrote:
>>> no-downgrading means that only a newer version can be installed. If a
>>> SWU contains the same version of what is already running, it must be
>>> rejected.
>> This behavior should probably be configurable, there are use cases where
>> it would make sense to allow flashing the same version as what is running
>> while not allowing older versions.
> 
> Yes, it would be better if the behavior is configurable or even if it is
> possible to pass to SWUpdate a generic rule for version detection.
> 
>> For example my build system produces
>> installer images along side swu files generated from the same rootfs.
>>
>> The installer images are used for initial automatic installation to the
>> internal hard disk from a USB flash drive, this is done by executing the
>> normal swu update from the running USB flash drive. I've designed the swu
>> so that it always tries to install to the embedded hard disk regardless
>> of where it is running from. This change would cause problems since due to
>> the installer images and swu files being built at the same time using the
>> same rootfs the versions will be the same and thus the automatic installation
>> will fail.
>>
>> For firmware I built targeting a different embedded system I used a multi-stage
>> migration process which also required installation of a swu file where the
>> version being installed is the same as the running version, this was due to
>> re-partitioning of the NAND by way of a ramdisk image installed via the legacy
>> firmware update method, once running from the ramdisk the swu would then be
>> flashed which would install itself with the new partition layout to the NAND.
>> Since the ramdisk migration image is built at the same time as the swu, the
>> versions would also be the same causing the migration to fail.
> 
> This is mostly due to the split of the update in a multistage process.
> 
>>
>> If one is using a dual image A/B partitioning scheme installation to both
>> partitions would also require the ability to flash images with the same
>> version.
> 
> Well, in this case I diagree. In a A/B partitioning schema, just one
> partition is considered valid because the stand-by can be in any
> possible state, even half installed and then broken. There is no
> advantages to install the same version on both copies.
> 
>>
>> In cases where not all components of the swu are installed as read only it
>> would likely also make sense to allow installation of the same version as a
>> way to reset to default.
>>
>>  From my understanding the main use case for this feature is to prevent
>> installing older vulnerable
> 
> The requirement for this use case is to avoid to install a vulnerable
> version and constrain to upgrade to a newer (hopefully better) version.
> Installing the same version is considered useless and potentially dangerous.
> 
>> and/or incompatible versions,
> 
> No, this was not a requirement. This looks to me a more strict
> requirement in your use case, because in a multi-stage process you
> should check that the application (or following stages) are compatible
> with the OS /rootfs. As this is a global check (the version apply to the
> whole SWU), there is no incompatibility in case of one-stage process.
> 
>> I'm curious
>> in what situations it would even make sense to prevent installation of the
>> same versions.
> 
> We can consider a A/B approach. If the current copy is vulnerable, the
> same copy can be installed in the spare storage. If the attacker is also
> able to switch between copies, he could theoretically avoid to upgrade
> in this copy to continue to use it to exploit the device. As I said, at
> least theoretically.
> 
> Best regards,
> Stefano Babic
> 
>>>
>>> Signed-off-by: Stefano Babic <sbabic@denx.de>
>>> Reported-by: Matthias Schöpfer <matthias.schoepfer@googlemail.com>
>>> ---
>>>
>>> Changes since V1:
>>> 	- adjust error message
>>>
>>>   core/parser.c | 4 ++--
>>>   1 file changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/core/parser.c b/core/parser.c
>>> index 74375fd..65dc8d1 100644
>>> --- a/core/parser.c
>>> +++ b/core/parser.c
>>> @@ -260,8 +260,8 @@ int parse(struct swupdate_cfg *sw, const char *descfile)
>>>   		__u64 currentversion = version_to_number(sw->globals.current_version);
>>>   		__u64 newversion = version_to_number(sw->version);
>>>   
>>> -		if (newversion < currentversion) {
>>> -			ERROR("No downgrading allowed: new version %s < installed %s",
>>> +		if (newversion <= currentversion) {
>>> +			ERROR("No downgrading allowed: new version %s <= installed %s",
>>>   				sw->version, sw->globals.current_version);
>>>   			return -EPERM;
>>>   		}
>>> -- 
>>> 2.17.1
>>
> 
>
James Hilliard Feb. 18, 2019, 9:27 a.m. UTC | #4
On Mon, Feb 18, 2019 at 2:13 AM 'Matthias Schöpfer' via swupdate
<swupdate@googlegroups.com> wrote:
>
> Hi!
>
> For the case of the initial install you mentioned, it would be a
> workaround to drop -N here, wouldn't it?
Well I use the same image for the installer so that would be a little tricky.
>
> Nevertheless, I guess, to satisfy all needs, it would be easiest thing
> to make a separate commandline switch, one that does strict (i.e. > )
> check and one that allows same version (i.e. >=) for whatever reasons.
Yeah, I'm thinking these are more separate, I'll throw together a patch.
>
> @James, the use case for forcing strict ( > ) is update through USB
> thumb drive, that would start an update loop, since the swu file gets
> found on every reboot and triggers udev and systemd jobs...
I think what you want there is a ( == ) check for that, so I'm thinking I'll
have a no-reinstall flag for that which just does a simple version string
comparison to prevent a USB update loop.
>
> Regards,
>
>         Matthias
>
> On 2/18/19 10:04 AM, Stefano Babic wrote:
> > Hi James,
> >
> > On 18/02/19 00:03, james.hilliard1@gmail.com wrote:
> >> On Wednesday, February 6, 2019 at 9:48:25 AM UTC-7, Stefano Babic wrote:
> >>> no-downgrading means that only a newer version can be installed. If a
> >>> SWU contains the same version of what is already running, it must be
> >>> rejected.
> >> This behavior should probably be configurable, there are use cases where
> >> it would make sense to allow flashing the same version as what is running
> >> while not allowing older versions.
> >
> > Yes, it would be better if the behavior is configurable or even if it is
> > possible to pass to SWUpdate a generic rule for version detection.
> >
> >> For example my build system produces
> >> installer images along side swu files generated from the same rootfs.
> >>
> >> The installer images are used for initial automatic installation to the
> >> internal hard disk from a USB flash drive, this is done by executing the
> >> normal swu update from the running USB flash drive. I've designed the swu
> >> so that it always tries to install to the embedded hard disk regardless
> >> of where it is running from. This change would cause problems since due to
> >> the installer images and swu files being built at the same time using the
> >> same rootfs the versions will be the same and thus the automatic installation
> >> will fail.
> >>
> >> For firmware I built targeting a different embedded system I used a multi-stage
> >> migration process which also required installation of a swu file where the
> >> version being installed is the same as the running version, this was due to
> >> re-partitioning of the NAND by way of a ramdisk image installed via the legacy
> >> firmware update method, once running from the ramdisk the swu would then be
> >> flashed which would install itself with the new partition layout to the NAND.
> >> Since the ramdisk migration image is built at the same time as the swu, the
> >> versions would also be the same causing the migration to fail.
> >
> > This is mostly due to the split of the update in a multistage process.
> >
> >>
> >> If one is using a dual image A/B partitioning scheme installation to both
> >> partitions would also require the ability to flash images with the same
> >> version.
> >
> > Well, in this case I diagree. In a A/B partitioning schema, just one
> > partition is considered valid because the stand-by can be in any
> > possible state, even half installed and then broken. There is no
> > advantages to install the same version on both copies.
> >
> >>
> >> In cases where not all components of the swu are installed as read only it
> >> would likely also make sense to allow installation of the same version as a
> >> way to reset to default.
> >>
> >>  From my understanding the main use case for this feature is to prevent
> >> installing older vulnerable
> >
> > The requirement for this use case is to avoid to install a vulnerable
> > version and constrain to upgrade to a newer (hopefully better) version.
> > Installing the same version is considered useless and potentially dangerous.
> >
> >> and/or incompatible versions,
> >
> > No, this was not a requirement. This looks to me a more strict
> > requirement in your use case, because in a multi-stage process you
> > should check that the application (or following stages) are compatible
> > with the OS /rootfs. As this is a global check (the version apply to the
> > whole SWU), there is no incompatibility in case of one-stage process.
> >
> >> I'm curious
> >> in what situations it would even make sense to prevent installation of the
> >> same versions.
> >
> > We can consider a A/B approach. If the current copy is vulnerable, the
> > same copy can be installed in the spare storage. If the attacker is also
> > able to switch between copies, he could theoretically avoid to upgrade
> > in this copy to continue to use it to exploit the device. As I said, at
> > least theoretically.
> >
> > Best regards,
> > Stefano Babic
> >
> >>>
> >>> Signed-off-by: Stefano Babic <sbabic@denx.de>
> >>> Reported-by: Matthias Schöpfer <matthias.schoepfer@googlemail.com>
> >>> ---
> >>>
> >>> Changes since V1:
> >>>     - adjust error message
> >>>
> >>>   core/parser.c | 4 ++--
> >>>   1 file changed, 2 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/core/parser.c b/core/parser.c
> >>> index 74375fd..65dc8d1 100644
> >>> --- a/core/parser.c
> >>> +++ b/core/parser.c
> >>> @@ -260,8 +260,8 @@ int parse(struct swupdate_cfg *sw, const char *descfile)
> >>>             __u64 currentversion = version_to_number(sw->globals.current_version);
> >>>             __u64 newversion = version_to_number(sw->version);
> >>>
> >>> -           if (newversion < currentversion) {
> >>> -                   ERROR("No downgrading allowed: new version %s < installed %s",
> >>> +           if (newversion <= currentversion) {
> >>> +                   ERROR("No downgrading allowed: new version %s <= installed %s",
> >>>                             sw->version, sw->globals.current_version);
> >>>                     return -EPERM;
> >>>             }
> >>> --
> >>> 2.17.1
> >>
> >
> >
>
>
> --
>
> Dr.-Ing. Matthias Schoepfer
> Mobile: +49 175 2062739
> email: matthias.schoepfer@googlemail.com
>
> --
> You received this message because you are subscribed to the Google Groups "swupdate" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to swupdate+unsubscribe@googlegroups.com.
> To post to this group, send email to swupdate@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
'Darko Komljenovic' via swupdate Feb. 18, 2019, 10:12 a.m. UTC | #5
Hi (James)!

On 2/18/19 10:27 AM, James Hilliard wrote:
> On Mon, Feb 18, 2019 at 2:13 AM 'Matthias Schöpfer' via swupdate
> <swupdate@googlegroups.com> wrote:
>> @James, the use case for forcing strict ( > ) is update through USB
>> thumb drive, that would start an update loop, since the swu file gets
>> found on every reboot and triggers udev and systemd jobs...
> I think what you want there is a ( == ) check for that, so I'm thinking I'll
> have a no-reinstall flag for that which just does a simple version string
> comparison to prevent a USB update loop.

Actually, I do not want do allow downgrades either. And, as you, I am 
using the same installer...

Regards,

     Matthias
James Hilliard Feb. 18, 2019, 10:24 a.m. UTC | #6
On Mon, Feb 18, 2019 at 3:12 AM Matthias Schoepfer
<matthias.schoepfer@googlemail.com> wrote:
>
> Hi (James)!
>
> On 2/18/19 10:27 AM, James Hilliard wrote:
> > On Mon, Feb 18, 2019 at 2:13 AM 'Matthias Schöpfer' via swupdate
> > <swupdate@googlegroups.com> wrote:
> >> @James, the use case for forcing strict ( > ) is update through USB
> >> thumb drive, that would start an update loop, since the swu file gets
> >> found on every reboot and triggers udev and systemd jobs...
> > I think what you want there is a ( == ) check for that, so I'm thinking I'll
> > have a no-reinstall flag for that which just does a simple version string
> > comparison to prevent a USB update loop.
>
> Actually, I do not want do allow downgrades either. And, as you, I am
> using the same installer...
I'm going to make the patch support that at the same time as well.

FYI the way I prevent looping is to have the installer manipulate the
boot order.
So when you boot to the USB drive it installs the swu which changes the
primary boot drive to the internal disk so that on reboot you no longer boot to
the USB installer drive.
>
> Regards,
>
>      Matthias
>
diff mbox series

Patch

diff --git a/core/parser.c b/core/parser.c
index 74375fd..65dc8d1 100644
--- a/core/parser.c
+++ b/core/parser.c
@@ -260,8 +260,8 @@  int parse(struct swupdate_cfg *sw, const char *descfile)
 		__u64 currentversion = version_to_number(sw->globals.current_version);
 		__u64 newversion = version_to_number(sw->version);
 
-		if (newversion < currentversion) {
-			ERROR("No downgrading allowed: new version %s < installed %s",
+		if (newversion <= currentversion) {
+			ERROR("No downgrading allowed: new version %s <= installed %s",
 				sw->version, sw->globals.current_version);
 			return -EPERM;
 		}