Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e55588c4 authored by Zhihao Cheng's avatar Zhihao Cheng Committed by Greg Kroah-Hartman
Browse files

ubi: Fix failure attaching when vid_hdr offset equals to (sub)page size



commit 1e020e1b96afdecd20680b5b5be2a6ffc3d27628 upstream.

Following process will make ubi attaching failed since commit
1b42b1a36fc946 ("ubi: ensure that VID header offset ... size"):

ID="0xec,0xa1,0x00,0x15" # 128M 128KB 2KB
modprobe nandsim id_bytes=$ID
flash_eraseall /dev/mtd0
modprobe ubi mtd="0,2048"  # set vid_hdr offset as 2048 (one page)
(dmesg):
  ubi0 error: ubi_attach_mtd_dev [ubi]: VID header offset 2048 too large.
  UBI error: cannot attach mtd0
  UBI error: cannot initialize UBI, error -22

Rework original solution, the key point is making sure
'vid_hdr_shift + UBI_VID_HDR_SIZE < ubi->vid_hdr_alsize',
so we should check vid_hdr_shift rather not vid_hdr_offset.
Then, ubi still support (sub)page aligined VID header offset.

Fixes: 1b42b1a36fc946 ("ubi: ensure that VID header offset ... size")
Signed-off-by: default avatarZhihao Cheng <chengzhihao1@huawei.com>
Tested-by: default avatarNicolas Schichan <nschichan@freebox.fr>
Tested-by: Miquel Raynal <miquel.raynal@bootlin.com> # v5.10, v4.19
Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a652c30f
Loading
Loading
Loading
Loading
+15 −6
Original line number Diff line number Diff line
@@ -644,12 +644,6 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024)
	ubi->ec_hdr_alsize = ALIGN(UBI_EC_HDR_SIZE, ubi->hdrs_min_io_size);
	ubi->vid_hdr_alsize = ALIGN(UBI_VID_HDR_SIZE, ubi->hdrs_min_io_size);

	if (ubi->vid_hdr_offset && ((ubi->vid_hdr_offset + UBI_VID_HDR_SIZE) >
	    ubi->vid_hdr_alsize)) {
		ubi_err(ubi, "VID header offset %d too large.", ubi->vid_hdr_offset);
		return -EINVAL;
	}

	dbg_gen("min_io_size      %d", ubi->min_io_size);
	dbg_gen("max_write_size   %d", ubi->max_write_size);
	dbg_gen("hdrs_min_io_size %d", ubi->hdrs_min_io_size);
@@ -667,6 +661,21 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024)
						ubi->vid_hdr_aloffset;
	}

	/*
	 * Memory allocation for VID header is ubi->vid_hdr_alsize
	 * which is described in comments in io.c.
	 * Make sure VID header shift + UBI_VID_HDR_SIZE not exceeds
	 * ubi->vid_hdr_alsize, so that all vid header operations
	 * won't access memory out of bounds.
	 */
	if ((ubi->vid_hdr_shift + UBI_VID_HDR_SIZE) > ubi->vid_hdr_alsize) {
		ubi_err(ubi, "Invalid VID header offset %d, VID header shift(%d)"
			" + VID header size(%zu) > VID header aligned size(%d).",
			ubi->vid_hdr_offset, ubi->vid_hdr_shift,
			UBI_VID_HDR_SIZE, ubi->vid_hdr_alsize);
		return -EINVAL;
	}

	/* Similar for the data offset */
	ubi->leb_start = ubi->vid_hdr_offset + UBI_VID_HDR_SIZE;
	ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size);