factor: fix an infinite loop with some large numbers

* src/factor.c (mulredc2): Add the carry to p1, which is the high word
of a two-word integer created by summing two single-word integers and is
therefore unable to overflow, instead of using a low word r0, which may
wrap around by adding the carry.
* tests/factor/mulredc2-infloop.sh: New file.
* tests/local.mk (all_tests): Add the new test.
* NEWS: Mention the bug fix.

Discovered by Anthropic's OSS Scanner, as bug ANT-2026-CFUR0JKW.
This commit is contained in:
Collin Funk committed 2026-10-23 19:30:36 -07:00
1 parent 3a1595e2af
commit 2c2a1334fa
4 files changed
+37 -2

No files matched your search

+4
View File
@@ -21,6 +21,10 @@ GNU coreutils NEWS -*- outline -*-
non-space characters, or the number itself when followed by spaces.
[bugs introduced in coreutils-9.8]
'factor' no longer infinite loops with certain large numbers, e.g.,
146077762747232966952776282887314548659.
[bugs introduced in coreutils-8.20]
'fold' no longer prematurely wraps lines with a wide character towards
the start of a line, followed by multiple backspaces. Also backspaces
after a tab character are accounted for correctly.
+2 -2
View File
@@ -1122,7 +1122,7 @@ mulredc2 (mp_limb_t *r1p,
q = mi * t0;
umul_ppmm (p1, p0, q, m0);
umul_ppmm (s1, s0, q, m1);
r0 += (t0 != 0); /* Carry */
p1 += (t0 != 0); /* Carry */
add_ssaaaa (r1, r0, r1, r0, 0, p1);
add_ssaaaa (r1, r0, r1, r0, 0, t1);
add_ssaaaa (r1, r0, r1, r0, s1, s0);
@@ -1149,7 +1149,7 @@ mulredc2 (mp_limb_t *r1p,
add_ssaaaa (r1, r0, s1, s0, 0, r1);
umul_ppmm (p1, p0, q, m0);
umul_ppmm (s1, s0, q, m1);
r0 += (t0 != 0); /* Carry */
p1 += (t0 != 0); /* Carry */
add_ssaaaa (r1, r0, r1, r0, 0, p1);
add_ssaaaa (r1, r0, r1, r0, 0, t1);
add_ssaaaa (r1, r0, r1, r0, s1, s0);
+30
View File
@@ -0,0 +1,30 @@
#!/bin/sh
# Test an invocation that would infinite loop due to a missing
# overflow check in mulredc2.
# Copyright (C) 2026 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
print_ver_ factor
printf '%s: %s %s\n' 146077762747232966952776282887314548659 37853 \
3859080198325970648370704643946703 >exp || framework_failure_
timeout 10 factor 146077762747232966952776282887314548659 >err >out || fail=1
compare exp out || fail=1
compare /dev/null err || fail=1
Exit $fail
+1
View File
@@ -376,6 +376,7 @@ all_tests = \
tests/expr/expr-multibyte.pl \
tests/factor/factor.pl \
tests/factor/factor-parallel.sh \
tests/factor/mulredc2-infloop.sh \
tests/misc/false-status.sh \
tests/fold/fold-characters.sh \
tests/fold/fold-nbsp.sh \