Package: libmpfr6 Version: 4.2.0-1 Severity: important Tags: upstream There are multiple bugs, more or less important, in GNU MPFR 4.2.0. Patches are available at https://www.mpfr.org/mpfr-4.2.0/#bugs
In particular: * For the mpfr_ui_pow_ui function, infinite loop in case of overflow. * The mpfr_rec_sqrt function may yield a stack overflow due to many small allocations in the stack, based on alloca(). This occurs on cases that are very hard to round. In practice, to build such cases, the precision of the input needs to be large enough (e.g. around 100000 bits). * MPFR can crash when a formatted output function is called with %.2147483648Rg in the format string (2147483648 = 2^31). See attached files for simple testcases (but the patches provide testcases for the testsuite). -- System Information: Debian Release: 12.0 APT prefers unstable-debug APT policy: (500, 'unstable-debug'), (500, 'testing-security'), (500, 'stable-updates'), (500, 'stable-security'), (500, 'unstable'), (500, 'testing'), (500, 'stable'), (1, 'experimental') merged-usr: no Architecture: amd64 (x86_64) Kernel: Linux 6.1.0-9-amd64 (SMP w/8 CPU threads; PREEMPT) Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE Locale: LANG=POSIX, LC_CTYPE=C.UTF-8 (charmap=UTF-8), LANGUAGE not set Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled Versions of packages libmpfr6 depends on: ii libc6 2.36-9 ii libgmp10 2:6.2.1+dfsg1-1.1 libmpfr6 recommends no packages. libmpfr6 suggests no packages. -- no debconf information -- Vincent Lefèvre <vinc...@vinc17.net> - Web: <https://www.vinc17.net/> 100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/> Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
#include <limits.h> #include <stdio.h> #include <mpfr.h> int main (void) { mpfr_exp_t emax_max; mpfr_t x; emax_max = mpfr_get_emax_max (); if (mpfr_set_emax (emax_max)) { fprintf (stderr, "ui_pow_ui-overflow error: mpfr_set_emax failed\n"); return 1; } mpfr_init2 (x, 8); /* The purpose of this test is more to check that mpfr_ui_pow_ui terminates (without taking much memory) rather than checking the value of x. On 2023-02-13, the +Inf case was not handled in the Ziv iteration, yielding an infinite loop, affecting mpfr_log10 in particular. See commit 90de094f0d9c309daca707aa227470d810866616 */ mpfr_ui_pow_ui (x, 5, ULONG_MAX, MPFR_RNDN); if (emax_max <= ULONG_MAX /* true with default _MPFR_EXP_FORMAT */ && ! mpfr_inf_p (x)) { fprintf (stderr, "ui_pow_ui-overflow error"); printf ("ui_pow_ui-overflow: expected +Inf, got "); mpfr_dump (x); return 1; } mpfr_clear (x); return 0; }
#include <stdio.h> #include <mpfr.h> int main (void) { mpfr_t x, y; int inex; mpfr_init2 (x, 123456); mpfr_init2 (y, 4); mpfr_set_ui (y, 9, MPFR_RNDN); mpfr_ui_div (x, 1, y, MPFR_RNDN); inex = mpfr_rec_sqrt (y, x, MPFR_RNDN); /* Let's also check the result, though this is not the real purpose of this test (a stack overflow just makes the program crash). 1/9 = 0.111000111000111000111000111000111000...E-3 and since the precision 123456 is divisible by 6, x > 1/9. Thus 1/sqrt(x) < 3. */ if (mpfr_nan_p (y) || mpfr_cmp_ui (y, 3) != 0 || inex <= 0) { printf ("mpfr_rec_sqrt error: expected 3 with inex > 0, got "); mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN); printf (" with inex=%d\n", inex); return 1; } mpfr_clear (x); mpfr_clear (y); return 0; }
#include <stdio.h> #include <mpfr.h> int main (void) { mpfr_t x; char buf1[3] = "xxx", buf2[3] = "xxx"; int r; mpfr_init2 (x, 128); mpfr_set_ui (x, 1, MPFR_RNDN); r = mpfr_snprintf (NULL, 0, "%.2147483648Rg\n", x); if (r != 2 && r >= 0) return 1; r = mpfr_snprintf (buf1, sizeof(buf1), "%.2147483648Rg\n", x); if (r != 2 && r >= 0) return 2; if (r >= 0 && (buf1[0] != '1' || buf1[1] != '\n' || buf1[2] != 0)) return 3; r = mpfr_sprintf (buf2, "%.2147483648Rg\n", x); if (r != 2 && r >= 0) return 4; if (r >= 0 && (buf2[0] != '1' || buf2[1] != '\n' || buf2[2] != 0)) return 5; mpfr_clear (x); return 0; }