Skip to content

Commit c639bdd

Browse files
committed
weak-modules2: obtain list of initrd modules from dracut (jsc#PED-1915)
After previous patch we ignore INITRD_MODULES. That means that we will obtain the list of modules to include from the current initrd. But that might not be enough if new modules are to be added. We should read the dracut configuration, which is supposed to replace INITRD_MODULES. Obtain the list of dracut configuration files (code copied from dracut 059) and parse the content to obtain the values of the variables that affect the list of modules ("drivers" in dracut nomenclature) to be included. This is not exactly like dracut's logic because we don't have the module autodetection. But it comes close, in particular if we add in the modules from the existing initrd. In practice, what matters most is that we understand "add_drivers+=" directives that 3rd party module authors may put into the dracut configuration. This code executes "arbitrary" scripts as root with bash, which is insecure. dracut does this, too, so this doesn't pose additional danger to the system. However, in wm2 we can source these scripts with reduced privileges, because we just need to set some variables. Signed-off-by: Martin Wilck <[email protected]>
1 parent e3261d9 commit c639bdd

File tree

3 files changed

+110
-4
lines changed

3 files changed

+110
-4
lines changed

get_dracut_drivers

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#! /bin/bash
2+
# This code reads a list of modules from stdin, and takes the
3+
# content of the dracut configuration files as argv[1].
4+
# It evaluates the dracut configuration to set the module-related
5+
# configuration variables add_drivers etc.
6+
# It appends the gathered module names to the input, and
7+
# filters the result using the regex from the omit_drivers variable.
8+
# The code is meant to be executed with decreased privileges,
9+
# in order to avoid sourcing arbitrary scripts as root.
10+
11+
[[ "${WM2_VERBOSE:-0}" -le 2 ]] || set -x
12+
13+
ME=${0##*/}
14+
add_drivers=""
15+
force_drivers=""
16+
omit_drivers=""
17+
drivers=""
18+
19+
eval "$1" ||
20+
echo "$0: error evaluating dracut configuration" >&2
21+
22+
# sanitize omit_drivers; code similar to dracut.sh 059
23+
# filter out empty lines; also handle the case where omit_drivers is empty
24+
omit_drivers_corrected="^[[:space:]]*$"
25+
for d in $omit_drivers; do
26+
[[ " $drivers $add_drivers " == *\ $d\ * ]] && continue
27+
[[ " $drivers $force_drivers " == *\ $d\ * ]] && continue
28+
omit_drivers_corrected+="|$d"
29+
done
30+
31+
if [[ "${WM2_VERBOSE:-0}" -gt 0 ]]; then
32+
echo "$ME: drivers='$drivers'" >&2
33+
echo "$ME: add_drivers='$add_drivers'" >&2
34+
echo "$ME: force_drivers='$force_drivers'" >&2
35+
echo "$ME: omit_drivers='$omit_drivers'" >&2
36+
echo "$ME: omit_drivers_corrected='$omit_drivers_corrected'" >&2
37+
fi
38+
39+
# The sed command below converts space-separated lists to newline-separated
40+
{
41+
cat
42+
echo $drivers $add_drivers $force_drivers
43+
} |
44+
sed -E 's/[[:space:]]+/\n/g;s/\n*$//' |
45+
grep -Ev "$omit_drivers_corrected"

suse-module-tools.spec

+2-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ install -pm 644 "depmod-00-system.conf" "%{buildroot}%{depmod_dir}/00-system.con
112112
# "/usr/lib/module-init-tools" name hardcoded in other packages
113113
install -d -m 755 "%{buildroot}/usr/lib/module-init-tools"
114114
install -pm 755 -t "%{buildroot}/usr/lib/module-init-tools/" \
115-
weak-modules2 driver-check.sh unblacklist lsinitrd-quick
115+
weak-modules2 driver-check.sh unblacklist lsinitrd-quick get_dracut_drivers
116116
install -pm 755 "regenerate-initrd-posttrans" "%{buildroot}/usr/lib/module-init-tools/"
117117
install -d -m 755 "%{buildroot}/usr/lib/module-init-tools/kernel-scriptlets"
118118
install -pm 755 "kernel-scriptlets/cert-script" "%{buildroot}/usr/lib/module-init-tools/kernel-scriptlets"
@@ -226,6 +226,7 @@ exit 0
226226
/usr/lib/module-init-tools/lsinitrd-quick
227227
/usr/lib/module-init-tools/unblacklist
228228
/usr/lib/module-init-tools/weak-modules2
229+
/usr/lib/module-init-tools/get_dracut_drivers
229230
%{_unitdir}/*.service
230231
%{_unitdir}/systemd-sysctl.service.d
231232
%{_modulesloaddir}

weak-modules2

+63-3
Original file line numberDiff line numberDiff line change
@@ -390,12 +390,72 @@ previous_version_of_kmp() {
390390
return $res
391391
}
392392

393-
get_initrd_basenames() {
394-
$LSINITRD /boot/initrd-$1 | \
395-
sed -rn 's:.*\<usr/lib/modules/.*/::p' | \
393+
# Create list of dracut configuration files to read, taking into
394+
# account priorities of the user and built-in configuration.
395+
# Copied from dracut.sh as of dracut 059 (GPL-2.0-or-later)
396+
dropindirs_sort() {
397+
local suffix=$1
398+
shift
399+
local -a files
400+
local f d
401+
402+
for d in "$@"; do
403+
for i in "$d/"*"$suffix"; do
404+
if [[ -e $i ]]; then
405+
printf "%s\n" "${i##*/}"
406+
fi
407+
done
408+
done | sort -Vu | {
409+
readarray -t files
410+
411+
for f in "${files[@]}"; do
412+
for d in "$@"; do
413+
if [[ -e "$d/$f" ]]; then
414+
printf "%s\n" "$d/$f"
415+
continue 2
416+
fi
417+
done
418+
done
419+
}
420+
}
421+
422+
get_current_basenames() {
423+
$LSINITRD /boot/initrd-$1 |
424+
sed -rn 's:.*\<usr/lib/modules/.*/::p' |
396425
strip_mod_extensions
397426
}
398427

428+
DRACUT_CONFFILE=/etc/dracut.conf
429+
DRACUT_CONFDIR=/etc/dracut.conf.d
430+
DRACUT_BUILTIN_CONFDIR=/usr/lib/dracut/dracut.conf.d
431+
GET_DRACUT_DRIVERS=/usr/lib/module-init-tools/get_dracut_drivers
432+
433+
get_initrd_basenames() {
434+
local setpriv=$(command -v setpriv)
435+
local conf= cf
436+
437+
[[ -x "$GET_DRACUT_DRIVERS" && "$setpriv" ]] || {
438+
echo "$0: unable to parse dracut configuration, skipping it" >&2
439+
get_current_basenames "$1"
440+
return
441+
}
442+
443+
[[ ! -f "$DRACUT_CONFFILE" ]] ||
444+
conf="$(cat "$DRACUT_CONFFILE")"
445+
446+
# Assemble the content of the dracut configuration files.
447+
# Make sure to put a newline between subsequent conf file contents.
448+
for cf in $(dropindirs_sort .conf "$DRACUT_CONFDIR" "$DRACUT_BUILTIN_CONFDIR"); do
449+
conf="$conf
450+
$(cat "$cf")"
451+
done
452+
453+
# run get_dracut_drivers with reduced privileges
454+
get_current_basenames "$1" |
455+
"$setpriv" --reuid=nobody --regid=nobody --clear-groups --inh-caps=-all \
456+
"$GET_DRACUT_DRIVERS" "$conf"
457+
}
458+
399459
# test if rebuilding initrd is needed for $krel.
400460
# stdin - list of changed modules ("_kernel_" for the whole kernel)
401461
needs_initrd() {

0 commit comments

Comments
 (0)