This is an automated email from the git hooks/post-receive script.

guillem pushed a commit to branch main
in repository dpkg.

View the commit online:
https://git.dpkg.org/cgit/dpkg/dpkg.git/commit/?id=916fa148466cec6f47793d47177bd32dfb05e489

commit 916fa148466cec6f47793d47177bd32dfb05e489
Author: Guillem Jover <[email protected]>
AuthorDate: Thu Nov 7 02:18:47 2024 +0100

    dpkg-deb: Add support for filesystem metadata checks
    
    This adds checks for unusual and/or unexpected ownership of the root
    directory for the to be built package.
    
    This will help catch invocations where the resulting filesystem metadata
    would be wrong and potentially a security issue, as the build has not
    been made with a root-equivalent runner, such as fakeroot, or preferably
    by passing the --root-owner-group option. This is part of the effort to
    default to rootless builds, and to try to help external packaging efforts
    that might not be using Debian tooling update their build scaffolding.
---
 src/at/deb-content.at | 26 +++++++++++++-------------
 src/at/deb-fields.at  |  6 +++---
 src/deb/build.c       | 25 +++++++++++++++++++++++++
 3 files changed, 41 insertions(+), 16 deletions(-)

diff --git a/src/at/deb-content.at b/src/at/deb-content.at
index f475603f9..a192c9493 100644
--- a/src/at/deb-content.at
+++ b/src/at/deb-content.at
@@ -11,7 +11,7 @@ AT_DATA([pkg-conff-duped/test-conffile-2], [test init
 ])
 AT_CHECK([
 # Duplicate conffile entries should produce a warning.
-dpkg-deb -b pkg-conff-duped
+dpkg-deb --root-owner-group -b pkg-conff-duped
 ], [0], [ignore], [dpkg-deb: warning: conffile name '/test-conffile-1' is 
duplicated
 dpkg-deb: warning: ignoring 1 warning about the control file(s)
 ])
@@ -23,7 +23,7 @@ AT_DATA([pkg-conff-noeol/test-conffile-1], [test init
 AT_CHECK([
 # Conffiles need a final newline to guarantee there's been no accidental
 # file truncation.
-dpkg-deb -b pkg-conff-noeol pkg-conff-noeol.deb
+dpkg-deb --root-owner-group -b pkg-conff-noeol pkg-conff-noeol.deb
 ], [2], [ignore], [dpkg-deb: error: conffile name '/test-conffile-1' is too 
long, or missing final newline
 ])
 
@@ -33,7 +33,7 @@ AT_DATA([pkg-conff-noabs/test-conffile-rel], [test init
 ])
 AT_CHECK([
 # Conffiles must use absolute pathnames.
-dpkg-deb -b pkg-conff-noabs pkg-conff-noabs.deb
+dpkg-deb --root-owner-group -b pkg-conff-noabs pkg-conff-noabs.deb
 ], [2], [ignore], [dpkg-deb: error: conffile name 'test-conffile-rel' is not 
an absolute pathname
 ])
 
@@ -41,7 +41,7 @@ DPKG_GEN_CONTROL([pkg-conff-empty])
 printf "   \n" >"pkg-conff-empty/DEBIAN/conffiles"
 AT_CHECK([
 # Conffiles must not contain empty lines.
-dpkg-deb -b pkg-conff-empty pkg-conff-empty.deb
+dpkg-deb --root-owner-group -b pkg-conff-empty pkg-conff-empty.deb
 ], [2], [ignore], [dpkg-deb: error: empty and whitespace-only lines are not 
allowed in conffiles
 ])
 
@@ -49,7 +49,7 @@ DPKG_GEN_CONTROL([pkg-conff-space-prefix])
 DPKG_GEN_CTRL_FILE([pkg-conff-space-prefix], [conffiles], [ /test-conffile])
 AT_CHECK([
 # Conffiles must not contain prefixed spaces.
-dpkg-deb -b pkg-conff-space-prefix pkg-conff-space-prefix.deb
+dpkg-deb --root-owner-group -b pkg-conff-space-prefix 
pkg-conff-space-prefix.deb
 ], [2], [ignore], [dpkg-deb: error: line with conffile filename 
'/test-conffile' has leading white spaces
 ])
 
@@ -57,7 +57,7 @@ DPKG_GEN_CONTROL([pkg-conff-unknown-flag])
 DPKG_GEN_CTRL_FILE([pkg-conff-unknown-flag], [conffiles], [unknown-flag 
/test-conffile])
 AT_CHECK([
 # Conffiles marked with an unknown flag.
-dpkg-deb -b pkg-conff-unknown-flag pkg-conff-unknown-flag.deb
+dpkg-deb --root-owner-group -b pkg-conff-unknown-flag 
pkg-conff-unknown-flag.deb
 ], [2], [ignore], [dpkg-deb: error: unknown flag 'unknown-flag' for conffile 
'/test-conffile'
 ])
 
@@ -65,7 +65,7 @@ DPKG_GEN_CONTROL([pkg-conff-missing-pathname])
 printf "unknown-flag \n" >"pkg-conff-missing-pathname/DEBIAN/conffiles"
 AT_CHECK([
 # Conffiles need a pathname, in addition to a flag.
-dpkg-deb -b pkg-conff-missing-pathname pkg-conff-missing-pathname.deb
+dpkg-deb --root-owner-group -b pkg-conff-missing-pathname 
pkg-conff-missing-pathname.deb
 ], [2], [ignore], [dpkg-deb: error: conffile name missing after flag 
'unknown-flag'
 ])
 
@@ -73,7 +73,7 @@ DPKG_GEN_CONTROL([pkg-conff-removed-missing])
 DPKG_GEN_CTRL_FILE([pkg-conff-removed-missing], [conffiles], 
[remove-on-upgrade /test-conffile-missing])
 AT_CHECK([
 # Conffiles marked for removal must not be present.
-dpkg-deb -b pkg-conff-removed-missing pkg-conff-removed-missing.deb
+dpkg-deb --root-owner-group -b pkg-conff-removed-missing 
pkg-conff-removed-missing.deb
 ], [0], [ignore], [])
 
 DPKG_GEN_CONTROL([pkg-conff-removed-duped])
@@ -82,7 +82,7 @@ remove-on-upgrade /test-conffile-2
 remove-on-upgrade /test-conffile-1])
 AT_CHECK([
 # Duplicate conffile entries should produce a warning.
-dpkg-deb -b pkg-conff-removed-duped
+dpkg-deb --root-owner-group -b pkg-conff-removed-duped
 ], [0], [ignore], [dpkg-deb: warning: conffile name '/test-conffile-1' is 
duplicated
 dpkg-deb: warning: ignoring 1 warning about the control file(s)
 ])
@@ -92,7 +92,7 @@ printf "remove-on-upgrade /test-conffile-1" 
>"pkg-conff-removed-noeol/DEBIAN/con
 AT_CHECK([
 # Conffiles need a final newline to guarantee there has been no accidental
 # file truncation.
-dpkg-deb -b pkg-conff-removed-noeol pkg-conff-removed-noeol.deb
+dpkg-deb --root-owner-group -b pkg-conff-removed-noeol 
pkg-conff-removed-noeol.deb
 ], [2], [ignore], [dpkg-deb: error: conffile name 'remove-on-upgrade 
/test-conffile-1' is too long, or missing final newline
 ])
 
@@ -102,7 +102,7 @@ AT_DATA([pkg-conff-removed-noabs/test-conffile-rel], [test 
init
 ])
 AT_CHECK([
 # Conffiles must use absolute pathnames.
-dpkg-deb -b pkg-conff-removed-noabs pkg-conff-removed-noabs.deb
+dpkg-deb --root-owner-group -b pkg-conff-removed-noabs 
pkg-conff-removed-noabs.deb
 ], [2], [ignore], [dpkg-deb: error: conffile name 'test-conffile-rel' is not 
an absolute pathname
 ])
 
@@ -112,7 +112,7 @@ AT_DATA([pkg-conff-removed-present/test-conffile-present], 
[test init
 ])
 AT_CHECK([
 # Conffiles marked for removal must not be present.
-dpkg-deb -b pkg-conff-removed-present pkg-conff-removed-present.deb
+dpkg-deb --root-owner-group -b pkg-conff-removed-present 
pkg-conff-removed-present.deb
 ], [2], [ignore], [dpkg-deb: error: conffile '/test-conffile-present' is 
present but is requested to be removed
 ])
 
@@ -121,7 +121,7 @@ touch 'pkg-deb-newline/file
 newline'
 AT_CHECK([
 # Cannot create package with newlines in filenames.
-dpkg-deb -b pkg-deb-newline
+dpkg-deb --root-owner-group -b pkg-deb-newline
 ], [2], [ignore], [dpkg-deb: error: newline not allowed in pathname './file
 newline'
 ])
diff --git a/src/at/deb-fields.at b/src/at/deb-fields.at
index ccc733af9..89c3e0e84 100644
--- a/src/at/deb-fields.at
+++ b/src/at/deb-fields.at
@@ -3,7 +3,7 @@ AT_KEYWORDS([dpkg-deb deb fields])
 
 DPKG_GEN_CONTROL([pkg-package-type-void])
 AT_CHECK([
-dpkg-deb -b pkg-package-type-void
+dpkg-deb --root-owner-group -b pkg-package-type-void
 # Test absence of Package-Type field.
 test -z "$(dpkg-deb -f pkg-package-type-void.deb Package-Type)"
 ], [0], [ignore])
@@ -12,7 +12,7 @@ DPKG_GEN_CONTROL([pkg-package-type-use])
 DPKG_MOD_CONTROL([pkg-package-type-use],
   [s/^Package: .*$/$&\nPackage-Type: udeb/])
 AT_CHECK([
-dpkg-deb -b pkg-package-type-use
+dpkg-deb --root-owner-group -b pkg-package-type-use
 # Test presence of Package-Type field.
 test -n "$(dpkg-deb -f pkg-package-type-use.deb Package-Type)"
 ], [0], [ignore])
@@ -29,7 +29,7 @@ DPKG_MOD_CONTROL([pkg-obsolete-fields],
 DPKG_MOD_CONTROL([pkg-obsolete-fields],
   [s/^Package:.*$/$&\nRecommended: recommends/])
 AT_CHECK([
-dpkg-deb -b pkg-obsolete-fields
+dpkg-deb --root-owner-group -b pkg-obsolete-fields
 ], [0], [ignore],
 [dpkg-deb: warning: parsing file 'pkg-obsolete-fields/DEBIAN/control' near 
line 2 package 'pkg-obsolete-fields':
  obsolete 'Recommended' field used
diff --git a/src/deb/build.c b/src/deb/build.c
index fbf6f75e0..5a50056fe 100644
--- a/src/deb/build.c
+++ b/src/deb/build.c
@@ -385,6 +385,30 @@ check_ctrl_control(const char *ctrldir)
   return pkg;
 }
 
+/**
+ * Check fsys permissions.
+ */
+static void
+check_fsys_perms(const char *rootdir)
+{
+  struct stat st;
+
+  if (opt_root_owner_group)
+    return;
+
+  if (lstat(rootdir, &st))
+    ohshite(_("cannot get root directory %s metadata"), rootdir);
+  if (!S_ISDIR(st.st_mode))
+    ohshit(_("root pathname %s is not a directory"), rootdir);
+  if (st.st_uid != 0 || st.st_gid != 0) {
+    warning(_("root directory %s has unusual owner or group %u:%u"),
+            rootdir, st.st_uid, st.st_gid);
+    info(_("Hint: you might need to pass --root-owner-group, "
+           "see <%s> for further details"),
+         "https://wiki.debian.org/Teams/Dpkg/RootlessBuilds";);
+  }
+}
+
 /**
  * Perform some sanity checks on the to-be-built package.
  *
@@ -401,6 +425,7 @@ check_build_files(const char *ctrldir, const char *rootdir)
   /* Start by reading in the control file so we can check its contents. */
   pkg = check_ctrl_control(ctrldir);
   check_ctrl_perms(ctrldir);
+  check_fsys_perms(rootdir);
   check_conffiles(ctrldir, rootdir);
 
   warns = warning_get_count();

-- 
Dpkg.Org's dpkg

Reply via email to