lib: add aur-build--sync helper

Instead of prefixing several pacsync/pacman commands with `sudo`, wrap
the commands in an `build--sync` helper. When configurating `sudoers`
rules, this is more granular than blanket `pacsync` and `pacman` rules:
only upgrading local repository targets is whitelisted.

Compared to the previous approach, --pacman-conf does not apply to local
repository upgrades. This makes it harder to inadvertendly shoot
yourself in the foot by passing on a potentially world-writeable file to
a privileged process.

A helper can also be overridden through AUR_EXEC_PATH, and called by
other scripts that wish to replicate a restrained local repository
upgrade.
This commit is contained in:
Alad Wenter 2022-07-20 22:08:48 +02:00
parent 24c1330509
commit 595e24b6ea
4 changed files with 98 additions and 57 deletions

View File

@ -471,26 +471,11 @@ while IFS= read -ru "$fd" path; do
if (( chroot )) || (( no_sync )); then
continue
else
# Propagate database to pacman
sudo pacsync "$db_name" "${pacconf_args[@]}"
sudo pacsync "$db_name" "${pacconf_args[@]}" --dbext=.files
# Verify if packages on the host can be upgraded from the local repository
targets=()
while IFS='/' read -r repo name; do
[[ $repo == "$db_name" ]] && targets+=("$repo/$name")
done < <(pacman -Sup --print-format '%r/%n' "${pacconf_args[@]}")
# Preserve pacman exit status
wait "$!"
if (( ${#targets[@]} )); then
msg >&2 'Upgrading installed local repository packages'
# XXX: replace with stdin input once makepkg does so:
# https://github.com/eli-schwartz/pacman/commit/80b118b48b38dd55224d33d54867c533c23b0040
sudo pacman -S --noconfirm "${pacconf_args[@]}" "${targets[@]}"
fi
# Helper which can be used for e.g. sudoers rules (#1012)
# Like `makepkg --syncdeps`, this affects the host and so uses the host
# pacman configuration. --pacman-conf (which may also point to
# a world-writeable file) is not applied.
sudo aur build--sync --repo "$db_name"
fi
done

62
lib/aur-build--sync Executable file
View File

@ -0,0 +1,62 @@
#!/bin/perl -T
# This script can be used in NOPASSWD rules (sudoers) or similar (doas/setuid
# wrappers) to upgrade packages in a local repository without password prompt.
# Use basic measures from perlsec(1perl) to limit security impact.
use strict;
use warnings;
use v5.20;
my $argv0 = 'build--sync';
# minimal path
$ENV{PATH} = "/bin:/usr/bin";
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
# option parsing
use Getopt::Long;
my $opt_repo; # tainted
GetOptions("d|repo=s" => \$opt_repo);
if (!length($opt_repo)) {
say STDERR "$argv0: repository not specified";
exit(1);
}
# limit valid characters for repository
if ($opt_repo =~ /^([-\@\w.]+)$/) {
$opt_repo = $1; # untainted
} else {
die "Bad data in '$opt_repo'";
}
# update pacman database
system 'pacsync', $opt_repo
and exit $? >> 8;
system 'pacsync', $opt_repo, '--dbext=.files'
and exit $? >> 8;
# verify if host packages can be upgraded from the local repository
my %targets;
my $pid = open(my $fh, "-|", 'pacman', '-Sup', '--print-format', '%r/%n');
if ($pid) { # parent
while (my $spec = <$fh>) {
chomp($spec);
my ($repo, $name) = split('/', $spec);
if ($repo eq $opt_repo) {
$targets{$spec} = 1; # untainted - we trust pacman output
}
};
waitpid($pid, 0);
exit(1) if $?;
}
if (scalar(keys %targets)) {
say STDERR "$argv0: upgrading packages in repository $opt_repo";
system 'pacman', '-S', '--noconfirm', keys %targets
and exit $? >> 8;
} else {
say STDERR 'there is nothing to do';
}
# vim: set et sw=4 sts=4 ft=perl:

View File

@ -1,7 +1,9 @@
## 11
* `aur-build`
+ retrieve local repository upgrades with `pacman -Sup`
+ add `aur-build--sync` helper for local repository upgrades
- `pacman -Syu --config` is replaced by `pacsync <repo>` and `pacman -S <repo>/<pkg>`
- local repository upgrades are now unaffected by `--pacman-conf`
* `aur-graph`
+ selectively disable/enable depends with `aur graph -v <TYPE>=[0|1]`

View File

@ -37,9 +37,9 @@ or
options are provided,
.B aur\-build
will also attempt to sync to the local repository with
.B pacman \-Syu
.BR pacsync (1)
and
.BR "pacman \-Fy" .
.BR "pacman \-S" .
See the
.B Repository updates
section for details.
@ -188,11 +188,17 @@ operations. For chroot builds, the file is also used inside the container.
.
.TP
.BI \-\-pacman\-conf= FILE
The file used for syncing and retrieving local repositories. For chroot
builds, the file is also used inside the container
The file used for retrieving local repositories
.RB ( aur\-repo " " \-\-config ).
For chroot builds, the file is also used for
.BR pacman (8)
operations inside the container
.RB ( aur\-chroot " " \-\-pacman\-conf ).
.BR makepkg (8)
calls are unaffected by this option.
calls and local repository upgrades (see the
.B Repository updates
section)
.B are unaffected by this option.
.
.SS makechrootpkg options
.TP
@ -382,18 +388,17 @@ of built packages, defaulting to
.
.SH NOTES
.SS Repository updates
When building on the host (outside of a container), any installed
packages in the local repository are upgraded to the latest available
version with
When building on the host (outside of a container), installed packages in the
local repository are upgraded to the latest available version with
.BR aur\-build\-\-sync .
.PP
This command runs
.BR pacsync <repository>
followed by
.BR "pacman \-S \-\-noconfirm" .
.BI "pacman \-S \-\-noconfirm " <repository>/<upgrades...>
This is comparable to
.BR "makepkg \-i" ,
but packages are only upgraded (installed) if they were installed beforehand.
Packages which define a
.I replaces
field are ignored if the target package is installed on the local system.
except that only packages which were installed beforehand are upgraded to a new version.
.
.SS Using a dedicated build user
While using a dedicated user for the build process does not increase
@ -423,17 +428,20 @@ the
.I build
user should be allowed to run
.BR pacman (8)
with elevated privileges. For example, create the
with elevated privileges.
.PP
For example, create the
.I /etc/sudoers.d/10_build
file with following contents:
file with the following contents:
.PP
.EX
build ALL = (root) NOPASSWD: /usr/bin/pacman
build ALL = (root) NOPASSWD: /usr/lib/aurutils/aur-build--sync
.EE
.PP
.BR aur\-build (1)
(and related programs such as
.BR aur\-sync (1))
and related programs such as
.BR aur\-sync (1)
may now be run as the new
.I build
user.
@ -493,29 +501,13 @@ is specified, package dependencies are installed with
.B makepkg
uses the
.B pacman \-S \-\-asdeps
command for this purpose. If other pacman options are desired for this
command, a wrapper script and the
command for this purpose. Other pacman options can be specified with a
wrapper script and the
.B PACMAN
environment variable have to be used. (See
environment variable. (See
.B ENVIRONMENT VARIABLES
in
.BR makepkg (8).)
.PP
For example, to use a custom
.BR pacman.conf (5)
file, create a wrapper script:
.PP
.EX
#!/bin/sh --
pacman --config </path/to/file> "$@"
.EE
.PP
and set the
.B PACMAN
environment variable to its path. (In this particular example,
building inside a container with dedicated
.BR pacman.conf(5)
is an alternative.)
.
.SH BUGS
Databases are built with