From ccec88f11a44746f78f88aac90f5172a52e04506 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Wed, 14 Sep 2022 15:51:55 -0400 Subject: [PATCH] FreeBSD: Fix integer conversion for vnlru_free{,_vfsops}() When reviewing #13875, I noticed that our FreeBSD code has an issue where it converts from `int64_t` to `int` when calling `vnlru_free{,_vfsops}()`. The result is that if the int64_t is `1 << 36`, the int will be 0, since the low bits are 0. Even when some low bits are set, a value such as `((1 << 36) + 1)` would truncate to 1, which is wrong. There is protection against this on 32-bit platforms, but on 64-bit platforms, there is no check to protect us, so we add a check. Reviewed-by: Alexander Motin Reviewed-by: Ryan Moeller Signed-off-by: Richard Yao Closes #13882 --- module/os/freebsd/zfs/arc_os.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/os/freebsd/zfs/arc_os.c b/module/os/freebsd/zfs/arc_os.c index b4833aded..f1a3a0faf 100644 --- a/module/os/freebsd/zfs/arc_os.c +++ b/module/os/freebsd/zfs/arc_os.c @@ -142,6 +142,12 @@ arc_prune_task(void *arg) int64_t nr_scan = (intptr_t)arg; arc_reduce_target_size(ptob(nr_scan)); + +#ifndef __ILP32__ + if (nr_scan > INT_MAX) + nr_scan = INT_MAX; +#endif + #if __FreeBSD_version >= 1300139 sx_xlock(&arc_vnlru_lock); vnlru_free_vfsops(nr_scan, &zfs_vfsops, arc_vnlru_marker);