Package: units
Version: 2.25-2
Severity: serious
Tags: patch
User: [email protected]
Usertags: origin-ubuntu resolute ubuntu-patch
Dear Maintainer,
units fail due to accessing memory out of array bounds:
$ units
Currency exchange rates from exchangerate-api.com (USD base) on 2026-01-17
Consumer price index data from US BLS, 2026-01-13
Segmentation fault units
The root cause units.c:1489 - outer loop variable i is reused when parsing
domain segments units.c:1529, units.c:1539 causing the memory access beyond
keyword array.
In Ubuntu, the attached patch was applied to achieve the following:
Use different variable to parse intervals to resolve the segmentation fault.
* d/p/do-not-use-loop-variable: resolve segmentation fault (LP:
#2144689).
Thanks for considering the patch.
-- System Information:
Debian Release: forky/sid
APT prefers questing-updates
APT policy: (500, 'questing-updates'), (500, 'questing-security'), (500,
'questing'), (100, 'questing-backports')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 6.17.0-19-generic (SMP w/32 CPU threads; PREEMPT)
Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_WARN, TAINT_OOT_MODULE
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
diff -Nru units-2.25/debian/patches/do-not-use-loop-variable.patch
units-2.25/debian/patches/do-not-use-loop-variable.patch
--- units-2.25/debian/patches/do-not-use-loop-variable.patch 1970-01-01
12:00:00.000000000 +1200
+++ units-2.25/debian/patches/do-not-use-loop-variable.patch 2026-03-18
10:06:19.000000000 +1300
@@ -0,0 +1,44 @@
+Description: Do not increment the loop variable
+ When parsing FN_DOMAIN intervals, newfunction reuses
+ the loop variable i, causing the segmentation fault
+ due to arrays out of bounds access.
+ This patch introduces a separate variable for the
+ interval parsing.
+Author: Vladimir Petko <[email protected]>
+Bug-Ubuntu: https://bugs.launchpad.net/bugs/2144689
+Forwarded: no
+Last-Update: 2026-03-18
+
+--- a/units.c
++++ b/units.c
+@@ -1377,7 +1377,7 @@
+ char *params[MAX_FUNC_PARAMS];
+ char *forward_dim[MAX_FUNC_PARAMS];
+ int param_count, extrachars;
+- int looking_for_keywords,i;
++ int looking_for_keywords,i,param_index;
+ struct interval domain[MAX_FUNC_PARAMS];
+ struct interval range;
+ int noerror = 0;
+@@ -1526,17 +1526,17 @@
+ if (i==FN_DOMAIN){
+ char *x=unitdef;
+ unitdef = parseinterval(unitdef, domain, unitname, linenum, file,
errfile, &errors, "domain=");
+- i=1;
++ param_index=1;
+ while(*unitdef && strchr(",[(",*unitdef)){
+ if (*unitdef==',') unitdef++;
+- if (i>=param_count){
++ if (param_index>=param_count){
+ if (errfile) fprintf(errfile,
+ "%s: definition of function '%s' has too many intervals
in domain in '%s' line %d\n",
+ progname,unitname,file,linenum);
+ BADFILE;
+ }
+- unitdef = parseinterval(unitdef, domain+i, unitname, linenum,
file, errfile, &errors, "domain=");
+- i++;
++ unitdef = parseinterval(unitdef, domain+param_index, unitname,
linenum, file, errfile, &errors, "domain=");
++ param_index++;
+ }
+ }
+ if (*unitdef!=' '){
diff -Nru units-2.25/debian/patches/series units-2.25/debian/patches/series
--- units-2.25/debian/patches/series 2026-02-20 06:30:49.000000000 +1300
+++ units-2.25/debian/patches/series 2026-03-18 10:06:19.000000000 +1300
@@ -1,2 +1,3 @@
no-currency-update-during-build.patch
packetizer.patch
+do-not-use-loop-variable.patch