libvirt-image-archlinux-basic-bin
MEDIUM
maintainer RubenKelevra
0 votes
scanned 2026-09-28 15:21:17.813621
Why flagged
One or more source=() URLs point to a host outside the trusted allowlist (github.com, gitlab.com, codeberg.org, pypi.org, …).
Triggered rules
Medium
source=() URL on a non-standard host
source_untrusted_domain
One or more source=() URLs point to a host outside the trusted allowlist (github.com, gitlab.com, codeberg.org, pypi.org, …).
-
PKGBUILD:21
"${_upstream_image}::https://geo.mirror.pkgbuild.com/images/v${pkgver}/${_upstream_image}"
Low
Few votes, recently uploaded
zero_votes_recent
Uploaded within the last 14 days with 2 or fewer community votes — little peer review so far.
PKGBUILD
1 offending line(s) highlighted
1
# Maintainer: @RubenKelevra <rubenkelevra@gmail.com>
2
3
_pkgname='archlinux'
4
_variant='basic'
5
pkgname="libvirt-image-${_pkgname}-basic-bin"
6
pkgver=20260915.594445
7
pkgrel=2
8
pkgdesc='Official Arch Linux basic QCOW2 template for libvirt without cloud-init'
9
arch=('x86_64')
10
url='https://gitlab.archlinux.org/archlinux/arch-boxes'
11
license=('LicenseRef-Various')
12
checkdepends=(
13
'libguestfs'
14
'linux'
15
'qemu-img'
16
)
17
_upstream_image="Arch-Linux-${CARCH}-${_variant}-${pkgver}.qcow2"
18
_template="${_pkgname}-${_variant}-${pkgver}-${CARCH}-template.qcow2"
19
_template_link="${_pkgname}-${_variant}-${CARCH}-template.qcow2"
20
source=(
21
"${_upstream_image}::https://geo.mirror.pkgbuild.com/images/v${pkgver}/${_upstream_image}"
22
"${_upstream_image}.sig::https://geo.mirror.pkgbuild.com/images/v${pkgver}/${_upstream_image}.sig"
23
'DISTRIBUTION-LICENSE'
24
)
25
noextract=("${_upstream_image}")
26
sha256sums=(
27
'e60a99fd359d37a2d95e68534d42ff1f84244b879e47712dc6714678fb67dbaf'
28
'SKIP'
29
'1227563c5cc845d4a1fd0dbd0aced043040edb36168ad3278e6341e638647e29'
30
)
31
validpgpkeys=('1B9A16984A4E8CB448712D2AE0B78BF4326C6F8F')
32
33
_install_payload() {
34
local root="${1:?missing package root}"
35
local image_dir="${root}/var/lib/libvirt/images"
36
37
install -Dm444 -- "${srcdir}/${_upstream_image}" "${image_dir}/${_template}"
38
ln -s -- "${_template}" "${image_dir}/${_template_link}"
39
install -Dm644 -- "${srcdir}/DISTRIBUTION-LICENSE" \
40
"${root}/usr/share/licenses/${pkgname}/LICENSE"
41
}
42
43
_check_payload() {
44
local root="${1:?missing package root}"
45
local check_owner="${2:-false}"
46
local image_path="${root}/var/lib/libvirt/images/${_template}"
47
local image_link="${root}/var/lib/libvirt/images/${_template_link}"
48
local license_path="${root}/usr/share/licenses/${pkgname}/LICENSE"
49
local manifest
50
51
[[ -f "${image_path}" ]] || return 1
52
[[ -L "${image_link}" ]] || return 1
53
[[ "$(readlink -- "${image_link}")" == "${_template}" ]] || return 1
54
[[ -f "${license_path}" ]] || return 1
55
[[ "$(stat -c '%a' -- "${image_path}")" == '444' ]] || return 1
56
[[ "$(stat -c '%a' -- "${license_path}")" == '644' ]] || return 1
57
[[ -z "$(find "${root}" -name '*.sig' -print -quit)" ]] || return 1
58
59
manifest="$(find "${root}" \( -type f -o -type l \) -printf '%P\n' | sort)"
60
[[ "${manifest}" == "$(printf '%s\n' \
61
"usr/share/licenses/${pkgname}/LICENSE" \
62
"var/lib/libvirt/images/${_template}" \
63
"var/lib/libvirt/images/${_template_link}")" ]] || return 1
64
65
if [[ "${check_owner}" == 'true' ]]; then
66
[[ "$(stat -c '%u:%g' -- "${image_path}")" == '0:0' ]] || return 1
67
[[ "$(stat -c '%u:%g' -- "${license_path}")" == '0:0' ]] || return 1
68
[[ "$(stat -c '%u:%g' -- "${image_link}")" == '0:0' ]] || return 1
69
fi
70
}
71
72
_check_guest() {
73
local image="${srcdir}/${_upstream_image}"
74
local guest_log="${srcdir}/check-guest-${_variant}.log"
75
local pacman_integrity_log="${srcdir}/check-pacman-integrity-${_variant}.log"
76
local guest_check
77
local os_id
78
local package_count
79
local base_rc
80
local cloud_init_rc
81
local qk_rc
82
local qkk_rc
83
local run_mode
84
local resolv_target
85
local journal_group
86
local file_output
87
local qemu_info
88
local warning_count
89
local parsed_count=0
90
local unexpected_count=0
91
local path
92
local reason
93
94
guest_check='
95
set +e
96
export LC_ALL=C
97
. /usr/lib/os-release
98
printf "__OS_ID__=%s\\n" "${ID:-}"
99
package_count=$(/usr/bin/pacman --config /dev/null -Qq 2>/dev/null | wc -l)
100
printf "__PACKAGE_COUNT__=%s\\n" "${package_count}"
101
/usr/bin/pacman --config /dev/null -Q base >/dev/null 2>&1
102
printf "__BASE_RC__=%d\\n" "$?"
103
/usr/bin/pacman --config /dev/null -Q cloud-init >/dev/null 2>&1
104
printf "__CLOUD_INIT_RC__=%d\\n" "$?"
105
printf "__RUN_MODE__=%s\\n" "$(stat -c %a /run 2>/dev/null)"
106
printf "__RESOLV_TARGET__=%s\\n" "$(readlink /etc/resolv.conf 2>/dev/null)"
107
printf "__JOURNAL_GROUP__=%s\\n" "$(stat -c %G /var/log/journal 2>/dev/null)"
108
qk_output="$(/usr/bin/pacman --config /dev/null -Qk 2>&1)"
109
qk_rc=$?
110
printf "__QK_BEGIN__\\n"
111
printf "%s\\n" "${qk_output}"
112
printf "__QK_RC__=%d\\n" "${qk_rc}"
113
# Preserve stderr on the sh-out stream, then discard pacman summary stdout.
114
qkk_stderr="$(/usr/bin/pacman --config /dev/null -Qkk 2>&1 >/dev/null)"
115
qkk_rc=$?
116
printf "__QKK_BEGIN__\\n"
117
printf "%s\\n" "${qkk_stderr}"
118
printf "__QKK_RC__=%d\\n" "${qkk_rc}"
119
exit 0
120
'
121
122
_marker_value() {
123
local marker="${1:?missing marker}"
124
local count
125
126
count="$(grep -c "^${marker}=" "${guest_log}" || true)"
127
(( count == 1 )) || {
128
printf 'guest verification marker %s occurred %d times\n' "${marker}" "${count}" >&2
129
return 1
130
}
131
sed -n "s/^${marker}=//p" "${guest_log}"
132
}
133
134
_is_expected_integrity_mismatch() {
135
local mismatch_path="${1:?missing mismatch path}"
136
local mismatch_reason="${2:?missing mismatch reason}"
137
138
case "${mismatch_path}" in
139
'/etc/resolv.conf')
140
# arch-boxes intentionally replaces the packaged file with systemd-resolved's symlink.
141
[[ "${mismatch_reason}" == 'File type mismatch' &&
142
"${resolv_target}" == '/run/systemd/resolve/stub-resolv.conf' ]]
143
;;
144
'/run')
145
# pacstrap pre-creates API mountpoints as 0555 before installing filesystem (mtree: 0755).
146
[[ "${mismatch_reason}" == 'Permissions mismatch' && "${run_mode}" == '555' ]]
147
;;
148
'/var/log/journal')
149
# systemd's tmpfiles hook intentionally assigns the systemd-journal group.
150
[[ "${mismatch_reason}" == 'GID mismatch' &&
151
"${journal_group}" == 'systemd-journal' ]]
152
;;
153
*)
154
return 1
155
;;
156
esac
157
}
158
159
rm -f -- "${guest_log}" "${pacman_integrity_log}"
160
161
printf '%s\n' 'check: QCOW2 structure'
162
file_output="$(file -L --brief -- "${image}")" || {
163
printf 'file failed for %s\n' "${image}" >&2
164
return 1
165
}
166
[[ "${file_output}" == *'QEMU QCOW'* ]] || {
167
printf 'unexpected image type: %s\n' "${file_output}" >&2
168
return 1
169
}
170
qemu_info="$(LC_ALL=C qemu-img info -- "${image}")" || {
171
printf 'qemu-img info failed for %s\n' "${image}" >&2
172
return 1
173
}
174
grep -Fxq 'file format: qcow2' <<< "${qemu_info}" || {
175
printf '%s\n' "${qemu_info}" >&2
176
return 1
177
}
178
if ! qemu-img check -q -- "${image}"; then
179
qemu-img check -- "${image}" || true
180
return 1
181
fi
182
183
printf '%s\n' 'check: read-only guest package database'
184
guestfish --ro -a "${image}" -i -- sh-out "${guest_check}" "${guest_log}" || {
185
cat -- "${guest_log}" 2>/dev/null || true
186
return 1
187
}
188
189
os_id="$(_marker_value '__OS_ID__')" || return 1
190
package_count="$(_marker_value '__PACKAGE_COUNT__')" || return 1
191
base_rc="$(_marker_value '__BASE_RC__')" || return 1
192
cloud_init_rc="$(_marker_value '__CLOUD_INIT_RC__')" || return 1
193
run_mode="$(_marker_value '__RUN_MODE__')" || return 1
194
resolv_target="$(_marker_value '__RESOLV_TARGET__')" || return 1
195
journal_group="$(_marker_value '__JOURNAL_GROUP__')" || return 1
196
qk_rc="$(_marker_value '__QK_RC__')" || return 1
197
qkk_rc="$(_marker_value '__QKK_RC__')" || return 1
198
199
[[ "${os_id}" == 'arch' ]] || return 1
200
[[ "${package_count}" =~ ^[0-9]+$ ]] || return 1
201
(( package_count > 0 )) || return 1
202
(( base_rc == 0 )) || return 1
203
(( cloud_init_rc != 0 )) || {
204
printf '%s\n' 'basic image unexpectedly contains cloud-init' >&2
205
return 1
206
}
207
if (( qk_rc != 0 )); then
208
cat -- "${guest_log}"
209
return 1
210
fi
211
(( qkk_rc <= 1 )) || {
212
cat -- "${guest_log}"
213
return 1
214
}
215
216
sed -n '/^__QKK_BEGIN__$/,/^__QKK_RC__=/ {
217
/^__QKK_BEGIN__$/d
218
/^__QKK_RC__=/d
219
p
220
}' "${guest_log}" > "${pacman_integrity_log}" || return 1
221
222
if grep -Eq '^(error|fatal):' "${pacman_integrity_log}"; then
223
cat -- "${pacman_integrity_log}"
224
return 1
225
fi
226
227
printf '%s\n' 'check: guest package mtree integrity'
228
warning_count="$(grep -c '^warning:' "${pacman_integrity_log}" || true)"
229
while IFS=$'\t' read -r path reason; do
230
(( parsed_count += 1 ))
231
if _is_expected_integrity_mismatch "${path}" "${reason}"; then
232
continue
233
fi
234
printf 'unexpected package-file mismatch: %s (%s)\n' "${path}" "${reason}" >&2
235
(( unexpected_count += 1 ))
236
done < <(
237
sed -n 's/^warning: [^:]*: \(\/.*\) (\(.*\))$/\1\t\2/p' "${pacman_integrity_log}"
238
)
239
240
if (( parsed_count != warning_count || unexpected_count != 0 )); then
241
cat -- "${pacman_integrity_log}"
242
printf 'pacman integrity warnings: total=%d parsed=%d unexpected=%d\n' \
243
"${warning_count}" "${parsed_count}" "${unexpected_count}" >&2
244
return 1
245
fi
246
}
247
248
check() {
249
_check_guest
250
}
251
252
package() {
253
_install_payload "${pkgdir}"
254
_check_payload "${pkgdir}" true
255
}
256
Changes since previous scan
--- PKGBUILD @ 2026-09-22 01:39+++ PKGBUILD @ 2026-09-28 15:21@@ -4,7 +4,7 @@ _variant='basic' pkgname="libvirt-image-${_pkgname}-basic-bin" pkgver=20260915.594445-pkgrel=1+pkgrel=2 pkgdesc='Official Arch Linux basic QCOW2 template for libvirt without cloud-init' arch=('x86_64') url='https://gitlab.archlinux.org/archlinux/arch-boxes'@@ -246,14 +246,7 @@ } check() {- local package_root="${srcdir}/check-package-root-${_variant}"- _check_guest-- printf '%s\n' 'check: staged package payload'- rm -rf -- "${package_root}"- _install_payload "${package_root}"- _check_payload "${package_root}" } package() {Scan history
| Scanned at (UTC) | Severity | Rules |
|---|---|---|
| 2026-09-28 15:21:17 | Medium | 2 |
| 2026-09-22 01:39:17 | Clean | 3 |
| 2026-09-22 01:36:45 | Medium | 2 |