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

guillem pushed a commit to branch master
in repository dpkg.

View the commit online:
https://git.dpkg.org/cgit/dpkg/dpkg.git/commit/?id=5490025f9acec8228026a5330f4a740f94f435cf

commit 5490025f9acec8228026a5330f4a740f94f435cf
Author: Guillem Jover <[email protected]>
AuthorDate: Sun Jul 5 16:39:46 2020 +0200

    Dpkg::Path: Refactor check_directory_traversal() out of 
Dpkg::Source::Package
    
    This might be useful in other contexts, it is going to get a bit more
    complex and it will make it possible to unit test it.
---
 debian/changelog               |  2 ++
 scripts/Dpkg/Path.pm           | 37 ++++++++++++++++++++++++++++++++++++-
 scripts/Dpkg/Source/Package.pm | 18 ++----------------
 3 files changed, 40 insertions(+), 17 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 94543441c..76d6d8dee 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -8,6 +8,8 @@ dpkg (1.20.4) UNRELEASED; urgency=medium
     - Dpkg::OpenPGP: Use a temporary directory for the GnuPG homedir in
       verify_signature(), to make sure we do not write to the user home
       directory, except for the trustkeys.db file if present.
+    - Dpkg::Path: Refactor new check_directory_traversal() function out of
+      Dpkg::Source::Package->extract().
   * Build system:
     - Add Module::Signature as configure recommends for CPAN.
   * Test suite:
diff --git a/scripts/Dpkg/Path.pm b/scripts/Dpkg/Path.pm
index f352cac35..ce55b5a54 100644
--- a/scripts/Dpkg/Path.pm
+++ b/scripts/Dpkg/Path.pm
@@ -19,11 +19,12 @@ package Dpkg::Path;
 use strict;
 use warnings;
 
-our $VERSION = '1.04';
+our $VERSION = '1.05';
 our @EXPORT_OK = qw(
     canonpath
     resolve_symlink
     check_files_are_the_same
+    check_directory_traversal
     find_command
     find_build_file
     get_control_path
@@ -34,8 +35,11 @@ our @EXPORT_OK = qw(
 
 use Exporter qw(import);
 use File::Spec;
+use File::Find;
 use Cwd qw(realpath);
 
+use Dpkg::ErrorHandling;
+use Dpkg::Gettext;
 use Dpkg::Arch qw(get_host_arch debarch_to_debtuple);
 use Dpkg::IPC;
 
@@ -202,6 +206,33 @@ sub resolve_symlink($) {
     }
 }
 
+=item check_directory_traversal($basedir, $dir)
+
+This function verifies that the directory $dir does not contain any symlink
+that goes beyond $basedir (which should be either equal or a parent of $dir).
+
+=cut
+
+sub check_directory_traversal {
+    my ($basedir, $dir) = @_;
+
+    my $canon_basedir = realpath($basedir);
+    my $check_symlinks = sub {
+        my $canon_pathname = realpath($_);
+        return if $canon_pathname =~ m/^\Q$canon_basedir\E/;
+
+        error(g_("pathname '%s' points outside source root"), $_);
+    };
+
+    find({
+        wanted => $check_symlinks,
+        no_chdir => 1,
+        follow => 1,
+        follow_skip => 2,
+    }, $dir);
+
+    return;
+}
 
 =item $cmdpath = find_command($command)
 
@@ -281,6 +312,10 @@ sub find_build_file($) {
 
 =head1 CHANGES
 
+=head2 Version 1.05 (dpkg 1.20.4)
+
+New function: check_directory_traversal().
+
 =head2 Version 1.04 (dpkg 1.17.11)
 
 Update semantics: find_command() now handles an empty or undef argument.
diff --git a/scripts/Dpkg/Source/Package.pm b/scripts/Dpkg/Source/Package.pm
index 9698b7527..1b52b0ee3 100644
--- a/scripts/Dpkg/Source/Package.pm
+++ b/scripts/Dpkg/Source/Package.pm
@@ -44,9 +44,7 @@ our @EXPORT_OK = qw(
 use Exporter qw(import);
 use POSIX qw(:errno_h :sys_wait_h);
 use Carp;
-use Cwd qw(realpath);
 use File::Temp;
-use File::Find;
 use File::Copy qw(cp);
 use File::Basename;
 
@@ -56,7 +54,7 @@ use Dpkg::Control;
 use Dpkg::Checksums;
 use Dpkg::Version;
 use Dpkg::Compression;
-use Dpkg::Path qw(check_files_are_the_same);
+use Dpkg::Path qw(check_files_are_the_same check_directory_traversal);
 use Dpkg::Vendor qw(run_vendor_hook);
 use Dpkg::Source::Format;
 use Dpkg::OpenPGP;
@@ -556,21 +554,9 @@ sub extract {
 
     # Check for directory traversals.
     if (not $self->{options}{skip_debianization}) {
-        my $canon_newdir = realpath($newdirectory);
-        my $check_symlinks = sub {
-            my $canon_pathname = realpath($_);
-            return if $canon_pathname =~ m/^\Q$canon_newdir\E/;
-
-            error(g_("pathname '%s' points outside source root"), $_);
-        };
         # We need to add a trailing slash to handle the debian directory
         # possibly being a symlink.
-        find({
-            wanted => $check_symlinks,
-            no_chdir => 1,
-            follow => 1,
-            follow_skip => 2,
-        }, "$newdirectory/debian/");
+        check_directory_traversal($newdirectory, "$newdirectory/debian/");
     }
 
     # Store format if non-standard so that next build keeps the same format

-- 
Dpkg.Org's dpkg

Reply via email to