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