[bug report] UBI: Unsorted Block Images

Dan Carpenter dan.carpenter at linaro.org
Tue Apr 1 01:11:43 PDT 2025


On Tue, Apr 01, 2025 at 02:46:35PM +0800, Zhihao Cheng wrote:
> 在 2025/3/31 23:14, Dan Carpenter 写道:
> > On Mon, Mar 31, 2025 at 08:43:55PM +0800, Zhihao Cheng wrote:
> > > 在 2025/3/31 17:46, Dan Carpenter 写道:
> > > Hi Dan,
> > > > Hello Artem B. Bityutskiy,
> > > > 
> > > > Commit 801c135ce73d ("UBI: Unsorted Block Images") from Jun 27, 2006
> > > > (linux-next), leads to the following Smatch static checker warning:
> > > > 
> > > > 	drivers/mtd/ubi/vtbl.c:844 ubi_read_volume_table()
> > > > 	warn: 'ubi->vtbl' can also be NULL
> > > > 
> > > [...]
> > > >      431          if (!leb_corrupted[0]) {
> > > >      432                  /* LEB 0 is OK */
> > > >      433                  if (leb[1])
> > > >      434                          leb_corrupted[1] = memcmp(leb[0], leb[1],
> > > >      435                                                    ubi->vtbl_size);
> > > >      436                  if (leb_corrupted[1]) {
> > > >      437                          ubi_warn(ubi, "volume table copy #2 is corrupted");
> > > >      438                          err = create_vtbl(ubi, ai, 1, leb[0]);
> > > >      439                          if (err)
> > > >      440                                  goto out_free;
> > > >      441                          ubi_msg(ubi, "volume table was restored");
> > > >      442                  }
> > > >      443
> > > >      444                  /* Both LEB 1 and LEB 2 are OK and consistent */
> > > >      445                  vfree(leb[1]);
> > > >      446                  return leb[0];
> > > >      447          } else {
> > > >      448                  /* LEB 0 is corrupted or does not exist */
> > > >      449                  if (leb[1]) {
> > > >                               ^^^^^^
> > > > Is this NULL check required?
> > > 
> > > Yes, leb 1 could be corrupted(eg. bad ec header), then the leb 1 won't be
> > > scanned during attaching, which means 'leb[1]' won't be initialized by
> > > process_lvol().
> > > > 
> > > >      450                          leb_corrupted[1] = vtbl_check(ubi, leb[1]);
> > > >      451                          if (leb_corrupted[1] < 0)
> > > >      452                                  goto out_free;
> > > >      453                  }
> > > >      454                  if (leb_corrupted[1]) {
> > > >      455                          /* Both LEB 0 and LEB 1 are corrupted */
> > > >      456                          ubi_err(ubi, "both volume tables are corrupted");
> > > >      457                          goto out_free;
> > > >      458                  }
> > > >      459
> > > >      460                  ubi_warn(ubi, "volume table copy #1 is corrupted");
> > > >                                                            ^^
> > > > This should say #0 I think?
> > > 
> > > I guess that '#1' refers to leb 0 and '#2' refers to leb 1.
> > > > 
> > > >      461                  err = create_vtbl(ubi, ai, 0, leb[1]);
> > > >                                                         ^^^^^^
> > > >      462                  if (err)
> > > >      463                          goto out_free;
> > > >      464                  ubi_msg(ubi, "volume table was restored");
> > > >      465
> > > >      466                  vfree(leb[0]);
> > > >      467                  return leb[1];
> > > >                                  ^^^^^^
> > > > The NULL check on line 449 makes Smatch think this can be NULL.
> > > 
> > > In theory, the 'NULL' won't be a return value, these cases are avoided by
> > > leb_corrupted checking branches.
> > 
> > No, that doesn't follow.  If leb[1] is NULL then we know that
> > leb_corrupted[1] is zero.  It's only set when leb[1] is non-NULL.
> > 
> 
> Hi Dan. The leb_corrupted array is initialized as '1' in line 369:
> 369         int leb_corrupted[UBI_LAYOUT_VOLUME_EBS] = {1, 1};
> 
> If leb[1] is NULL. the leb_corrupted[1] is non-zero, then the function will
> exit in following branch:
>  454                 if (leb_corrupted[1]) {
>  455                         /* Both LEB 0 and LEB 1 are corrupted */
>  456                         ubi_err(ubi, "both volume tables are
> corrupted");
>  457                         goto out_free;
>  458                 }
> 
> Am i missing something?
> 

Sorry, yeah.  I got mixed up with the line before.  I apologize for that.

regards,
dan carpenter




More information about the linux-mtd mailing list