Package: pbuilder
Version: 0.231
Severity: wishlist
X-Debbugs-Cc: u122...@gmail.com

Dear Maintainer,

I hope this message finds you well. I am writing to address a feature 
enhancement for the current pbuilder (version 0.231). As you are aware, 
pbuilder already supports the ability to bind-mount directories into the chroot 
environment via the `--bindmounts` command-line option (as documented in 
pbuilder.8) and the configuration item `BINDMOUNTS` in `pbuilderrc.5`. This 
functionality is generally sufficient for our applications, allowing us to 
simulate build environments effectively.

However, there are scenarios where we require more control over the 
bind-mounting process. Specifically, there are instances when we need to mount 
external file systems/folders into the chroot without the expectation that they 
can be written to or edited. For example, it might be necessary to bind-mount 
an external database or repository for read-only access during the build 
process.

With this in mind, I would like to propose the implementation of a read-only 
bind-mount option, both as a command-line flag and a configuration item. This 
would provide the additional control needed for cases where write access should 
be strictly prohibited.

I have prepared a patch that introduces this functionality. My preliminary 
testing with `pbuilder build *.dsc` and `pbuilder login (chroot)` suggests that 
it operates as expected for my use cases. I suppose this enhancement will be 
beneficial to the community, allowing for more secure and predictable build 
environments.

I would greatly appreciate your consideration of this request. If you find the 
patch satisfactory or if there are any concerns or suggestions for improvement, 
please let me know. Thank you for your time and attention to this matter.



Thanks,
Best regards,
Xiangyu LIU


# ---------------------------------------- patch 
--------------------------------------------------
diff -Narup a/bash_completion.d/pbuilder b/bash_completion.d/pbuilder
--- a/bash_completion.d/pbuilder        2020-02-16 00:49:39.000000000 +0800
+++ b/bash_completion.d/pbuilder        2024-06-24 12:52:01.013999672 +0800
@@ -57,7 +57,7 @@ _pbuilder()
                 --buildresult --aptcache --removepackages --extrapackages 
--configfile
                 --hookdir --debemail --debbuildopts --logfile --pkgname-logfile
                 --aptconfdir --timeout --override-config  --binary-arch 
--binary-indep
-                --preserve-buildplace --bindmounts --debug --twice 
--autocleanaptcache
+                --preserve-buildplace --bindmounts --bindmountsro --debug 
--twice --autocleanaptcache
                 --compressprog --debootstrapopts --save-after-login 
--save-after-exec
                 --debootstrap' \
                 -- "$cur" ) )
diff -Narup a/examples/lvmpbuilder/lib/lvmbuilder-checkparams 
b/examples/lvmpbuilder/lib/lvmbuilder-checkparams
--- a/examples/lvmpbuilder/lib/lvmbuilder-checkparams   2018-11-23 
18:51:49.000000000 +0800
+++ b/examples/lvmpbuilder/lib/lvmbuilder-checkparams   2024-06-24 
12:52:01.013999672 +0800
@@ -88,6 +88,11 @@ while [ -n "$1" ]; do
            warn_option $1;
            shift; shift;
            ;;
+        --bindmountsro)
+            BINDMOUNTSRO="${BINDMOUNTSRO} $2"
+            warn_option $1;
+            shift; shift;
+            ;;
        --save-after-login|--save-after-exec)
            SAVE_AFTER_LOGIN=yes;
            warn_option $1;
diff -Narup a/pbuilder.8 b/pbuilder.8
--- a/pbuilder.8        2019-03-15 22:24:28.000000000 +0800
+++ b/pbuilder.8        2024-06-24 12:53:43.223999282 +0800
@@ -535,6 +535,14 @@ specified in a space-delimited manner, s
 .B """/srv /somedir /someotherdir"""
 
 .TP
+.BI "\-\-bindmountsro " "bind-mount-points"
+Bind-mount the specified directories to inside the chroot (read-only mode).
+.I "bind-mount-points"
+is a space-delimited list of directories to bind-mount (in read-only mode) 
which should be
+specified in a space-delimited manner, surrounded in double quotations, like:
+.B """/srv /somedir /someotherdir"""
+
+.TP
 .BI "\-\-debootstrapopts " "\-\-variant=buildd" " " "\-\-keyring" " " 
"/usr/share/keyrings/debian\-archive\-keyring.gpg"
 Add extra command-line options to debootstrap.
 
diff -Narup a/pbuilder-checkparams b/pbuilder-checkparams
--- a/pbuilder-checkparams      2019-03-23 21:16:18.000000000 +0800
+++ b/pbuilder-checkparams      2024-06-24 12:52:01.013999672 +0800
@@ -273,6 +273,10 @@ while [ -n "$1" ]; do
         BINDMOUNTS="${BINDMOUNTS} $2"
         shift; shift;
         ;;
+    --bindmountsro)
+        BINDMOUNTSRO="${BINDMOUNTSRO} $2"
+        shift; shift;
+        ;;
     --debootstrapopts)
         # specify this option to set --variant=buildd value to debootstrap
         DEBOOTSTRAPOPTS[${#DEBOOTSTRAPOPTS[@]}]="$2";
@@ -452,6 +456,8 @@ fi
 
 # sort BINDMOUNTS to ensure that deeper directories are mounted last
 BINDMOUNTS="$(for i in $BINDMOUNTS; do echo $i; done | sort -u)"
+# sort BINDMOUNTSRO to ensure that deeper directories are mounted last
+BINDMOUNTSRO="$(for i in $BINDMOUNTSRO; do echo $i; done | sort -u)"
 
 if [ "$ALLOWUNTRUSTED" = "yes" ]; then
     
PBUILDERSATISFYDEPENDSOPT[${#PBUILDERSATISFYDEPENDSOPT[@]}]='--allow-untrusted'
diff -Narup a/pbuilder-modules b/pbuilder-modules
--- a/pbuilder-modules  2020-01-18 23:28:49.000000000 +0800
+++ b/pbuilder-modules  2024-06-24 12:52:01.013999672 +0800
@@ -78,6 +78,7 @@ pbuilder main options:
  --binary-arch
  --preserve-buildplace
  --bindmounts [bind-mount-point]
+ --bindmountsro [bind-mount-point in read-only mode]
  --debug
  --debootstrapopts [debootstrap options]
  --save-after-login/--save-after-exec
@@ -281,6 +282,9 @@ function umountproc () {
     for mnt in $BINDMOUNTS; do
         reversed="$mnt $reversed"
     done
+    for mnt in $BINDMOUNTSRO; do
+        reversed="$mnt $reversed"
+    done
     for mnt in $reversed; do
         umount_one "${mnt#*:}"
     done
@@ -472,6 +476,7 @@ function mountproc () {
         mount -t firmlink /servers "$BUILDPLACE/servers" || true
         mounted[${#mounted[@]}]="$BUILDPLACE/servers"
     fi
+    # Normal mount
     MOUNTPARAMS="-obind"
     [ "$DEB_BUILD_ARCH_OS" = "linux" ] && MOUNTPARAMS="${MOUNTPARAMS} 
--make-private"
     [ "$DEB_BUILD_ARCH_OS" = "kfreebsd" ] && MOUNTPARAMS="-t nullfs"
@@ -479,6 +484,40 @@ function mountproc () {
         mntpoint=${mnt#*:}
         mnt=${mnt%%:*}
         if [ "$mnt" = "$mntpoint" ]; then
+            log.i "Mounting $mnt"
+        else
+            log.i "Mounting $mnt to $mntpoint"
+        fi
+        if [ -d "$mnt" ]; then
+            create_mntpoint_cmd="mkdir -p"
+        else
+            create_mntpoint_cmd="touch"
+        fi
+        if $create_mntpoint_cmd "$BUILDPLACE/$mntpoint" &&
+            mount $MOUNTPARAMS "$mnt" "$BUILDPLACE/$mntpoint"; then
+            # successful.
+            mounted[${#mounted[@]}]="$BUILDPLACE/$mnt"
+        else
+            # this part of code is the only part which is supposed to fail.
+            # When unsuccessful, backtrack / umount and abort.
+            if [ -n "${mounted[*]}" ]; then
+                log.i "error recovery: umount successfully mounted 
mount-points: ${mounted[@]}"
+                for umnt in "${mounted[@]}"; do
+                    log.i "umounting $umnt"
+                    umount "$umnt"
+                done
+            fi
+            exit 1
+        fi
+    done
+    # Normal mount in read-only mode
+    MOUNTPARAMS="-o bind,ro"
+    [ "$DEB_BUILD_ARCH_OS" = "linux" ] && MOUNTPARAMS="${MOUNTPARAMS} 
--make-private"
+    [ "$DEB_BUILD_ARCH_OS" = "kfreebsd" ] && MOUNTPARAMS="-t nullfs"
+    for mnt in $BINDMOUNTSRO; do
+        mntpoint=${mnt#*:}
+        mnt=${mnt%%:*}
+        if [ "$mnt" = "$mntpoint" ]; then
             log.i "Mounting $mnt"
         else
             log.i "Mounting $mnt to $mntpoint"
diff -Narup a/pbuilderrc b/pbuilderrc
--- a/pbuilderrc        2020-12-08 22:55:39.000000000 +0800
+++ b/pbuilderrc        2024-06-24 12:52:01.013999672 +0800
@@ -115,6 +115,10 @@ BUILDUSERNAME=pbuilder
 # inside the chroot.
 BINDMOUNTS=""
 
+# BINDMOUNTSRO is a space separated list of things to mount (in read-only mode)
+# inside the chroot.
+BINDMOUNTSRO=""
+
 # Set the debootstrap variant to 'buildd' type.
 DEBOOTSTRAPOPTS=(
     '--variant=buildd'
diff -Narup a/pbuilderrc.5 b/pbuilderrc.5
--- a/pbuilderrc.5      2020-12-08 22:55:48.000000000 +0800
+++ b/pbuilderrc.5      2024-06-24 12:52:01.013999672 +0800
@@ -81,6 +81,20 @@ An Example:
 BINDMOUNTS="/home /mnt/test /home/joe/repo:/var/repo"
 .EE
 .TP
+.BI "BINDMOUNTSRO=" "directories-to-bind-mount[:internal-mountpoint]"
+When this value is set, pbuilder will mount these directories using
+bind-mount, but make them read-only. Different directories are space separated,
+a column can optionally specify a mount destination inside the chroot.
+.br
+Do not bind-mount
+.BR "/" .
+.br
+An Example:
+
+.EX
+BINDMOUNTSRO="/home /mnt/test /home/joe/repo:/var/repo"
+.EE
+.TP
 .BI "BUILDDIR=" "/build"
 The directory inside the chroot where the build happens.
 This directory will contain the build products; the source packages will be






-- System Information:
Debian Release: 12.6
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable-security'), (500, 
'proposed-updates'), (500, 'testing'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 6.6.35-02.custom.lfsdefaulthuge-sign (SMP w/8 CPU threads)
Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages pbuilder depends on:
ii  debconf [debconf-2.0]  1.5.82
ii  dpkg-dev               1.21.22

Versions of packages pbuilder recommends:
pn  debootstrap | cdebootstrap  <none>
pn  devscripts                  <none>
ii  eatmydata                   130-2
pn  fakeroot                    <none>
ii  iproute2                    6.1.0-3
ii  sudo                        1.9.13p3-1+deb12u1

Versions of packages pbuilder suggests:
pn  cowdancer   <none>
pn  gdebi-core  <none>

-- debconf information excluded

Reply via email to