scaffold: aports overlay, build script, CI workflow, README

Kernel aport forked from pmaports 7.1.2-r0, repointed at milos-linux
combined-stable with the tested FP6 config (+EFI_ZBOOT for packaging);
imsd + nftables aports from the pending pmaports submission. build.sh
carries TODO(validate) markers - not yet run end-to-end.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jorijn van der Graaf 2026-08-08 15:42:45 +02:00
commit de2e819a16
26 changed files with 9095 additions and 0 deletions

View file

@ -0,0 +1,91 @@
From d648a5fd7f95d961126605d59da5ad007c265bda Mon Sep 17 00:00:00 2001
From: Aelin Reidel <aelin@mainlining.org>
Date: Wed, 17 Jun 2026 00:38:17 +0200
Subject: [PATCH] resolve_btfids: preserve tag and parameter names when
processing implicit args
process_kfunc_with_implicit_args() obtains parameter names through
btf__name_by_offset() and passes them to btf__add_func_param() while
constructing a new function prototype. Tag names are processed in a
similar fashion.
The returned name pointer references memory owned by the BTF object.
btf__add_func_param(), btf__add_decl_tag(), etc. modify the same BTF and
may grow its internal storage, invalidating previously returned string
pointers.
This can result in btf__add_func_param(), btf__add_decl_tag(), etc.
dereferencing a stale pointer when copying the string, leading to crashes
in strset__add_str().
Duplicate the parameter name before calling btf__add_func_param() so it
remains valid across BTF updates.
Fixes: 9d199965990c ("resolve_btfids: Support for KF_IMPLICIT_ARGS")
Cc: stable@vger.kernel.org
Signed-off-by: Aelin Reidel <aelin@mainlining.org>
---
tools/bpf/resolve_btfids/main.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index f8a91fa7584f..94b89e9c942e 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -1113,6 +1113,7 @@ static int process_kfunc_with_implicit_args(struct btf2btf_context *ctx, struct
{
s32 idx, new_proto_id, new_func_id, proto_id;
const char *param_name, *tag_name;
+ char *tmp_param_name, *tmp_tag_name;
const struct btf_param *params;
enum btf_func_linkage linkage;
char tmp_name[KSYM_NAME_LEN];
@@ -1163,18 +1164,22 @@ static int process_kfunc_with_implicit_args(struct btf2btf_context *ctx, struct
if (strcmp(tag_name, "bpf_kfunc") == 0)
continue;
+ tmp_tag_name = strdup(tag_name);
idx = btf_decl_tag(t)->component_idx;
if (btf_kflag(t))
- err = btf__add_decl_attr(btf, tag_name, new_func_id, idx);
+ err = btf__add_decl_attr(btf, tmp_tag_name, new_func_id, idx);
else
- err = btf__add_decl_tag(btf, tag_name, new_func_id, idx);
+ err = btf__add_decl_tag(btf, tmp_tag_name, new_func_id, idx);
if (err < 0) {
pr_err("ERROR: resolve_btfids: failed to add decl tag %s for %s\n",
- tag_name, tmp_name);
+ tmp_tag_name, tmp_name);
+ free(tmp_tag_name);
return -EINVAL;
}
+
+ free(tmp_tag_name);
}
add_new_proto:
@@ -1193,12 +1198,17 @@ static int process_kfunc_with_implicit_args(struct btf2btf_context *ctx, struct
if (is_kf_implicit_arg(btf, &params[i]))
break;
param_name = btf__name_by_offset(btf, params[i].name_off);
- err = btf__add_func_param(btf, param_name, params[i].type);
+ tmp_param_name = strdup(param_name);
+ if (!tmp_param_name)
+ return -ENOMEM;
+ err = btf__add_func_param(btf, tmp_param_name, params[i].type);
if (err < 0) {
pr_err("ERROR: resolve_btfids: failed to add param %s for %s\n",
- param_name, kfunc->name);
+ tmp_param_name, kfunc->name);
+ free(tmp_param_name);
return err;
}
+ free(tmp_param_name);
t = (struct btf_type *)btf__type_by_id(btf, proto_id);
}
--
2.54.0

View file

@ -0,0 +1,90 @@
# Fork of pmaports device/testing/linux-postmarketos-qcom-milos (7.1.2-r0),
# overlaid via pmbootstrap so it shadows the upstream aport. Differences:
# source is the Catcrafts combined-stable branch (upstream v7.1.2-milos tag +
# the FP6 bring-up carries), and the config is the exact one the development
# FP6 runs, plus CONFIG_EFI_ZBOOT for the packaging below.
maintainer="Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>"
_flavor="postmarketos-qcom-milos"
pkgname=linux-$_flavor
pkgver=7.1.2
# always sorts above the upstream aport (r0..r99)
pkgrel=100
pkgdesc="Milos mainline kernel + Catcrafts FP6 bring-up carries (combined-stable)"
arch="aarch64"
_carch="arm64"
url="https://forgejo.catcrafts.net/Catcrafts/milos-linux"
license="GPL-2.0-only"
options="!strip !check !tracedeps
pmb:cross-native
pmb:kconfigcheck-community
pmb:kconfigcheck-uefi
"
makedepends="
bison
clang
elfutils-dev
findutils
flex
installkernel
linux-headers
lld
llvm
openssl-dev
pahole
perl
python3
zstd
"
_config="config-$_flavor.$arch"
# Pinned by CI: the instance has source archives disabled, so the tarball is
# generated with git-archive (prefix milos-linux/) from combined-stable and
# placed next to this APKBUILD before `pmbootstrap checksum` runs. See
# build.sh at the repository root.
_commit="REPLACED_BY_CI"
source="
milos-linux-$_commit.tar.gz
0001-resolve_btfids-preserve-tag-and-parameter-names-when.patch
$_config
"
builddir="$srcdir/milos-linux"
prepare() {
default_prepare
cp "$srcdir/config-$_flavor.$arch" .config
}
build() {
unset LDFLAGS
make ARCH="$_carch" LLVM=1 \
KBUILD_BUILD_VERSION="$((pkgrel + 1 ))-$_flavor"
}
package() {
# ZBOOT EFI decompressor for EFI booting
install -Dm644 "$builddir/arch/$_carch/boot/vmlinuz.efi" \
"$pkgdir/boot/linux.efi"
# Old GZIP'd kernel image for boot.img compatibility
install -Dm644 "$builddir/arch/$_carch/boot/vmlinuz" \
"$pkgdir/boot/vmlinuz"
make modules_install dtbs_install \
ARCH="$_carch" \
LLVM=1 \
INSTALL_PATH="$pkgdir"/boot/ \
INSTALL_MOD_PATH="$pkgdir"/usr \
INSTALL_MOD_STRIP=1 \
INSTALL_DTBS_PATH="$pkgdir"/boot/dtbs
rm -f "$pkgdir"/lib/modules/*/build "$pkgdir"/lib/modules/*/source
install -D "$builddir"/include/config/kernel.release \
"$pkgdir"/usr/share/kernel/$_flavor/kernel.release
}
sha512sums="
REPLACED_BY_CI milos-linux-REPLACED_BY_CI.tar.gz
4e705e038a91466a86fc5317b0028c2220aa1e7a4807e5d86db2f9ac815a927c59666a8f21ed50c4632147d3ce183d8042378a76f95341dbcd3db1047faf39e3 0001-resolve_btfids-preserve-tag-and-parameter-names-when.patch
REPLACED_BY_CI config-postmarketos-qcom-milos.aarch64
"

View file

@ -0,0 +1,181 @@
maintainer="Clayton Craft <clayton@craftyguy.net>"
pkgname=postmarketos-config-nftables
pkgver=1
pkgrel=5
pkgdesc="nftables firewall configuration for postmarketOS"
url="https://gitlab.com/postmarketos"
arch="noarch"
license="MIT"
depends="openssh-nftrules"
# No subpackage for ausweisapp2 and localsend
# They are also on flathub, and
# install_if won't work
subpackages="
$pkgname-openusb
$pkgname-log
$pkgname-chromecast
$pkgname-docker
$pkgname-imsd
$pkgname-mdns
$pkgname-moshserver
$pkgname-networkmanager
$pkgname-rdpserver
$pkgname-upnp-client:upnp_client
$pkgname-vlc-chromecast:vlc_chromecast
$pkgname-vncserver
$pkgname-wifi-display:wifi_display
"
source="
rules/00_log_all.nft
rules/01_imsd.nft
rules/01_wwan.nft
rules/10_dhcp.nft
rules/50_ausweisapp2.nft
rules/50_localsend.nft
rules/50_mdns.nft
rules/50_rdpserver.nft
rules/50_upnp_client.nft
rules/50_vlc_chromecast.nft
rules/50_vncserver.nft
rules/51_docker.nft
rules/51_hotspot.nft
rules/51_usb_inet.nft
rules/51_wifi_display.nft
rules/60_usb.nft
rules/99_drop_log.nft
networkmanager.conf
"
options="!check" # No tests
package() {
cd rules
for _i in ./*; do
install -Dm644 "$_i" "$pkgdir"/etc/nftables.d/"$_i"
done
ln -s ../../usr/share/nftables.avail/50_sshd.nft "$pkgdir/etc/nftables.d/50_sshd.nft"
ln -s ../../usr/share/nftables.avail/50_mosh.nft "$pkgdir/etc/nftables.d/50_mosh.nft"
}
openusb() {
depends="$pkgname"
description="Adds a rule to accept all incoming connections to the usb* interface"
amove etc/nftables.d/60_usb.nft
}
log() {
depends="$pkgname"
description="Enables logging of nftable events"
amove etc/nftables.d/00_log_all.nft
amove etc/nftables.d/99_drop_log.nft
}
chromecast() {
depends="$pkgname $pkgname-mdns"
description="Enables networking for Chromium Chromecast"
install_if="$pkgname=$pkgver-r$pkgrel chromium"
# meta package is empty
mkdir -p "$subpkgdir"
}
docker() {
depends="$pkgname"
description="Enables networking for Docker"
install_if="$pkgname=$pkgver-r$pkgrel docker"
amove etc/nftables.d/51_docker.nft
}
imsd() {
depends="$pkgname"
description="Accepts imsd's IPsec-protected IMS traffic on the IMS PDN"
install_if="$pkgname=$pkgver-r$pkgrel imsd"
amove etc/nftables.d/01_imsd.nft
}
mdns() {
depends="$pkgname"
description="Enables networking for mDNS"
amove etc/nftables.d/50_mdns.nft
}
moshserver() {
depends="$pkgname mosh-nftrules"
description="Enables networking for mosh server"
install_if="$pkgname=$pkgver-r$pkgrel mosh-server"
amove etc/nftables.d/50_mosh.nft
}
upnp_client() {
depends="$pkgname"
description="Enables networking for SSDP/UPnP client"
install_if="$pkgname=$pkgver-r$pkgrel libupnp"
amove etc/nftables.d/50_upnp_client.nft
}
vlc_chromecast() {
depends="$pkgname $pkgname-chromecast"
description="Enables networking for VLC Chromecast casting"
install_if="$pkgname=$pkgver-r$pkgrel vlc"
amove etc/nftables.d/50_vlc_chromecast.nft
}
rdpserver() {
depends="$pkgname"
description="Enables networking for RDP Server"
install_if="$pkgname=$pkgver-r$pkgrel freerdp-libs"
amove etc/nftables.d/50_rdpserver.nft
}
vncserver() {
depends="$pkgname"
description="Enables networking for VNC Server"
amove etc/nftables.d/50_vncserver.nft
}
wifi_display() {
depends="$pkgname"
description="Enables networking for peer-to-peer Wi-Fi Displays (Miracast)"
amove etc/nftables.d/51_wifi_display.nft
}
networkmanager() {
depends="$pkgname"
description="Enables nftables backend in NetworkManager"
install_if="$pkgname=$pkgver-r$pkgrel networkmanager"
install -Dm644 "$srcdir"/networkmanager.conf \
"$subpkgdir"/usr/lib/NetworkManager/conf.d/50-nftables.conf
}
sha512sums="
166d77bcccc85a3db24af85010d07241cf193bccd79064863fbf9da7be4426364e9f9a9e0668c2c8018ada470d0fda30fe8eba24d24a2d4150af1d78af31b9b7 00_log_all.nft
c33f7d4e1956969ab88b90b16ab1ba04dde70bd843c640db65de8e6645386ce74dbe6bc66bd435e8818ef78d9d9baeb332798fb810d030ac968e60b48a8d67ac 01_imsd.nft
d13d9dca1fcae5c363b59c3f5d1210a33a15b763b0c4b9f722e1cdd03317838e1b503134a17359bb0b6d657d46c2fc6a5fbe6614487f28cbe58f8947fe1edb92 01_wwan.nft
ae6a8ac03d4643004f5ce9279083bc12a215ceb2ee66993a26ab5620bb1aab347541eb1729b38cc7ec9d232de07e0176bc59475669741dfa2588c9e1ec4a4958 10_dhcp.nft
a3f3fc76a636b1bed9de251f93cef46139b06e1c13113a6b6100ef08e79d249cb89a1b61d9b6bfbec73bdefdeb47360a6bb048488b4bccc2dccfc26d0635b579 50_ausweisapp2.nft
31792b874373c12e133b184b39cb04394ca1746ea825746310c8ab9cb28c503f55b0e139cea2d4115db8cdeb9a2155a97abb410e79a9a967d48678d7882e9f3c 50_localsend.nft
597bf66783379691962f4b87a29e6219d5f87ef17d49b261c7b1eebe54561deafce4be77de3b39252c10b7b4452ac5b55870dd30605d7d0f074d27b06d1dfa6d 50_mdns.nft
54f7e043b22097fd31d925b1fb34c57f1b4b01331efa34ec0552a8259c217a29e317335df4ce6b4c2abcf2f6565c582c4304be5ac08ba8fd2a988c0af89412f3 50_rdpserver.nft
5779bbcc55e411ec4da58e4e7eaaa6918cdcea5b8818cd72ab93be2d1108f020861457dbd8079a60b0912f84d05eb7b42274cc9a0577f66e8322f3596b89b411 50_upnp_client.nft
9207bef8d2df8d728521aef19f3c6ccb5c645a0295617b54722a6867c86b29c13502a01747eb3c91602f416f60bdc2bfa18dfb4906e17494923996596b6b1444 50_vlc_chromecast.nft
c688e768c709ad17685641a6ba543f84e8466080356712073e06108fc1707109f590be45b8a0aca8d0d95171c5afe69887f71b78fe56444912dd0582a461f477 50_vncserver.nft
76ac156ee80f895ab4f574f70f4ee9f960dfd23a3381bbbf7c744bea919b98f69e91e2eaa10425dfeaf5dbe77b745ec1dd82cb94953835873baffd9e5d89e166 51_docker.nft
1ce70bb71c9008b6c727a2c26d11467be3b5a0cb9815a8bb0790150c7958457b22b110e35ba974973b9579d44bd14219985d85597c954b5fa8cf77bf206c959b 51_hotspot.nft
ea7d8a652808ba6ae92de6dfc9f7d57415e411a04db3a41d1480f254b3a3a574558dbee2e7259e5d527527a11ca3aace7bb9edc7e023b0f4f67afceefeeb9e88 51_usb_inet.nft
c243534219eca3ea31504eef9ea88f8c2e00f2340e9dec3d381459a84a09a7390c8327eac43ae38155f6d7a059327cb26be63451a1ba280664fc1da81b27f7be 51_wifi_display.nft
0e86974602622c03f0b34acd048e3a31157c0226ab4b5ec093a19696af3fc9637ed84cecf0d190941e4bd3afeb0c76a37245fa850abef46778cd1235ad8106df 60_usb.nft
1532899534d7432a7708620cf1053ab80635fffe038a2352eb890c35fba4247c3b9ab3d0b028da1be765e5feb9b5a5b3a8107f4aa79f790d17930d38535a2288 99_drop_log.nft
ea738469e68b8a8038f301b0cb901cd305445321ee24c4b4025365b4b95d5c61113a5bb24ab4efaa73eda23c2e06984d3e58395584fcb8887cf1595ea99542da networkmanager.conf
"

View file

@ -0,0 +1,2 @@
[main]
firewall-backend=nftables

View file

@ -0,0 +1,9 @@
#!/usr/sbin/nft -f
table inet filter {
chain input {
log
}
}

View file

@ -0,0 +1,15 @@
#!/usr/sbin/nft -f
table inet filter {
chain input {
# imsd's IPsec-protected SIP ports on the IMS PDN. Ordered before
# 01_wwan.nft's qmapmux drop: the ESP-decapsulated inbound flows
# arrive on qmapmux* and would be dropped there. The comment is
# load-bearing — imsd's ims-pdn-up.sh checks for it and skips its
# runtime rule insertion when this rule is present.
iifname "qmapmux*" tcp dport 45061-45062 accept comment "imsd-protected-ports"
iifname "qmapmux*" udp dport 45061-45062 accept comment "imsd-protected-ports"
}
}

View file

@ -0,0 +1,11 @@
#!/usr/sbin/nft -f
table inet filter {
chain input {
# drop all incoming connections on wwan
iifname "wwan*" drop comment "drop all connections on wwan"
iifname "qmapmux*" drop comment "drop all connections on qmapmux"
}
}

View file

@ -0,0 +1,15 @@
#!/usr/sbin/nft -f
table inet filter {
chain input {
# Allow DHCP server on usb*
iifname "usb*" udp dport bootps accept comment "accept incoming DHCP on usb*"
# Allow DHCP server on wlan* for hotspot
iifname "wlan*" udp dport bootps accept comment "accept incoming DHCP on wlan*"
# Allow DHCP server on p2p-wlan* for WiFi Display
iifname "p2p-wlan*" udp dport bootps accept comment "accept incoming DHCP on p2p-wlan*"
}
}

View file

@ -0,0 +1,7 @@
#!/usr/sbin/nft -f
table inet filter {
chain input {
tcp dport 24727 accept comment "accept connections for BundID AusweisApp2"
}
}

View file

@ -0,0 +1,8 @@
#!/usr/sbin/nft -f
table inet filter {
chain input {
udp dport 53317 accept comment "localsend device discovery"
tcp dport 53317 accept comment "localsend file transfer"
}
}

View file

@ -0,0 +1,7 @@
#!/usr/sbin/nft -f
table inet filter {
chain input {
udp sport mdns udp dport mdns accept comment "accept incoming mDNS traffic"
}
}

View file

@ -0,0 +1,7 @@
#!/usr/sbin/nft -f
table inet filter {
chain input {
tcp dport 3389 accept comment "accept RDP"
}
}

View file

@ -0,0 +1,7 @@
#!/usr/sbin/nft -f
table inet filter {
chain input {
udp sport 1900 accept comment "accept SSDP/UPnP replies"
}
}

View file

@ -0,0 +1,7 @@
#!/usr/sbin/nft -f
table inet filter {
chain input {
tcp dport 8010 accept comment "accept VLC Chromecast"
}
}

View file

@ -0,0 +1,7 @@
#!/usr/sbin/nft -f
table inet filter {
chain input {
tcp dport 5900 accept comment "accept VNC"
}
}

View file

@ -0,0 +1,11 @@
#!/usr/sbin/nft -f
table inet filter {
chain input {
iifname "docker*" accept comment "Allow incoming network traffic from Docker"
}
chain forward {
iifname "docker*" accept comment "Allow outgoing network traffic from Docker"
ct state {established, related} counter accept comment "accept established connections"
}
}

View file

@ -0,0 +1,15 @@
#!/usr/sbin/nft -f
table inet filter {
chain input {
# allow DNS from wlan*
iifname "wlan*" tcp dport 53 accept comment "Accept DNS over TCP on wlan*"
iifname "wlan*" udp dport 53 accept comment "Accept DNS over UDP on wlan*"
}
chain forward {
iifname "wlan*" accept comment "Accept forwarding from wlan*"
}
}

View file

@ -0,0 +1,11 @@
#!/usr/sbin/nft -f
table inet filter {
chain input {
iifname "usb*" accept comment "Allow incoming network traffic from USB"
}
chain forward {
iifname "usb*" accept comment "Allow outgoing network traffic from USB"
ct state {established, related} counter accept comment "accept established connections"
}
}

View file

@ -0,0 +1,10 @@
#!/usr/sbin/nft -f
table inet filter {
chain input {
# allow DNS from wlan*
iifname "p2p-wlan*" tcp dport 7236 accept comment "Accept Wi-Fi Display Protocol over TCP on p2p-wlan*"
}
}

View file

@ -0,0 +1,13 @@
#!/usr/sbin/nft -f
# Allow all traffic from usb-ethernet interfaces for debugging
# and porting.
table inet filter {
chain input {
# allow all from USB net
iifname "usb*" accept comment "accept USB net"
}
}

View file

@ -0,0 +1,9 @@
#!/usr/sbin/nft -f
table inet filter {
chain input {
log prefix "DROP: " flags all drop
}
}

View file

@ -0,0 +1,48 @@
maintainer="Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>"
pkgname=imsd
pkgver=0.3.0
pkgrel=0
pkgdesc="Userspace IMS/VoLTE daemon for mainline Linux phones"
url="https://forgejo.catcrafts.net/Catcrafts/imsd"
# other arches: nothing wrong known, just never run there
arch="aarch64 x86_64"
license="GPL-3.0-only"
# the media leg dlopen's the AMR-WB codecs; pw-record/pw-play drive PipeWire —
# none of which abuild's .so auto-scan can see
depends="modemmanager opencore-amr vo-amrwbenc pipewire-tools"
# clang/libc++ C++26-modules build (upstream Makefile); llvm-runtimes ships
# the libc++ std module sources the build precompiles
makedepends="clang lld libc++-dev llvm-libunwind-dev llvm-runtimes glib-dev pkgconf"
# the versioned provides both satisfies soc-qcom-modem's 81voltd dependency
# and excludes the real package: 81voltd serves the modem firmware's own
# ims-PDN requests, which races imsd for the PDN and flaps it (a new prefix
# every ~2.5 min) — two IMS stacks cannot share one PDN. Installing imsd is
# an explicit choice to hand the IMS PDN to userspace.
provides="81voltd=$pkgver-r$pkgrel"
# no OpenRC service yet: the unit's PDN-bring-up/env-file sequencing is only
# tested under systemd; an initd is welcome once someone can verify one
subpackages="$pkgname-systemd"
source="$pkgname-$pkgver.tar.gz::$url/archive/v$pkgver.tar.gz"
builddir="$srcdir/$pkgname"
build() {
make
}
check() {
make check
}
package() {
make install DESTDIR="$pkgdir"
}
systemd() {
install_if="$pkgname=$pkgver-r$pkgrel systemd"
amove usr/lib/systemd/system
}
sha512sums="
PLACEHOLDER_RUN_PMBOOTSTRAP_CHECKSUM_AFTER_V0_3_0_TAG_EXISTS imsd-0.3.0.tar.gz
"