about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNguyễn Gia Phong <cnx@loang.net>2025-04-12 22:50:05 +0900
committerNguyễn Gia Phong <cnx@loang.net>2025-04-12 22:50:05 +0900
commit573c25f78d4dc34896c49776d29538408ab7de92 (patch)
tree1e0c881360d168041407cc86c27331399b93a395
parent14ddbfc439cd38ad6c5288ef3da87288f059854a (diff)
downloadloftix-573c25f78d4dc34896c49776d29538408ab7de92.tar.gz
Simplify buggy packages' definition
-rw-r--r--REUSE.toml3
-rw-r--r--bugs/README.md67
-rw-r--r--bugs/cve/2016/9265/34.mp3 (renamed from bugs/cve/2016/9264/globaloverflow)bin8 -> 8 bytes
-rw-r--r--bugs/cve/2016/9265/45.mp3bin0 -> 148 bytes
-rw-r--r--loftix/bugs.scm357
-rw-r--r--loftix/transform.scm12
6 files changed, 211 insertions, 228 deletions
diff --git a/REUSE.toml b/REUSE.toml
index 87c2bbb..df87ff0 100644
--- a/REUSE.toml
+++ b/REUSE.toml
@@ -43,7 +43,8 @@ SPDX-License-Identifier = 'CC0-1.0'
 
 [[annotations]]
 path = [ 'bugs/cve/2016/8691/11.crash',
-         'bugs/cve/2016/9264/globaloverflow',
+         'bugs/cve/2016/9265/34.mp3',
+         'bugs/cve/2016/9265/45.mp3',
          'bugs/cve/2016/9387/jas_matrix.jp2',
          'bugs/cve/2016/9557/signed-int-overflow.jp2',
          'bugs/cve/2016/10092/heapoverflow.tiff',
diff --git a/bugs/README.md b/bugs/README.md
index b3d5abf..d0672d1 100644
--- a/bugs/README.md
+++ b/bugs/README.md
@@ -84,12 +84,12 @@
 
 - CVE-2012-2806: [heap buffer overflow][chromium-40058947]
 
-      guix shell -e '(@@ (loftix bugs) libjpeg-turbo-1.2.0-asan)'
+      guix shell libjpeg-turbo-with-asan@1.2.0
       djpeg cve/2012/2806/cnode0006-heap-buffer-overflow-796.jpg
 
 - CVE-2017-15232: [null pointer dereference][mozjpeg-268]
 
-      guix shell -e '(@@ (loftix bugs) libjpeg-turbo-1.5.2)'
+      guix shell libjpeg-turbo@1.5.2
       djpeg -crop "1x1+16+16" -onepass -dither ordered -dct float -colors 8\
         -targa -grayscale -outfile /dev/null cve/2017/15232/1.jpg
       djpeg -crop "1x1+16+16" -onepass -dither ordered -dct float -colors 8\
@@ -97,7 +97,7 @@
 
 - CVE-2018-14498: [heap buffer overflow][libjpeg-turbo-258]
 
-      guix shell -e '(@@ (loftix bugs) libjpeg-turbo-1.5.3-asan)'
+      guix shell libjpeg-turbo-with-asan@1.5.3
       cjpeg -outfile /dev/null cve/2018/14498/hbo_rdbmp.c:209_1.bmp
       cjpeg -outfile /dev/null cve/2018/14498/hbo_rdbmp.c:209_2.bmp
       cjpeg -outfile /dev/null cve/2018/14498/hbo_rdbmp.c:210_1.bmp
@@ -106,46 +106,47 @@
 
 - CVE-2018-19664: [heap buffer overflow][libjpeg-turbo-305]
 
-      guix shell -e '(@@ (loftix bugs) libjpeg-turbo-2.0.1-asan)'
+      guix shell libjpeg-turbo-with-asan@2.0.1
       djpeg -colors 256 -bmp cve/2018/19664/heap-buffer-overflow-2.jpg
 
 ## libming
 
-- CVE-2016-9264: [global buffer overflow][oss-sec-20161110-9]
+- CVE-2016-9265: [division by zero][oss-sec-20161110-9]
 
-      guix shell -e '(@@ (loftix bugs) libming-0.4.7-asan)'
-      listmp3 cve/2016/9264/globaloverflow
+      guix shell libming@0.4.7
+      listmp3 cve/2016/9265/34.mp3
+      listmp3 cve/2016/9265/45.mp3
 
 - CVE-2018-8806: [use after free][libming-128]
 
-      guix shell -e '(@@ (loftix bugs) libming-0.4.8-asan)'
+      guix shell libming-with-asan@0.4.8
       swftophp cve/2018/8806/heap-use-after-free.swf
 
 - CVE-2018-8964: [use after free][libming-130]
 
-      guix shell -e '(@@ (loftix bugs) libming-0.4.8-asan)'
+      guix shell libming-with-asan@0.4.8
       swftophp cve/2018/8964/heap-use-after-free.swf
 
 ## libtiff
 
 - BZ#2633: [heap buffer overflow][maptools-2633]:
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.7-asan)'
+      guix shell libtiff-with-asan@4.0.7
       tiff2ps maptools/2633/heapoverflow.tiff
 
 - CVE-2014-8128: [buffer overflow][maptools-2489]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.3)'
+      guix shell libtiff@4.0.3
       thumbnail cve/2014/8128/03_thumbnail.tiff /dev/null
 
 - CVE-2016-3186: [buffer overflow][redhat-1319503]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.6)'
-      echo y | gif2tiff cve/2016/3186/crash.gif /dev/null
+      guix shell libtiff@4.0.6
+      gif2tiff cve/2016/3186/crash.gif -
 
 - CVE-2016-3623: [division by zero][maptools-2569]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.6)'
+      guix shell libtiff@4.0.6
       tar xvf $(guix build -S libtiff@4.0.6)\
         tiff-4.0.6/test/images/logluv-3c-16b.tiff
       rgb2ycbcr -h 0 tiff-4.0.6/test/images/logluv-3c-16b.tiff /dev/null
@@ -153,37 +154,37 @@
 
 - CVE-2016-5314: [heap buffer overflow][maptools-2554]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.6-asan)'
+      guix shell libtiff-with-asan@4.0.6
       rgb2ycbcr cve/2016/5314/oobw.tiff /dev/null
 
 - CVE-2016-5321: [invalid read][maptools-2558]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.6)'
+      guix shell libtiff@4.0.6
       tiffcrop cve/2016/5321/ill-read.tiff /dev/null
 
 - CVE-2016-9273: [heap buffer overflow][maptools-2587]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.6-asan)'
+      guix shell libtiff-with-asan@4.0.6
       tiffsplit cve/2016/9273/test049.tiff
 
 - CVE-2016-9532: [heap buffer overflow][maptools-2592]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.6)'
+      guix shell libtiff-with-asan@4.0.6
       tiffcrop cve/2016/9532/heap-buffer-overflow.tiff /dev/null
 
 - CVE-2016-10092: [heap buffer overflow][maptools-2622]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.7-asan)'
+      guix shell libtiff-with-asan@4.0.7
       tiffcrop -i cve/2016/10092/heapoverflow.tiff /dev/null
 
 - CVE-2016-10093: [heap buffer overflow][maptools-2610]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.7-asan)'
+      guix shell libtiff-with-asan@4.0.7
       tiffcp -i cve/2016/10093/heapoverflow.tiff /dev/null
 
 - CVE-2016-10094: [heap buffer overflow][maptools-2640]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.7-asan)'
+      guix shell libtiff-with-asan@4.0.7
       tiff2pdf cve/2016/10094/heapoverflow.tiff -o /dev/null
 
 - CVE-2016-10266: [division by zero][maptools-2596]
@@ -198,65 +199,65 @@
 
 - CVE-2016-10268: [heap buffer overflow][maptools-2598]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.7-asan)'
+      guix shell libtiff-with-asan@4.0.7
       tiffcp -i cve/2016/10268/heapoverflow.tiff /dev/null
 
 - CVE-2016-10271: [heap buffer overflow][maptools-2620]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.7-asan)'
+      guix shell libtiff-with-asan@4.0.7
       tiffcrop -i cve/2016/10271/heapoverflow.tiff /dev/null
 
 - CVE-2016-10272: [heap buffer overflow][maptools-2624]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.7-asan)'
+      guix shell libtiff-with-asan@4.0.7
       tiffcrop -i cve/2016/10272/heapoverflow.tiff /dev/null
 
 - CVE-2017-5225: [heap buffer overflow][maptools-2656]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.7-asan)'
+      guix shell libtiff-with-asan@4.0.7
       tiffcp -p separate cve/2017/5225/2656.tiff /dev/null
       tiffcp -p contig cve/2017/5225/2657.tiff /dev/null
 
 - CVE-2017-7595: [division by zero][maptools-2653]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.7)'
+      guix shell libtiff@4.0.7
       tiffcp -i cve/2017/7595/fpe.tiff /dev/null
 
 - cve-2017-7599: [float cast overflow][maptools-2646]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.7-ubsan-float-cast-overflow)'
+      guix shell libtiff-with-ubsan-float-cast-overflow@4.0.7
       tiffcp -i cve/2017/7599/outside-short.tiff /dev/null
 
 - cve-2017-7600: [float cast overflow][maptools-2647]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.7-ubsan-float-cast-overflow)'
+      guix shell libtiff-with-ubsan-float-cast-overflow@4.0.7
       tiffcp -i cve/2017/7600/outside-unsigned-char.tiff /dev/null
 
 - CVE-2017-7601: [signed integer overflow][maptools-2648]
 
-      guix shell -e '(@@ (loftix bugs) libtiff-4.0.7-ubsan)'
+      guix shell libtiff-with-ubsan@4.0.7
       tiffcp -i cve/2017/7601/shift-long.tiff /dev/null
 
 ## libxml2
 
 - CVE-2012-5134: [heap buffer overflow][chromium-40076524]
 
-      guix shell -e '(@@ (loftix bugs) libxml2-2.9.0-asan)'
+      guix shell libxml2-with-asan@2.9.0
       xmllint cve/2012/5134/bad.xml
 
 - CVE-2016-1838: [heap buffer overflow][chromium-42452154]
 
-      guix shell -e '(@@ (loftix bugs) libxml2-2.9.3-asan)'
+      guix shell libxml2-with-asan@2.9.3
       xmllint cve/2016/1838/attachment_316158
 
 - CVE-2016-1839: [heap buffer overflow][chromium-42452152]
 
-      guix shell -e '(@@ (loftix bugs) libxml2-2.9.3-asan)'
+      guix shell libxml2-with-asan@2.9.3
       xmllint --html cve/2016/1839/asan_heap-oob
 
 - CVE-2017-5969: [null pointer derefence][oss-sec-20161105-3]
 
-      guix shell -e '(@@ (loftix bugs) libxml2-2.9.4
+      guix shell libxml2@2.9.4
       xmllint --recover cve/2017/5969/crash-libxml2-recover.xml
 
 ## potrace
diff --git a/bugs/cve/2016/9264/globaloverflow b/bugs/cve/2016/9265/34.mp3
index 24f6f72..24f6f72 100644
--- a/bugs/cve/2016/9264/globaloverflow
+++ b/bugs/cve/2016/9265/34.mp3
Binary files differdiff --git a/bugs/cve/2016/9265/45.mp3 b/bugs/cve/2016/9265/45.mp3
new file mode 100644
index 0000000..2c30b61
--- /dev/null
+++ b/bugs/cve/2016/9265/45.mp3
Binary files differdiff --git a/loftix/bugs.scm b/loftix/bugs.scm
index 0c6001a..db5f911 100644
--- a/loftix/bugs.scm
+++ b/loftix/bugs.scm
@@ -29,18 +29,22 @@
   #:use-module (guix git-download)
   #:use-module ((guix licenses) #:prefix license:)
   #:use-module (guix packages)
-  #:use-module (guix utils)
-  #:use-module (srfi srfi-26))
+  #:use-module (guix utils))
 
 (define (at-version base version uri checksum)
   (package
     (inherit base)
     (version version)
     (source
-     (origin
-       (inherit (package-source base))
-       (uri (uri version))
-       (sha256 (base32 checksum))))))
+     (let ((src (package-source base)))
+       (origin
+         (inherit src)
+         (uri uri)
+         (sha256 (base32 checksum))
+         (file-name (cond ((eq? (origin-method src) git-fetch)
+                           (git-file-name (package-name base) version))
+                          ((eq? (origin-method src) url-fetch)
+                           (origin-file-name src)))))))))
 
 (define (binutils-at-version base version checksum)
   (at-version
@@ -51,7 +55,7 @@
         (inherit (package-source base))
         (patches '()))))
    version
-   (cut string-append "mirror://gnu/binutils/binutils-" <> ".tar.bz2")
+   (string-append "mirror://gnu/binutils/binutils-" version ".tar.bz2")
    checksum))
 
 (define-public binutils-2.32
@@ -84,6 +88,19 @@
     (name (string-append (package-name base) "-with-asan"))
     (arguments
      (case (build-system-name (package-build-system base))
+       ((cmake)
+        (substitute-keyword-arguments (package-arguments base)
+          ((#:phases phases #~%standard-phases)
+           (with-imported-modules '((loftix transform))
+             #~(modify-phases #$phases
+                 (add-before 'configure 'set-env
+                   (lambda _
+                     (use-modules (loftix transform))
+                     (append-env "CFLAGS" "-fsanitize=address" "-O2 -g")
+                     (append-env "LDFLAGS" "-fsanitize=address" #f)
+                     (setenv "ASAN_OPTIONS" "detect_leaks=0"))))))
+          ((#:tests? _ #f)
+           #f)))
        ((gnu)
         (substitute-keyword-arguments (package-arguments base)
           ((#:make-flags flags #~'())
@@ -124,7 +141,7 @@
   (at-version
    base
    version
-   (cut string-append "mirror://gnu/coreutils/coreutils-" <> ".tar.xz")
+   (string-append "mirror://gnu/coreutils/coreutils-" version ".tar.xz")
    checksum))
 
 (define-public coreutils-8.26
@@ -226,7 +243,6 @@
   (jasper-at-version "1.900.5"
                      "1fvy4ngc6064g128q4484qpinsn05y9qw6lrccc4czhalla2w26m"))
 
-;; TODO: static build for taosc.
 (define-public jasper-1.900.3
   (jasper-at-version "1.900.3"
                      "106xwiyn40k5yrnny198mzscvyd18rza9clhd2nl6xvcsz73swrn"))
@@ -247,70 +263,48 @@
 (define-public libarchive-with-ubsan-3.2.0
   (with-ubsan libarchive-3.2.0))
 
-(define-public libjpeg-turbo-1.5.2
-  (package
-    (inherit libjpeg-turbo)
-    (name "libjpeg-turbo")
-    (version "1.5.2")
-    (source (origin
-              (method url-fetch)
-              (uri (string-append "mirror://sourceforge/libjpeg-turbo/"
-                                  version "/libjpeg-turbo-" version ".tar.gz"))
-              (sha256
-               (base32
-                "0a5m0psfp5952y5vrcs0nbdz1y9wqzg2ms0xwrx752034wxr964h"))))
-    (build-system gnu-build-system)
-    (arguments '(#:make-flags '("LDFLAGS=-static")
-                 #:test-target "test"))))
+(define (libjpeg-turbo-at-version base version checksum)
+  (at-version
+   base
+   version
+   (string-append "mirror://sourceforge/libjpeg-turbo/" version
+                  "/libjpeg-turbo-" version ".tar.gz")
+   checksum))
 
-(define-public libjpeg-turbo-1.5.3-asan
-  (package
-    (inherit libjpeg-turbo-1.5.2)
-    (name "libjpeg-turbo")
-    (version "1.5.3")
-    (source (origin
-              (method url-fetch)
-              (uri (string-append "mirror://sourceforge/libjpeg-turbo/"
-                                  version "/libjpeg-turbo-" version ".tar.gz"))
-              (sha256
-               (base32
-                "08r5b5mywwrxv4axvq80dm31cklz81grczlzlxr2xqa6pgi90j5j"))))
-    (arguments '(#:make-flags '("CFLAGS=-O2 -g -fsanitize=address"
-                                "LDFLAGS=-static -fsanitize=address")))))
+(define-public libjpeg-turbo-2.0.1
+  (libjpeg-turbo-at-version
+   libjpeg-turbo
+   "2.0.1"
+   "1zv6z093l3x3jzygvni7b819j7xhn6d63jhcdrckj7fz67n6ry75"))
 
-(define-public libjpeg-turbo-1.2.0-asan
-  (package
-    (inherit libjpeg-turbo-1.5.3-asan)
-    (name "libjpeg-turbo")
-    (version "1.2.0")
-    (source (origin
-              (method url-fetch)
-              (uri (string-append "mirror://sourceforge/libjpeg-turbo/"
-                                  version "/libjpeg-turbo-" version ".tar.gz"))
-              (sha256
-               (base32
-                "13pra36wn2djw2aq5vvbaf81m9jxdjixvpd8bw71nni9n6lv57b2"))))))
+(define-public libjpeg-turbo-1.5.3
+  (libjpeg-turbo-at-version
+   (package
+     (inherit libjpeg-turbo)
+     (build-system gnu-build-system)
+     (arguments
+      (substitute-keyword-arguments (package-arguments libjpeg-turbo)
+        ((#:configure-flags _) #~'())))) ;discard CMake flags
+   "1.5.3"
+   "08r5b5mywwrxv4axvq80dm31cklz81grczlzlxr2xqa6pgi90j5j"))
 
-(define-public libjpeg-turbo-2.0.1-asan
-  (package
-    (inherit libjpeg-turbo)
-    (name "libjpeg-turbo")
-    (version "2.0.1")
-    (source (origin
-              (method url-fetch)
-              (uri (string-append "mirror://sourceforge/libjpeg-turbo/"
-                                  version "/libjpeg-turbo-" version ".tar.gz"))
-              (sha256
-               (base32
-                "1zv6z093l3x3jzygvni7b819j7xhn6d63jhcdrckj7fz67n6ry75"))))
-    (arguments '(#:phases (modify-phases %standard-phases
-                            (add-before 'configure 'set-env
-                              (lambda _
-                                (setenv "CFLAGS" "-O2 -g -fsanitize=address")
-                                (setenv "LDFLAGS" "-fsanitize=address"))))
-                 #:configure-flags '("-DCMAKE_INSTALL_LIBDIR:PATH=lib")))))
-
-(define-public libming-0.4.8-asan
+(define-public libjpeg-turbo-1.5.2
+  (libjpeg-turbo-at-version
+   libjpeg-turbo-1.5.3
+   "1.5.2"
+   "0a5m0psfp5952y5vrcs0nbdz1y9wqzg2ms0xwrx752034wxr964h"))
+
+(define-public libjpeg-turbo-1.2.0
+  (libjpeg-turbo-at-version
+   libjpeg-turbo-1.5.3
+   "1.2.0"
+   "13pra36wn2djw2aq5vvbaf81m9jxdjixvpd8bw71nni9n6lv57b2"))
+
+(define-public libjpeg-turbo-with-asan-2.0.1 (with-asan libjpeg-turbo-2.0.1))
+(define-public libjpeg-turbo-with-asan-1.5.3 (with-asan libjpeg-turbo-1.5.3))
+(define-public libjpeg-turbo-with-asan-1.2.0 (with-asan libjpeg-turbo-1.2.0))
+
+(define-public libming-0.4.8
   (package
     (name "libming")
     (version "0.4.8")
@@ -325,8 +319,7 @@
               (patches (search-patches
                          "patches/libming-parallel-make.patch"))))
     (build-system gnu-build-system)
-    (arguments '(#:make-flags '("CFLAGS=-O2 -g -fcommon -fsanitize=address"
-                                "LDFLAGS=-static -fsanitize=address")
+    (arguments '(#:make-flags '("CFLAGS=-O2 -g -fcommon")
                  #:tests? #f))
     (native-inputs (list autoconf automake bison flex libtool pkgconf swig))
     (inputs (list freetype giflib libpng))
@@ -336,54 +329,26 @@ It can be used from PHP, Perl, Ruby, Python, C, C++ and Java.")
     (home-page "https://github.com/libming/libming")
     (license (list license:lgpl2.1+ license:gpl2+))))
 
-(define-public libming-0.4.7-asan
-  (package
-    (inherit libming-0.4.8-asan)
-    (name "libming")
-    (version "0.4.7")
-    (source (origin
-              (method git-fetch)
-              (uri (git-reference
-                    (url "https://github.com/libming/libming")
-                    (commit "ming-0_4_7")))
-              (sha256
-               (base32 "17ngz1n1mnknixzchywkhbw9s3scad8ajmk97gx14xbsw1603gd2"))
-              (file-name (git-file-name name version))
-              (patches (search-patches
-                         "patches/libming-parallel-make.patch"))))))
-
-(define-public libtiff-4.0.3
-  (package
-    (inherit libtiff)
-    (version "4.0.3")
-    (source (origin
-             (method url-fetch)
-             (uri (string-append "ftp://ftp.remotesensing.org/pub/libtiff/tiff-"
-                    version ".tar.gz"))
-             (sha256
-              (base32 "0wj8d1iwk9vnpax2h29xqc2hwknxg3s0ay2d5pxkg59ihbifn6pa"))))
-    (outputs '("out"))))
+(define-public libming-with-asan-0.4.8
+  (with-asan libming-0.4.8))
 
-(define-public libtiff-4.0.6
-  (package
-    (inherit libtiff)
-    (version "4.0.6")
-    (source (origin
-              (method url-fetch)
-              (uri (string-append
-                     "ftp://ftp.remotesensing.org/pub/libtiff/tiff-" version
-                     ".tar.gz"))
-              (sha256
-               (base32
-                "136nf1rj9dp5jgv1p7z4dk0xy3wki1w0vfjbk82f645m0w4samsd"))))
-    (arguments '(#:make-flags '("LDFLAGS=-static")))
-    (outputs '("out"))))
+(define (libming-at-version base version checksum)
+  (at-version
+   base
+   version
+   (git-reference
+    (url "https://github.com/libming/libming")
+    (commit (string-append "ming-"
+                           (string-map (lambda (char)
+                                         (if (eq? char #\.) #\_ char))
+                                       version))))
+   checksum))
 
-(define-public libtiff-4.0.6-asan
-  (package
-    (inherit libtiff-4.0.6)
-    (arguments '(#:make-flags '("CFLAGS=-O2 -g -fsanitize=address"
-                                "LDFLAGS=-static -fsanitize=address")))))
+(define-public libming-0.4.7
+  (libming-at-version
+   libming-0.4.8
+   "0.4.7"
+   "17ngz1n1mnknixzchywkhbw9s3scad8ajmk97gx14xbsw1603gd2"))
 
 (define-public libtiff-4.0.7
   (package
@@ -398,84 +363,92 @@ It can be used from PHP, Perl, Ruby, Python, C, C++ and Java.")
                 "06ghqhr4db1ssq0acyyz49gr8k41gzw6pqb6mbn5r7jqp77s4hwz"))))
     (outputs '("out"))))
 
-(define-public libtiff-4.0.7-asan
-  (package
-    (inherit libtiff-4.0.7)
-    (arguments '(#:make-flags '("CFLAGS=-O2 -g -fsanitize=address"
-                                "LDFLAGS=-static -fsanitize=address")))))
+(define (libtiff-at-version base version checksum)
+  (at-version
+   base
+   version
+   (string-append
+    "ftp://ftp.remotesensing.org/pub/libtiff/tiff-" version ".tar.gz")
+   checksum))
 
-(define-public libtiff-4.0.7-ubsan
-  (package
-    (inherit libtiff-4.0.7)
-    (arguments '(#:make-flags
-                 (list (string-append
-                         "CFLAGS=-O2 -g -fsanitize=undefined"
-                         " -fno-sanitize-recover=undefined")
-                       "LDFLAGS=-static -fsanitize=undefined")
-                 ;; Tests fail with ubsan enabled^
-                 #:tests? #f))))
-
-(define-public libtiff-4.0.7-ubsan-float-cast-overflow
-  (package
-    (inherit libtiff-4.0.7)
-    (arguments '(#:make-flags
-                 (list (string-append
-                         "CFLAGS=-O2 -g -fsanitize=float-cast-overflow"
-                         " -fno-sanitize-recover=float-cast-overflow")
-                       "LDFLAGS=-static -fsanitize=float-cast-overflow")))))
+(define-public libtiff-4.0.6
+  (libtiff-at-version
+   libtiff-4.0.7
+   "4.0.6"
+   "136nf1rj9dp5jgv1p7z4dk0xy3wki1w0vfjbk82f645m0w4samsd"))
 
-(define-public libxml2-2.9.4
-  (package
-    (inherit libxml2)
-    (name "libxml2")
-    (version "2.9.4")
-    (source (origin
-              (method url-fetch)
-              (uri (string-append "ftp://xmlsoft.org/libxml2/libxml2-"
-                                  version ".tar.gz"))
-              (sha256
-               (base32
-                "0g336cr0bw6dax1q48bblphmchgihx9p1pjmxdnrd6sh3qci3fgz"))))
-    (arguments '(#:make-flags '("LDFLAGS=-static")))
-    ;; $XML_CATALOG_FILES lists 'catalog.xml' files found in under the 'xml'
-    ;; sub-directory of any given package.
-    (native-search-paths (list (search-path-specification
-                                (variable "XML_CATALOG_FILES")
-                                (separator " ")
-                                (files '("xml"))
-                                (file-pattern "^catalog\\.xml$")
-                                (file-type 'regular))))
-    (search-paths native-search-paths)))
-
-(define-public libxml2-2.9.3-asan
-  (package
-    (inherit libxml2-2.9.4)
-    (name "libxml2")
-    (version "2.9.3")
-    (source (origin
-              (method url-fetch)
-              (uri (string-append "ftp://xmlsoft.org/libxml2/libxml2-"
-                                  version ".tar.gz"))
-              (sha256
-               (base32
-                "0bd17g6znn2r98gzpjppsqjg33iraky4px923j3k8kdl8qgy7sad"))))
-    (arguments '(#:make-flags '("CFLAGS=-O2 -g -fsanitize=address"
-                                "LDFLAGS=-static -fsanitize=address")
-                 ;; Tests fail with ASan enabled^
-                 #:tests? #f))))
+(define-public libtiff-4.0.3
+  (libtiff-at-version
+   libtiff-4.0.7
+   "4.0.3"
+   "0wj8d1iwk9vnpax2h29xqc2hwknxg3s0ay2d5pxkg59ihbifn6pa"))
 
-(define-public libxml2-2.9.0-asan
+(define-public libtiff-with-asan-4.0.7 (with-asan libtiff-4.0.7))
+(define-public libtiff-with-asan-4.0.6 (with-asan libtiff-4.0.6))
+(define-public libtiff-with-ubsan-4.0.7 (with-ubsan libtiff-4.0.7))
+
+(define (with-ubsan-float-cast-overflow base)
   (package
-    (inherit libxml2-2.9.3-asan)
-    (name "libxml2")
-    (version "2.9.0")
-    (source (origin
-              (method url-fetch)
-              (uri (string-append "ftp://xmlsoft.org/libxml2/libxml2-"
-                                  version ".tar.gz"))
-              (sha256
-               (base32
-                "10ib8bpar2pl68aqksfinvfmqknwnk7i35ibq6yjl8dpb0cxj9dd"))))))
+    (inherit base)
+    (name (string-append (package-name base)
+                         "-with-ubsan-float-cast-overflow"))
+    (arguments
+     (case (build-system-name (package-build-system base))
+       ((gnu)
+        (substitute-keyword-arguments (package-arguments base)
+          ((#:make-flags flags #~'())
+           (with-imported-modules '((loftix transform))
+             #~((@ (loftix transform) append-make-flag)
+                #$flags
+                `(("CFLAGS"
+                   ,(string-append
+                     "-fsanitize=float-cast-overflow"
+                     " -fno-sanitize-recover=float-cast-overflow")
+                   "-O2 -g")
+                  ("LDFLAGS" "-fsanitize=float-cast-overflow")))))
+          ((#:tests? _ #f)
+           #f)))))))
+
+(define-public libtiff-with-ubsan-float-cast-overflow-4.0.7
+  (with-ubsan-float-cast-overflow libtiff-4.0.7))
+
+(define (libxml2-at-version base version checksum)
+  (at-version
+   base
+   version
+   (string-append "ftp://xmlsoft.org/libxml2/libxml2-" version ".tar.gz")
+   checksum))
+
+(define-public libxml2-2.9.4
+  (libxml2-at-version
+   (package
+     (inherit libxml2)
+     ;; $XML_CATALOG_FILES lists 'catalog.xml' files found in under the 'xml'
+     ;; sub-directory of any given package.
+     (native-search-paths (list (search-path-specification
+                                 (variable "XML_CATALOG_FILES")
+                                 (separator " ")
+                                 (files '("xml"))
+                                 (file-pattern "^catalog\\.xml$")
+                                 (file-type 'regular))))
+     (search-paths native-search-paths))
+   "2.9.4"
+   "0g336cr0bw6dax1q48bblphmchgihx9p1pjmxdnrd6sh3qci3fgz"))
+
+(define-public libxml2-2.9.3
+  (libxml2-at-version
+   libxml2-2.9.4
+   "2.9.3"
+   "0bd17g6znn2r98gzpjppsqjg33iraky4px923j3k8kdl8qgy7sad"))
+
+(define-public libxml2-2.9.0
+  (libxml2-at-version
+   libxml2-2.9.4
+   "2.9.0"
+   "10ib8bpar2pl68aqksfinvfmqknwnk7i35ibq6yjl8dpb0cxj9dd"))
+
+(define-public libxml2-with-asan-2.9.3 (with-asan libxml2-2.9.3))
+(define-public libxml2-with-asan-2.9.0 (with-asan libxml2-2.9.0))
 
 (define-public potrace-1.11
   (package
diff --git a/loftix/transform.scm b/loftix/transform.scm
index 7eac95b..4edea16 100644
--- a/loftix/transform.scm
+++ b/loftix/transform.scm
@@ -1,4 +1,4 @@
-;;; Package transformations
+;;; Package recipe transformations
 ;;;
 ;;; SPDX-FileCopyrightText: 2025 Nguyễn Gia Phong
 ;;; SPDX-License-Identifier: GPL-3.0-or-later
@@ -7,7 +7,15 @@
   #:use-module (ice-9 match)
   #:use-module (ice-9 receive)
   #:use-module (srfi srfi-1)
-  #:export (append-make-flag))
+  #:export (append-env
+            append-make-flag))
+
+(define (append-env name addition default)
+  (setenv name
+          (let ((value (or (getenv name) default)))
+            (if value
+                (string-append value " " addition)
+                addition))))
 
 (define (append-make-flag original additions)
   (let ((orig-ls (map (lambda (flag)