Skip to contentSkip to conversation

Rootless builds, again

PATCH New Jan Kiszka 1 participant 6 messages Aug 27

lore
Share & tools
lore

Jan Kiszka

author
#0 lore raw

v3 cover Rootless builds, again

After fixing (hopefully) all remaining issues in Isar, kas, and our gitlab-cloud-ci, we should now be ready to merge this.

Changes to v2:
- update to kas 5.5
- bump Isar once more, plus not-yet-merged patch
- run rootless builds against rootless runner

Jan

CC Quirin Gylstorff <[email protected]>

Jan Kiszka (2):
Update Isar revision
ci: Select rootless runner

Quirin Gylstorff (3):
update to kas 5.5
switch to isar-rootless
update README.md for rootless build

 .gitlab-ci.yml                                |  10 +-
 .reproducible-check-ci.yml                    |   5 +-
 Kconfig                                       |   2 +-
 README.md                                     |   7 +-
 ...map-nobody-nogroup-as-dedicated-bloc.patch |  68 ++++
 kas-cip.yml                                   |   8 +-
 kas-container                                 | 329 ++++++++++--------
 7 files changed, 269 insertions(+), 160 deletions(-)
 create mode 100644 isar-patches/0001-rootless-always-map-nobody-nogroup-as-dedicated-bloc.patch
Signature · 1 line
2.47.3
author
#1 lore raw

PATCH v3 1/5 update to kas 5.5

From: Quirin Gylstorff <[email protected]>

[Jan: moved from 5.4 to 5.5]
---
 .gitlab-ci.yml |   2 +-
 Kconfig        |   2 +-
 kas-cip.yml    |   2 +-
 kas-container  | 329 +++++++++++++++++++++++++++----------------------
 4 files changed, 187 insertions(+), 148 deletions(-)
.gitlab-ci.yml +1 -1
index d46a9efb..9aa186c6 100644
@@ -34,7 +34,7 @@ stages:
   - cve-check
 
 default:
-  image: ghcr.io/siemens/kas/kas-isar:5.2
+  image: ghcr.io/siemens/kas/kas-isar:5.5
   before_script:
     - export http_proxy=$HTTP_PROXY
     - export https_proxy=$HTTPS_PROXY
Kconfig +1 -1
index 19f8e24b..3a9444db 100644
@@ -17,7 +17,7 @@ config KAS_INCLUDE_MAIN
 
 config KAS_BUILD_SYSTEM
 	string
-	default "isar"
+	default "isar-privileged"
 
 config ARCH_AMD64
 	bool
kas-cip.yml +1 -1
index 7a3af452..97b333a1 100644
@@ -15,7 +15,7 @@ header:
 distro: cip-core-trixie
 target: cip-core-image
 
-build_system: isar
+build_system: isar-privileged
 
 repos:
   cip-core:
kas-container +184 -145

543 lines not on this page · raw message

Signature · 1 line
2.47.3
author
#2 lore raw

PATCH v3 2/5 Update Isar revision

In reply to Jan Kiszka

From: Jan Kiszka <[email protected]>

One not-yet-merged patch is needed to make Isar compatible with gitlab-cloud-ci in rootless mode.

---
 ...map-nobody-nogroup-as-dedicated-bloc.patch | 68 +++++++++++++++++++
 kas-cip.yml                                   |  6 +-
 2 files changed, 73 insertions(+), 1 deletion(-)
 create mode 100644 isar-patches/0001-rootless-always-map-nobody-nogroup-as-dedicated-bloc.patch
isar-patches/0001-rootless-always-map-nobody-nogroup-as-dedicated-bloc.patch new file +68 -0
new file mode 100644
index 00000000..6c58c194
@@ -0,0 +1,68 @@
+From ea8f6d883a494430ff7db4ee95a875edee23c020 Mon Sep 17 00:00:00 2001
+From: Felix Moessbauer <[email protected]>
+Date: Thu, 20 Aug 2026 17:10:29 +0200
+Subject: [PATCH] rootless: always map nobody/nogroup as dedicated block
+
+The nobody/nogroup ids were mapped as part of the linear id range,
+with an extra single-id mapping added only if the range was too small
+to contain them. The extra mapping was guarded by "uid_cnt < nobody_id",
+but the linear range ends at uid_cnt-2, so it covers nobody only for
+uid_cnt >= 65536. For a count of 65534 or 65535 neither the linear range
+nor the guard mapped nobody.
+
+Relying on the linear range to cover nobody is unsafe in general. If that
+range covers the outer id that --map-root-user maps to, unshare punches a
+hole out of the mapping, and per unshare(1) this "may result in the
+highest user ID of the mapping not being mapped". That highest id is
+exactly nobody. This happens whenever the subid range overlaps the id of
+the calling user, e.g. with
+
+  builder:0:65536
+
+where the mapped block 1..65534 contains the builder's own uid. The
+resulting namespace then silently lacks a nobody mapping, while a range
+like 100000:65536 is unaffected and hides the problem.
+
+Map nobody/nogroup as a separate block at the top of the range and cap
+the linear range at nobody_id-1. The separate block does not overlap
+--map-root-user, so it survives, and a hole now at most costs id 65533.
+
+Fixes: 4fedb1ae ("add support for fully rootless builds")
+Signed-off-by: Felix Moessbauer <[email protected]>
+---
+ meta/classes-global/base.bbclass | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/meta/classes-global/base.bbclass b/meta/classes-global/base.bbclass
+index d96ebef4..8f81ab70 100644
+--- a/meta/classes-global/base.bbclass
++++ b/meta/classes-global/base.bbclass
+@@ -470,15 +470,19 @@ def run_privileged_cmd(d):
+         nobody_subid = uid_base + uid_cnt - 1
+         gid_base, gid_cnt = get_subid_range('/etc/subgid', d)
+         nogroup_subid = gid_base + gid_cnt - 1
++        # nobody/nogroup need a dedicated block at the top of the range. As part
++        # of the linear range they are lost whenever that range covers the outer
++        # id of --map-root-user, because unshare then punches out a hole and
++        # drops the highest id of the range.
++        uid_linear_cnt = min(uid_cnt - 2, nobody_id - 1)
++        gid_linear_cnt = min(gid_cnt - 2, nobody_id - 1)
+         cmd = 'unshare --mount --pid --uts --ipc --user' \
+               ' --kill-child' \
+               ' --setuid 0 --setgid 0 --fork' \
+-              f' --map-users  1:{uid_base+1}:{uid_cnt-2}' \
+-              f' --map-groups 1:{gid_base+1}:{gid_cnt-2}'
+-        if uid_cnt < nobody_id:
+-            cmd += f' --map-users  {nobody_id}:{nobody_subid}:1'
+-        if gid_cnt < nobody_id:
+-            cmd += f' --map-groups {nobody_id}:{nogroup_subid}:1'
++              f' --map-users  1:{uid_base+1}:{uid_linear_cnt}' \
++              f' --map-groups 1:{gid_base+1}:{gid_linear_cnt}' \
++              f' --map-users  {nobody_id}:{nobody_subid}:1' \
++              f' --map-groups {nobody_id}:{nogroup_subid}:1'
+         cmd += " --map-root-user"
+     else:
+         cmd = 'sudo -E'
+-- 
+2.47.3
+
kas-cip.yml +5 -1
index 97b333a1..61cc9225 100644
@@ -22,9 +22,13 @@ repos:
 
   isar:
     url: https://github.com/ilbers/isar.git
-    commit: 481db3b2e8949336576e50a78aaf5d101f52c8d2
+    commit: 436bc96f3869b4a139357afbabb039caf4df7c5c
     layers:
       meta:
+    patches:
+      p1:
+        path: isar-patches/0001-rootless-always-map-nobody-nogroup-as-dedicated-bloc.patch
+        repo: cip-core
 
 bblayers_conf_header:
   standard: |
Signature · 1 line
2.47.3
author
#3 lore raw

PATCH v3 3/5 switch to isar-rootless

In reply to Jan Kiszka

From: Quirin Gylstorff <[email protected]>

---
 .reproducible-check-ci.yml | 3 +--
 Kconfig                    | 2 +-
 kas-cip.yml                | 2 +-
 3 files changed, 3 insertions(+), 4 deletions(-)
.reproducible-check-ci.yml +1 -2
index 1246a641..4f4649ee 100644
@@ -39,8 +39,7 @@
     # Deploy .wic, .swu and wic partitions for build1
     - deploy_rb_artifacts build1
     # clean
-    - sudo rm -rf build/tmp
-    - sudo rm -rf build/sstate-cache
+    - kas purge --isar-rootless ${base_yaml}
     # Build 2nd time
     - !reference [.build_base, script]
     # Deploy .wic, .swu and wic partitions for build2
Kconfig +1 -1
index 3a9444db..7575d89c 100644
@@ -17,7 +17,7 @@ config KAS_INCLUDE_MAIN
 
 config KAS_BUILD_SYSTEM
 	string
-	default "isar-privileged"
+	default "isar-rootless"
 
 config ARCH_AMD64
 	bool
kas-cip.yml +1 -1
index 61cc9225..43aeb2d6 100644
@@ -15,7 +15,7 @@ header:
 distro: cip-core-trixie
 target: cip-core-image
 
-build_system: isar-privileged
+build_system: isar-rootless
 
 repos:
   cip-core:
Signature · 1 line
2.47.3
author
#4 lore raw

PATCH v3 4/5 update README.md for rootless build

In reply to Jan Kiszka

From: Quirin Gylstorff <[email protected]>

[Jan: adjust wording, reference kas docs]
---
 README.md | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
README.md +3 -4
index 05291744..f84adadc 100644
@@ -10,10 +10,9 @@ from scratch.
 
 ## Building Target Images
 
-Install docker or podman and make sure you have required permissions to start
-privileged containers. For docker, you need to be part of respective docker
-group (`sudo usermod -aG docker <USER>`). Privileged podman requires sudo
-rights for the caller (`<USER> ALL=(root) SETENV: /usr/bin/podman` in sudoers).
+Install docker or podman. For true unprivileged builds, podman is recommended.
+See [kas documentation](https://kas.readthedocs.io/en/latest/userguide/kas-container.html)
+for more details.
 
 Open up the image configuration menu and select the desired target and its
 options:
Signature · 1 line
2.47.3
author
#5 lore raw

PATCH v3 5/5 ci: Select rootless runner

In reply to Jan Kiszka

From: Jan Kiszka <[email protected]>

We need to explicitly select a runner that is launching build containers in unprivileged mode. This is primarily due to the bug in kas 5.4 which breaks the parallel start of multiple kas-isar containers on the same host. At the same time, such tagging allows us to phase out the privileged runner at some point in way that would clearly block legacy jobs.

---
 .gitlab-ci.yml             | 8 ++++----
 .reproducible-check-ci.yml | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)
.gitlab-ci.yml +4 -4
index 9aa186c6..8dbe62d2 100644
@@ -1,7 +1,7 @@
 #
 # CIP Core, generic profile
 #
-# Copyright (c) Siemens AG, 2019-2025
+# Copyright (c) Siemens AG, 2019-2026
 # Copyright (c) Toshiba Corporation, 2020
 #
 # Authors:
@@ -53,7 +53,7 @@ default:
       when: never
     - if: $CI_COMMIT_BRANCH != "master"
   tags:
-    - large
+    - large-rootless
   variables:
     base_yaml: "kas-cip.yml:kas/board/${target}.yml"
   script:
@@ -917,7 +917,7 @@ cve-checks:
   needs: []
   image: registry.gitlab.com/cip-project/cip-core/debian-cve-checker:build-latest
   tags:
-    - large
+    - large-rootless
   script:
     - scripts/run-cve-checks.sh
   rules:
@@ -936,7 +936,7 @@ lavacli-container:
   stage: build
   image: quay.io/buildah/stable:v1.41.4
   tags:
-    - large
+    - large-rootless
   before_script:
     - buildah login -u $CI_REGISTRY_USER --password $CI_REGISTRY_PASSWORD $CI_REGISTRY
   script:
.reproducible-check-ci.yml +1 -1
index 4f4649ee..de9f3fbd 100644
@@ -21,7 +21,7 @@
     extension: security
   stage: build
   tags:
-    - large
+    - large-rootless
   rules:
     - if: $CI_PIPELINE_SOURCE == "schedule" && $REPRODUCIBLE_BUILDS
   script:
Signature · 1 line
2.47.3