From: Michael Tokarev Date: Thu, 17 Nov 2022 20:51:03 +0000 (+0300) Subject: fruit: fixup size_t overflow check X-Git-Tag: tdb-1.4.13~234 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4e36eec244507430991971466d79891e7fd3a7d7;p=thirdparty%2Fsamba.git fruit: fixup size_t overflow check https://bugzilla.samba.org/show_bug.cgi?id=13622 . The check ('bandsize > SIZE_MAX/nbands' is wrong, since it caps the total size to the wrong data type size_t instead of off_t -- samba is always built with LFS support so off_t is always 64bits, while size_t is 32bit son a 32bit platform. This has caused issues already, capping size of the bands: https://bugs.debian.org/974868 . Since there's another overflow check already, let's just fold this one to the following one and log a more complete error message. Signed-off-by: Michael Tokarev Reviewed-by: Ralph Boehme Reviewed-by: Pavel Filipenský Autobuild-User(master): Pavel Filipensky Autobuild-Date(master): Sat Jan 4 20:47:35 UTC 2025 on atb-devel-224 --- diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c index 76ad0133186..39deb16105d 100644 --- a/source3/modules/vfs_fruit.c +++ b/source3/modules/vfs_fruit.c @@ -5260,22 +5260,15 @@ static bool fruit_tmsize_do_dirent(vfs_handle_struct *handle, return true; } - /* - * Arithmetic on 32-bit systems may cause overflow, depending on - * size_t precision. First we check its unlikely, then we - * force the precision into target off_t, then we check that - * the total did not overflow either. - */ - if (bandsize > SIZE_MAX/nbands) { - DBG_ERR("tmsize potential overflow: bandsize [%zu] nbands [%zu]\n", - bandsize, nbands); - return false; - } tm_size = (off_t)bandsize * (off_t)nbands; - - if (state->total_size + tm_size < state->total_size) { - DBG_ERR("tm total size overflow: bandsize [%zu] nbands [%zu]\n", - bandsize, nbands); + if (tm_size / nbands != bandsize || + state->total_size + tm_size < state->total_size) + { + DBG_ERR("tm size overflow: total_size [%jd]" + " bandsize [%zu] nbands [%zu]\n", + (intmax_t)state->total_size, + bandsize, + nbands); return false; }