kernel: backport fix for recently introduced UBI bug
Import commit "ubi: Fix failure attaching when vid_hdr offset equals to (sub)page size" which did not yet make it to stable upstream Linux trees. Fixes: #12232 Fixes: #12339 Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
		| @@ -0,0 +1,69 @@ | ||||
| From 1e020e1b96afdecd20680b5b5be2a6ffc3d27628 Mon Sep 17 00:00:00 2001 | ||||
| From: Zhihao Cheng <chengzhihao1@huawei.com> | ||||
| Date: Mon, 6 Mar 2023 09:33:08 +0800 | ||||
| Subject: [PATCH] ubi: Fix failure attaching when vid_hdr offset equals to | ||||
|  (sub)page size | ||||
|  | ||||
| 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: Zhihao Cheng <chengzhihao1@huawei.com> | ||||
| Tested-by: Nicolas Schichan <nschichan@freebox.fr> | ||||
| Tested-by: Miquel Raynal <miquel.raynal@bootlin.com> # v5.10, v4.19 | ||||
| Signed-off-by: Richard Weinberger <richard@nod.at> | ||||
| --- | ||||
|  drivers/mtd/ubi/build.c | 21 +++++++++++++++------ | ||||
|  1 file changed, 15 insertions(+), 6 deletions(-) | ||||
|  | ||||
| --- a/drivers/mtd/ubi/build.c | ||||
| +++ b/drivers/mtd/ubi/build.c | ||||
| @@ -665,12 +665,6 @@ static int io_init(struct ubi_device *ub | ||||
|  	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); | ||||
| @@ -688,6 +682,21 @@ static int io_init(struct ubi_device *ub | ||||
|  						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); | ||||
| @@ -0,0 +1,69 @@ | ||||
| From 1e020e1b96afdecd20680b5b5be2a6ffc3d27628 Mon Sep 17 00:00:00 2001 | ||||
| From: Zhihao Cheng <chengzhihao1@huawei.com> | ||||
| Date: Mon, 6 Mar 2023 09:33:08 +0800 | ||||
| Subject: [PATCH] ubi: Fix failure attaching when vid_hdr offset equals to | ||||
|  (sub)page size | ||||
|  | ||||
| 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: Zhihao Cheng <chengzhihao1@huawei.com> | ||||
| Tested-by: Nicolas Schichan <nschichan@freebox.fr> | ||||
| Tested-by: Miquel Raynal <miquel.raynal@bootlin.com> # v5.10, v4.19 | ||||
| Signed-off-by: Richard Weinberger <richard@nod.at> | ||||
| --- | ||||
|  drivers/mtd/ubi/build.c | 21 +++++++++++++++------ | ||||
|  1 file changed, 15 insertions(+), 6 deletions(-) | ||||
|  | ||||
| --- a/drivers/mtd/ubi/build.c | ||||
| +++ b/drivers/mtd/ubi/build.c | ||||
| @@ -664,12 +664,6 @@ static int io_init(struct ubi_device *ub | ||||
|  	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); | ||||
| @@ -687,6 +681,21 @@ static int io_init(struct ubi_device *ub | ||||
|  						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); | ||||
| @@ -8,7 +8,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | ||||
|  | ||||
| --- a/drivers/mtd/ubi/build.c | ||||
| +++ b/drivers/mtd/ubi/build.c | ||||
| @@ -1192,6 +1192,73 @@ static struct mtd_info * __init open_mtd | ||||
| @@ -1201,6 +1201,73 @@ static struct mtd_info * __init open_mtd | ||||
|  	return mtd; | ||||
|  } | ||||
|   | ||||
| @@ -82,7 +82,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | ||||
|  static int __init ubi_init(void) | ||||
|  { | ||||
|  	int err, i, k; | ||||
| @@ -1275,6 +1342,12 @@ static int __init ubi_init(void) | ||||
| @@ -1284,6 +1351,12 @@ static int __init ubi_init(void) | ||||
|  		} | ||||
|  	} | ||||
|   | ||||
|   | ||||
| @@ -8,7 +8,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | ||||
|  | ||||
| --- a/drivers/mtd/ubi/build.c | ||||
| +++ b/drivers/mtd/ubi/build.c | ||||
| @@ -1191,6 +1191,73 @@ static struct mtd_info * __init open_mtd | ||||
| @@ -1200,6 +1200,73 @@ static struct mtd_info * __init open_mtd | ||||
|  	return mtd; | ||||
|  } | ||||
|   | ||||
| @@ -82,7 +82,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | ||||
|  static int __init ubi_init(void) | ||||
|  { | ||||
|  	int err, i, k; | ||||
| @@ -1274,6 +1341,12 @@ static int __init ubi_init(void) | ||||
| @@ -1283,6 +1350,12 @@ static int __init ubi_init(void) | ||||
|  		} | ||||
|  	} | ||||
|   | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Daniel Golle
					Daniel Golle