** Tags added: kernel-daily-bug -- You received this bug notification because you are subscribed to linux in Ubuntu. Matching subscriptions: Bgg, Bmail, Nb https://bugs.launchpad.net/bugs/2148773 Title: Broken run-parts invocation in kernel maintainer scripts Status in linux package in Ubuntu: New Bug description: **Title:** `linux-image-unsigned-7.0.0-070000-generic` (and siblings) ship maintainer scripts that call `run-parts` with two directory arguments, which `debianutils` rejects — every `dpkg` phase that runs the scripts fails. **Target:** Ubuntu Mainline Kernel PPA / `kernel.ubuntu.com/mainline` **Affected build:** `v7.0` / `7.0.0-070000.202604122140` **Severity:** High — package is uninstallable on stock Ubuntu 24.04 (and any system with `debianutils >= 5.x`). --- ## 1. Summary The maintainer scripts (`preinst`, `postinst`, `postrm`, `prerm`) in the v7.0 mainline kernel `.deb`s invoke `run-parts` with **two** directory arguments: ```sh run-parts --report --exit-on-error --arg=$version --arg=$image_path \ /etc/kernel/<phase>.d /usr/share/kernel/<phase>.d ``` `run-parts(8)` from `debianutils` accepts **exactly one** directory operand. With two, it aborts: ``` run-parts: missing operand Try 'run-parts --help' for more information. ``` exit status `1`. This breaks every `dpkg` phase in which the scripts run: install (`preinst`), configure (`postinst` triggers), upgrade, and removal. ## 2. Affected packages Inspection of all four `.deb`s from `v7.0`: | Package | Buggy maintainer scripts | |----------------------------------------------|--------------------------------------------------------------------| | `linux-image-unsigned-7.0.0-070000-generic` | `preinst`, `postinst` (inside heredoc for trigger file), `postrm`, `prerm` | | `linux-modules-7.0.0-070000-generic` | `postinst` (inside heredoc) | | `linux-headers-7.0.0-070000-generic` | `postinst` (uses `header_postinst.d` dirs) | | `linux-headers-7.0.0-070000` (arch: all) | clean | ## 3. Reproduction On a fresh Ubuntu 24.04 host: ```sh wget https://kernel.ubuntu.com/mainline/v7.0/amd64/linux-image-unsigned-7.0.0-070000-generic_7.0.0-070000.202604122140_amd64.deb wget https://kernel.ubuntu.com/mainline/v7.0/amd64/linux-modules-7.0.0-070000-generic_7.0.0-070000.202604122140_amd64.deb sudo dpkg -i linux-modules-*.deb linux-image-unsigned-*.deb ``` Observed: ``` Setting up linux-image-unsigned-7.0.0-070000-generic (7.0.0-070000.202604122140) ... run-parts: missing operand Try 'run-parts --help' for more information. dpkg: error processing package linux-image-unsigned-7.0.0-070000-generic (--configure): installed linux-image-unsigned-7.0.0-070000-generic package post-installation script subprocess returned error exit status 1 ``` Direct `run-parts` reproducer (Ubuntu 24.04, `debianutils 5.17`): ```sh mkdir -p /tmp/a /tmp/b run-parts --report /tmp/a # exit 0 run-parts --report /tmp/a /tmp/b # exit 1: missing operand ``` Result: the kernel package is left in `iHR` / `install reinstreq half- installed` state, `update-initramfs` never runs, no GRUB entry is generated. `/boot/vmlinuz-7.0.0-070000-generic` is present, `/boot/initrd.img-7.0.0-070000-generic` is missing, and the system cannot boot the new kernel. ## 4. Root cause The buggy pattern (from `linux-image-unsigned-*` `preinst`): ```sh if [ -d /etc/kernel/preinst.d ] || [ -d /usr/share/kernel/preinst.d ]; then DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \ --arg=$image_path /etc/kernel/preinst.d /usr/share/kernel/preinst.d fi ``` The `||` in the guard ensures the call fires as soon as *either* directory exists, and the call itself passes *both* directories as positional arguments. This violates `run-parts`' single-directory contract and has always done so; the script is broken regardless of which directories are present. The same shape occurs in `postinst` (wrapped in a heredoc that produces the trigger script `/usr/lib/linux/triggers/$version`, which is later executed via `sh "$trigger"` during trigger processing), `postrm`, and `prerm`, with the corresponding `*.d` paths. ## 5. Suggested fix Replace each two-directory `run-parts` invocation with a loop that calls `run-parts` once per directory. For the direct-invocation variant: ```diff -if [ -d /etc/kernel/preinst.d ] || [ -d /usr/share/kernel/preinst.d ]; then - DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \ - --arg=$image_path /etc/kernel/preinst.d /usr/share/kernel/preinst.d -fi +for dir in /etc/kernel/preinst.d /usr/share/kernel/preinst.d; do + if [ -d "$dir" ]; then + DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error \ + --arg="$version" --arg="$image_path" "$dir" + fi +done ``` For the heredoc-embedded variant in `postinst` (image & modules packages), the loop must go *inside* the heredoc so that the generated trigger file iterates at trigger-processing time. `$dir` must be escaped (`\$dir`) to defer expansion; `$version` / `$image_path` / `$*` should continue to expand at heredoc-write time: ```diff if [ -d /etc/kernel/postinst.d ] || [ -d /usr/share/kernel/postinst.d ]; then mkdir -p /usr/lib/linux/triggers cat - >/usr/lib/linux/triggers/$version <<EOF -DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \ - --arg=$image_path /etc/kernel/postinst.d /usr/share/kernel/postinst.d +for dir in /etc/kernel/postinst.d /usr/share/kernel/postinst.d; do + if [ -d "\$dir" ]; then + DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error \\ + --arg=$version --arg=$image_path "\$dir" + fi +done EOF dpkg-trigger --no-await linux-update-$version fi ``` Apply the equivalent change to `postrm`, `prerm`, and to the `postinst` of `linux-modules-*` and `linux-headers-*-generic`. An alternative fix — collapsing to a single invocation — does **not** work, because `run-parts` does not support multiple directories even in recent `debianutils` releases. ## 6. Workaround (for users) 1. Extract the three affected `.deb`s with `dpkg-deb -R`. 2. Patch `preinst` / `postinst` / `postrm` / `prerm` as shown above. 3. Repack with `dpkg-deb --root-owner-group -b <dir> <file>.deb` — produces `root:root`-owned archive contents without requiring `fakeroot`. 4. `sudo dpkg -i` the three patched `.deb`s plus the unaffected `linux-headers-*_all.deb`. This procedure was used to successfully install 7.0.0-070000-generic on an Ubuntu 24.04 host. Post-install: initramfs was generated, GRUB entry was added, reboot succeeds, `uname -r` reports `7.0.0-070000-generic`. ## 7. Environment where reproduced - Ubuntu 24.04 LTS - `debianutils 5.17` (source of `run-parts`) - `dpkg 1.22.x` - x86_64 / UEFI / GRUB 2.12 - Previous working kernel: `6.8.0-110-generic` Same `run-parts` semantics are documented in the `debianutils` upstream manpage at least since 2006; the constraint is not new. ## 8. References - `run-parts(8)` — debianutils - Source of the bug: maintainer scripts generated by the mainline build of v7.0 at `kernel.ubuntu.com/mainline/v7.0/` - This pattern likely regressed from an earlier, correct template that either looped over the directories or only referenced `/etc/kernel/<phase>.d`. Scripts in older mainline builds (e.g. v6.x) should be diffed against v7.0 to locate the introducing change. --- *Reported from a downstream reproduction during kernel upgrade of a QEMU golden image. Full reproduction log and patched artifacts available on request.* To manage notifications about this bug go to: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2148773/+subscriptions
Комментариев нет:
Отправить комментарий