base-files: fix sysupgrade for kernel-out-of-UBI
authorRodrigo Balerdi <lanchon@gmail.com>
Mon, 2 May 2022 08:33:01 +0000 (05:33 -0300)
committerDaniel Golle <daniel@makrotopia.org>
Mon, 2 May 2022 11:42:15 +0000 (12:42 +0100)
Commit ecbcc0b59551 bricks devices on which the raw kernel and UBI mtd
partitions overlap.

This is the case of the ZyXEL NR7101 for example. Its OEM bootloader has
no UBI support. OpenWrt splits the stock kernel mtd partition into a raw
kernel part used by the bootloader and a UBI part used to store rootfs
and rootfs_data. Running mtd erase on the complete partition during
sysupgrade erases the UBI part and results in a soft brick.

Arguably the best solution would be to fix the partition layouts so that
kernel and UBI partitions do not overlap, also including a stock_kernel
partition to help reverting to stock firmware. This would have the added
benefit of protecting UBI from kernel images that are excessively large.

Fixes: ecbcc0b59551 ("base-files: safer sysupgrade.tar for kernel-out-of-UBI")
Reported-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: Rodrigo Balerdi <lanchon@gmail.com>
package/base-files/files/lib/upgrade/nand.sh

index 5ecdb0ff23636b6a95edf8edf7b33c4f78703700..c9960bf9d44d1d2375b20398e56465cca54e1582 100644 (file)
@@ -305,7 +305,11 @@ nand_upgrade_tar() {
        local ubi_kernel_length
        if [ "$kernel_length" ]; then
                if [ "$kernel_mtd" ]; then
-                       mtd erase "$CI_KERNPART"
+                       # On some devices, the raw kernel and ubi partitions overlap.
+                       # These devices brick if the kernel partition is erased.
+                       # Hence only invalidate kernel for now.
+                       dd if=/dev/zero bs=4096 count=1 2>/dev/null | \
+                               mtd write - "$CI_KERNPART"
                else
                        ubi_kernel_length="$kernel_length"
                fi
@@ -322,7 +326,7 @@ nand_upgrade_tar() {
        if [ "$kernel_length" ]; then
                if [ "$kernel_mtd" ]; then
                        tar xf "$tar_file" "$board_dir/kernel" -O | \
-                               mtd -n write - "$CI_KERNPART"
+                               mtd write - "$CI_KERNPART"
                else
                        local kern_ubivol="$( nand_find_volume $ubidev "$CI_KERNPART" )"
                        tar xf "$tar_file" "$board_dir/kernel" -O | \