This document provides a base to backport security patches provided
by Freexian Debian ELTS into Raspberry PI OS packages. We describe
a git-based workflow, particularly using git-buildpackage, focusing also
on source debian packages in "3.0 (quilt)" format, so the (security) patches
to be backported should be found in the debian/patches/ directory, and
applied according to debian/patches/series.
Prerequisites
The final outcome of following the workflow described in this document are
debian source packages.
You should have a working setup to build the binary packages from these source packages in a clean
environment, taking the source debian package as input.
This means building the packages using sbuild (+schroots), pbuilder,
cowbuilder or similar. You should also have the building system able to
produce binary packages for the target architecture (such as armhf).
Also, this document assumes you know how to download source packages from
the Raspberry PI OS and from Freexian Debian Extended LTS repositories. Either
by using apt-get source, or using dget.
The Freexian Debian Extended LTS source package repositories are the same
as those documented in
How to use Extended LTS).
If you are not familiar with git-buildpackage, quilt and their workflows,
we invite you to read the documentation listed at the end of the document.
Workflow
Generally the Raspberry PI OS packages include modifications on top of a
specific Debian package. Those changes should mainly be present in the
debian sources (the debian/ directory). For example, in the debian/rules
file, or modifying the patches found in debian/patches/. The Debian Extended
LTS security updates would also add new patches to the debian/patches/
directory, so the final goal of this workflow is to “merge” both the Raspberry
PI OS and the Freexian Debian Extended LTS changes together.
- Prepare a git repository from the source packages
As mentioned above, this document describes a git-based workflow. We document
creating a git repository from scratch, but you may adapt the workflow to
existing git repositories. Please refer to the git-buildpackage
documentation, mentioned in the References at the end of the document.
To create the git repository from scratch, you need to download the source
packages first. We take as an example the glibc package from Debian 10
“buster”, and the Raspberry PI OS adaptations.
As of July 2024, the latest glibc package released for Raspberry PI OS
(legacy), based on buster, was glibc 2.28-10+rpt2+rpi1+deb10u2, as it is found at
the
Raspberry PI OS glibc archive.
It was based on glibc 2.28-10+deb10u2, from Debian 10 LTS.
This specific glibc release is no longer available in any Debian regular
repository. For the sake of the exercise, you can download it from
https://snapshot.debian.org:
workdir$ dget -d https://snapshot.debian.org/archive/debian-security/20221017T122748Z/pool/updates/main/g/glibc/glibc_2.28-10+deb10u2.dsc
However, in practice, all the Debian Extended LTS source packages that you need should be available in the Freexian repositories.
The following command creates a git repository inside the glibc directory:
workdir$ cd glibc
workdir/glibc$ gbp import-dsc --pristine-tar --debian-branch=debian/buster --upstream-branch=upstream/2.28.x glibc_2.28-10+deb10u2.dsc
With the above command we tell gbp import-dsc to use pristine-tar(1), to
place the upstream code in the upstream/2.28.x branch, and the debian sources
in the debian/buster branch. This follows the
recommended layout for Git packaging repositories (DEP-14).
You can run git branch to take a look at the resulting branches in the
repository:
workdir/glibc$ git branch
* debian/buster
pristine-tar
upstream/2.28.x
gbp import-dsc also creates upstream and debian tags for that release.
Now, for the Raspberry PI OS source package. First we have to download it:
workdir$ dget -d https://archive.raspberrypi.org/debian/pool/main/g/glibc/glibc_2.28-10+rpt2+rpi1+deb10u2.dsc
Then import the Raspberry PI OS glibc source package, putting the debian
sources in the rpbios/buster branch.
workdir/glibc$ gbp import-dsc --pristine-tar --debian-branch=rbpios/buster --upstream-branch=upstream/2.28.x --create-missing-branches ../glibc_2.28-10+rpt2+rpi1+deb10u2.dsc
You should have now these branches in the repository:
workdir/glibc$ git branch
* debian/buster
pristine-tar
rbpios/buster
upstream/2.28.x
As well as the following tags:
workdir/glibc$ git tag
debian/2.28-10+deb10u2
debian/2.28-10+rpt2+rpi1+deb10u2
upstream/2.28
We can take a look at the differences between both packages with git diff.
To limit the size of the document, we highlight here the differences in the
patches applied and those in debian/rules:
workdir/glibc$ git diff debian/2.28-10+deb10u2 debian/2.28-10+rpt2+rpi1+deb10u2
[...]
diff --git a/debian/patches/series b/debian/patches/series
index 211d5981..7bb55643 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -28,12 +28,14 @@ alpha/submitted-fts64.diff
alpha/submitted-makecontext.diff
arm/local-sigaction.diff
-arm/unsubmitted-ldconfig-cache-abi.diff
-arm/unsubmitted-ldso-abi-check.diff
+#arm/unsubmitted-ldconfig-cache-abi.diff
+#arm/unsubmitted-ldso-abi-check.diff
arm/local-soname-hack.diff
arm/local-vfp-sysdeps.diff
arm/unsubmitted-ldso-multilib.diff
arm/local-arm-futex.diff
+arm/sht_relr_new.diff
+arm/glibc-tls-libwidevinecdm.so-since-4.10.2252.0-has-TLS-with.patch
hppa/local-inlining.diff
[...]
diff --git a/debian/rules b/debian/rules
index de564b5f..cda61b8f 100755
--- a/debian/rules
+++ b/debian/rules
@@ -98,7 +98,7 @@ BASE_CXX = g++
BASE_MIG = mig
DEB_GCC_VERSION ?= -8
-RUN_TESTSUITE = yes
+RUN_TESTSUITE = no
TIMEOUTFACTOR = 25
# Set cross and native compiler names, including version.
Since the Raspberry PI OS glibc package is very close to the Debian package, we can create a fake merge commit for being able to “import” the changes from the next Debian release in a practical way:
workdir/glibc$ git checkout rbpios/buster
workdir/glibc$ git merge -s ours debian/buster
- Importing changes from a new Debian Extended LTS release
Let’s consider now a new release of glibc was published, taking
glibc_2.28-10+deb10u3 as example. It is from this version that you want to
import the security fixes.
Again we’ll use snapshot.debian.org as a source for our howto, but you’ll be getting your updates from the Freexian ELTS repo.
After downloading the new release, import the new source package with gbp import-dsc and merge it into the debian/buster branch:
workdir/glibc$ gbp import-dsc --pristine-tar --debian-branch=debian/buster --upstream-branch=upstream/2.28.x ../glibc_2.28-10+deb10u3.dsc
You can take a look at the differences between the two glibc Debian releases. These differences should be the patches that have been included in the last release, and that you want to apply to the Raspberry PI OS package. Again, to keep this document short, we show only part of the output:
workdir/glibc$ git diff debian/2.28-10+deb10u2 debian/2.28-10+deb10u3
[...]
diff --git a/debian/patches/series b/debian/patches/series
index 211d5981..023965ab 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -175,3 +175,6 @@ all/git-CVE-2021-33574-mq_notify-use-after-free.diff
all/git-CVE-2021-35942-wordexp-handle-overflow-in-positional-parameter-numb.diff
all/git-CVE-2022-23218-Buffer-overflow-in-sunrpc-svcunix_cre.diff
all/git-CVE-2022-23219-Buffer-overflow-in-sunrpc-clnt_create.diff
+
+all/git-0001-iconv-ISO-2022-CN-EXT-fix-out-of-bound-writes-when-w.patch
+all/git-0002-misc-test-errno-linux-Handle-EINVAL-from-quotactl.patch
[...]
If you take a look at the debian/changelog from debian/2.28-10+deb10u3, you
will find that these two patches listed above related to CVE-2024-2961. To
import the last debian sources (including the patches) into the Raspberry PI OS
buster branch, run git merge:
workdir/glibc$ git checkout rbpios/buster
workdir/glibc$ git merge debian/buster
Auto-merging debian/changelog
CONFLICT (content): Merge conflict in debian/changelog
Auto-merging debian/patches/series
Automatic merge failed; fix conflicts and then commit the result.
You should manually fix the conflicts in debian/changelog, resulting in
something like this:
glibc (2.28-10+deb10u3) buster-security; urgency=medium
* Non-maintainer upload by the LTS Team.
* CVE-2024-2961: Out-of-bounds write in iconv ISO-2022-CN-EXT module
* Don't ignore test failures during the build.
-- Adrian Bunk <bunk@debian.org> Tue, 23 Apr 2024 19:23:00 +0300
glibc (2.28-10+rpt2+rpi1+deb10u2) buster; urgency=medium
* arm/glibc-tls-libwidevinecdm.so-since-4.10.2252.0-has-TLS-with.patch
- https://lkml.org/lkml/2020/7/3/754
* arm/sht_relr_new.diff
- https://github.com/xbmc/inputstream.adaptive/issues/678#issuecomment-839295299
* Disable arm/unsubmitted-ldconfig-cache-abi.diff
* Disable arm/unsubmitted-ldso-abi-check.diff
-- Serge Schneider <serge@raspberrypi.com> Thu, 25 May 2023 16:59:39 +0100
You can check that the differences with the debian/buster branch are similar
to those before importing the new release:
workdir/glibc$ git diff debian/buster HEAD
[...]
diff --git a/debian/patches/series b/debian/patches/series
index 023965ab..b4ba2d60 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -28,12 +28,14 @@ alpha/submitted-fts64.diff
alpha/submitted-makecontext.diff
arm/local-sigaction.diff
-arm/unsubmitted-ldconfig-cache-abi.diff
-arm/unsubmitted-ldso-abi-check.diff
+#arm/unsubmitted-ldconfig-cache-abi.diff
+#arm/unsubmitted-ldso-abi-check.diff
arm/local-soname-hack.diff
arm/local-vfp-sysdeps.diff
arm/unsubmitted-ldso-multilib.diff
arm/local-arm-futex.diff
+arm/sht_relr_new.diff
+arm/glibc-tls-libwidevinecdm.so-since-4.10.2252.0-has-TLS-with.patch
hppa/local-inlining.diff
diff --git a/debian/rules b/debian/rules
index de564b5f..cda61b8f 100755
--- a/debian/rules
+++ b/debian/rules
@@ -98,7 +98,7 @@ BASE_CXX = g++
BASE_MIG = mig
DEB_GCC_VERSION ?= -8
-RUN_TESTSUITE = yes
+RUN_TESTSUITE = no
TIMEOUTFACTOR = 25
# Set cross and native compiler names, including version.
[...]
For creating a new release based on this merge, you need to add a new changelog
entry. You can use gbp dch for that, but you need to adjust the version
manually, to make sure the new version will be higher than the one currently
available in Raspberry PI OS. In this case, the version should be
2.28-10+rpt2+rpi1+deb10u3, and the resulting debian/changelog:
glibc(2.28-10+rpt2+rpi1+deb10u3) buster; urgency=medium
* Import changes from Debian changes 2.28-10+deb10u3
-- Package Maintainer <maintainer@example.com> Thu, 04 Jul 2024 15:10:25 -0300
You need to verify that the patches apply cleanly:
workdir/glibc$ export QUILT_PATCHES=debian/patches
workdir/glibc$ quilt push -a
If everything goes well, quilt should be able to apply the full list of
patches without conflicts or fuzz:
[...]
Applying patch debian/patches/all/git-0002-misc-test-errno-linux-Handle-EINVAL-from-quotactl.patch
patching file sysdeps/unix/sysv/linux/test-errno-linux.c
Now at patch debian/patches/all/git-0002-misc-test-errno-linux-Handle-EINVAL-from-quotactl.patch
In case quilt cannot apply a patch or a patch applies with fuzz, you should manually fix the conflicts and
refresh the patch with quilt refresh. Patches that apply with fuzz usually do not require editing and only need a quilt refresh. Repeat iteratively until all the
patches apply cleanly.
- Build the source package
Once you are finished updating the patches, you can create the source package with debuild or gbp buildpackage. For example:
workdir/glibc$ gbp buildpackage --git-builder=/usr/bin/debuild --git-debian-branch=rbpios/buster --git-no-create-orig -us -uc -S -nc
You should find the files that compose the debian source package (.dsc etc.)
in the parent directory (workdir/ in this example), and you can use them to
build the binary package from them.
For future releases, you should only need to repeat steps 2 and 3.
Making your packages available in a repository
Beyond integrating the security fixes and building the binary packages, you may be interested in making your packages available via a repository for apt. There are different tools that can be used for that purpose. Describing them in detail is beyond the scope of this document, but we list some of the here for convenience:
- aptly: https://www.aptly.info/
- mini-dinstall: https://wiki.debian.org/DebianRepository/SetupWithMinidinstall
- reprepro: https://wiki.debian.org/DebianRepository/SetupWithReprepro
You can find more information about in the Debian Administrator’s Handbook.
References
The workflow described here relies on the git-buildpackage and quilt tools.
You can find more information about them in:
- the git-buildpackage manual: https://honk.sigxcpu.org/projects/git-buildpackage/manual-html/
- the
quilt(1)manual page