read files passed as --aptopt and --dpkgopt outside the unshared namespace to avoid permission issues

This commit is contained in:
Johannes Schauer Marin Rodrigues 2024-01-09 11:21:53 +01:00
parent 99d2579e0b
commit dd94ee3b84
Signed by untrusted user: josch
GPG key ID: F2CBA5C78FBD83E1

View file

@ -1953,7 +1953,7 @@ sub run_setup() {
# since we do not know the dpkg version inside the chroot at this # since we do not know the dpkg version inside the chroot at this
# point, we can only omit it in chrootless mode # point, we can only omit it in chrootless mode
if ($options->{mode} ne 'chrootless' if ($options->{mode} ne 'chrootless'
or scalar @{ $options->{dpkgopts} } > 0) { or length $options->{dpkgopts} > 0) {
push @directories, '/etc/dpkg/dpkg.cfg.d/'; push @directories, '/etc/dpkg/dpkg.cfg.d/';
} }
# if dpkg and apt operate from the outside we need some more # if dpkg and apt operate from the outside we need some more
@ -2083,26 +2083,11 @@ sub run_setup() {
close $fh; close $fh;
} }
if (scalar @{ $options->{aptopts} } > 0 if (length $options->{aptopts} > 0
and (!-e "$options->{root}/etc/apt/apt.conf.d/99mmdebstrap")) { and (!-e "$options->{root}/etc/apt/apt.conf.d/99mmdebstrap")) {
open my $fh, '>', "$options->{root}/etc/apt/apt.conf.d/99mmdebstrap" open my $fh, '>', "$options->{root}/etc/apt/apt.conf.d/99mmdebstrap"
or error "cannot open /etc/apt/apt.conf.d/99mmdebstrap: $!"; or error "cannot open /etc/apt/apt.conf.d/99mmdebstrap: $!";
foreach my $opt (@{ $options->{aptopts} }) { print $fh $options->{aptopts};
if (-r $opt) {
# flush handle because copy() uses syswrite() which bypasses
# buffered IO
$fh->flush();
copy $opt, $fh or error "cannot copy $opt: $!";
} else {
print $fh $opt;
if ($opt !~ /;$/) {
print $fh ';';
}
if ($opt !~ /\n$/) {
print $fh "\n";
}
}
}
close $fh; close $fh;
if ($verbosity_level >= 3) { if ($verbosity_level >= 3) {
debug "content of /etc/apt/apt.conf.d/99mmdebstrap:"; debug "content of /etc/apt/apt.conf.d/99mmdebstrap:";
@ -2110,7 +2095,7 @@ sub run_setup() {
} }
} }
if (scalar @{ $options->{dpkgopts} } > 0 if (length $options->{dpkgopts} > 0
and (!-e "$options->{root}/etc/dpkg/dpkg.cfg.d/99mmdebstrap")) { and (!-e "$options->{root}/etc/dpkg/dpkg.cfg.d/99mmdebstrap")) {
# FIXME: in chrootless mode, dpkg will only read the configuration # FIXME: in chrootless mode, dpkg will only read the configuration
# from the host -- see #808203 # from the host -- see #808203
@ -2120,19 +2105,7 @@ sub run_setup() {
} }
open my $fh, '>', "$options->{root}/etc/dpkg/dpkg.cfg.d/99mmdebstrap" open my $fh, '>', "$options->{root}/etc/dpkg/dpkg.cfg.d/99mmdebstrap"
or error "cannot open /etc/dpkg/dpkg.cfg.d/99mmdebstrap: $!"; or error "cannot open /etc/dpkg/dpkg.cfg.d/99mmdebstrap: $!";
foreach my $opt (@{ $options->{dpkgopts} }) { print $fh $options->{dpkgopts};
if (-r $opt) {
# flush handle because copy() uses syswrite() which bypasses
# buffered IO
$fh->flush();
copy $opt, $fh or error "cannot copy $opt: $!";
} else {
print $fh $opt;
if ($opt !~ /\n$/) {
print $fh "\n";
}
}
}
close $fh; close $fh;
if ($verbosity_level >= 3) { if ($verbosity_level >= 3) {
debug "content of /etc/dpkg/dpkg.cfg.d/99mmdebstrap:"; debug "content of /etc/dpkg/dpkg.cfg.d/99mmdebstrap:";
@ -4520,8 +4493,8 @@ sub main() {
architectures => [$hostarch], architectures => [$hostarch],
mode => 'auto', mode => 'auto',
format => 'auto', format => 'auto',
dpkgopts => [], dpkgopts => '',
aptopts => [], aptopts => '',
apttrusted => $apttrusted, apttrusted => $apttrusted,
apttrustedparts => $apttrustedparts, apttrustedparts => $apttrustedparts,
noop => [], noop => [],
@ -4588,8 +4561,43 @@ sub main() {
}, },
'architectures=s@' => \$options->{architectures}, 'architectures=s@' => \$options->{architectures},
'mode=s' => \$options->{mode}, 'mode=s' => \$options->{mode},
'dpkgopt=s@' => \$options->{dpkgopts}, 'dpkgopt=s' => sub {
'aptopt=s@' => \$options->{aptopts}, my ($opt_name, $opt_value) = @_;
if (-r $opt_value) {
open my $fh, '<', $opt_value
or error "failed to open $opt_value: $!";
$options->{dpkgopts} .= do { local $/; <$fh> };
if ($options->{dpkgopts} !~ /\n$/) {
print $fh "\n";
}
close $fh;
} else {
$options->{dpkgopts} .= $opt_value;
if ($opt_value !~ /\n$/) {
$options->{dpkgopts} .= "\n";
}
}
},
'aptopt=s' => sub {
my ($opt_name, $opt_value) = @_;
if (-r $opt_value) {
open my $fh, '<', $opt_value
or error "failed to open $opt_value: $!";
$options->{aptopts} .= do { local $/; <$fh> };
if ($options->{aptopts} !~ /\n$/) {
print $fh "\n";
}
close $fh;
} else {
$options->{aptopts} .= $opt_value;
if ($opt_value !~ /;$/) {
$options->{aptopts} .= ';';
}
if ($opt_value !~ /\n$/) {
$options->{aptopts} .= "\n";
}
}
},
'keyring=s' => sub { 'keyring=s' => sub {
my ($opt_name, $opt_value) = @_; my ($opt_name, $opt_value) = @_;
if ($opt_value =~ /"/) { if ($opt_value =~ /"/) {