diff --git a/src/util/fs_helpers.cpp b/src/util/fs_helpers.cpp index 3efc9fda4b3..e2b4c899c99 100644 --- a/src/util/fs_helpers.cpp +++ b/src/util/fs_helpers.cpp @@ -179,11 +179,13 @@ int RaiseFileDescriptorLimit(int min_fd) // Check the (possibly raised) current soft limit against the special // value of RLIM_INFINITY. Some platforms implement this as the maximum // uint64, others as int64 (-1). Avoid casting even if the return type - // is changed to uint64_t. - if (limitFD.rlim_cur == RLIM_INFINITY) { + // is changed to uint64_t. We also cap unlikely but possible values + // that would overflow int. + if (limitFD.rlim_cur == RLIM_INFINITY || + std::cmp_greater_equal(limitFD.rlim_cur, std::numeric_limits::max())) { return std::numeric_limits::max(); } - return limitFD.rlim_cur; + return static_cast(limitFD.rlim_cur); } return min_fd; // getrlimit failed, assume it's fine #endif diff --git a/test/functional/feature_init.py b/test/functional/feature_init.py index ee28a2871a5..e7c226b2556 100755 --- a/test/functional/feature_init.py +++ b/test/functional/feature_init.py @@ -348,6 +348,15 @@ class InitTest(BitcoinTestFramework): self.log.info("Testing node startup with RLIM_INFINITY fd limit") self.restart_node_with_fd_limit(self.RLIM_INFINITY) + def init_rlimit_large_test(self): + """Test that bitcoind starts correctly when the soft RLIMIT_NOFILE limit is above INT_MAX.""" + if self.RLIM_INFINITY is None: + self.log.info("Skipping: resource module not available") + return + + self.log.info("Testing node startup with fd limit above INT_MAX") + self.restart_node_with_fd_limit(1 << 31) + def run_test(self): self.init_pid_test() self.init_stress_test_interrupt() @@ -355,6 +364,7 @@ class InitTest(BitcoinTestFramework): self.break_wait_test() self.init_empty_test() self.init_rlimit_test() + self.init_rlimit_large_test() if __name__ == '__main__':